* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 1:20 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 1:20 UTC (permalink / raw
To: gentoo-commits
commit: 1eb500455f051e89e803715f3819aea48550848d
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 01:18:02 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 01:18:02 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1eb50045
Updated the 02040_all_embedded-library-shared patch for the 5.0.92 release.
---
00000_index.txt | 7 +-
02040_all_embedded-library-shared-5.0.92.patch | 1541 ++++++++++++++++++++++++
2 files changed, 1547 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index be149dc..19cb0f8 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -267,7 +267,12 @@
# This is really a symlink to the old mysql-community version
@patch 02040_all_embedded-library-shared-5.0.83.patch
-@ver 5.0.83.00 to 5.00.99.99
+@ver 5.0.83.00 to 5.00.91.99
+@pn mysql
+@@ Take libmysqld to be a proper shared library.
+
+@patch 02040_all_embedded-library-shared-5.0.92.patch
+@ver 5.0.92.00 to 5.00.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
diff --git a/02040_all_embedded-library-shared-5.0.92.patch b/02040_all_embedded-library-shared-5.0.92.patch
new file mode 100644
index 0000000..913272b
--- /dev/null
+++ b/02040_all_embedded-library-shared-5.0.92.patch
@@ -0,0 +1,1541 @@
+Convert all of the static libraries for the embedded libmysqld to build as
+shared.
+
+This enables amarok's mysql extension to properly build as a shared object,
+without statically including libmysqld or nor forcing libmysqld to be built
+with -fPIC.
+
+Thanks to <pageexec@freemail.hu> for the @plt fixes.
+Thanks to Diego Elio Pettenò <flameeyes@gentoo.org> for all the extensive build
+system help with libtool conversions.
+
+Gentoo-Bug: 238487
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=238487
+MySQL-Bug-URL: http://bugs.mysql.com/bug.php?id=39288
+MySQL-Bug: 39288
+MySQL-Lists-URL: http://lists.mysql.com/internals/35947
+X-Patch-URL: http://bugs.gentoo.org/attachment.cgi?id=188019&action=view
+Signed-off-by: Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+
+diff -ur mysql-5.0.77-old/client/Makefile.am mysql-5.0.77/client/Makefile.am
+--- mysql-5.0.77-old/client/Makefile.am 2009-04-12 02:30:59.000000000 +0000
++++ mysql-5.0.77/client/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -37,7 +37,7 @@
+ $(top_srcdir)/mysys/my_copy.c \
+ $(top_srcdir)/mysys/my_mkdir.c
+
+-mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
++mysqltest_LDADD = $(top_builddir)/regex/libregex.la $(LDADD)
+ mysqlbinlog_SOURCES = mysqlbinlog.cc \
+ $(top_srcdir)/mysys/mf_tempdir.c \
+ $(top_srcdir)/mysys/my_new.cc
+diff -ur mysql-5.0.77-old/config/ac-macros/ha_innodb.m4 mysql-5.0.77/config/ac-macros/ha_innodb.m4
+--- mysql-5.0.77-old/config/ac-macros/ha_innodb.m4 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/config/ac-macros/ha_innodb.m4 2009-04-12 03:03:22.000000000 +0000
+@@ -25,40 +25,35 @@
+ dnl Some libs are listed several times, in order for gcc to sort out
+ dnl circular references.
+ innodb_libs="\
+- \$(top_builddir)/innobase/usr/libusr.a\
+- \$(top_builddir)/innobase/srv/libsrv.a\
+- \$(top_builddir)/innobase/dict/libdict.a\
+- \$(top_builddir)/innobase/que/libque.a\
+- \$(top_builddir)/innobase/srv/libsrv.a\
+- \$(top_builddir)/innobase/ibuf/libibuf.a\
+- \$(top_builddir)/innobase/row/librow.a\
+- \$(top_builddir)/innobase/pars/libpars.a\
+- \$(top_builddir)/innobase/btr/libbtr.a\
+- \$(top_builddir)/innobase/trx/libtrx.a\
+- \$(top_builddir)/innobase/read/libread.a\
+- \$(top_builddir)/innobase/usr/libusr.a\
+- \$(top_builddir)/innobase/buf/libbuf.a\
+- \$(top_builddir)/innobase/ibuf/libibuf.a\
+- \$(top_builddir)/innobase/eval/libeval.a\
+- \$(top_builddir)/innobase/log/liblog.a\
+- \$(top_builddir)/innobase/fsp/libfsp.a\
+- \$(top_builddir)/innobase/fut/libfut.a\
+- \$(top_builddir)/innobase/fil/libfil.a\
+- \$(top_builddir)/innobase/lock/liblock.a\
+- \$(top_builddir)/innobase/mtr/libmtr.a\
+- \$(top_builddir)/innobase/page/libpage.a\
+- \$(top_builddir)/innobase/rem/librem.a\
+- \$(top_builddir)/innobase/thr/libthr.a\
+- \$(top_builddir)/innobase/sync/libsync.a\
+- \$(top_builddir)/innobase/data/libdata.a\
+- \$(top_builddir)/innobase/mach/libmach.a\
+- \$(top_builddir)/innobase/ha/libha.a\
+- \$(top_builddir)/innobase/dyn/libdyn.a\
+- \$(top_builddir)/innobase/mem/libmem.a\
+- \$(top_builddir)/innobase/sync/libsync.a\
+- \$(top_builddir)/innobase/ut/libut.a\
+- \$(top_builddir)/innobase/os/libos.a\
+- \$(top_builddir)/innobase/ut/libut.a"
++ \$(top_builddir)/innobase/usr/libusr.la\
++ \$(top_builddir)/innobase/srv/libsrv.la\
++ \$(top_builddir)/innobase/dict/libdict.la\
++ \$(top_builddir)/innobase/que/libque.la\
++ \$(top_builddir)/innobase/ibuf/libibuf.la\
++ \$(top_builddir)/innobase/row/librow.la\
++ \$(top_builddir)/innobase/pars/libpars.la\
++ \$(top_builddir)/innobase/btr/libbtr.la\
++ \$(top_builddir)/innobase/trx/libtrx.la\
++ \$(top_builddir)/innobase/read/libread.la\
++ \$(top_builddir)/innobase/buf/libbuf.la\
++ \$(top_builddir)/innobase/eval/libeval.la\
++ \$(top_builddir)/innobase/log/liblog.la\
++ \$(top_builddir)/innobase/fsp/libfsp.la\
++ \$(top_builddir)/innobase/fut/libfut.la\
++ \$(top_builddir)/innobase/fil/libfil.la\
++ \$(top_builddir)/innobase/lock/liblock.la\
++ \$(top_builddir)/innobase/mtr/libmtr.la\
++ \$(top_builddir)/innobase/page/libpage.la\
++ \$(top_builddir)/innobase/rem/librem.la\
++ \$(top_builddir)/innobase/thr/libthr.la\
++ \$(top_builddir)/innobase/sync/libsync.la\
++ \$(top_builddir)/innobase/data/libdata.la\
++ \$(top_builddir)/innobase/mach/libmach.la\
++ \$(top_builddir)/innobase/ha/libha.la\
++ \$(top_builddir)/innobase/dyn/libdyn.la\
++ \$(top_builddir)/innobase/mem/libmem.la\
++ \$(top_builddir)/innobase/ut/libut.la\
++ \$(top_builddir)/innobase/os/libos.la"
+
+ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"])
+ ;;
+diff -ur mysql-5.0.77-old/configure.in mysql-5.0.77/configure.in
+--- mysql-5.0.77-old/configure.in 2009-04-12 02:30:59.000000000 +0000
++++ mysql-5.0.77/configure.in 2009-04-12 03:03:22.000000000 +0000
+@@ -253,7 +253,7 @@
+ fi
+
+ # Still need ranlib for readline; local static use only so no libtool.
+-AC_PROG_RANLIB
++#AC_PROG_RANLIB
+ # We use libtool
+ #AC_LIBTOOL_WIN32_DLL
+ AC_PROG_LIBTOOL
+@@ -574,6 +574,9 @@
+ # We need an ANSI C compiler
+ AM_PROG_CC_STDC
+
++# Testing as sugggested by Diego
++AM_PROG_CC_C_O
++
+ # We need an assembler, too
+ AM_PROG_AS
+ CCASFLAGS="$CCASFLAGS $ASFLAGS"
+@@ -2705,9 +2708,9 @@
+
+ if test "$THREAD_SAFE_CLIENT" = "no"
+ then
+- sql_client_dirs="strings regex mysys dbug extra libmysql client"
++ sql_client_dirs="strings regex dbug mysys extra libmysql client"
+ else
+- sql_client_dirs="strings regex mysys dbug extra libmysql libmysql_r client"
++ sql_client_dirs="strings regex dbug mysys extra libmysql libmysql_r client"
+ linked_client_targets="$linked_client_targets linked_libmysql_r_sources"
+ AC_CONFIG_FILES(libmysql_r/Makefile)
+ AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
+@@ -2736,13 +2739,11 @@
+ export CC CXX CFLAGS CXXFLAGS LD LDFLAGS AR
+ ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' CXXFLAGS='$CXXFLAGS'"
+
++AM_CONDITIONAL([NEED_THREADS], [test x"$with_server" != xno -o x"$THREAD_SAFE_CLIENT" != xno])
+ if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"
+ then
+ AC_DEFINE([THREAD], [1],
+ [Define if you want to have threaded code. This may be undef on client code])
+- # Avoid _PROGRAMS names
+- THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
+- AC_SUBST(THREAD_LOBJECTS)
+ fi
+
+ if test "$with_server" = "no"
+@@ -2750,7 +2751,7 @@
+ AM_CONDITIONAL([BUILD_INNODB_TOOLS], [false])
+ else
+ server_scripts="mysqld_safe mysql_install_db"
+- sql_server_dirs="strings mysys dbug extra regex"
++ sql_server_dirs="strings dbug mysys extra regex"
+
+
+ #
+diff -ur mysql-5.0.77-old/dbug/Makefile.am mysql-5.0.77/dbug/Makefile.am
+--- mysql-5.0.77-old/dbug/Makefile.am 2009-04-12 02:31:07.000000000 +0000
++++ mysql-5.0.77/dbug/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a
+-pkglib_LIBRARIES = libdbug.a
++LDADD = ../mysys/libmysys.la ../strings/libmystrings.la
++noinst_LTLIBRARIES = libdbug.la
+ noinst_HEADERS = dbug_long.h
+-libdbug_a_SOURCES = dbug.c sanity.c
++libdbug_la_SOURCES = dbug.c sanity.c
+ EXTRA_DIST = example1.c example2.c example3.c \
+ user.r monty.doc readme.prof dbug_add_tags.pl \
+ my_main.c main.c factorial.c dbug_analyze.c \
+@@ -31,11 +31,11 @@
+
+
+ # Must be linked with libs that are not compiled yet
+-noinst_PROGRAMS = factorial dbug_analyze
++EXTRA_PROGRAMS = factorial dbug_analyze
+ factorial_SOURCES = my_main.c factorial.c
+ dbug_analyze_SOURCES = dbug_analyze.c
+
+-all: user.t user.ps
++check-local: user.t user.ps
+
+ user.t: user.r $(NROFF_INC)
+ -nroff -mm user.r > $@
+diff -ur mysql-5.0.77-old/extra/Makefile.am mysql-5.0.77/extra/Makefile.am
+--- mysql-5.0.77-old/extra/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/extra/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,8 +15,7 @@
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ @ndbcluster_includes@ -I$(top_srcdir)/sql
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
+ $(ZLIB_LIBS)
+ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
+ $(top_builddir)/include/sql_state.h \
+diff -ur mysql-5.0.77-old/heap/Makefile.am mysql-5.0.77/heap/Makefile.am
+--- mysql-5.0.77-old/heap/Makefile.am 2009-04-12 02:30:58.000000000 +0000
++++ mysql-5.0.77/heap/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -14,14 +14,13 @@
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libheap.a ../mysys/libmysys.a ../dbug/libdbug.a \
+- ../strings/libmystrings.a
+-pkglib_LIBRARIES = libheap.a
++LDADD = libheap.la ../mysys/libmysys.la
++pkglib_LTLIBRARIES = libheap.la
+ noinst_PROGRAMS = hp_test1 hp_test2
+ hp_test1_LDFLAGS = @NOINST_LDFLAGS@
+ hp_test2_LDFLAGS = @NOINST_LDFLAGS@
+ noinst_HEADERS = heapdef.h
+-libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
++libheap_la_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
+ hp_rrnd.c hp_scan.c hp_update.c hp_write.c hp_delete.c \
+ hp_rsame.c hp_create.c hp_rename.c hp_rfirst.c \
+ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \
+diff -ur mysql-5.0.77-old/innobase/btr/Makefile.am mysql-5.0.77/innobase/btr/Makefile.am
+--- mysql-5.0.77-old/innobase/btr/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/btr/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libbtr.a
++noinst_LTLIBRARIES = libbtr.la
+
+-libbtr_a_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c
++libbtr_la_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/buf/Makefile.am mysql-5.0.77/innobase/buf/Makefile.am
+--- mysql-5.0.77-old/innobase/buf/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/buf/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libbuf.a
++noinst_LTLIBRARIES = libbuf.la
+
+-libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
++libbuf_la_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/configure.in mysql-5.0.77/innobase/configure.in
+--- mysql-5.0.77-old/innobase/configure.in 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/configure.in 2009-04-12 03:03:22.000000000 +0000
+@@ -32,7 +32,7 @@
+ CXXFLAGS="$CXXFLAGS "
+
+ AC_PROG_CC
+-AC_PROG_RANLIB
++#AC_PROG_RANLIB
+ AC_PROG_INSTALL
+ AC_PROG_LIBTOOL
+ AC_CHECK_HEADERS(aio.h sched.h)
+@@ -126,14 +126,4 @@
+ fi
+ AC_SUBST(ARFLAGS)
+
+-AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl
+- buf/Makefile data/Makefile dnl
+- dict/Makefile dyn/Makefile dnl
+- eval/Makefile fil/Makefile fsp/Makefile fut/Makefile dnl
+- ha/Makefile ibuf/Makefile include/Makefile dnl
+- lock/Makefile log/Makefile dnl
+- mach/Makefile mem/Makefile mtr/Makefile dnl
+- page/Makefile pars/Makefile que/Makefile dnl
+- read/Makefile rem/Makefile row/Makefile dnl
+- srv/Makefile sync/Makefile thr/Makefile trx/Makefile dnl
+- usr/Makefile)
++AC_OUTPUT(Makefile)
+diff -ur mysql-5.0.77-old/innobase/data/Makefile.am mysql-5.0.77/innobase/data/Makefile.am
+--- mysql-5.0.77-old/innobase/data/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/data/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdata.a
++noinst_LTLIBRARIES = libdata.la
+
+-libdata_a_SOURCES = data0data.c data0type.c
++libdata_la_SOURCES = data0data.c data0type.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/dict/Makefile.am mysql-5.0.77/innobase/dict/Makefile.am
+--- mysql-5.0.77-old/innobase/dict/Makefile.am 2009-04-12 02:31:07.000000000 +0000
++++ mysql-5.0.77/innobase/dict/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdict.a
++noinst_LTLIBRARIES = libdict.la
+
+-libdict_a_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\
++libdict_la_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\
+ dict0mem.c
+
+ EXTRA_PROGRAMS =
+diff -ur mysql-5.0.77-old/innobase/dyn/Makefile.am mysql-5.0.77/innobase/dyn/Makefile.am
+--- mysql-5.0.77-old/innobase/dyn/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/dyn/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdyn.a
++noinst_LTLIBRARIES = libdyn.la
+
+-libdyn_a_SOURCES = dyn0dyn.c
++libdyn_la_SOURCES = dyn0dyn.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/eval/Makefile.am mysql-5.0.77/innobase/eval/Makefile.am
+--- mysql-5.0.77-old/innobase/eval/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/eval/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libeval.a
++noinst_LTLIBRARIES = libeval.la
+
+-libeval_a_SOURCES = eval0eval.c eval0proc.c
++libeval_la_SOURCES = eval0eval.c eval0proc.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/fil/Makefile.am mysql-5.0.77/innobase/fil/Makefile.am
+--- mysql-5.0.77-old/innobase/fil/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/fil/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfil.a
++noinst_LTLIBRARIES = libfil.la
+
+-libfil_a_SOURCES = fil0fil.c
++libfil_la_SOURCES = fil0fil.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/fsp/Makefile.am mysql-5.0.77/innobase/fsp/Makefile.am
+--- mysql-5.0.77-old/innobase/fsp/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/fsp/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,9 +16,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfsp.a
++noinst_LTLIBRARIES = libfsp.la
+
+-libfsp_a_SOURCES = fsp0fsp.c
++libfsp_la_SOURCES = fsp0fsp.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/fut/Makefile.am mysql-5.0.77/innobase/fut/Makefile.am
+--- mysql-5.0.77-old/innobase/fut/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/fut/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfut.a
++noinst_LTLIBRARIES = libfut.la
+
+-libfut_a_SOURCES = fut0fut.c fut0lst.c
++libfut_la_SOURCES = fut0fut.c fut0lst.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/ha/Makefile.am mysql-5.0.77/innobase/ha/Makefile.am
+--- mysql-5.0.77-old/innobase/ha/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/ha/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libha.a
++noinst_LTLIBRARIES = libha.la
+
+-libha_a_SOURCES = ha0ha.c hash0hash.c
++libha_la_SOURCES = ha0ha.c hash0hash.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/ibuf/Makefile.am mysql-5.0.77/innobase/ibuf/Makefile.am
+--- mysql-5.0.77-old/innobase/ibuf/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/ibuf/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libibuf.a
++noinst_LTLIBRARIES = libibuf.la
+
+-libibuf_a_SOURCES = ibuf0ibuf.c
++libibuf_la_SOURCES = ibuf0ibuf.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/lock/Makefile.am mysql-5.0.77/innobase/lock/Makefile.am
+--- mysql-5.0.77-old/innobase/lock/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/lock/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = liblock.a
++noinst_LTLIBRARIES = liblock.la
+
+-liblock_a_SOURCES = lock0lock.c
++liblock_la_SOURCES = lock0lock.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/log/Makefile.am mysql-5.0.77/innobase/log/Makefile.am
+--- mysql-5.0.77-old/innobase/log/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/log/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = liblog.a
++noinst_LTLIBRARIES = liblog.la
+
+-liblog_a_SOURCES = log0log.c log0recv.c
++liblog_la_SOURCES = log0log.c log0recv.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/mach/Makefile.am mysql-5.0.77/innobase/mach/Makefile.am
+--- mysql-5.0.77-old/innobase/mach/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/mach/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmach.a
++noinst_LTLIBRARIES = libmach.la
+
+-libmach_a_SOURCES = mach0data.c
++libmach_la_SOURCES = mach0data.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/Makefile.am mysql-5.0.77/innobase/Makefile.am
+--- mysql-5.0.77-old/innobase/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,14 +15,35 @@
+
+ # Process this file with automake to create Makefile.in
+
+-AUTOMAKE_OPTIONS = foreign
+-TAR = gtar
+-
+ noinst_HEADERS = ib_config.h
+
+-SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \
+- ha ibuf include lock log mach mem mtr page \
+- pars que read rem row srv sync thr trx usr
++INCLUDES = -I$(srcdir)/include -I$(srcdir)/../include
++
++pkglib_LTLIBRARIES = libinnobase.la
++
++libinnobase_la_SOURCES = btr/btr0btr.c btr/btr0cur.c \
++ btr/btr0pcur.c btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \
++ buf/buf0lru.c buf/buf0rea.c data/data0data.c data/data0type.c \
++ dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c \
++ dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \
++ eval/eval0eval.c eval/eval0proc.c fil/fil0fil.c \
++ fsp/fsp0fsp.c fut/fut0fut.c fut/fut0lst.c ha/ha0ha.c \
++ ha/hash0hash.c ibuf/ibuf0ibuf.c lock/lock0lock.c \
++ log/log0log.c log/log0recv.c mach/mach0data.c \
++ mem/mem0mem.c mem/mem0pool.c mtr/mtr0mtr.c mtr/mtr0log.c \
++ os/os0proc.c os/os0sync.c os/os0thread.c os/os0file.c \
++ page/page0page.c page/page0cur.c pars/pars0grm.c pars/lexyy.c \
++ pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c \
++ que/que0que.c read/read0read.c rem/rem0rec.c rem/rem0cmp.c \
++ row/row0ins.c row/row0mysql.c row/row0purge.c row/row0row.c \
++ row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c \
++ row/row0upd.c row/row0vers.c srv/srv0srv.c srv/srv0que.c \
++ srv/srv0start.c sync/sync0arr.c sync/sync0rw.c \
++ sync/sync0sync.c thr/thr0loc.c trx/trx0purge.c \
++ trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c \
++ trx/trx0trx.c trx/trx0undo.c usr/usr0sess.c ut/ut0byte.c \
++ ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c
++
+ EXTRA_DIST = CMakeLists.txt
+
+ # Don't update the files from bitkeeper
+diff -ur mysql-5.0.77-old/innobase/mem/Makefile.am mysql-5.0.77/innobase/mem/Makefile.am
+--- mysql-5.0.77-old/innobase/mem/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/mem/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmem.a
++noinst_LTLIBRARIES = libmem.la
+
+-libmem_a_SOURCES = mem0mem.c mem0pool.c
++libmem_la_SOURCES = mem0mem.c mem0pool.c
+
+ EXTRA_DIST = mem0dbg.c
+
+diff -ur mysql-5.0.77-old/innobase/mtr/Makefile.am mysql-5.0.77/innobase/mtr/Makefile.am
+--- mysql-5.0.77-old/innobase/mtr/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/mtr/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmtr.a
++noinst_LTLIBRARIES = libmtr.la
+
+-libmtr_a_SOURCES = mtr0mtr.c mtr0log.c
++libmtr_la_SOURCES = mtr0mtr.c mtr0log.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/os/Makefile.am mysql-5.0.77/innobase/os/Makefile.am
+--- mysql-5.0.77-old/innobase/os/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/os/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libos.a
++noinst_LTLIBRARIES = libos.la
+
+-libos_a_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c
++libos_la_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/page/Makefile.am mysql-5.0.77/innobase/page/Makefile.am
+--- mysql-5.0.77-old/innobase/page/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/page/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libpage.a
++noinst_LTLIBRARIES = libpage.la
+
+-libpage_a_SOURCES = page0page.c page0cur.c
++libpage_la_SOURCES = page0page.c page0cur.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/pars/Makefile.am mysql-5.0.77/innobase/pars/Makefile.am
+--- mysql-5.0.77-old/innobase/pars/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/pars/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,11 +15,11 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libpars.a
++noinst_LTLIBRARIES = libpars.la
+
+ noinst_HEADERS = pars0grm.h
+
+-libpars_a_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c
++libpars_la_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/que/Makefile.am mysql-5.0.77/innobase/que/Makefile.am
+--- mysql-5.0.77-old/innobase/que/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/que/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libque.a
++noinst_LTLIBRARIES = libque.la
+
+-libque_a_SOURCES = que0que.c
++libque_la_SOURCES = que0que.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/read/Makefile.am mysql-5.0.77/innobase/read/Makefile.am
+--- mysql-5.0.77-old/innobase/read/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/read/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libread.a
++noinst_LTLIBRARIES = libread.la
+
+-libread_a_SOURCES = read0read.c
++libread_la_SOURCES = read0read.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/rem/Makefile.am mysql-5.0.77/innobase/rem/Makefile.am
+--- mysql-5.0.77-old/innobase/rem/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/rem/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = librem.a
++noinst_LTLIBRARIES = librem.la
+
+-librem_a_SOURCES = rem0rec.c rem0cmp.c
++librem_la_SOURCES = rem0rec.c rem0cmp.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/row/Makefile.am mysql-5.0.77/innobase/row/Makefile.am
+--- mysql-5.0.77-old/innobase/row/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/row/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = librow.a
++noinst_LTLIBRARIES = librow.la
+
+-librow_a_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\
++librow_la_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\
+ row0uins.c row0umod.c row0undo.c row0upd.c row0vers.c
+
+ EXTRA_PROGRAMS =
+diff -ur mysql-5.0.77-old/innobase/srv/Makefile.am mysql-5.0.77/innobase/srv/Makefile.am
+--- mysql-5.0.77-old/innobase/srv/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/srv/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libsrv.a
++noinst_LTLIBRARIES = libsrv.la
+
+-libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c
++libsrv_la_SOURCES = srv0srv.c srv0que.c srv0start.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/sync/Makefile.am mysql-5.0.77/innobase/sync/Makefile.am
+--- mysql-5.0.77-old/innobase/sync/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/sync/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libsync.a
++noinst_LTLIBRARIES = libsync.la
+
+-libsync_a_SOURCES = sync0arr.c sync0rw.c sync0sync.c
++libsync_la_SOURCES = sync0arr.c sync0rw.c sync0sync.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/thr/Makefile.am mysql-5.0.77/innobase/thr/Makefile.am
+--- mysql-5.0.77-old/innobase/thr/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/thr/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libthr.a
++noinst_LTLIBRARIES = libthr.la
+
+-libthr_a_SOURCES = thr0loc.c
++libthr_la_SOURCES = thr0loc.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/trx/Makefile.am mysql-5.0.77/innobase/trx/Makefile.am
+--- mysql-5.0.77-old/innobase/trx/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/trx/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libtrx.a
++noinst_LTLIBRARIES = libtrx.la
+
+-libtrx_a_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\
++libtrx_la_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\
+ trx0sys.c trx0trx.c trx0undo.c
+
+ EXTRA_PROGRAMS =
+diff -ur mysql-5.0.77-old/innobase/usr/Makefile.am mysql-5.0.77/innobase/usr/Makefile.am
+--- mysql-5.0.77-old/innobase/usr/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/usr/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libusr.a
++noinst_LTLIBRARIES = libusr.la
+
+-libusr_a_SOURCES = usr0sess.c
++libusr_la_SOURCES = usr0sess.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/innobase/ut/Makefile.am mysql-5.0.77/innobase/ut/Makefile.am
+--- mysql-5.0.77-old/innobase/ut/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/innobase/ut/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libut.a
++noinst_LTLIBRARIES = libut.la
+
+-libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c
++libut_la_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c
+
+ EXTRA_PROGRAMS =
+
+diff -ur mysql-5.0.77-old/libmysql/Makefile.am mysql-5.0.77/libmysql/Makefile.am
+--- mysql-5.0.77-old/libmysql/Makefile.am 2009-04-12 02:30:59.000000000 +0000
++++ mysql-5.0.77/libmysql/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -106,8 +106,8 @@
+ echo "# This file is autogenerated from Makefile.am" >> $$dir/Makefile; \
+ echo 'CFLAGS= -I. -DUNDEF_THREADS_HACK' >>$$dir/Makefile; \
+ echo "obj=$$objs" >>$$dir/Makefile; \
+- echo 'all: libmysql.a' >>$$dir/Makefile; \
+- echo 'libmysql.a: $$(obj)' >>$$dir/Makefile; \
++ echo 'all: libmysql.la' >>$$dir/Makefile; \
++ echo 'libmysql.la: $$(obj)' >>$$dir/Makefile; \
+ echo ' $$(AR) r $$@ $$?' >>$$dir/Makefile; \
+ gtar cvzf $$dir.tar.gz $$dir; \
+ cd $$dir; gmake
+diff -ur mysql-5.0.77-old/libmysqld/examples/Makefile.am mysql-5.0.77/libmysqld/examples/Makefile.am
+--- mysql-5.0.77-old/libmysqld/examples/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/libmysqld/examples/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -35,12 +35,12 @@
+ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
+ $(openssl_includes)
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.la @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
+ @NDB_SCI_LIBS@
+
+ mysqltest_embedded_LINK = $(CXXLINK)
+ mysqltest_embedded_SOURCES = mysqltest.c
+-mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a
++mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.la
+
+ mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+ my_readline.h sql_string.h completion_hash.h
+diff -ur mysql-5.0.77-old/libmysqld/Makefile.am mysql-5.0.77/libmysqld/Makefile.am
+--- mysql-5.0.77-old/libmysqld/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/libmysqld/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -32,10 +32,10 @@
+ -I$(top_srcdir)/regex \
+ $(openssl_includes) @ZLIB_INCLUDES@
+
+-noinst_LIBRARIES = libmysqld_int.a
+-pkglib_LIBRARIES = libmysqld.a
++noinst_LTLIBRARIES = libmysqld_int.la
++pkglib_LTLIBRARIES = libmysqld.la
+ SUBDIRS = . examples
+-libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
++#libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
+ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
+ my_time.c
+ sqlexamplessources = ha_example.cc ha_tina.cc
+@@ -67,50 +67,22 @@
+ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
+ ha_blackhole.cc ha_archive.cc my_user.c
+
+-libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources)
+-libmysqld_a_SOURCES=
++libmysqld_int_la_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources)
++#libmysqld_la_SOURCES=
++libmysqld_la_SOURCES= libmysqld.c lib_sql.cc emb_qcache.cc
+
+ # automake misses these
+ sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
+
+-# The following libraries should be included in libmysqld.a
+-INC_LIB= $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/myisam/libmyisam.a \
+- $(top_builddir)/myisammrg/libmyisammrg.a \
+- $(top_builddir)/heap/libheap.a \
+- @innodb_libs@ @bdb_libs_with_path@ \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/vio/libvio.a @NDB_SCI_LIBS@
+-
+-
+-#
+-# 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 `echo $(INC_LIB) | sort -u`
+-else
+- -rm -f libmysqld.a
+- if test "$(host_os)" = "netware" ; \
+- then \
+- $(libmysqld_a_AR) libmysqld.a libmysqld_int.a $(INC_LIB) ; \
+- else \
+- 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
++# The following libraries should be included in libmysqld.la
++libmysqld_la_LIBADD= $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/myisam/libmyisam.la \
++ $(top_builddir)/myisammrg/libmyisammrg.la \
++ $(top_builddir)/heap/libheap.la \
++ $(top_builddir)/innobase/libinnobase.la @bdb_libs_with_path@ \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/vio/libvio.la @NDB_SCI_LIBS@ \
++ libmysqld_int.la
+
+ ## XXX: any time the client interface changes, we'll need to bump
+ ## the version info for libmysqld; however, it's possible for the
+diff -ur mysql-5.0.77-old/myisam/Makefile.am mysql-5.0.77/myisam/Makefile.am
+--- mysql-5.0.77-old/myisam/Makefile.am 2009-04-12 02:30:58.000000000 +0000
++++ mysql-5.0.77/myisam/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,27 +16,27 @@
+ EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt
+ pkgdata_DATA = mi_test_all mi_test_all.res
+
+-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-pkglib_LIBRARIES = libmyisam.a
++INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
++ -I$(top_builddir)/sql -I$(top_srcdir)/sql
++LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(ZLIB_LIBS)
++noinst_LTLIBRARIES = libmyisam.la
+ bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
+-myisamchk_DEPENDENCIES= $(LIBRARIES)
+-myisamlog_DEPENDENCIES= $(LIBRARIES)
+-myisampack_DEPENDENCIES=$(LIBRARIES)
++myisamchk_DEPENDENCIES= $(LTLIBRARIES)
++myisamlog_DEPENDENCIES= $(LTLIBRARIES)
++myisampack_DEPENDENCIES=$(LTLIBRARIES)
+ noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
+ noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
+-mi_test1_DEPENDENCIES= $(LIBRARIES)
+-mi_test2_DEPENDENCIES= $(LIBRARIES)
+-mi_test3_DEPENDENCIES= $(LIBRARIES)
+-#ft_test1_DEPENDENCIES= $(LIBRARIES)
+-#ft_eval_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
+-rt_test_DEPENDENCIES= $(LIBRARIES)
+-sp_test_DEPENDENCIES= $(LIBRARIES)
+-libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
++mi_test1_DEPENDENCIES= $(LTLIBRARIES)
++mi_test2_DEPENDENCIES= $(LTLIBRARIES)
++mi_test3_DEPENDENCIES= $(LTLIBRARIES)
++#ft_test1_DEPENDENCIES= $(LTLIBRARIES)
++#ft_eval_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_DEPENDENCIES= $(LTLIBRARIES)
++rt_test_DEPENDENCIES= $(LTLIBRARIES)
++sp_test_DEPENDENCIES= $(LTLIBRARIES)
++libmyisam_la_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
+ mi_rnext.c mi_rnext_same.c \
+ mi_search.c mi_page.c mi_key.c mi_locking.c \
+ mi_rrnd.c mi_scan.c mi_cache.c \
+diff -ur mysql-5.0.77-old/myisammrg/Makefile.am mysql-5.0.77/myisammrg/Makefile.am
+--- mysql-5.0.77-old/myisammrg/Makefile.am 2009-04-12 02:31:07.000000000 +0000
++++ mysql-5.0.77/myisammrg/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -14,9 +14,9 @@
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmyisammrg.a
++noinst_LTLIBRARIES = libmyisammrg.la
+ noinst_HEADERS = myrg_def.h
+-libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
++libmyisammrg_la_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
+ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
+ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
+ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
+diff -ur mysql-5.0.77-old/mysys/Makefile.am mysql-5.0.77/mysys/Makefile.am
+--- mysql-5.0.77-old/mysys/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/mysys/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -18,11 +18,9 @@
+ MYSQLBASEdir= $(prefix)
+ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include -I$(srcdir)
+-pkglib_LIBRARIES = libmysys.a
+-LDADD = libmysys.a ../dbug/libdbug.a \
+- ../strings/libmystrings.a
++pkglib_LTLIBRARIES = libmysys.la
+ noinst_HEADERS = mysys_priv.h my_static.h
+-libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
++libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
+ mf_path.c mf_loadpath.c my_file.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
+ my_pread.c my_write.c my_getpagesize.c \
+@@ -49,21 +47,26 @@
+ my_quick.c my_lockmem.c my_static.c \
+ my_sync.c my_getopt.c my_mkdir.c \
+ default_modify.c default.c \
+- my_compress.c checksum.c raid.cc \
++ my_compress.c checksum.c raid.cc \
+ my_net.c my_port.c my_sleep.c \
+ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
+ my_gethostbyname.c rijndael.c my_aes.c sha1.c \
+ my_handler.c my_netware.c my_largepage.c \
+- my_memmem.c \
+- my_windac.c my_access.c base64.c my_libwrap.c
++ my_memmem.c my_windac.c my_access.c base64.c \
++ my_libwrap.c
++libmysys_la_LIBADD = $(top_builddir)/dbug/libdbug.la $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
++if NEED_THREADS
++libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c my_pthread.c my_thr_init.c
++endif
++
+ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
+ thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \
+ my_wincond.c my_winthread.c CMakeLists.txt
+-libmysys_a_LIBADD = @THREAD_LOBJECTS@
+-# test_dir_DEPENDENCIES= $(LIBRARIES)
+-# testhash_DEPENDENCIES= $(LIBRARIES)
+-# test_charset_DEPENDENCIES= $(LIBRARIES)
+-# charset2html_DEPENDENCIES= $(LIBRARIES)
++# test_dir_DEPENDENCIES= $(LTLIBRARIES)
++# testhash_DEPENDENCIES= $(LTLIBRARIES)
++# test_charset_DEPENDENCIES= $(LTLIBRARIES)
++# charset2html_DEPENDENCIES= $(LTLIBRARIES)
+ EXTRA_PROGRAMS =
+ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
+ -DDATADIR="\"$(MYSQLDATAdir)\"" \
+@@ -74,8 +77,6 @@
+ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ @DEFS@
+
+-libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
+-
+ # I hope this always does the right thing. Otherwise this is only test programs
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+@@ -84,41 +85,41 @@
+ # which automaticly removes the object files you use to compile a final program
+ #
+
+-test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
++test_thr_alarm$(EXEEXT): thr_alarm.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_alarm.c
+
+-test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
++test_thr_lock$(EXEEXT): thr_lock.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_lock.c test_thr_lock.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_lock.c
+
+-test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
++test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
+ $(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
+ $(RM) -f test_vsnprintf.c
+
+-test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
++test_io_cache$(EXEEXT): mf_iocache.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.c
+
+-test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
++test_dir$(EXEEXT): test_dir.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
+
+-test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
++test_charset$(EXEEXT): test_charset.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
+
+-testhash$(EXEEXT): testhash.c $(LIBRARIES)
++testhash$(EXEEXT): testhash.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
+
+-test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
++test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
+ $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_gethwaddr.c
+
+-test_base64$(EXEEXT): base64.c $(LIBRARIES)
++test_base64$(EXEEXT): base64.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/base64.c ./test_base64.c
+ $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_base64.c
+diff -ur mysql-5.0.77-old/netware/Makefile.am mysql-5.0.77/netware/Makefile.am
+--- mysql-5.0.77-old/netware/Makefile.am 2009-04-12 02:30:58.000000000 +0000
++++ mysql-5.0.77/netware/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,14 +16,13 @@
+
+ if HAVE_NETWARE
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I..
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la
+ bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
+ mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
+ mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
+ mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
+ libmysql_SOURCES= libmysqlmain.c
+-libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a \
++libmysql_LDADD = ../libmysql/.libs/libmysqlclient.la \
+ @openssl_libs@ @yassl_libs@
+
+ netware_build_files = client/mysql.def client/mysqladmin.def \
+diff -ur mysql-5.0.77-old/pstack/Makefile.am mysql-5.0.77/pstack/Makefile.am
+--- mysql-5.0.77-old/pstack/Makefile.am 2009-04-12 02:30:57.000000000 +0000
++++ mysql-5.0.77/pstack/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -27,8 +27,8 @@
+ EXTRA_DIST= $(SRC)
+
+ if COMPILE_PSTACK
+-pkglib_LIBRARIES = libpstack.a
+-libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
++pkglib_LTLIBRARIES = libpstack.la
++libpstack_la_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
+ endif
+
+ # Don't update the files from bitkeeper
+diff -ur mysql-5.0.77-old/regex/Makefile.am mysql-5.0.77/regex/Makefile.am
+--- mysql-5.0.77-old/regex/Makefile.am 2009-04-12 02:30:58.000000000 +0000
++++ mysql-5.0.77/regex/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-noinst_LIBRARIES = libregex.a
+-LDADD= libregex.a $(top_builddir)/strings/libmystrings.a
++noinst_LTLIBRARIES = libregex.la
++LDADD= libregex.la $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
+-libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
++libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
+ noinst_PROGRAMS = re
+ re_SOURCES = split.c debug.c main.c
+ re_LDFLAGS= @NOINST_LDFLAGS@
+diff -ur mysql-5.0.77-old/server-tools/instance-manager/Makefile.am mysql-5.0.77/server-tools/instance-manager/Makefile.am
+--- mysql-5.0.77-old/server-tools/instance-manager/Makefile.am 2009-04-12 02:30:59.000000000 +0000
++++ mysql-5.0.77/server-tools/instance-manager/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -24,8 +24,7 @@
+ # default_options.h, generated from default_options.h.in)
+ # See automake/autoconf docs for details
+
+-noinst_LTLIBRARIES= liboptions.la
+-noinst_LIBRARIES= libnet.a
++noinst_LTLIBRARIES= liboptions.la libnet.la
+
+ liboptions_la_CXXFLAGS= $(CXXFLAGS) \
+ -DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
+@@ -37,17 +36,17 @@
+ -DPROTOCOL_VERSION=@PROTOCOL_VERSION@
+
+ liboptions_la_SOURCES= options.h options.cc priv.h priv.cc
+-liboptions_la_LIBADD= $(top_builddir)/libmysql/get_password.lo
++
++liboptions_la_LIBADD= $(top_builddir)/libmysql/libmysqlclient.la
+
+ # MySQL sometimes uses symlinks to reuse code
+ # All symlinked files are grouped in libnet.a
+
+-nodist_libnet_a_SOURCES= net_serv.cc client_settings.h
+-libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \
+- $(top_builddir)/sql/pack.$(OBJEXT) \
+- $(top_builddir)/sql/sql_state.$(OBJEXT) \
+- $(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
+- $(top_builddir)/sql/client.$(OBJEXT)
++nodist_libnet_la_SOURCES= net_serv.cc client_settings.h \
++ $(srcdir)/../../sql/password.c $(srcdir)/../../sql/pack.c \
++ $(srcdir)/../../sql/sql_state.c $(srcdir)/../../sql/mini_client_errors.c \
++ $(srcdir)/../../sql/client.c
++
+
+ CLEANFILES= net_serv.cc client_settings.h
+
+@@ -79,11 +78,11 @@
+ portability.h
+
+ mysqlmanager_LDADD= liboptions.la \
+- libnet.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
++ libnet.la \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+
+
+diff -ur mysql-5.0.77-old/sql/Makefile.am mysql-5.0.77/sql/Makefile.am
+--- mysql-5.0.77-old/sql/Makefile.am 2009-04-12 02:30:57.000000000 +0000
++++ mysql-5.0.77/sql/Makefile.am 2009-04-12 05:04:23.000000000 +0000
+@@ -22,25 +22,24 @@
+ @bdb_includes@ @innodb_includes@ @ndbcluster_includes@ \
+ -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_srcdir)/regex -I$(srcdir) \
+- $(openssl_includes)
++ $(openssl_includes)
+ WRAPLIBS= @WRAPLIBS@
+ SUBDIRS = share
+ libexec_PROGRAMS = mysqld
+ EXTRA_PROGRAMS = gen_lex_hash
+ bin_PROGRAMS = mysql_tzinfo_to_sql
+ gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
+-LDADD = $(top_builddir)/myisam/libmyisam.a \
+- $(top_builddir)/myisammrg/libmyisammrg.a \
+- $(top_builddir)/heap/libheap.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ @NDB_SCI_LIBS@
+-
+-mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
+- @bdb_libs@ @innodb_libs@ @pstack_libs@ \
+- @innodb_system_libs@ \
++LDADD = $(top_builddir)/myisam/libmyisam.la \
++ $(top_builddir)/myisammrg/libmyisammrg.la \
++ $(top_builddir)/heap/libheap.la \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/regex/libregex.la \
++ @ZLIB_LIBS@ @NDB_SCI_LIBS@
++
++mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
++ @bdb_libs@ $(top_builddir)/innobase/libinnobase.la \
++ @pstack_libs@ @innodb_system_libs@ \
+ @ndbcluster_libs@ @ndbcluster_system_libs@ \
+ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
+ $(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
+@@ -52,45 +51,36 @@
+ procedure.h sql_class.h sql_lex.h sql_list.h \
+ sql_manager.h sql_map.h sql_string.h unireg.h \
+ sql_error.h field.h handler.h mysqld_suffix.h \
+- sql_profile.h \
+- ha_myisammrg.h\
+- ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
+- ha_ndbcluster.h ha_ndbcluster_cond.h \
+- opt_range.h protocol.h \
+- sql_select.h structs.h table.h sql_udf.h hash_filo.h\
+- lex.h lex_symbol.h sql_acl.h sql_crypt.h \
+- log_event.h sql_repl.h slave.h \
+- stacktrace.h sql_sort.h sql_cache.h set_var.h \
+- spatial.h gstream.h client_settings.h tzfile.h \
+- tztime.h my_decimal.h\
++ sql_profile.h ha_heap.h ha_berkeley.h ha_innodb.h \
++ ha_ndbcluster.h ha_ndbcluster_cond.h opt_range.h \
++ protocol.h sql_select.h structs.h table.h sql_udf.h \
++ hash_filo.h lex.h lex_symbol.h sql_acl.h sql_crypt.h \
++ log_event.h sql_repl.h slave.h stacktrace.h sql_sort.h \
++ sql_cache.h set_var.h spatial.h gstream.h \
++ client_settings.h tzfile.h tztime.h my_decimal.h \
+ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
+- parse_file.h sql_view.h sql_trigger.h \
+- sql_array.h sql_cursor.h \
+- examples/ha_example.h ha_archive.h \
+- examples/ha_tina.h ha_blackhole.h \
++ parse_file.h sql_view.h sql_trigger.h \
++ sql_array.h sql_cursor.h examples/ha_example.h \
++ ha_archive.h examples/ha_tina.h ha_blackhole.h \
+ ha_federated.h
+-mysqld_SOURCES = sql_lex.cc sql_handler.cc \
+- item.cc item_sum.cc item_buff.cc item_func.cc \
+- item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
+- thr_malloc.cc item_create.cc item_subselect.cc \
+- item_row.cc item_geofunc.cc \
+- field.cc strfunc.cc key.cc sql_class.cc sql_list.cc \
+- net_serv.cc protocol.cc sql_state.c \
+- lock.cc my_lock.c \
+- sql_string.cc sql_manager.cc sql_map.cc \
+- mysqld.cc password.c hash_filo.cc hostname.cc \
+- set_var.cc sql_parse.cc sql_yacc.yy \
+- sql_base.cc table.cc sql_select.cc sql_insert.cc \
+- sql_prepare.cc sql_error.cc sql_locale.cc \
+- sql_profile.cc \
+- sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
+- procedure.cc item_uniq.cc sql_test.cc \
+- log.cc log_event.cc init.cc derror.cc sql_acl.cc \
+- unireg.cc des_key_file.cc \
+- discover.cc time.cc opt_range.cc opt_sum.cc \
+- records.cc filesort.cc handler.cc \
+- ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
+- ha_berkeley.cc ha_innodb.cc \
++mysqld_SOURCES = sql_lex.cc sql_handler.cc item.cc item_sum.cc \
++ item_buff.cc item_func.cc item_cmpfunc.cc \
++ item_strfunc.cc item_timefunc.cc thr_malloc.cc \
++ item_create.cc item_subselect.cc item_row.cc \
++ item_geofunc.cc field.cc strfunc.cc key.cc \
++ sql_class.cc sql_list.cc net_serv.cc protocol.cc \
++ sql_state.c lock.cc my_lock.c sql_string.cc \
++ sql_manager.cc sql_map.cc mysqld.cc password.c \
++ hash_filo.cc hostname.cc set_var.cc sql_parse.cc \
++ sql_yacc.yy sql_base.cc table.cc sql_select.cc \
++ sql_insert.cc sql_prepare.cc sql_error.cc \
++ sql_locale.cc sql_profile.cc sql_update.cc \
++ sql_delete.cc uniques.cc sql_do.cc procedure.cc \
++ item_uniq.cc sql_test.cc log.cc log_event.cc \
++ init.cc derror.cc sql_acl.cc unireg.cc \
++ des_key_file.cc discover.cc time.cc opt_range.cc \
++ opt_sum.cc records.cc filesort.cc handler.cc \
++ ha_heap.cc ha_berkeley.cc ha_innodb.cc \
+ ha_ndbcluster.cc ha_ndbcluster_cond.cc \
+ sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
+ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
+@@ -98,14 +88,13 @@
+ slave.cc sql_repl.cc sql_union.cc sql_derived.cc \
+ client.c sql_client.cc mini_client_errors.c pack.c\
+ stacktrace.c repl_failsafe.h repl_failsafe.cc \
+- sql_olap.cc sql_view.cc \
+- gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
+- tztime.cc my_time.c my_user.c my_decimal.cc\
+- sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
+- sp_cache.cc parse_file.cc sql_trigger.cc \
+- examples/ha_example.cc ha_archive.cc \
+- examples/ha_tina.cc ha_blackhole.cc \
+- ha_federated.cc
++ sql_olap.cc sql_view.cc gstream.cc spatial.cc \
++ sql_help.cc sql_cursor.cc tztime.cc my_time.c \
++ my_user.c my_decimal.cc sp_head.cc sp_pcontext.cc \
++ sp_rcontext.cc sp.cc sp_cache.cc parse_file.cc \
++ sql_trigger.cc examples/ha_example.cc ha_archive.cc \
++ examples/ha_tina.cc ha_blackhole.cc ha_federated.cc \
++ ha_myisam.cc ha_myisammrg.cc
+
+ gen_lex_hash_SOURCES = gen_lex_hash.cc
+ gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
+diff -ur mysql-5.0.77-old/strings/Makefile.am mysql-5.0.77/strings/Makefile.am
+--- mysql-5.0.77-old/strings/Makefile.am 2009-04-12 02:30:57.000000000 +0000
++++ mysql-5.0.77/strings/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,7 +16,7 @@
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmystrings.a
++noinst_LTLIBRARIES = libmystrings.la
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+@@ -37,7 +37,7 @@
+ endif
+ endif
+
+-libmystrings_a_SOURCES = $(ASRCS) $(CSRCS)
++libmystrings_la_SOURCES = $(ASRCS) $(CSRCS)
+ noinst_PROGRAMS = conf_to_src
+ # Default charset definitions
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+@@ -54,25 +54,25 @@
+ strnmov-sparc.s strstr-sparc.s strxmov-sparc.s \
+ t_ctype.h CMakeLists.txt
+
+-libmystrings_a_LIBADD=
+-conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c
+-conf_to_src_LDADD=
++libmystrings_la_LIBADD=
++conf_to_src_SOURCES = conf_to_src.c
++conf_to_src_LDADD = libmystrings.la
+ #force static linking of conf_to_src - essential when linking against
+ #custom installation of libc
+-conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
++#conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+
+ # This is because the dependency tracking misses @FOO@ vars in sources.
+ #strtoull.o: @CHARSET_OBJS@
+
+
+-FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
++FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+
+-str_test: str_test.c $(pkglib_LIBRARIES)
+- $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LIBRARIES)
++str_test: str_test.c $(pkglib_LTLIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LTLIBRARIES)
+
+-test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES)
++test_decimal$(EXEEXT): decimal.c $(pkglib_LTLIBRARIES)
+ $(CP) $(srcdir)/decimal.c ./test_decimal.c
+- $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LTLIBRARIES)
+ $(RM) -f ./test_decimal.c
+
+ # Don't update the files from bitkeeper
+diff -ur mysql-5.0.77-old/strings/strings-x86.s mysql-5.0.77/strings/strings-x86.s
+--- mysql-5.0.77-old/strings/strings-x86.s 2009-04-12 02:30:57.000000000 +0000
++++ mysql-5.0.77/strings/strings-x86.s 2009-04-12 03:03:22.000000000 +0000
+@@ -293,7 +293,7 @@
+ movl %esp,%ebp
+ pushl 12(%ebp) # search
+ pushl 8(%ebp) # str
+- call strstr
++ call strstr@plt
+ add $8,%esp
+ or %eax,%eax
+ jz si_99 # Not found, return NULL
+diff -ur mysql-5.0.77-old/tests/Makefile.am mysql-5.0.77/tests/Makefile.am
+--- mysql-5.0.77-old/tests/Makefile.am 2009-04-12 02:31:04.000000000 +0000
++++ mysql-5.0.77/tests/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -42,11 +42,11 @@
+
+ insert_test_SOURCES= insert_test.c
+ select_test_SOURCES= select_test.c
+-insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+-select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++insert_test_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
++select_test_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+
+ bug25714_SOURCES= bug25714.c
+-bug25714_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++bug25714_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+
+ # Fix for mit-threads
+ DEFS = -DUNDEF_THREADS_HACK
+diff -ur mysql-5.0.77-old/tools/Makefile.am mysql-5.0.77/tools/Makefile.am
+--- mysql-5.0.77-old/tools/Makefile.am 2009-04-12 02:30:58.000000000 +0000
++++ mysql-5.0.77/tools/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -23,7 +23,7 @@
+
+ bin_PROGRAMS= mysqltestmanager
+ mysqltestmanager_SOURCES= mysqlmanager.c
+-mysqltestmanager_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++mysqltestmanager_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+ DEF= -DUNDEF_THREADS_HACK
+
+ # Don't update the files from bitkeeper
+diff -ur mysql-5.0.77-old/vio/Makefile.am mysql-5.0.77/vio/Makefile.am
+--- mysql-5.0.77-old/vio/Makefile.am 2009-04-12 02:30:59.000000000 +0000
++++ mysql-5.0.77/vio/Makefile.am 2009-04-12 03:03:22.000000000 +0000
+@@ -16,11 +16,12 @@
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ $(openssl_includes)
+ LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs)
+-pkglib_LIBRARIES = libvio.a
++pkglib_LTLIBRARIES = libvio.la
+
+ noinst_HEADERS = vio_priv.h
+
+-libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
++libvio_la_LIBADD = -lssl
++libvio_la_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
+
+ EXTRA_DIST= CMakeLists.txt
+
+diff -Nuar mysql.orig/ndb/src/common/util/Makefile.am mysql/ndb/src/common/util/Makefile.am
+--- mysql.orig/ndb/src/common/util/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/common/util/Makefile.am 2009-04-11 16:36:38.520666040 -0700
+@@ -31,9 +31,9 @@
+ testBitmask_SOURCES = testBitmask.cpp
+ testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testBitmask.cpp : Bitmask.cpp
+ rm -f testBitmask.cpp
+diff -Nuar mysql.orig/ndb/src/cw/cpcd/Makefile.am mysql/ndb/src/cw/cpcd/Makefile.am
+--- mysql.orig/ndb/src/cw/cpcd/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/cw/cpcd/Makefile.am 2009-04-11 16:36:32.185153480 -0700
+@@ -19,9 +19,9 @@
+
+ LDADD_LOC = \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ include $(top_srcdir)/ndb/config/common.mk.am
+ include $(top_srcdir)/ndb/config/type_util.mk.am
+diff -Nuar mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.am mysql/ndb/src/kernel/blocks/dbdict/Makefile.am
+--- mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/kernel/blocks/dbdict/Makefile.am 2009-04-11 16:37:40.586744073 -0700
+@@ -26,9 +26,9 @@
+ LDADD += \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+diff -Nuar mysql.orig/ndb/src/kernel/Makefile.am mysql/ndb/src/kernel/Makefile.am
+--- mysql.orig/ndb/src/kernel/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/kernel/Makefile.am 2009-04-11 16:37:20.953412135 -0700
+@@ -66,9 +66,9 @@
+ $(top_builddir)/ndb/src/mgmapi/libmgmapi.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+diff -Nuar mysql.orig/ndb/src/mgmclient/Makefile.am mysql/ndb/src/mgmclient/Makefile.am
+--- mysql.orig/ndb/src/mgmclient/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/mgmclient/Makefile.am 2009-04-11 16:36:16.280363648 -0700
+@@ -37,9 +37,9 @@
+ ../common/portlib/libportlib.la \
+ @readline_link@ \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @TERMCAP_LIB@ @NDB_SCI_LIBS@
+
+ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+diff -Nuar mysql.orig/ndb/src/mgmsrv/Makefile.am mysql/ndb/src/mgmsrv/Makefile.am
+--- mysql.orig/ndb/src/mgmsrv/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/src/mgmsrv/Makefile.am 2009-04-11 16:36:22.920358437 -0700
+@@ -40,9 +40,9 @@
+
+ LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CommandInterpreter.lo \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @readline_link@ \
+ @NDB_SCI_LIBS@ \
+ @TERMCAP_LIB@
+diff -Nuar mysql.orig/ndb/test/run-test/Makefile.am mysql/ndb/test/run-test/Makefile.am
+--- mysql.orig/ndb/test/run-test/Makefile.am 2009-04-11 16:31:18.000000000 -0700
++++ mysql/ndb/test/run-test/Makefile.am 2009-04-11 16:36:07.367509286 -0700
+@@ -32,9 +32,9 @@
+ INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include
+ LDADD_LOC = $(top_builddir)/ndb/test/src/libNDBT.a \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ wrappersdir=$(prefix)/bin
+ wrappers_SCRIPTS=atrt-testBackup atrt-mysql-test-run
+diff -Nuar mysql.orig/ndb/config/type_ndbapitest.mk.am mysql/ndb/config/type_ndbapitest.mk.am
+--- mysql.orig/ndb/config/type_ndbapitest.mk.am 2009-01-15 09:47:06.000000000 -0800
++++ mysql/ndb/config/type_ndbapitest.mk.am 2009-04-11 16:44:10.268399273 -0700
+@@ -15,9 +15,9 @@
+
+ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ INCLUDES += -I$(top_srcdir) \
+ -I$(top_builddir)/include \
+diff -Nuar mysql.orig/ndb/config/type_ndbapitools.mk.am mysql/ndb/config/type_ndbapitools.mk.am
+--- mysql.orig/ndb/config/type_ndbapitools.mk.am 2009-01-15 09:47:06.000000000 -0800
++++ mysql/ndb/config/type_ndbapitools.mk.am 2009-04-11 16:44:04.156084503 -0700
+@@ -15,9 +15,9 @@
+
+ LDADD += \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ INCLUDES += -I$(srcdir) \
+ -I$(top_builddir)/include \
+diff -Nuar mysql.orig/ndb/config/win-libraries mysql/ndb/config/win-libraries
+--- mysql.orig/ndb/config/win-libraries 2009-01-15 09:47:06.000000000 -0800
++++ mysql/ndb/config/win-libraries 2009-04-11 16:44:33.724336658 -0700
+@@ -21,7 +21,7 @@
+ # the same goes for mysys and strings
+ lib=$i
+ case $i in
+- *libdbug.a | *libmysys.a | *libmystrings.a)
++ *libdbug.la | *libmysys.la | *libmystrings.la)
+ lib=`echo $i | sed s'!dbug\/lib!!' | sed 's!mysys\/lib!!' | sed 's!strings\/libmy!!'`
+ echo "Changing from $i to $lib"
+ ;;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 1:25 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 1:25 UTC (permalink / raw
To: gentoo-commits
commit: 8857534d098e5801748d5c960d7d3f8422cbe61e
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 01:23:09 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 01:23:09 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=8857534d
Updated 07300_all_mysql_embedded_compilefix patch for 5.0.92 release.
---
00000_index.txt | 7 ++++++-
07300_all_mysql_embedded_compilefix-5.0.92.patch | 11 +++++++++++
2 files changed, 17 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 19cb0f8..1aab7b7 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -659,7 +659,12 @@
@@ Bug #308999: Fix false positives with between OK/"Table is already up to date" output
@patch 07300_all_mysql_embedded_compilefix-5.0.91.patch
-@ver 5.00.91.00 to 5.00.99.99
+@ver 5.00.91.00 to 5.00.91.99
+@pn mysql
+@@ Compile fix for bug introduced by upstream in 5.0.91
+
+@patch 07300_all_mysql_embedded_compilefix-5.0.92.patch
+@ver 5.00.92.00 to 5.00.99.99
@pn mysql
@@ Compile fix for bug introduced by upstream in 5.0.91
diff --git a/07300_all_mysql_embedded_compilefix-5.0.92.patch b/07300_all_mysql_embedded_compilefix-5.0.92.patch
new file mode 100644
index 0000000..26a4c87
--- /dev/null
+++ b/07300_all_mysql_embedded_compilefix-5.0.92.patch
@@ -0,0 +1,11 @@
+diff -Nuar mysql-5.0.91.orig//sql/sql_parse.cc mysql-5.0.91//sql/sql_parse.cc
+--- mysql-5.0.91.orig//sql/sql_parse.cc 2010-05-05 14:07:10.000000000 +0000
++++ mysql-5.0.91//sql/sql_parse.cc 2010-05-21 20:29:16.714903163 +0000
+@@ -499,6 +499,7 @@
+ big packets indefinitely, this is a previously established behavior
+ that needs to be preserved as to not break backwards compatibility.
+ */
++#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ thd->net.skip_big_packet= TRUE;
+ #endif
+ /* Ready to handle queries */
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 1:34 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 1:34 UTC (permalink / raw
To: gentoo-commits
commit: 271b66d409730bffd9915be20d7a2db3219a92cb
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 01:31:58 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 01:31:58 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=271b66d4
Updated 10020_all_microslow_innodb-percona patch to the 5.0.92 release.
---
00000_index.txt | 7 +-
10020_all_microslow_innodb-percona-5.0.92.patch | 2492 +++++++++++++++++++++++
2 files changed, 2498 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1aab7b7..0d7be5e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -772,10 +772,15 @@
@@ Percona 5.0.87-b20-20091116: profiling from SHOW PROFILE to slow.log
@patch 10021_all_profiling_slow-percona-5.0.91-b22-20100522.patch
-@ver 5.00.91.00 to 5.00.99.99
+@ver 5.00.91.00 to 5.00.91.99
@pn mysql
@@ Percona 5.0.91-b22-20100522: profiling from SHOW PROFILE to slow.log
+@patch 10021_all_profiling_slow-percona-5.0.92.patch
+@ver 5.00.92.00 to 5.00.99.99
+@pn mysql
+@@ Percona 5.0.92: profiling from SHOW PROFILE to slow.log
+
@patch 10030_all_userstatv2-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
diff --git a/10020_all_microslow_innodb-percona-5.0.92.patch b/10020_all_microslow_innodb-percona-5.0.92.patch
new file mode 100644
index 0000000..d2d4eb7
--- /dev/null
+++ b/10020_all_microslow_innodb-percona-5.0.92.patch
@@ -0,0 +1,2492 @@
+diff -r 1242d4575291 include/my_getopt.h
+--- a/include/my_getopt.h Tue Jul 28 23:39:12 2009 -0700
++++ b/include/my_getopt.h Tue Jul 28 23:42:44 2009 -0700
+@@ -28,7 +28,8 @@
+ #define GET_ULL 8
+ #define GET_STR 9
+ #define GET_STR_ALLOC 10
+-#define GET_DISABLED 11
++#define GET_MICROTIME 11
++#define GET_DISABLED 12
+
+ #define GET_ASK_ADDR 128
+ #define GET_TYPE_MASK 127
+diff -r 1242d4575291 include/my_time.h
+--- a/include/my_time.h Tue Jul 28 23:39:12 2009 -0700
++++ b/include/my_time.h Tue Jul 28 23:42:44 2009 -0700
+@@ -140,7 +140,7 @@
+ int my_date_to_str(const MYSQL_TIME *l_time, char *to);
+ int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
+ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
+-
++ulonglong my_timer(ulonglong *ltime, ulonglong frequency);
+ C_MODE_END
+
+ #endif /* _my_time_h_ */
+diff -r 1242d4575291 innobase/buf/buf0buf.c
+--- a/innobase/buf/buf0buf.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/buf/buf0buf.c Tue Jul 28 23:42:44 2009 -0700
+@@ -37,6 +37,10 @@
+ #include "log0log.h"
+ #include "trx0undo.h"
+ #include "srv0srv.h"
++#include "trx0trx.h"
++
++/* prototypes for new functions added to ha_innodb.cc */
++trx_t* innobase_get_trx();
+
+ /*
+ IMPLEMENTATION OF THE BUFFER POOL
+@@ -1086,6 +1090,36 @@
+ return(block);
+ }
+
++inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
++{
++ ulint block_hash;
++ ulint block_hash_byte;
++ byte block_hash_offset;
++
++ ut_ad(block);
++
++ if (!srv_slow_log || !trx || !trx->take_stats)
++ return;
++
++ if (!trx->distinct_page_access_hash) {
++ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
++ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
++ }
++
++ block_hash = ut_hash_ulint((block->space << 20) + block->space +
++ block->offset, DPAH_SIZE << 3);
++ block_hash_byte = block_hash >> 3;
++ block_hash_offset = (byte) block_hash & 0x07;
++ if (block_hash_byte < 0 || block_hash_byte >= DPAH_SIZE)
++ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", block_hash_byte, block_hash_offset);
++ if (block_hash_offset < 0 || block_hash_offset > 7)
++ fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %lu !!!\n", block_hash_byte, block_hash_offset);
++ if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
++ trx->distinct_page_access++;
++ trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
++ return;
++}
++
+ /************************************************************************
+ This is the general function used to get access to a database page. */
+
+@@ -1108,6 +1142,11 @@
+ ulint fix_type;
+ ibool success;
+ ibool must_read;
++ trx_t* trx = NULL;
++ ulint sec;
++ ulint ms;
++ ib_longlong start_time;
++ ib_longlong finish_time;
+
+ ut_ad(mtr);
+ ut_ad((rw_latch == RW_S_LATCH)
+@@ -1119,6 +1158,9 @@
+ #ifndef UNIV_LOG_DEBUG
+ ut_ad(!ibuf_inside() || ibuf_page(space, offset));
+ #endif
++ if (srv_slow_log) {
++ trx = innobase_get_trx();
++ }
+ buf_pool->n_page_gets++;
+ loop:
+ block = NULL;
+@@ -1148,7 +1190,7 @@
+ return(NULL);
+ }
+
+- buf_read_page(space, offset);
++ buf_read_page(space, offset, trx);
+
+ #ifdef UNIV_DEBUG
+ buf_dbg_counter++;
+@@ -1261,6 +1303,11 @@
+ /* Let us wait until the read operation
+ completes */
+
++ if (srv_slow_log && trx && trx->take_stats)
++ {
++ ut_usectime(&sec, &ms);
++ start_time = (ib_longlong)sec * 1000000 + ms;
++ }
+ for (;;) {
+ mutex_enter(&block->mutex);
+
+@@ -1276,6 +1323,12 @@
+ break;
+ }
+ }
++ if (srv_slow_log && trx && trx->take_stats && start_time)
++ {
++ ut_usectime(&sec, &ms);
++ finish_time = (ib_longlong)sec * 1000000 + ms;
++ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
++ }
+ }
+
+ fix_type = MTR_MEMO_BUF_FIX;
+@@ -1296,12 +1349,17 @@
+ /* In the case of a first access, try to apply linear
+ read-ahead */
+
+- buf_read_ahead_linear(space, offset);
++ buf_read_ahead_linear(space, offset, trx);
+ }
+
+ #ifdef UNIV_IBUF_DEBUG
+ ut_a(ibuf_count_get(block->space, block->offset) == 0);
+ #endif
++
++ if (srv_slow_log) {
++ _increment_page_get_statistics(block, trx);
++ }
++
+ return(block->frame);
+ }
+
+@@ -1326,6 +1384,7 @@
+ ibool accessed;
+ ibool success;
+ ulint fix_type;
++ trx_t* trx = NULL;
+
+ ut_ad(mtr && block);
+ ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
+@@ -1440,7 +1499,7 @@
+ read-ahead */
+
+ buf_read_ahead_linear(buf_frame_get_space_id(guess),
+- buf_frame_get_page_no(guess));
++ buf_frame_get_page_no(guess), trx);
+ }
+
+ #ifdef UNIV_IBUF_DEBUG
+@@ -1448,6 +1507,11 @@
+ #endif
+ buf_pool->n_page_gets++;
+
++ if (srv_slow_log) {
++ trx = innobase_get_trx();
++ _increment_page_get_statistics(block, trx);
++ }
++
+ return(TRUE);
+ }
+
+@@ -1470,6 +1534,7 @@
+ buf_block_t* block;
+ ibool success;
+ ulint fix_type;
++ trx_t* trx = NULL;
+
+ ut_ad(mtr);
+ ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH));
+@@ -1559,6 +1624,11 @@
+ #endif
+ buf_pool->n_page_gets++;
+
++ if (srv_slow_log) {
++ trx = innobase_get_trx();
++ _increment_page_get_statistics(block, trx);
++ }
++
+ return(TRUE);
+ }
+
+diff -r 1242d4575291 innobase/buf/buf0rea.c
+--- a/innobase/buf/buf0rea.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/buf/buf0rea.c Tue Jul 28 23:42:44 2009 -0700
+@@ -70,7 +70,8 @@
+ treat the tablespace as dropped; this is a timestamp we
+ use to stop dangling page reads from a tablespace
+ which we have DISCARDed + IMPORTed back */
+- ulint offset) /* in: page number */
++ ulint offset, /* in: page number */
++ trx_t* trx)
+ {
+ buf_block_t* block;
+ ulint wake_later;
+@@ -140,10 +141,10 @@
+
+ ut_a(block->state == BUF_BLOCK_FILE_PAGE);
+
+- *err = fil_io(OS_FILE_READ | wake_later,
++ *err = _fil_io(OS_FILE_READ | wake_later,
+ sync, space,
+ offset, 0, UNIV_PAGE_SIZE,
+- (void*)block->frame, (void*)block);
++ (void*)block->frame, (void*)block, trx);
+ ut_a(*err == DB_SUCCESS);
+
+ if (sync) {
+@@ -174,8 +175,9 @@
+ the page at the given page number does not get
+ read even if we return a value > 0! */
+ ulint space, /* in: space id */
+- ulint offset) /* in: page number of a page which the current thread
++ ulint offset, /* in: page number of a page which the current thread
+ wants to access */
++ trx_t* trx)
+ {
+ ib_longlong tablespace_version;
+ buf_block_t* block;
+@@ -270,7 +272,7 @@
+ if (!ibuf_bitmap_page(i)) {
+ count += buf_read_page_low(&err, FALSE, ibuf_mode
+ | OS_AIO_SIMULATED_WAKE_LATER,
+- space, tablespace_version, i);
++ space, tablespace_version, i, trx);
+ if (err == DB_TABLESPACE_DELETED) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+@@ -314,7 +316,8 @@
+ /* out: number of page read requests issued: this can
+ be > 1 if read-ahead occurred */
+ ulint space, /* in: space id */
+- ulint offset) /* in: page number */
++ ulint offset, /* in: page number */
++ trx_t* trx)
+ {
+ ib_longlong tablespace_version;
+ ulint count;
+@@ -323,13 +326,13 @@
+
+ tablespace_version = fil_space_get_version(space);
+
+- count = buf_read_ahead_random(space, offset);
++ count = buf_read_ahead_random(space, offset, trx);
+
+ /* We do the i/o in the synchronous aio mode to save thread
+ switches: hence TRUE */
+
+ count2 = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+- tablespace_version, offset);
++ tablespace_version, offset, trx);
+ srv_buf_pool_reads+= count2;
+ if (err == DB_TABLESPACE_DELETED) {
+ ut_print_timestamp(stderr);
+@@ -374,8 +377,9 @@
+ /*==================*/
+ /* out: number of page read requests issued */
+ ulint space, /* in: space id */
+- ulint offset) /* in: page number of a page; NOTE: the current thread
++ ulint offset, /* in: page number of a page; NOTE: the current thread
+ must want access to this page (see NOTE 3 above) */
++ trx_t* trx)
+ {
+ ib_longlong tablespace_version;
+ buf_block_t* block;
+@@ -556,7 +560,7 @@
+ if (!ibuf_bitmap_page(i)) {
+ count += buf_read_page_low(&err, FALSE, ibuf_mode
+ | OS_AIO_SIMULATED_WAKE_LATER,
+- space, tablespace_version, i);
++ space, tablespace_version, i, trx);
+ if (err == DB_TABLESPACE_DELETED) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+@@ -625,10 +629,10 @@
+ for (i = 0; i < n_stored; i++) {
+ if ((i + 1 == n_stored) && sync) {
+ buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE,
+- space_ids[i], space_versions[i], page_nos[i]);
++ space_ids[i], space_versions[i], page_nos[i], NULL);
+ } else {
+ buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE,
+- space_ids[i], space_versions[i], page_nos[i]);
++ space_ids[i], space_versions[i], page_nos[i], NULL);
+ }
+
+ if (err == DB_TABLESPACE_DELETED) {
+@@ -704,11 +708,11 @@
+
+ if ((i + 1 == n_stored) && sync) {
+ buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
+- tablespace_version, page_nos[i]);
++ tablespace_version, page_nos[i], NULL);
+ } else {
+ buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
+ | OS_AIO_SIMULATED_WAKE_LATER,
+- space, tablespace_version, page_nos[i]);
++ space, tablespace_version, page_nos[i], NULL);
+ }
+ }
+
+diff -r 1242d4575291 innobase/fil/fil0fil.c
+--- a/innobase/fil/fil0fil.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/fil/fil0fil.c Tue Jul 28 23:42:44 2009 -0700
+@@ -3527,7 +3527,7 @@
+ node->name, node->handle, buf,
+ offset_low, offset_high,
+ UNIV_PAGE_SIZE * n_pages,
+- NULL, NULL);
++ NULL, NULL, NULL);
+ #endif
+ if (success) {
+ node->size += n_pages;
+@@ -3851,7 +3851,7 @@
+ Reads or writes data. This operation is asynchronous (aio). */
+
+ ulint
+-fil_io(
++_fil_io(
+ /*===*/
+ /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
+ if we are trying to do i/o on a tablespace
+@@ -3877,8 +3877,9 @@
+ void* buf, /* in/out: buffer where to store read data
+ or from where to write; in aio this must be
+ appropriately aligned */
+- void* message) /* in: message for aio handler if non-sync
++ void* message, /* in: message for aio handler if non-sync
+ aio used, else ignored */
++ trx_t* trx)
+ {
+ fil_system_t* system = fil_system;
+ ulint mode;
+@@ -4018,7 +4019,7 @@
+ #else
+ /* Queue the aio request */
+ ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
+- offset_low, offset_high, len, node, message);
++ offset_low, offset_high, len, node, message, trx);
+ #endif
+ ut_a(ret);
+
+diff -r 1242d4575291 innobase/include/buf0rea.h
+--- a/innobase/include/buf0rea.h Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/include/buf0rea.h Tue Jul 28 23:42:44 2009 -0700
+@@ -10,6 +10,7 @@
+ #define buf0rea_h
+
+ #include "univ.i"
++#include "trx0types.h"
+ #include "buf0types.h"
+
+ /************************************************************************
+@@ -25,7 +26,8 @@
+ /* out: number of page read requests issued: this can
+ be > 1 if read-ahead occurred */
+ ulint space, /* in: space id */
+- ulint offset);/* in: page number */
++ ulint offset, /* in: page number */
++ trx_t* trx);
+ /************************************************************************
+ Applies linear read-ahead if in the buf_pool the page is a border page of
+ a linear read-ahead area and all the pages in the area have been accessed.
+@@ -55,8 +57,9 @@
+ /*==================*/
+ /* out: number of page read requests issued */
+ ulint space, /* in: space id */
+- ulint offset);/* in: page number of a page; NOTE: the current thread
++ ulint offset, /* in: page number of a page; NOTE: the current thread
+ must want access to this page (see NOTE 3 above) */
++ trx_t* trx);
+ /************************************************************************
+ Issues read requests for pages which the ibuf module wants to read in, in
+ order to contract the insert buffer tree. Technically, this function is like
+diff -r 1242d4575291 innobase/include/fil0fil.h
+--- a/innobase/include/fil0fil.h Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/include/fil0fil.h Tue Jul 28 23:42:44 2009 -0700
+@@ -534,8 +534,11 @@
+ /************************************************************************
+ Reads or writes data. This operation is asynchronous (aio). */
+
++#define fil_io(type, sync, space_id, block_offset, byte_offset, len, buf, message) \
++ _fil_io(type, sync, space_id, block_offset, byte_offset, len, buf, message, NULL)
++
+ ulint
+-fil_io(
++_fil_io(
+ /*===*/
+ /* out: DB_SUCCESS, or DB_TABLESPACE_DELETED
+ if we are trying to do i/o on a tablespace
+@@ -561,8 +564,9 @@
+ void* buf, /* in/out: buffer where to store read data
+ or from where to write; in aio this must be
+ appropriately aligned */
+- void* message); /* in: message for aio handler if non-sync
++ void* message, /* in: message for aio handler if non-sync
+ aio used, else ignored */
++ trx_t* trx);
+ /************************************************************************
+ Reads data from a space to a buffer. Remember that the possible incomplete
+ blocks at the end of file are ignored: they are not taken into account when
+diff -r 1242d4575291 innobase/include/os0file.h
+--- a/innobase/include/os0file.h Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/include/os0file.h Tue Jul 28 23:42:44 2009 -0700
+@@ -11,6 +11,8 @@
+
+ #include "univ.i"
+
++#include "trx0types.h"
++
+ #ifndef __WIN__
+ #include <dirent.h>
+ #include <sys/stat.h>
+@@ -421,8 +423,11 @@
+ /***********************************************************************
+ Requests a synchronous read operation. */
+
++#define os_file_read(file, buf, offset, offset_high, n) \
++ _os_file_read(file, buf, offset, offset_high, n, NULL)
++
+ ibool
+-os_file_read(
++_os_file_read(
+ /*=========*/
+ /* out: TRUE if request was
+ successful, FALSE if fail */
+@@ -432,7 +437,8 @@
+ offset where to read */
+ ulint offset_high,/* in: most significant 32 bits of
+ offset */
+- ulint n); /* in: number of bytes to read */
++ ulint n, /* in: number of bytes to read */
++ trx_t* trx);
+ /***********************************************************************
+ Rewind file to its start, read at most size - 1 bytes from it to str, and
+ NUL-terminate str. All errors are silently ignored. This function is
+@@ -584,7 +590,8 @@
+ can be used to identify a completed aio
+ operation); if mode is OS_AIO_SYNC, these
+ are ignored */
+- void* message2);
++ void* message2,
++ trx_t* trx);
+ /****************************************************************************
+ Wakes up all async i/o threads so that they know to exit themselves in
+ shutdown. */
+diff -r 1242d4575291 innobase/include/srv0srv.h
+--- a/innobase/include/srv0srv.h Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/include/srv0srv.h Tue Jul 28 23:42:44 2009 -0700
+@@ -27,6 +27,8 @@
+ #define SRV_AUTO_EXTEND_INCREMENT \
+ (srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
+
++extern ibool srv_slow_log;
++
+ /* This is set to TRUE if the MySQL user has set it in MySQL */
+ extern ibool srv_lower_case_table_names;
+
+diff -r 1242d4575291 innobase/include/trx0trx.h
+--- a/innobase/include/trx0trx.h Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/include/trx0trx.h Tue Jul 28 23:42:44 2009 -0700
+@@ -668,6 +668,17 @@
+ /*------------------------------*/
+ char detailed_error[256]; /* detailed error message for last
+ error, or empty. */
++ /*------------------------------*/
++ ulint io_reads;
++ ib_longlong io_read;
++ ulint io_reads_wait_timer;
++ ib_longlong lock_que_wait_ustarted;
++ ulint lock_que_wait_timer;
++ ulint innodb_que_wait_timer;
++ ulint distinct_page_access;
++#define DPAH_SIZE 8192
++ byte* distinct_page_access_hash;
++ ibool take_stats;
+ };
+
+ #define TRX_MAX_N_THREADS 32 /* maximum number of concurrent
+diff -r 1242d4575291 innobase/lock/lock0lock.c
+--- a/innobase/lock/lock0lock.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/lock/lock0lock.c Tue Jul 28 23:42:44 2009 -0700
+@@ -1806,6 +1806,8 @@
+ {
+ lock_t* lock;
+ trx_t* trx;
++ ulint sec;
++ ulint ms;
+
+ #ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&kernel_mutex));
+@@ -1861,6 +1863,10 @@
+ trx->que_state = TRX_QUE_LOCK_WAIT;
+ trx->was_chosen_as_deadlock_victim = FALSE;
+ trx->wait_started = time(NULL);
++ if (srv_slow_log && trx->take_stats) {
++ ut_usectime(&sec, &ms);
++ trx->lock_que_wait_ustarted = (ib_longlong)sec * 1000000 + ms;
++ }
+
+ ut_a(que_thr_stop(thr));
+
+@@ -3514,7 +3520,9 @@
+ {
+ lock_t* lock;
+ trx_t* trx;
+-
++ ulint sec;
++ ulint ms;
++
+ #ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&kernel_mutex));
+ #endif /* UNIV_SYNC_DEBUG */
+@@ -3564,6 +3572,10 @@
+ return(DB_SUCCESS);
+ }
+
++ if (srv_slow_log && trx->take_stats) {
++ ut_usectime(&sec, &ms);
++ trx->lock_que_wait_ustarted = (ib_longlong)sec * 1000000 + ms;
++ }
+ trx->que_state = TRX_QUE_LOCK_WAIT;
+ trx->was_chosen_as_deadlock_victim = FALSE;
+ trx->wait_started = time(NULL);
+diff -r 1242d4575291 innobase/os/os0file.c
+--- a/innobase/os/os0file.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/os/os0file.c Tue Jul 28 23:42:44 2009 -0700
+@@ -14,6 +14,8 @@
+ #include "srv0start.h"
+ #include "fil0fil.h"
+ #include "buf0buf.h"
++#include "trx0sys.h"
++#include "trx0trx.h"
+
+ #if defined(UNIV_HOTBACKUP) && defined(__WIN__)
+ /* Add includes for the _stat() call to compile on Windows */
+@@ -1903,9 +1905,13 @@
+ #ifndef __WIN__
+ /***********************************************************************
+ Does a synchronous read operation in Posix. */
++
++#define os_file_pread(file, buf, n, offset, offset_high) \
++ _os_file_pread(file, buf, n, offset, offset_high, NULL);
++
+ static
+ ssize_t
+-os_file_pread(
++_os_file_pread(
+ /*==========*/
+ /* out: number of bytes read, -1 if error */
+ os_file_t file, /* in: handle to a file */
+@@ -1913,12 +1919,17 @@
+ ulint n, /* in: number of bytes to read */
+ ulint offset, /* in: least significant 32 bits of file
+ offset from where to read */
+- ulint offset_high) /* in: most significant 32 bits of
+- offset */
++ ulint offset_high, /* in: most significant 32 bits of
++ offset */
++ trx_t* trx)
+ {
+ off_t offs;
+ ssize_t n_bytes;
+-
++ ulint sec;
++ ulint ms;
++ ib_longlong start_time;
++ ib_longlong finish_time;
++
+ ut_a((offset & 0xFFFFFFFFUL) == offset);
+
+ /* If off_t is > 4 bytes in size, then we assume we can pass a
+@@ -1937,7 +1948,13 @@
+ }
+
+ os_n_file_reads++;
+-
++ if (srv_slow_log && trx && trx->take_stats)
++ {
++ trx->io_reads++;
++ trx->io_read += n;
++ ut_usectime(&sec, &ms);
++ start_time = (ib_longlong)sec * 1000000 + ms;
++ }
+ #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
+ os_mutex_enter(os_file_count_mutex);
+ os_file_n_pending_preads++;
+@@ -1951,6 +1968,13 @@
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
++ if (srv_slow_log && trx && trx->take_stats && start_time)
++ {
++ ut_usectime(&sec, &ms);
++ finish_time = (ib_longlong)sec * 1000000 + ms;
++ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
++ }
++
+ return(n_bytes);
+ #else
+ {
+@@ -1981,6 +2005,13 @@
+ os_n_pending_reads--;
+ os_mutex_exit(os_file_count_mutex);
+
++ if (srv_slow_log && trx && trx->take_stats && start_time)
++ {
++ ut_usectime(&sec, &ms);
++ finish_time = (ib_longlong)sec * 1000000 + ms;
++ trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
++ }
++
+ return(ret);
+ }
+ #endif
+@@ -2103,7 +2134,7 @@
+ Requests a synchronous positioned read operation. */
+
+ ibool
+-os_file_read(
++_os_file_read(
+ /*=========*/
+ /* out: TRUE if request was
+ successful, FALSE if fail */
+@@ -2113,7 +2144,8 @@
+ offset where to read */
+ ulint offset_high, /* in: most significant 32 bits of
+ offset */
+- ulint n) /* in: number of bytes to read */
++ ulint n, /* in: number of bytes to read */
++ trx_t* trx)
+ {
+ #ifdef __WIN__
+ BOOL ret;
+@@ -2177,7 +2209,7 @@
+ os_bytes_read_since_printout += n;
+
+ try_again:
+- ret = os_file_pread(file, buf, n, offset, offset_high);
++ ret = _os_file_pread(file, buf, n, offset, offset_high, trx);
+
+ if ((ulint)ret == n) {
+
+@@ -3137,7 +3169,8 @@
+ offset */
+ ulint offset_high, /* in: most significant 32 bits of
+ offset */
+- ulint len) /* in: length of the block to read or write */
++ ulint len, /* in: length of the block to read or write */
++ trx_t* trx)
+ {
+ os_aio_slot_t* slot;
+ #ifdef WIN_ASYNC_IO
+@@ -3390,7 +3423,8 @@
+ can be used to identify a completed aio
+ operation); if mode is OS_AIO_SYNC, these
+ are ignored */
+- void* message2)
++ void* message2,
++ trx_t* trx)
+ {
+ os_aio_array_t* array;
+ os_aio_slot_t* slot;
+@@ -3429,8 +3463,8 @@
+ wait in the Windows case. */
+
+ if (type == OS_FILE_READ) {
+- return(os_file_read(file, buf, offset,
+- offset_high, n));
++ return(_os_file_read(file, buf, offset,
++ offset_high, n, trx));
+ }
+
+ ut_a(type == OS_FILE_WRITE);
+@@ -3463,8 +3497,13 @@
+ ut_error;
+ }
+
++ if (trx && type == OS_FILE_READ)
++ {
++ trx->io_reads++;
++ trx->io_read += n;
++ }
+ slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
+- name, buf, offset, offset_high, n);
++ name, buf, offset, offset_high, n, trx);
+ if (type == OS_FILE_READ) {
+ if (os_aio_use_native_aio) {
+ #ifdef WIN_ASYNC_IO
+diff -r 1242d4575291 innobase/srv/srv0srv.c
+--- a/innobase/srv/srv0srv.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/srv/srv0srv.c Tue Jul 28 23:42:44 2009 -0700
+@@ -48,6 +48,8 @@
+ #include "srv0start.h"
+ #include "row0mysql.h"
+
++ibool srv_slow_log = 0;
++
+ /* This is set to TRUE if the MySQL user has set it in MySQL; currently
+ affects only FOREIGN KEY definition parsing */
+ ibool srv_lower_case_table_names = FALSE;
+@@ -1002,6 +1004,10 @@
+ ibool has_slept = FALSE;
+ srv_conc_slot_t* slot = NULL;
+ ulint i;
++ ib_longlong start_time = 0L;
++ ib_longlong finish_time = 0L;
++ ulint sec;
++ ulint ms;
+
+ /* If trx has 'free tickets' to enter the engine left, then use one
+ such ticket */
+@@ -1060,6 +1066,7 @@
+ if (SRV_THREAD_SLEEP_DELAY > 0)
+ {
+ os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
++ trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
+ }
+
+ trx->op_info = "";
+@@ -1115,12 +1122,23 @@
+ /* Go to wait for the event; when a thread leaves InnoDB it will
+ release this thread */
+
++ if (srv_slow_log && trx->take_stats) {
++ ut_usectime(&sec, &ms);
++ start_time = (ib_longlong)sec * 1000000 + ms;
++ }
++
+ trx->op_info = "waiting in InnoDB queue";
+
+ os_event_wait(slot->event);
+
+ trx->op_info = "";
+
++ if (srv_slow_log && trx->take_stats && start_time) {
++ ut_usectime(&sec, &ms);
++ finish_time = (ib_longlong)sec * 1000000 + ms;
++ trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
++ }
++
+ os_fast_mutex_lock(&srv_conc_mutex);
+
+ srv_conc_n_waiting_threads--;
+diff -r 1242d4575291 innobase/trx/trx0trx.c
+--- a/innobase/trx/trx0trx.c Tue Jul 28 23:39:12 2009 -0700
++++ b/innobase/trx/trx0trx.c Tue Jul 28 23:42:44 2009 -0700
+@@ -190,6 +190,15 @@
+ trx->global_read_view_heap = mem_heap_create(256);
+ trx->global_read_view = NULL;
+ trx->read_view = NULL;
++
++ trx->io_reads = 0;
++ trx->io_read = 0;
++ trx->io_reads_wait_timer = 0;
++ trx->lock_que_wait_timer = 0;
++ trx->innodb_que_wait_timer = 0;
++ trx->distinct_page_access = 0;
++ trx->distinct_page_access_hash = NULL;
++ trx->take_stats = FALSE;
+
+ /* Set X/Open XA transaction identification to NULL */
+ memset(&trx->xid, 0, sizeof(trx->xid));
+@@ -230,6 +239,11 @@
+
+ trx->mysql_process_no = os_proc_get_number();
+
++ if (srv_slow_log && trx->take_stats) {
++ trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
++ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
++ }
++
+ return(trx);
+ }
+
+@@ -366,6 +380,12 @@
+ /*===============*/
+ trx_t* trx) /* in, own: trx object */
+ {
++ if (trx->distinct_page_access_hash)
++ {
++ mem_free(trx->distinct_page_access_hash);
++ trx->distinct_page_access_hash= NULL;
++ }
++
+ thr_local_free(trx->mysql_thread_id);
+
+ mutex_enter(&kernel_mutex);
+@@ -389,6 +409,12 @@
+ /*====================*/
+ trx_t* trx) /* in, own: trx object */
+ {
++ if (trx->distinct_page_access_hash)
++ {
++ mem_free(trx->distinct_page_access_hash);
++ trx->distinct_page_access_hash= NULL;
++ }
++
+ mutex_enter(&kernel_mutex);
+
+ trx_free(trx);
+@@ -1064,7 +1090,10 @@
+ trx_t* trx) /* in: transaction */
+ {
+ que_thr_t* thr;
+-
++ ulint sec;
++ ulint ms;
++ ib_longlong now;
++
+ #ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&kernel_mutex));
+ #endif /* UNIV_SYNC_DEBUG */
+@@ -1080,6 +1109,11 @@
+ thr = UT_LIST_GET_FIRST(trx->wait_thrs);
+ }
+
++ if (srv_slow_log && trx->take_stats) {
++ ut_usectime(&sec, &ms);
++ now = (ib_longlong)sec * 1000000 + ms;
++ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
++ }
+ trx->que_state = TRX_QUE_RUNNING;
+ }
+
+@@ -1093,6 +1127,9 @@
+ trx_t* trx) /* in: transaction in the TRX_QUE_LOCK_WAIT state */
+ {
+ que_thr_t* thr;
++ ulint sec;
++ ulint ms;
++ ib_longlong now;
+
+ #ifdef UNIV_SYNC_DEBUG
+ ut_ad(mutex_own(&kernel_mutex));
+@@ -1109,6 +1146,11 @@
+ thr = UT_LIST_GET_FIRST(trx->wait_thrs);
+ }
+
++ if (srv_slow_log && trx->take_stats) {
++ ut_usectime(&sec, &ms);
++ now = (ib_longlong)sec * 1000000 + ms;
++ trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
++ }
+ trx->que_state = TRX_QUE_RUNNING;
+ }
+
+diff -r 1242d4575291 mysys/my_getopt.c
+--- a/mysys/my_getopt.c Tue Jul 28 23:39:12 2009 -0700
++++ b/mysys/my_getopt.c Tue Jul 28 23:42:44 2009 -0700
+@@ -827,7 +827,8 @@
+ #endif
+ break;
+ default:
+- DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL);
++ DBUG_ASSERT((optp->var_type & GET_TYPE_MASK) == GET_ULL
++ || (optp->var_type & GET_TYPE_MASK) == GET_MICROTIME);
+ break;
+ }
+
+@@ -1061,6 +1062,9 @@
+ case GET_ULONG:
+ printf("%lu\n", *((ulong*) value));
+ break;
++ case GET_MICROTIME:
++ printf("%6f\n", ((double)(*((longlong*) value))) / 1000000.0);
++ break;
+ case GET_LL:
+ printf("%s\n", llstr(*((longlong*) value), buff));
+ break;
+diff -r 1242d4575291 patch_info/microslow_innodb.info
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/patch_info/microslow_innodb.info Tue Jul 28 23:42:44 2009 -0700
+@@ -0,0 +1,15 @@
++File=microslow_innodb.patch
++Name=Extended statistics in slow.log
++Version=1.2
++Author=Percona <info@percona.com>
++License=GPL
++Comment=
++Changelog
++2008-11-26
++YK: Fix inefficient determination of trx, Make not to call useless gettimeofday when don't use slow log. Make log_slow_queries dynamic (bool).
++
++2008-11-07
++VT: Moved log_slow_rate_limit in SHOW VARIABLE into right place
++
++2008-11
++Arjen Lentz: Fixups (backward compatibility) by Arjen Lentz <arjen@openquery.com.au>
+diff -r 1242d4575291 scripts/mysqldumpslow.sh
+--- a/scripts/mysqldumpslow.sh Tue Jul 28 23:39:12 2009 -0700
++++ b/scripts/mysqldumpslow.sh Tue Jul 28 23:42:44 2009 -0700
+@@ -83,8 +83,8 @@
+ s/^#? Time: \d{6}\s+\d+:\d+:\d+.*\n//;
+ my ($user,$host) = s/^#? User\@Host:\s+(\S+)\s+\@\s+(\S+).*\n// ? ($1,$2) : ('','');
+
+- s/^# Query_time: (\d+) Lock_time: (\d+) Rows_sent: (\d+).*\n//;
+- my ($t, $l, $r) = ($1, $2, $3);
++ s/^# Query_time: (\d+(\.\d+)?) Lock_time: (\d+(\.\d+)?) Rows_sent: (\d+(\.\d+)?).*\n//;
++ my ($t, $l, $r) = ($1, $3, $5);
+ $t -= $l unless $opt{l};
+
+ # remove fluff that mysqld writes to log when it (re)starts:
+diff -r 1242d4575291 sql-common/my_time.c
+--- a/sql-common/my_time.c Tue Jul 28 23:39:12 2009 -0700
++++ b/sql-common/my_time.c Tue Jul 28 23:42:44 2009 -0700
+@@ -1253,3 +1253,37 @@
+ return 0;
+ }
+
++/*
++ int my_timer(ulonglong *ltime, ulonglong frequency)
++
++ For performance measurement this function returns the number
++ of microseconds since the epoch (SVr4, BSD 4.3, POSIX 1003.1-2001)
++ or system start (Windows platforms).
++
++ For windows platforms frequency value (obtained via
++ QueryPerformanceFrequency) has to be specified. The global frequency
++ value is set in mysqld.cc.
++
++ If Windows platform doesn't support QueryPerformanceFrequency we will
++ obtain the time via GetClockCount, which supports microseconds only.
++*/
++
++ulonglong my_timer(ulonglong *ltime, ulonglong frequency)
++{
++ ulonglong newtime= 0;
++#ifdef __WIN__
++ if (frequency)
++ {
++ QueryPerformanceCounter((LARGE_INTEGER *)&newtime);
++ newtime/= (frequency * 1000000);
++ } else
++ newtime= (GetTickCount() * 1000; /* GetTickCount only returns milliseconds */
++#else
++ struct timeval t;
++ if (gettimeofday(&t, NULL) != -1)
++ newtime= (ulonglong)t.tv_sec * 1000000 + t.tv_usec;
++#endif
++ if (ltime)
++ *ltime= newtime;
++ return newtime;
++}
+diff -r 1242d4575291 sql/filesort.cc
+--- a/sql/filesort.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/filesort.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -180,6 +180,7 @@
+ {
+ statistic_increment(thd->status_var.filesort_scan_count, &LOCK_status);
+ }
++ thd->query_plan_flags|= QPLAN_FILESORT;
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+@@ -245,6 +246,7 @@
+ }
+ else
+ {
++ thd->query_plan_flags|= QPLAN_FILESORT_DISK;
+ if (table_sort.buffpek && table_sort.buffpek_len < maxbuffer)
+ {
+ x_free(table_sort.buffpek);
+@@ -1116,6 +1118,7 @@
+
+ statistic_increment(current_thd->status_var.filesort_merge_passes,
+ &LOCK_status);
++ current_thd->query_plan_fsort_passes++;
+ if (param->not_killable)
+ {
+ killed= ¬_killable;
+diff -r 1242d4575291 sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/ha_innodb.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -1,3 +1,4 @@
++
+ /* Copyright (C) 2000-2005 MySQL AB & Innobase Oy
+
+ This program is free software; you can redistribute it and/or modify
+@@ -819,9 +820,34 @@
+ trx->check_unique_secondary = TRUE;
+ }
+
++ if (thd->variables.log_slow_verbosity & SLOG_V_INNODB) {
++ trx->take_stats = TRUE;
++ } else {
++ trx->take_stats = FALSE;
++ }
++
+ return(trx);
+ }
+
++/*************************************************************************
++Gets current trx. */
++extern "C"
++trx_t*
++innobase_get_trx()
++{
++ THD *thd=current_thd;
++ if (likely(thd != 0)) {
++ return((trx_t*) thd->ha_data[innobase_hton.slot]);
++ } else {
++ return(NULL);
++ }
++}
++
++void
++innobase_update_var_slow_log()
++{
++ srv_slow_log = (ibool) opt_slow_log;
++}
+
+ /*************************************************************************
+ Construct ha_innobase handler. */
+@@ -1324,6 +1350,8 @@
+
+ /* -------------- Log files ---------------------------*/
+
++ srv_slow_log = (ibool) opt_slow_log;
++
+ /* The default dir for log files is the datadir of MySQL */
+
+ if (!innobase_log_group_home_dir) {
+@@ -4697,6 +4725,12 @@
+ trx->check_unique_secondary = FALSE;
+ }
+
++ if (thd->variables.log_slow_verbosity & SLOG_V_INNODB) {
++ trx->take_stats = TRUE;
++ } else {
++ trx->take_stats = FALSE;
++ }
++
+ if (lower_case_table_names) {
+ srv_lower_case_table_names = TRUE;
+ } else {
+@@ -4962,6 +4996,12 @@
+ trx->check_unique_secondary = FALSE;
+ }
+
++ if (thd->variables.log_slow_verbosity & SLOG_V_INNODB) {
++ trx->take_stats = TRUE;
++ } else {
++ trx->take_stats = FALSE;
++ }
++
+ name_len = strlen(name);
+
+ assert(name_len < 1000);
+@@ -5049,6 +5089,12 @@
+ trx->check_foreigns = FALSE;
+ }
+
++ if (current_thd->variables.log_slow_verbosity & SLOG_V_INNODB) {
++ trx->take_stats = TRUE;
++ } else {
++ trx->take_stats = FALSE;
++ }
++
+ error = row_drop_database_for_mysql(namebuf, trx);
+ my_free(namebuf, MYF(0));
+
+@@ -5115,6 +5161,12 @@
+ trx->check_foreigns = FALSE;
+ }
+
++ if (current_thd->variables.log_slow_verbosity & SLOG_V_INNODB) {
++ trx->take_stats = TRUE;
++ } else {
++ trx->take_stats = FALSE;
++ }
++
+ name_len1 = strlen(from);
+ name_len2 = strlen(to);
+
+@@ -6122,6 +6174,7 @@
+ {
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ trx_t* trx;
++ int i;
+
+ DBUG_ENTER("ha_innobase::external_lock");
+ DBUG_PRINT("enter",("lock_type: %d", lock_type));
+@@ -6245,7 +6298,24 @@
+
+ if (trx->n_mysql_tables_in_use == 0) {
+
+- trx->mysql_n_tables_locked = 0;
++ current_thd->innodb_was_used = TRUE;
++ current_thd->innodb_io_reads += trx->io_reads;
++ current_thd->innodb_io_read += trx->io_read;
++ current_thd->innodb_io_reads_wait_timer += trx->io_reads_wait_timer;
++ current_thd->innodb_lock_que_wait_timer += trx->lock_que_wait_timer;
++ current_thd->innodb_innodb_que_wait_timer += trx->innodb_que_wait_timer;
++ current_thd->innodb_page_access += trx->distinct_page_access;
++
++ trx->io_reads = 0;
++ trx->io_read = 0;
++ trx->io_reads_wait_timer = 0;
++ trx->lock_que_wait_timer = 0;
++ trx->innodb_que_wait_timer = 0;
++ trx->distinct_page_access = 0;
++ if (trx->distinct_page_access_hash)
++ memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
++
++ trx->mysql_n_tables_locked = 0;
+ prebuilt->used_in_HANDLER = FALSE;
+
+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
+diff -r 1242d4575291 sql/ha_innodb.h
+--- a/sql/ha_innodb.h Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/ha_innodb.h Tue Jul 28 23:42:44 2009 -0700
+@@ -271,6 +271,8 @@
+
+ int innobase_start_trx_and_assign_read_view(THD* thd);
+
++void innobase_update_var_slow_log();
++
+ /***********************************************************************
+ This function is used to prepare X/Open XA distributed transaction */
+
+diff -r 1242d4575291 sql/log.cc
+--- a/sql/log.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/log.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -2289,11 +2289,12 @@
+ */
+
+ bool MYSQL_LOG::write(THD *thd,const char *query, uint query_length,
+- time_t query_start_arg)
++ time_t query_start_arg, ulonglong query_start_timer)
+ {
+ bool error=0;
+ time_t current_time;
+- if (!is_open())
++ ulonglong current_timer;
++ if (!opt_slow_log || !is_open())
+ return 0;
+ DBUG_ENTER("MYSQL_LOG::write");
+
+@@ -2303,7 +2304,8 @@
+ int tmp_errno=0;
+ char buff[80],*end;
+ end=buff;
+- if (!(thd->options & OPTION_UPDATE_LOG))
++ if (!(thd->options & OPTION_UPDATE_LOG) &&
++ !(thd->slave_thread && opt_log_slow_slave_statements))
+ {
+ VOID(pthread_mutex_unlock(&LOCK_log));
+ DBUG_RETURN(0);
+@@ -2333,22 +2335,72 @@
+ if (my_b_printf(&log_file, "# User@Host: %s[%s] @ %s [%s]\n",
+ sctx->priv_user ?
+ sctx->priv_user : "",
+- sctx->user ? sctx->user : "",
++ sctx->user ? sctx->user : (thd->slave_thread ? "SQL_SLAVE" : ""),
+ sctx->host ? sctx->host : "",
+ sctx->ip ? sctx->ip : "") ==
+ (uint) -1)
+ tmp_errno=errno;
+ }
+- if (query_start_arg)
++ if (query_start_timer)
+ {
++ char buf[5][20];
++ ulonglong current_timer= my_timer(¤t_timer, frequency);
++ snprintf(buf[0], 20, "%.6f", (current_timer ? (current_timer - query_start_timer):0) / 1000000.0);
++ snprintf(buf[1], 20, "%.6f", (thd->timer_after_lock - query_start_timer) / 1000000.0);
++ if (!query_length)
++ {
++ thd->sent_row_count= thd->examined_row_count= 0;
++ thd->row_count= 0;
++ thd->innodb_was_used= FALSE;
++ thd->query_plan_flags= QPLAN_NONE;
++ thd->query_plan_fsort_passes= 0;
++ }
++
+ /* For slow query log */
+ if (my_b_printf(&log_file,
+- "# Query_time: %lu Lock_time: %lu Rows_sent: %lu Rows_examined: %lu\n",
+- (ulong) (current_time - query_start_arg),
+- (ulong) (thd->time_after_lock - query_start_arg),
++ "# Thread_id: %lu Schema: %s\n" \
++ "# Query_time: %s Lock_time: %s Rows_sent: %lu Rows_examined: %lu Rows_affected: %lu Rows_read: %lu\n",
++ (ulong) thd->thread_id, (thd->db ? thd->db : ""),
++ buf[0], buf[1],
+ (ulong) thd->sent_row_count,
+- (ulong) thd->examined_row_count) == (uint) -1)
++ (ulong) thd->examined_row_count,
++ ((long) thd->row_count_func > 0 ) ? (ulong) thd->row_count_func : 0,
++ (ulong) thd->row_count) == (uint) -1)
+ tmp_errno=errno;
++ if ((thd->variables.log_slow_verbosity & SLOG_V_QUERY_PLAN) &&
++ my_b_printf(&log_file,
++ "# QC_Hit: %s Full_scan: %s Full_join: %s Tmp_table: %s Tmp_table_on_disk: %s\n" \
++ "# Filesort: %s Filesort_on_disk: %s Merge_passes: %lu\n",
++ ((thd->query_plan_flags & QPLAN_QC) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FULL_SCAN) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FULL_JOIN) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_TMP_TABLE) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_TMP_DISK) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FILESORT) ? "Yes" : "No"),
++ ((thd->query_plan_flags & QPLAN_FILESORT_DISK) ? "Yes" : "No"),
++ thd->query_plan_fsort_passes) == (uint) -1)
++ tmp_errno=errno;
++ if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) && thd->innodb_was_used)
++ {
++ snprintf(buf[2], 20, "%.6f", thd->innodb_io_reads_wait_timer / 1000000.0);
++ snprintf(buf[3], 20, "%.6f", thd->innodb_lock_que_wait_timer / 1000000.0);
++ snprintf(buf[4], 20, "%.6f", thd->innodb_innodb_que_wait_timer / 1000000.0);
++ if (my_b_printf(&log_file,
++ "# InnoDB_IO_r_ops: %lu InnoDB_IO_r_bytes: %lu InnoDB_IO_r_wait: %s\n" \
++ "# InnoDB_rec_lock_wait: %s InnoDB_queue_wait: %s\n" \
++ "# InnoDB_pages_distinct: %lu\n",
++ (ulong) thd->innodb_io_reads,
++ (ulong) thd->innodb_io_read,
++ buf[2], buf[3], buf[4],
++ (ulong) thd->innodb_page_access) == (uint) -1)
++ tmp_errno=errno;
++ }
++ else
++ {
++ if ((thd->variables.log_slow_verbosity & SLOG_V_INNODB) &&
++ my_b_printf(&log_file,"# No InnoDB statistics available for this query\n") == (uint) -1)
++ tmp_errno=errno;
++ }
+ }
+ if (thd->db && strcmp(thd->db,db))
+ { // Database changed
+diff -r 1242d4575291 sql/log_event.cc
+--- a/sql/log_event.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/log_event.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -2061,6 +2061,7 @@
+ /* Execute the query (note that we bypass dispatch_command()) */
+ const char* found_semicolon= NULL;
+ mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
++ log_slow_statement(thd);
+
+ }
+ else
+diff -r 1242d4575291 sql/mysql_priv.h
+--- a/sql/mysql_priv.h Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/mysql_priv.h Tue Jul 28 23:42:44 2009 -0700
+@@ -507,6 +507,78 @@
+
+ #define STRING_BUFFER_USUAL_SIZE 80
+
++/* Slow log */
++
++struct msl_opts
++{
++ ulong val;
++ const char *name;
++};
++
++#define SLOG_V_MICROTIME 1 << 0
++#define SLOG_V_QUERY_PLAN 1 << 1
++#define SLOG_V_INNODB 1 << 2
++/* ... */
++#define SLOG_V_INVALID 1 << 31
++#define SLOG_V_NONE SLOG_V_MICROTIME
++
++static const struct msl_opts slog_verb[]=
++{
++ /* Basic flags */
++
++ { SLOG_V_MICROTIME, "microtime" },
++ { SLOG_V_QUERY_PLAN, "query_plan" },
++ { SLOG_V_INNODB, "innodb" },
++
++ /* End of baisc flags */
++
++ { 0, "" },
++
++ /* Complex flags */
++
++ { SLOG_V_MICROTIME, "minimal" },
++ { SLOG_V_MICROTIME|SLOG_V_QUERY_PLAN, "standard" },
++ { SLOG_V_MICROTIME|SLOG_V_QUERY_PLAN|SLOG_V_INNODB, "full" },
++
++ /* End of complex flags */
++
++ { SLOG_V_INVALID, (char *)0 }
++};
++
++#define QPLAN_NONE 0
++#define QPLAN_QC 1 << 0
++#define QPLAN_QC_NO 1 << 1
++#define QPLAN_FULL_SCAN 1 << 2
++#define QPLAN_FULL_JOIN 1 << 3
++#define QPLAN_TMP_TABLE 1 << 4
++#define QPLAN_TMP_DISK 1 << 5
++#define QPLAN_FILESORT 1 << 6
++#define QPLAN_FILESORT_DISK 1 << 7
++/* ... */
++#define QPLAN_MAX 1 << 31
++
++#define SLOG_F_QC_NO QPLAN_QC_NO
++#define SLOG_F_FULL_SCAN QPLAN_FULL_SCAN
++#define SLOG_F_FULL_JOIN QPLAN_FULL_JOIN
++#define SLOG_F_TMP_TABLE QPLAN_TMP_TABLE
++#define SLOG_F_TMP_DISK QPLAN_TMP_DISK
++#define SLOG_F_FILESORT QPLAN_FILESORT
++#define SLOG_F_FILESORT_DISK QPLAN_FILESORT_DISK
++#define SLOG_F_INVALID 1 << 31
++#define SLOG_F_NONE 0
++
++static const struct msl_opts slog_filter[]=
++{
++ { SLOG_F_QC_NO, "qc_miss" },
++ { SLOG_F_FULL_SCAN, "full_scan" },
++ { SLOG_F_FULL_JOIN, "full_join" },
++ { SLOG_F_TMP_TABLE, "tmp_table" },
++ { SLOG_F_TMP_DISK, "tmp_table_on_disk" },
++ { SLOG_F_FILESORT, "filesort" },
++ { SLOG_F_FILESORT_DISK, "filesort_on_disk" },
++ { SLOG_F_INVALID, (char *)0 }
++};
++
+ enum enum_parsing_place
+ {
+ NO_MATTER,
+@@ -1365,6 +1437,7 @@
+ extern bool using_update_log, opt_large_files, server_id_supplied;
+ extern bool opt_update_log, opt_bin_log, opt_error_log;
+ extern my_bool opt_log, opt_slow_log, opt_log_queries_not_using_indexes;
++extern char *opt_slow_logname;
+ extern bool opt_disable_networking, opt_skip_show_db;
+ extern my_bool opt_character_set_client_handshake;
+ extern bool volatile abort_loop, shutdown_in_progress, grant_option;
+@@ -1376,7 +1449,8 @@
+ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
+ extern my_bool opt_secure_auth;
+ extern char* opt_secure_file_priv;
+-extern my_bool opt_log_slow_admin_statements;
++extern my_bool opt_log_slow_admin_statements, opt_log_slow_slave_statements;
++extern my_bool opt_use_global_long_query_time;
+ extern my_bool sp_automatic_privileges, opt_noacl;
+ extern my_bool opt_old_style_user_limits, trust_function_creators;
+ extern uint opt_crash_binlog_innodb;
+diff -r 1242d4575291 sql/mysqld.cc
+--- a/sql/mysqld.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/mysqld.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -176,7 +176,6 @@
+ static void getvolumeID(BYTE *volumeName);
+ #endif /* __NETWARE__ */
+
+-
+ #ifdef _AIX41
+ int initgroups(const char *,unsigned int);
+ #endif
+@@ -411,10 +410,13 @@
+ my_bool opt_secure_auth= 0;
+ char* opt_secure_file_priv= 0;
+ my_bool opt_log_slow_admin_statements= 0;
++my_bool opt_log_slow_slave_statements= 0;
++my_bool opt_use_global_long_query_time= 0;
+ my_bool lower_case_file_system= 0;
+ my_bool opt_large_pages= 0;
+ uint opt_large_page_size= 0;
+ my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
++char* opt_slow_logname= 0;
+ /*
+ True if there is at least one per-hour limit for some user, so we should
+ check them before each query (and possibly reset counters when hour is
+@@ -509,6 +511,7 @@
+ Ge_creator ge_creator;
+ Le_creator le_creator;
+
++ulonglong frequency= 0;
+
+ FILE *bootstrap_file;
+ int bootstrap_error;
+@@ -588,7 +591,7 @@
+ static int cleanup_done;
+ static ulong opt_specialflag, opt_myisam_block_size;
+ static char *opt_logname, *opt_update_logname, *opt_binlog_index_name;
+-static char *opt_slow_logname, *opt_tc_heuristic_recover;
++static char *opt_tc_heuristic_recover;
+ static char *mysql_home_ptr, *pidfile_name_ptr;
+ static char **defaults_argv;
+ static char *opt_bin_logname;
+@@ -3697,6 +3700,8 @@
+ unireg_abort(1);
+ }
+ }
++ if (!QueryPerformanceFrequency((LARGE_INTEGER *)&frequency))
++ frequency= 0;
+ #endif /* __WIN__ */
+
+ if (init_common_variables(MYSQL_CONFIG_NAME,
+@@ -4947,7 +4952,7 @@
+ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
+ OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
+ OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
+- OPT_LONG_QUERY_TIME,
++ OPT_LONG_QUERY_TIME, OPT_MIN_EXAMINED_ROW_LIMIT,
+ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
+ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
+ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
+@@ -5038,11 +5043,18 @@
+ OPT_TIMED_MUTEXES,
+ OPT_OLD_STYLE_USER_LIMITS,
+ OPT_LOG_SLOW_ADMIN_STATEMENTS,
++ OPT_LOG_SLOW_SLAVE_STATEMENTS,
++ OPT_LOG_SLOW_RATE_LIMIT,
++ OPT_LOG_SLOW_VERBOSITY,
++ OPT_LOG_SLOW_FILTER,
+ OPT_TABLE_LOCK_WAIT_TIMEOUT,
+ OPT_PLUGIN_DIR,
+ OPT_PORT_OPEN_TIMEOUT,
+ OPT_MERGE,
+ OPT_PROFILING,
++ OPT_SLOW_LOG,
++ OPT_SLOW_QUERY_LOG_FILE,
++ OPT_USE_GLOBAL_LONG_QUERY_TIME,
+ OPT_INNODB_ROLLBACK_ON_TIMEOUT,
+ OPT_SECURE_FILE_PRIV,
+ OPT_KEEP_FILES_ON_CREATE,
+@@ -5441,10 +5453,19 @@
+ (gptr*) &opt_log_slow_admin_statements,
+ (gptr*) &opt_log_slow_admin_statements,
+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
++ "Log slow replicated statements to the slow log if it is open.",
++ (gptr*) &opt_log_slow_slave_statements,
++ (gptr*) &opt_log_slow_slave_statements,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ {"log-slow-queries", OPT_SLOW_QUERY_LOG,
+ "Log slow queries to this log file. Defaults logging to hostname-slow.log file. Must be enabled to activate other slow log options.",
+ (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
++ {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE,
++ "Log slow queries to given log file. Defaults logging to hostname-slow.log. Must be enabled to activate other slow log options.",
++ (gptr*) &opt_slow_logname, (gptr*) &opt_slow_logname, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
+ {"log-tc", OPT_LOG_TC,
+ "Path to transaction coordinator log (used for transactions that affect "
+ "more than one storage engine, when binary log is disabled)",
+@@ -5808,6 +5829,9 @@
+ "Tells the slave thread to continue replication when a query returns an error from the provided list.",
+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ #endif
++ {"slow-query-log", OPT_SLOW_LOG,
++ "Enable|disable slow query log", (gptr*) &opt_slow_log,
++ (gptr*) &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
+ {"socket", OPT_SOCKET, "Socket file to use for connection.",
+ (gptr*) &mysqld_unix_port, (gptr*) &mysqld_unix_port, 0, GET_STR,
+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+@@ -6110,11 +6134,31 @@
+ (gptr*) 0,
+ 0, (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100,
+ 1, 100, 0, 1, 0},
+- {"long_query_time", OPT_LONG_QUERY_TIME,
+- "Log all queries that have taken more than long_query_time seconds to execute to file.",
+- (gptr*) &global_system_variables.long_query_time,
+- (gptr*) &max_system_variables.long_query_time, 0, GET_ULONG,
+- REQUIRED_ARG, 10, 1, LONG_TIMEOUT, 0, 1, 0},
++ {"log_slow_filter", OPT_LOG_SLOW_FILTER,
++ "Log only the queries that followed certain execution plan. Multiple flags allowed in a comma-separated string. [qc_miss, full_scan, full_join, tmp_table, tmp_table_on_disk, filesort, filesort_on_disk]",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_F_NONE, 0, 0},
++ {"log_slow_rate_limit", OPT_LOG_SLOW_RATE_LIMIT,
++ "Rate limit statement writes to slow log to only those from every (1/log_slow_rate_limit) session.",
++ (gptr*) &global_system_variables.log_slow_rate_limit,
++ (gptr*) &max_system_variables.log_slow_rate_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 1, 1, LONG_MAX, 0, 1L, 0},
++ {"log_slow_verbosity", OPT_LOG_SLOW_VERBOSITY,
++ "Choose how verbose the messages to your slow log will be. Multiple flags allowed in a comma-separated string. [microtime, query_plan, innodb]",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, SLOG_V_MICROTIME, 0, 0},
++ {"long_query_time", OPT_LONG_QUERY_TIME,
++ "Log all queries that have taken more than long_query_time seconds to execute to file.",
++ (gptr*) &global_system_variables.long_query_time,
++ (gptr*) &max_system_variables.long_query_time, 0, GET_MICROTIME,
++ REQUIRED_ARG, 10000000, 0, LONG_TIMEOUT * 1000000, 0, 1, 0},
++ {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
++ "Don't log queries which examine less than min_examined_row_limit rows to file.",
++ (gptr*) &global_system_variables.min_examined_row_limit,
++ (gptr*) &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, LONG_MAX, 0, 1L, 0},
++ {"use_global_long_query_time", OPT_USE_GLOBAL_LONG_QUERY_TIME,
++ "Control always use global long_query_time or local long_query_time.",
++ (gptr*) &opt_use_global_long_query_time, (gptr*) &opt_use_global_long_query_time,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
+ "If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system",
+ (gptr*) &lower_case_table_names,
+@@ -6893,7 +6937,11 @@
+ global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
+ max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
+ global_system_variables.old_passwords= 0;
+-
++ global_system_variables.long_query_time = 10000000;
++ max_system_variables.long_query_time = LONG_TIMEOUT * 1000000;
++ global_system_variables.log_slow_verbosity= SLOG_V_MICROTIME;
++ global_system_variables.log_slow_filter= SLOG_F_NONE;
++
+ /*
+ Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
+ when collecting index statistics for MyISAM tables.
+@@ -7364,6 +7412,35 @@
+ case OPT_BOOTSTRAP:
+ opt_noacl=opt_bootstrap=1;
+ break;
++ case OPT_LOG_SLOW_FILTER:
++ if ((global_system_variables.log_slow_filter=
++ msl_flag_resolve_by_name(slog_filter, argument,
++ SLOG_F_NONE, SLOG_F_INVALID)) == SLOG_F_INVALID)
++ {
++ fprintf(stderr,"Invalid argument in log_slow_filter: %s\n", argument);
++ exit(1);
++ }
++ break;
++ case OPT_LOG_SLOW_VERBOSITY:
++ if ((global_system_variables.log_slow_verbosity=
++ msl_flag_resolve_by_name(slog_verb, argument,
++ SLOG_V_NONE, SLOG_V_INVALID)) == SLOG_V_INVALID)
++ {
++ fprintf(stderr,"Invalid argument in log_slow_verbosity: %s\n", argument);
++ exit(1);
++ }
++ break;
++ case OPT_LONG_QUERY_TIME:
++ {
++ double doubleslow = strtod(argument,NULL);
++ if (doubleslow < 0 || doubleslow > (LONG_TIMEOUT))
++ {
++ fprintf(stderr,"Out of range long_query_time value: %s\n", argument);
++ exit(1);
++ }
++ global_system_variables.long_query_time = (ulonglong) (doubleslow * 1000000);
++ break;
++ }
+ case OPT_STORAGE_ENGINE:
+ {
+ if ((enum db_type)((global_system_variables.table_type=
+@@ -7696,10 +7773,14 @@
+ if (opt_bdb)
+ sql_print_warning("this binary does not contain BDB storage engine");
+ #endif
+- if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes) &&
++ if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
++ opt_log_slow_slave_statements) &&
+ !opt_slow_log)
+- sql_print_warning("options --log-slow-admin-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
+-
++ {
++ sql_print_warning("options --log-slow-admin-statements, --log-slow-slave-statements and --log-queries-not-using-indexes have no effect if --log-slow-queries is not set");
++ opt_log_slow_slave_statements= FALSE;
++ }
++
+ if (argc > 0)
+ {
+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\nUse --help to get a list of available options\n", my_progname, *argv);
+diff -r 1242d4575291 sql/set_var.cc
+--- a/sql/set_var.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/set_var.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -217,9 +217,13 @@
+ sys_log_queries_not_using_indexes("log_queries_not_using_indexes",
+ &opt_log_queries_not_using_indexes);
+ sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
+-sys_var_thd_ulong sys_long_query_time("long_query_time",
++sys_var_thd_microtime sys_long_query_time("long_query_time",
+ &SV::long_query_time);
++sys_var_bool_ptr sys_use_global_long_query_time("use_global_long_query_time",
++ &opt_use_global_long_query_time);
+ sys_var_bool_const_ptr sys_log_slow("log_slow_queries", &opt_slow_log);
++sys_var_log_slow sys_slow_query_log("slow_query_log", &opt_slow_log);
++sys_var_const_str_ptr sys_slow_query_log_file("slow_query_log_file", &opt_slow_logname);
+ sys_var_thd_bool sys_low_priority_updates("low_priority_updates",
+ &SV::low_priority_updates,
+ fix_low_priority_updates);
+@@ -283,6 +287,8 @@
+ &SV::max_tmp_tables);
+ sys_var_long_ptr sys_max_write_lock_count("max_write_lock_count",
+ &max_write_lock_count);
++sys_var_thd_ulong sys_min_examined_row_limit("min_examined_row_limit",
++ &SV::min_examined_row_limit);
+ sys_var_thd_ulong sys_multi_range_count("multi_range_count",
+ &SV::multi_range_count);
+ sys_var_long_ptr sys_myisam_data_pointer_size("myisam_data_pointer_size",
+@@ -327,6 +333,20 @@
+ sys_var_bool_ptr sys_relay_log_purge("relay_log_purge",
+ &relay_log_purge);
+ #endif
++sys_var_thd_ulong sys_log_slow_rate_limit("log_slow_rate_limit",
++ &SV::log_slow_rate_limit);
++sys_var_thd_msl_flag sys_log_slow_filter("log_slow_filter",
++ &SV::log_slow_filter,
++ SLOG_F_NONE,
++ SLOG_F_NONE,
++ SLOG_F_INVALID,
++ slog_filter);
++sys_var_thd_msl_flag sys_log_slow_verbosity("log_slow_verbosity",
++ &SV::log_slow_verbosity,
++ SLOG_V_NONE,
++ SLOG_V_MICROTIME,
++ SLOG_V_INVALID,
++ slog_verb);
+ sys_var_long_ptr sys_rpl_recovery_rank("rpl_recovery_rank",
+ &rpl_recovery_rank);
+ sys_var_long_ptr sys_query_cache_size("query_cache_size",
+@@ -697,6 +717,10 @@
+ &sys_log_off,
+ &sys_log_queries_not_using_indexes,
+ &sys_log_slow,
++ &sys_log_slow_filter,
++ &sys_log_slow_rate_limit,
++ &sys_log_slow_verbosity,
++ &sys_use_global_long_query_time,
+ &sys_log_update,
+ &sys_log_warnings,
+ &sys_long_query_time,
+@@ -720,6 +744,7 @@
+ &sys_max_tmp_tables,
+ &sys_max_user_connections,
+ &sys_max_write_lock_count,
++ &sys_min_examined_row_limit,
+ &sys_multi_range_count,
+ &sys_myisam_data_pointer_size,
+ &sys_myisam_max_sort_file_size,
+@@ -773,6 +798,8 @@
+ &sys_slave_skip_counter,
+ #endif
+ &sys_slow_launch_time,
++ &sys_slow_query_log,
++ &sys_slow_query_log_file,
+ &sys_sort_buffer,
+ &sys_sql_big_tables,
+ &sys_sql_low_priority_updates,
+@@ -994,8 +1021,11 @@
+ {"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
+ #endif
+ {sys_log_slow.name, (char*) &sys_log_slow, SHOW_SYS},
++ {sys_log_slow_filter.name, (char*) &sys_log_slow_filter, SHOW_SYS},
++ {sys_log_slow_rate_limit.name, (char*) &sys_log_slow_rate_limit, SHOW_SYS},
++ {sys_log_slow_verbosity.name, (char*) &sys_log_slow_verbosity, SHOW_SYS},
+ {sys_log_warnings.name, (char*) &sys_log_warnings, SHOW_SYS},
+- {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_SYS},
++ {sys_long_query_time.name, (char*) &sys_long_query_time, SHOW_MICROTIME},
+ {sys_low_priority_updates.name, (char*) &sys_low_priority_updates, SHOW_SYS},
+ {"lower_case_file_system", (char*) &lower_case_file_system, SHOW_MY_BOOL},
+ {"lower_case_table_names", (char*) &lower_case_table_names, SHOW_INT},
+@@ -1022,6 +1052,7 @@
+ {sys_max_tmp_tables.name, (char*) &sys_max_tmp_tables, SHOW_SYS},
+ {sys_max_user_connections.name,(char*) &sys_max_user_connections, SHOW_SYS},
+ {sys_max_write_lock_count.name, (char*) &sys_max_write_lock_count,SHOW_SYS},
++ {sys_min_examined_row_limit.name, (char*) &sys_min_examined_row_limit, SHOW_SYS},
+ {sys_multi_range_count.name, (char*) &sys_multi_range_count, SHOW_SYS},
+ {sys_myisam_data_pointer_size.name, (char*) &sys_myisam_data_pointer_size, SHOW_SYS},
+ {sys_myisam_max_sort_file_size.name, (char*) &sys_myisam_max_sort_file_size,
+@@ -1109,6 +1140,8 @@
+ {sys_slave_trans_retries.name,(char*) &sys_slave_trans_retries, SHOW_SYS},
+ #endif
+ {sys_slow_launch_time.name, (char*) &sys_slow_launch_time, SHOW_SYS},
++ {sys_slow_query_log.name, (char*) &sys_slow_query_log, SHOW_SYS},
++ {sys_slow_query_log_file.name,(char*) &sys_slow_query_log_file, SHOW_SYS},
+ #ifdef HAVE_SYS_UN_H
+ {"socket", (char*) &mysqld_unix_port, SHOW_CHAR_PTR},
+ #endif
+@@ -1149,6 +1182,7 @@
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+ {sys_updatable_views_with_limit.name,
+ (char*) &sys_updatable_views_with_limit,SHOW_SYS},
++ {sys_use_global_long_query_time.name, (char*) &sys_use_global_long_query_time, SHOW_SYS},
+ {sys_version.name, (char*) &sys_version, SHOW_SYS},
+ #ifdef HAVE_BERKELEY_DB
+ {sys_version_bdb.name, (char*) &sys_version_bdb, SHOW_SYS},
+@@ -1777,6 +1811,17 @@
+ }
+
+
++bool sys_var_thd_microtime::check(THD *thd, set_var *var)
++{
++ if (var->value->result_type() == DECIMAL_RESULT)
++ var->save_result.ulonglong_value= (ulonglong)(var->value->val_real() * 1000000);
++ else
++ var->save_result.ulonglong_value= (ulonglong)(var->value->val_int() * 1000000);
++
++ return 0;
++}
++
++
+ bool sys_var_thd_bool::update(THD *thd, set_var *var)
+ {
+ if (var->type == OPT_GLOBAL)
+@@ -1933,6 +1978,19 @@
+ pthread_mutex_unlock(&LOCK_global_system_variables);
+ return new Item_int(value);
+ }
++ case SHOW_MICROTIME:
++ {
++ longlong value;
++ char buff[80];
++ int len;
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ value= *(longlong*) value_ptr(thd, var_type, base);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ len = snprintf(buff, 80, "%f", ((double) value) / 1000000.0);
++ return new Item_float(buff,len);
++ }
+ case SHOW_HA_ROWS:
+ {
+ ha_rows value;
+@@ -2765,6 +2823,30 @@
+ }
+
+
++bool sys_var_log_slow::update(THD *thd, set_var *var)
++{
++ bool ret;
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ if (var->save_result.ulong_value)
++ {
++ if(!mysql_slow_log.is_open())
++ {
++ mysql_slow_log.open_slow_log(opt_slow_logname);
++ }
++ }
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ ret = sys_var_bool_ptr::update(thd, var);
++
++#ifdef HAVE_INNOBASE_DB
++ innobase_update_var_slow_log();
++#endif
++
++ return(ret);
++}
++
++
+ #ifdef HAVE_REPLICATION
+ bool sys_var_slave_skip_counter::check(THD *thd, set_var *var)
+ {
+@@ -3549,6 +3631,191 @@
+ #endif
+ }
+
++/* Slow log stuff */
++
++ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len)
++{
++ ulong i;
++
++ for (i=0; opts[i].name; i++)
++ {
++ if (!my_strnncoll(&my_charset_latin1,
++ (const uchar *)name, len,
++ (const uchar *)opts[i].name, strlen(opts[i].name)))
++ return opts[i].val;
++ }
++ return opts[i].val;
++}
++
++ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list,
++ const ulong none_val, const ulong invalid_val)
++{
++ const char *p, *e;
++ ulong val= none_val;
++
++ if (!*names_list)
++ return val;
++
++ for (p= e= names_list; ; e++)
++ {
++ ulong i;
++
++ if (*e != ',' && *e)
++ continue;
++ for (i=0; opts[i].name; i++)
++ {
++ if (!my_strnncoll(&my_charset_latin1,
++ (const uchar *)p, e - p,
++ (const uchar *)opts[i].name, strlen(opts[i].name)))
++ {
++ val= val | opts[i].val;
++ break;
++ }
++ }
++ if (opts[i].val == invalid_val)
++ return invalid_val;
++ if (!*e)
++ break;
++ p= e + 1;
++ }
++ return val;
++}
++
++const char *msl_option_get_name(const struct msl_opts *opts, ulong val)
++{
++ for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
++ {
++ if (opts[i].val == val)
++ return opts[i].name;
++ }
++ return "*INVALID*";
++}
++
++char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val)
++{
++ uint offset= 0;
++
++ *buf= '\0';
++ for (ulong i=0; opts[i].name && opts[i].name[0]; i++)
++ {
++ if (opts[i].val & val)
++ offset+= snprintf(buf+offset, STRING_BUFFER_USUAL_SIZE - offset - 1,
++ "%s%s", (offset ? "," : ""), opts[i].name);
++ }
++ return buf;
++}
++
++/****************************************************************************
++ Functions to handle log_slow_verbosity
++****************************************************************************/
++
++/* Based upon sys_var::check_enum() */
++
++bool sys_var_thd_msl_option::check(THD *thd, set_var *var)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ ulong verb= this->invalid_val;
++ if (!(res=var->value->val_str(&str)) ||
++ (var->save_result.ulong_value=
++ (ulong) (verb= msl_option_resolve_by_name(this->opts, res->ptr(), res->length()))) == this->invalid_val)
++ goto err;
++ return 0;
++ }
++
++err:
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
++ return 1;
++}
++
++byte *sys_var_thd_msl_option::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ ulong val;
++ val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ const char *verbosity= msl_option_get_name(this->opts, val);
++ return (byte *) verbosity;
++}
++
++
++void sys_var_thd_msl_option::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) this->default_val;
++ else
++ thd->variables.*offset= (ulong) (global_system_variables.*offset);
++}
++
++
++bool sys_var_thd_msl_option::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.ulong_value;
++ else
++ thd->variables.*offset= var->save_result.ulong_value;
++ return 0;
++}
++
++/****************************************************************************
++ Functions to handle log_slow_filter
++****************************************************************************/
++
++/* Based upon sys_var::check_enum() */
++
++bool sys_var_thd_msl_flag::check(THD *thd, set_var *var)
++{
++ char buff[2 * STRING_BUFFER_USUAL_SIZE];
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ ulong filter= this->none_val;
++ if (!(res=var->value->val_str(&str)) ||
++ (var->save_result.ulong_value=
++ (ulong) (filter= msl_flag_resolve_by_name(this->flags, res->ptr(), this->none_val,
++ this->invalid_val))) == this->invalid_val)
++ goto err;
++ return 0;
++ }
++
++err:
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), var->var->name);
++ return 1;
++}
++
++byte *sys_var_thd_msl_flag::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ ulong val;
++ val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ msl_flag_get_name(this->flags, this->flags_string, val);
++ return (byte *) this->flags_string;
++}
++
++
++void sys_var_thd_msl_flag::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) this->default_val;
++ else
++ thd->variables.*offset= (ulong) (global_system_variables.*offset);
++}
++
++
++bool sys_var_thd_msl_flag::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.ulong_value;
++ else
++ thd->variables.*offset= var->save_result.ulong_value;
++ return 0;
++}
++
+ /****************************************************************************
+ Functions to handle table_type
+ ****************************************************************************/
+diff -r 1242d4575291 sql/set_var.h
+--- a/sql/set_var.h Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/set_var.h Tue Jul 28 23:42:44 2009 -0700
+@@ -132,6 +132,7 @@
+ };
+
+
++
+ class sys_var_ulonglong_ptr :public sys_var
+ {
+ public:
+@@ -168,6 +169,13 @@
+ bool check_update_type(Item_result type) { return 0; }
+ };
+
++class sys_var_log_slow :public sys_var_bool_ptr
++{
++public:
++ sys_var_log_slow(const char *name_arg, my_bool *value_arg)
++ :sys_var_bool_ptr(name_arg, value_arg) {}
++ bool update(THD *thd, set_var *var);
++};
+
+ class sys_var_bool_const_ptr : public sys_var
+ {
+@@ -340,7 +348,6 @@
+ }
+ };
+
+-
+ class sys_var_thd_ulong :public sys_var_thd
+ {
+ sys_check_func check_func;
+@@ -360,7 +367,6 @@
+ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ };
+
+-
+ class sys_var_thd_ha_rows :public sys_var_thd
+ {
+ public:
+@@ -378,7 +384,6 @@
+ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
+ };
+
+-
+ class sys_var_thd_ulonglong :public sys_var_thd
+ {
+ public:
+@@ -407,6 +412,19 @@
+ }
+ };
+
++class sys_var_thd_microtime :public sys_var_thd_ulonglong
++{
++public:
++ sys_var_thd_microtime(const char *name_arg, ulonglong SV::*offset_arg)
++ :sys_var_thd_ulonglong(name_arg, offset_arg)
++ {}
++ SHOW_TYPE show_type() { return SHOW_MICROTIME; }
++ bool check(THD *thd, set_var *var);
++ bool check_update_type(Item_result type)
++ {
++ return type != INT_RESULT && type != DECIMAL_RESULT;
++ }
++};
+
+ class sys_var_thd_bool :public sys_var_thd
+ {
+@@ -478,6 +496,66 @@
+ };
+
+
++class sys_var_thd_msl_option :public sys_var_thd
++{
++protected:
++ ulong SV::*offset;
++ const ulong none_val;
++ const ulong default_val;
++ const ulong invalid_val;
++ const struct msl_opts *opts;
++public:
++ sys_var_thd_msl_option(const char *name_arg, ulong SV::*offset_arg,
++ const ulong none_val_arg,
++ const ulong default_val_arg,
++ const ulong invalid_val_arg,
++ const struct msl_opts *opts_arg)
++ :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
++ default_val(default_val_arg), invalid_val(invalid_val_arg),
++ opts(opts_arg)
++ {}
++ bool check(THD *thd, set_var *var);
++ SHOW_TYPE show_type() { return SHOW_CHAR; }
++ bool check_update_type(Item_result type)
++ {
++ return type != STRING_RESULT; /* Only accept strings */
++ }
++ void set_default(THD *thd, enum_var_type type);
++ bool update(THD *thd, set_var *var);
++ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
++};
++
++
++class sys_var_thd_msl_flag :public sys_var_thd
++{
++protected:
++ char flags_string[2 * STRING_BUFFER_USUAL_SIZE];
++ ulong SV::*offset;
++ const ulong none_val;
++ const ulong default_val;
++ const ulong invalid_val;
++ const struct msl_opts *flags;
++public:
++ sys_var_thd_msl_flag(const char *name_arg, ulong SV::*offset_arg,
++ const ulong none_val_arg,
++ const ulong default_val_arg,
++ const ulong invalid_val_arg,
++ const struct msl_opts *flags_arg)
++ :sys_var_thd(name_arg), offset(offset_arg), none_val(none_val_arg),
++ default_val(default_val_arg), invalid_val(invalid_val_arg),
++ flags(flags_arg)
++ {}
++ bool check(THD *thd, set_var *var);
++ SHOW_TYPE show_type() { return SHOW_CHAR; }
++ bool check_update_type(Item_result type)
++ {
++ return type != STRING_RESULT; /* Only accept strings */
++ }
++ void set_default(THD *thd, enum_var_type type);
++ bool update(THD *thd, set_var *var);
++ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base);
++};
++
+ class sys_var_thd_storage_engine :public sys_var_thd
+ {
+ protected:
+@@ -1109,3 +1187,11 @@
+ bool process_key_caches(int (* func) (const char *name, KEY_CACHE *));
+ void delete_elements(I_List<NAMED_LIST> *list,
+ void (*free_element)(const char*, gptr));
++
++/* Slow log functions */
++
++ulong msl_option_resolve_by_name(const struct msl_opts *opts, const char *name, ulong len);
++ulong msl_flag_resolve_by_name(const struct msl_opts *opts, const char *names_list,
++ const ulong none_val, const ulong invalid_val);
++const char *msl_option_get_name(const struct msl_opts *opts, ulong val);
++char *msl_flag_get_name(const struct msl_opts *opts, char *buf, ulong val);
+diff -r 1242d4575291 sql/slave.cc
+--- a/sql/slave.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/slave.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -2983,6 +2983,12 @@
+ + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
+ thd->slave_thread = 1;
+ set_slave_thread_options(thd);
++ if (opt_log_slow_slave_statements)
++ {
++ thd->enable_slow_log= TRUE;
++ /* Slave thread is excluded from rate limiting the slow log writes. */
++ thd->write_to_slow_log= TRUE;
++ }
+ thd->client_capabilities = CLIENT_LOCAL_FILES;
+ thd->real_id=pthread_self();
+ pthread_mutex_lock(&LOCK_thread_count);
+diff -r 1242d4575291 sql/sql_cache.cc
+--- a/sql/sql_cache.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_cache.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -1402,6 +1402,7 @@
+
+ thd->limit_found_rows = query->found_rows();
+ thd->status_var.last_query_cost= 0.0;
++ thd->query_plan_flags|= QPLAN_QC;
+
+ BLOCK_UNLOCK_RD(query_block);
+ DBUG_RETURN(1); // Result sent to client
+@@ -1409,6 +1410,7 @@
+ err_unlock:
+ STRUCT_UNLOCK(&structure_guard_mutex);
+ err:
++ thd->query_plan_flags|= QPLAN_QC_NO;
+ DBUG_RETURN(0); // Query was not cached
+ }
+
+diff -r 1242d4575291 sql/sql_class.cc
+--- a/sql/sql_class.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_class.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -190,7 +190,7 @@
+ table_map_for_update(0),
+ global_read_lock(0), is_fatal_error(0),
+ transaction_rollback_request(0), is_fatal_sub_stmt_error(0),
+- rand_used(0), time_zone_used(0),
++ rand_used(0), time_zone_used(0), user_timer(0),
+ last_insert_id_used(0), last_insert_id_used_bin_log(0), insert_id_used(0),
+ clear_next_insert_id(0), in_lock_tables(0), bootstrap(0),
+ derived_tables_processing(FALSE), spcont(NULL),
+@@ -2251,6 +2251,12 @@
+ backup->cuted_fields= cuted_fields;
+ backup->client_capabilities= client_capabilities;
+ backup->savepoints= transaction.savepoints;
++ backup->innodb_io_reads= innodb_io_reads;
++ backup->innodb_io_read= innodb_io_read;
++ backup->innodb_io_reads_wait_timer= innodb_io_reads_wait_timer;
++ backup->innodb_lock_que_wait_timer= innodb_lock_que_wait_timer;
++ backup->innodb_innodb_que_wait_timer= innodb_innodb_que_wait_timer;
++ backup->innodb_page_access= innodb_page_access;
+
+ if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
+ options&= ~OPTION_BIN_LOG;
+@@ -2267,7 +2273,13 @@
+ sent_row_count= 0;
+ cuted_fields= 0;
+ transaction.savepoints= 0;
+-
++ innodb_io_reads= 0;
++ innodb_io_read= 0;
++ innodb_io_reads_wait_timer= 0;
++ innodb_lock_que_wait_timer= 0;
++ innodb_innodb_que_wait_timer= 0;
++ innodb_page_access= 0;
++
+ /* Surpress OK packets in case if we will execute statements */
+ net.no_send_ok= TRUE;
+ }
+@@ -2320,6 +2332,12 @@
+ */
+ examined_row_count+= backup->examined_row_count;
+ cuted_fields+= backup->cuted_fields;
++ innodb_io_reads+= backup->innodb_io_reads;
++ innodb_io_read+= backup->innodb_io_read;
++ innodb_io_reads_wait_timer+= backup->innodb_io_reads_wait_timer;
++ innodb_lock_que_wait_timer+= backup->innodb_lock_que_wait_timer;
++ innodb_innodb_que_wait_timer+= backup->innodb_innodb_que_wait_timer;
++ innodb_page_access+= backup->innodb_page_access;
+ }
+
+
+diff -r 1242d4575291 sql/sql_class.h
+--- a/sql/sql_class.h Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_class.h Tue Jul 28 23:42:44 2009 -0700
+@@ -43,6 +43,7 @@
+ extern char internal_table_name[2];
+ extern char empty_c_string[1];
+ extern const char **errmesg;
++extern ulonglong frequency;
+
+ #define TC_LOG_PAGE_SIZE 8192
+ #define TC_LOG_MIN_SIZE (3*TC_LOG_PAGE_SIZE)
+@@ -321,7 +322,7 @@
+ bool write(THD *thd, enum enum_server_command command,
+ const char *format, ...) ATTRIBUTE_FORMAT(printf, 4, 5);
+ bool write(THD *thd, const char *query, uint query_length,
+- time_t query_start=0);
++ time_t query_start=0, ulonglong query_start_timer=0);
+ bool write(Log_event* event_info); // binary log write
+ bool write(THD *thd, IO_CACHE *cache, Log_event *commit_event);
+
+@@ -527,13 +528,14 @@
+ ulong auto_increment_increment, auto_increment_offset;
+ ulong bulk_insert_buff_size;
+ ulong join_buff_size;
+- ulong long_query_time;
++ ulonglong long_query_time;
+ ulong max_allowed_packet;
+ ulong max_error_count;
+ ulong max_length_for_sort_data;
+ ulong max_sort_length;
+ ulong max_tmp_tables;
+ ulong max_insert_delayed_threads;
++ ulong min_examined_row_limit;
+ ulong multi_range_count;
+ ulong myisam_repair_threads;
+ ulong myisam_sort_buff_size;
+@@ -549,10 +551,13 @@
+ ulong preload_buff_size;
+ ulong profiling_history_size;
+ ulong query_cache_type;
++ ulong log_slow_rate_limit;
+ ulong read_buff_size;
+ ulong read_rnd_buff_size;
+ ulong div_precincrement;
+ ulong sortbuff_size;
++ ulong log_slow_filter;
++ ulong log_slow_verbosity;
+ ulong table_type;
+ ulong tx_isolation;
+ ulong completion_type;
+@@ -1129,6 +1134,12 @@
+ uint in_sub_stmt;
+ bool enable_slow_log, insert_id_used, clear_next_insert_id;
+ bool last_insert_id_used;
++ ulong innodb_io_reads;
++ ulonglong innodb_io_read;
++ ulong innodb_io_reads_wait_timer;
++ ulong innodb_lock_que_wait_timer;
++ ulong innodb_innodb_que_wait_timer;
++ ulong innodb_page_access;
+ my_bool no_send_ok;
+ SAVEPOINT *savepoints;
+ };
+@@ -1185,6 +1196,11 @@
+ class THD :public Statement,
+ public Open_tables_state
+ {
++private:
++ inline ulonglong query_start_timer() { return start_timer; }
++ inline void set_timer() { if (user_timer) start_timer=timer_after_lock=user_timer; else timer_after_lock=my_timer(&start_timer, frequency); }
++ inline void end_timer() { my_timer(&start_timer, frequency); }
++ inline void lock_timer() { my_timer(&timer_after_lock, frequency); }
+ public:
+ /*
+ Constant for THD::where initialization in the beginning of every query.
+@@ -1293,10 +1309,24 @@
+ */
+ const char *where;
+ time_t start_time,time_after_lock,user_time;
++ ulonglong start_timer,timer_after_lock, user_timer;
+ time_t connect_time,thr_create_time; // track down slow pthread_create
+ thr_lock_type update_lock_default;
+ Delayed_insert *di;
+
++ bool write_to_slow_log;
++
++ bool innodb_was_used;
++ ulong innodb_io_reads;
++ ulonglong innodb_io_read;
++ ulong innodb_io_reads_wait_timer;
++ ulong innodb_lock_que_wait_timer;
++ ulong innodb_innodb_que_wait_timer;
++ ulong innodb_page_access;
++
++ ulong query_plan_flags;
++ ulong query_plan_fsort_passes;
++
+ /* <> 0 if we are inside of trigger or stored function. */
+ uint in_sub_stmt;
+
+@@ -1696,11 +1726,11 @@
+ sql_print_information("time() failed with %d", errno);
+ }
+
+- inline time_t query_start() { query_start_used=1; return start_time; }
+- inline void set_time() { if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }}
+- inline void end_time() { safe_time(&start_time); }
+- inline void set_time(time_t t) { time_after_lock=start_time=user_time=t; }
+- inline void lock_time() { safe_time(&time_after_lock); }
++ inline time_t query_start() { query_start_timer(); query_start_used=1; return start_time; }
++ inline void set_time() { set_timer(); if (user_time) start_time=time_after_lock=user_time; else { safe_time(&start_time); time_after_lock= start_time; }}
++ inline void end_time() { end_timer(); safe_time(&start_time); }
++ inline void set_time(time_t t) { set_timer(); time_after_lock=start_time=user_time=t; }
++ inline void lock_time() { lock_timer(); safe_time(&time_after_lock); }
+ /*TODO: this will be obsolete when we have support for 64 bit my_time_t */
+ inline bool is_valid_time()
+ {
+diff -r 1242d4575291 sql/sql_parse.cc
+--- a/sql/sql_parse.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_parse.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -20,6 +20,7 @@
+ #include <m_ctype.h>
+ #include <myisam.h>
+ #include <my_dir.h>
++#include <my_time.h>
+
+ #ifdef HAVE_INNOBASE_DB
+ #include "ha_innodb.h"
+@@ -1227,6 +1228,15 @@
+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
+ my_net_set_write_timeout(net, thd->variables.net_write_timeout);
+
++ /*
++ If rate limiting of slow log writes is enabled, decide whether to log this
++ new thread's queries or not. Uses extremely simple algorithm. :)
++ */
++ thd->write_to_slow_log= FALSE;
++ if (thd->variables.log_slow_rate_limit <= 1 ||
++ (thd->thread_id % thd->variables.log_slow_rate_limit) == 0)
++ thd->write_to_slow_log= TRUE;
++
+ while (!net->error && net->vio != 0 &&
+ !(thd->killed == THD::KILL_CONNECTION))
+ {
+@@ -2353,28 +2363,57 @@
+ return; // Don't set time for sub stmt
+
+ start_of_query= thd->start_time;
+- thd->end_time(); // Set start time
++ ulonglong start_of_query_timer= thd->start_timer;
++ thd->end_time(); // Set start timea
++
++
++ /* Follow the slow log filter configuration. */
++ if (thd->variables.log_slow_filter != SLOG_F_NONE &&
++ (!(thd->variables.log_slow_filter & thd->query_plan_flags) ||
++ ((thd->variables.log_slow_filter & SLOG_F_QC_NO) &&
++ (thd->query_plan_flags & QPLAN_QC))))
++ return;
++
++ /*
++ Low long_query_time value most likely means user is debugging stuff and even
++ though some thread's queries are not supposed to be logged b/c of the rate
++ limit, if one of them takes long enough (>= 1 second) it will be sensible
++ to make an exception and write to slow log anyway.
++ */
++
++ if (opt_use_global_long_query_time)
++ thd->variables.long_query_time = global_system_variables.long_query_time;
++
++ /* Do not log this thread's queries due to rate limiting. */
++ if (thd->write_to_slow_log != TRUE
++ && (thd->variables.long_query_time >= 1000000
++ || (ulong) (thd->start_timer - thd->timer_after_lock) < 1000000))
++ return;
++
+
+ /*
+ Do not log administrative statements unless the appropriate option is
+ set; do not log into slow log if reading from backup.
+ */
+- if (thd->enable_slow_log && !thd->user_time)
++ if (thd->enable_slow_log &&
++ (!thd->user_time || (thd->slave_thread && opt_log_slow_slave_statements))
++ )
++
+ {
+ thd_proc_info(thd, "logging slow query");
+
+- if ((thd->start_time > thd->time_after_lock &&
+- (ulong) (thd->start_time - thd->time_after_lock) >
+- thd->variables.long_query_time) ||
+- ((thd->server_status &
+- (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
+- opt_log_queries_not_using_indexes &&
+- /* == SQLCOM_END unless this is a SHOW command */
+- thd->lex->orig_sql_command == SQLCOM_END))
++ if (((ulong) (thd->start_timer - thd->timer_after_lock) >=
++ thd->variables.long_query_time ||
++ (thd->server_status &
++ (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
++ opt_log_queries_not_using_indexes &&
++ /* == SQLCOM_END unless this is a SHOW command */
++ thd->lex->orig_sql_command == SQLCOM_END) &&
++ thd->examined_row_count >= thd->variables.min_examined_row_limit)
+ {
+ thd_proc_info(thd, "logging slow query");
+ thd->status_var.long_query_count++;
+- mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
++ mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query, start_of_query_timer);
+ }
+ }
+ }
+@@ -2669,6 +2708,8 @@
+ context.resolve_in_table_list_only((TABLE_LIST*)select_lex->
+ table_list.first);
+
++ /* Reset the counter at all cases for the extended slow query log */
++ thd->row_count= 1;
+ /*
+ Reset warning count for each query that uses tables
+ A better approach would be to reset this for any commands
+@@ -6203,6 +6244,15 @@
+ thd->total_warn_count=0; // Warnings for this query
+ thd->rand_used= 0;
+ thd->sent_row_count= thd->examined_row_count= 0;
++ thd->innodb_was_used= FALSE;
++ thd->innodb_io_reads= 0;
++ thd->innodb_io_read= 0;
++ thd->innodb_io_reads_wait_timer= 0;
++ thd->innodb_lock_que_wait_timer= 0;
++ thd->innodb_innodb_que_wait_timer= 0;
++ thd->innodb_page_access= 0;
++ thd->query_plan_flags= QPLAN_NONE;
++ thd->query_plan_fsort_passes= 0;
+ }
+ DBUG_VOID_RETURN;
+ }
+diff -r 1242d4575291 sql/sql_select.cc
+--- a/sql/sql_select.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_select.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -6272,8 +6272,11 @@
+ {
+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
+ if (statistics)
++ {
+ statistic_increment(join->thd->status_var.select_scan_count,
+ &LOCK_status);
++ join->thd->query_plan_flags|= QPLAN_FULL_SCAN;
++ }
+ }
+ }
+ else
+@@ -6288,8 +6291,11 @@
+ {
+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
+ if (statistics)
++ {
+ statistic_increment(join->thd->status_var.select_full_join_count,
+ &LOCK_status);
++ join->thd->query_plan_flags|= QPLAN_FULL_JOIN;
++ }
+ }
+ }
+ if (!table->no_keyread)
+@@ -9350,6 +9356,7 @@
+ (ulong) rows_limit,test(group)));
+
+ statistic_increment(thd->status_var.created_tmp_tables, &LOCK_status);
++ thd->query_plan_flags|= QPLAN_TMP_TABLE;
+
+ if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
+ temp_pool_slot = bitmap_set_next(&temp_pool);
+@@ -10210,6 +10217,7 @@
+ }
+ statistic_increment(table->in_use->status_var.created_tmp_disk_tables,
+ &LOCK_status);
++ table->in_use->query_plan_flags|= QPLAN_TMP_DISK;
+ table->s->db_record_offset= 1;
+ DBUG_RETURN(0);
+ err:
+diff -r 1242d4575291 sql/sql_show.cc
+--- a/sql/sql_show.cc Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/sql_show.cc Tue Jul 28 23:42:44 2009 -0700
+@@ -1560,6 +1560,12 @@
+ case SHOW_LONGLONG:
+ end= longlong10_to_str(*(longlong*) value, buff, 10);
+ break;
++ case SHOW_MICROTIME:
++ show_type= ((sys_var*) value)->show_type();
++ value= (char*) ((sys_var*) value)->value_ptr(thd, value_type,
++ &null_lex_str);
++ end= buff + sprintf(buff, "%f", (((double) (*(ulonglong*)value))) / 1000000.0);
++ break;
+ case SHOW_HA_ROWS:
+ end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
+ break;
+diff -r 1242d4575291 sql/structs.h
+--- a/sql/structs.h Tue Jul 28 23:39:12 2009 -0700
++++ b/sql/structs.h Tue Jul 28 23:42:44 2009 -0700
+@@ -168,8 +168,8 @@
+ enum SHOW_TYPE
+ {
+ SHOW_UNDEF,
+- SHOW_LONG, SHOW_LONGLONG, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
+- SHOW_DOUBLE_STATUS,
++ SHOW_LONG, SHOW_LONGLONG, SHOW_MICROTIME, SHOW_INT, SHOW_CHAR, SHOW_CHAR_PTR,
++ SHOW_DOUBLE_STATUS,
+ SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUERIES,
+ SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
+ SHOW_VARS,
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 1:42 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 1:42 UTC (permalink / raw
To: gentoo-commits
commit: 6af5b9755546974ef03c103850407c75a747451a
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 01:39:55 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 01:39:55 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=6af5b975
Fix previous commit by touching the correct patch reference on 00000_index.txt.
---
00000_index.txt | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 0d7be5e..b3dc69b 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -752,10 +752,15 @@
@@ Percona 5.0.87-b20-20091116: Extended statistics in slow.log
@patch 10020_all_microslow_innodb-percona-5.0.91-b22-20100522.patch
-@ver 5.00.91.00 to 5.00.99.99
+@ver 5.00.91.00 to 5.00.91.99
@pn mysql
@@ Percona 5.0.91-b22-20100522: Extended statistics in slow.log
+@patch 10020_all_microslow_innodb-percona-5.0.92.patch
+@ver 5.00.92.00 to 5.00.99.99
+@pn mysql
+@@ Percona 5.0.92: Extended statistics in slow.log
+
@patch 10021_all_profiling_slow-percona-5.0.83-b17-20090706.patch
@ver 5.00.83.00 to 5.00.83.99
@pn mysql
@@ -772,15 +777,10 @@
@@ Percona 5.0.87-b20-20091116: profiling from SHOW PROFILE to slow.log
@patch 10021_all_profiling_slow-percona-5.0.91-b22-20100522.patch
-@ver 5.00.91.00 to 5.00.91.99
+@ver 5.00.91.00 to 5.00.99.99
@pn mysql
@@ Percona 5.0.91-b22-20100522: profiling from SHOW PROFILE to slow.log
-@patch 10021_all_profiling_slow-percona-5.0.92.patch
-@ver 5.00.92.00 to 5.00.99.99
-@pn mysql
-@@ Percona 5.0.92: profiling from SHOW PROFILE to slow.log
-
@patch 10030_all_userstatv2-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 1:47 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 1:47 UTC (permalink / raw
To: gentoo-commits
commit: 0ea25b0ad332f7e4acee80e9025ce324e22511c4
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 01:45:20 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 01:45:20 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0ea25b0a
Updated 10030_all_userstatv2-percona patch for the 5.0.92 release. Seems this release dropped os2 support.
---
00000_index.txt | 7 +-
10030_all_userstatv2-percona-5.0.92.patch | 4373 +++++++++++++++++++++++++++++
2 files changed, 4379 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index b3dc69b..94a582a 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -807,10 +807,15 @@
@@ Percona 5.0.87-b20-20091116: SHOW USER/TABLE/INDEX statistics
@patch 10030_all_userstatv2-percona-5.0.91-b22-20100522.patch
-@ver 5.00.91.00 to 5.00.99.99
+@ver 5.00.91.00 to 5.00.91.99
@pn mysql
@@ Percona 5.0.91-b22-20100522: SHOW USER/TABLE/INDEX statistics
+@patch 10030_all_userstatv2-percona-5.0.92.patch
+@ver 5.00.92.00 to 5.00.99.99
+@pn mysql
+@@ Percona 5.0.92: SHOW USER/TABLE/INDEX statistics
+
@patch 10040_all_microsec_process-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
diff --git a/10030_all_userstatv2-percona-5.0.92.patch b/10030_all_userstatv2-percona-5.0.92.patch
new file mode 100644
index 0000000..7ae1249
--- /dev/null
+++ b/10030_all_userstatv2-percona-5.0.92.patch
@@ -0,0 +1,4373 @@
+diff -r 592f6c3641ba BUILD/Makefile.in
+--- a/BUILD/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/BUILD/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -146,6 +146,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba Docs/Makefile.in
+--- a/Docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/Docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba Makefile.in
+--- a/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba SSL/Makefile.in
+--- a/SSL/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/SSL/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba client/Makefile.in
+--- a/client/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/client/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -247,6 +247,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/Makefile.in
+--- a/cmd-line-utils/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -157,6 +157,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/libedit/Makefile.in
+--- a/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -166,6 +166,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/readline/Makefile.in
+--- a/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -173,6 +173,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba configure
+--- a/configure Wed Jul 29 13:33:34 2009 -0700
++++ b/configure Wed Jul 29 13:34:11 2009 -0700
+@@ -35347,7 +35347,91 @@
+ # We also disable for SCO for the time being, the headers for the
+ # thread library we use conflicts with other headers.
+ ;;
+- *)
++*)
++ # most systems require the program be linked with librt library to use
++ # the function clock_gettime
++ my_save_LIBS="$LIBS"
++ LIBS=""
++
++echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5
++echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6
++if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-lrt $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char clock_gettime ();
++int
++main ()
++{
++clock_gettime ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -z "$ac_c_werror_flag"
++ || test ! -s conftest.err'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_rt_clock_gettime=yes
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_lib_rt_clock_gettime=no
++fi
++rm -f conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_rt_clock_gettime" >&5
++echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6
++if test $ac_cv_lib_rt_clock_gettime = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBRT 1
++_ACEOF
++
++ LIBS="-lrt $LIBS"
++
++fi
++
++ LIBRT=$LIBS
++ LIBS="$my_save_LIBS"
++
++
++ LIBS="$LIBS $LIBRT"
++
+ for ac_func in clock_gettime
+ do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+@@ -38791,7 +38875,7 @@
+
+ fi
+
+-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
+
+
+
+diff -r 592f6c3641ba configure.in
+--- a/configure.in Wed Jul 29 13:33:34 2009 -0700
++++ b/configure.in Wed Jul 29 13:34:11 2009 -0700
+@@ -2136,7 +2136,18 @@
+ # We also disable for SCO for the time being, the headers for the
+ # thread library we use conflicts with other headers.
+ ;;
+- *) AC_CHECK_FUNCS(clock_gettime)
++*)
++ # most systems require the program be linked with librt library to use
++ # the function clock_gettime
++ my_save_LIBS="$LIBS"
++ LIBS=""
++ AC_CHECK_LIB(rt,clock_gettime)
++ LIBRT=$LIBS
++ LIBS="$my_save_LIBS"
++ AC_SUBST(LIBRT)
++
++ LIBS="$LIBS $LIBRT"
++ AC_CHECK_FUNCS(clock_gettime)
+ ;;
+ esac
+
+@@ -2772,7 +2783,7 @@
+ AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
+ fi
+
+-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
+
+ AC_SUBST(CLIENT_LIBS)
+ AC_SUBST(NON_THREADED_LIBS)
+diff -r 592f6c3641ba dbug/Makefile.in
+--- a/dbug/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/dbug/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -192,6 +192,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/Makefile.in
+--- a/extra/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -240,6 +240,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/Makefile.in
+--- a/extra/yassl/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -142,6 +142,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/src/Makefile.in
+--- a/extra/yassl/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -151,6 +151,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/Makefile.in
+--- a/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -142,6 +142,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/benchmark/Makefile.in
+--- a/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -153,6 +153,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/src/Makefile.in
+--- a/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -164,6 +164,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/test/Makefile.in
+--- a/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -153,6 +153,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/testsuite/Makefile.in
+--- a/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba heap/Makefile.in
+--- a/heap/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/heap/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -202,6 +202,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba include/Makefile.in
+--- a/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -160,6 +160,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba include/mysql_com.h
+--- a/include/mysql_com.h Wed Jul 29 13:33:34 2009 -0700
++++ b/include/mysql_com.h Wed Jul 29 13:34:11 2009 -0700
+@@ -25,6 +25,7 @@
+ #define USERNAME_LENGTH 16
+ #define SERVER_VERSION_LENGTH 60
+ #define SQLSTATE_LENGTH 5
++#define LIST_PROCESS_HOST_LEN 64
+
+ /*
+ USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
+@@ -106,6 +107,11 @@
+ thread */
+ #define REFRESH_MASTER 128 /* Remove all bin logs in the index
+ and truncate the index */
++#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */
++#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */
++#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */
++#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/
++#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */
+
+ /* The following can't be set with mysql_refresh() */
+ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */
+diff -r 592f6c3641ba libmysql/Makefile.in
+--- a/libmysql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -224,6 +224,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysql_r/Makefile.in
+--- a/libmysql_r/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysql_r/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -221,6 +221,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysqld/Makefile.in
+--- a/libmysqld/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysqld/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -246,6 +246,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysqld/examples/Makefile.in
+--- a/libmysqld/examples/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysqld/examples/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -192,6 +192,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba man/Makefile.in
+--- a/man/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/man/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -151,6 +151,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba myisam/Makefile.in
+--- a/myisam/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/myisam/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -235,6 +235,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba myisammrg/Makefile.in
+--- a/myisammrg/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/myisammrg/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -183,6 +183,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/Makefile.in
+--- a/mysql-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -161,6 +161,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/ndb/Makefile.in
+--- a/mysql-test/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -147,6 +147,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/r/information_schema.result
+--- a/mysql-test/r/information_schema.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/information_schema.result Wed Jul 29 13:34:11 2009 -0700
+@@ -37,10 +37,12 @@
+ select * from v1;
+ c
+ CHARACTER_SETS
++CLIENT_STATISTICS
+ COLLATIONS
+ COLLATION_CHARACTER_SET_APPLICABILITY
+ COLUMNS
+ COLUMN_PRIVILEGES
++INDEX_STATISTICS
+ KEY_COLUMN_USAGE
+ PROFILING
+ ROUTINES
+@@ -50,8 +52,10 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ USER_PRIVILEGES
++USER_STATISTICS
+ VIEWS
+ columns_priv
+ db
+@@ -83,6 +87,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -102,6 +107,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -121,6 +127,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -594,12 +601,13 @@
+ where table_schema='information_schema' limit 2;
+ TABLE_NAME TABLE_TYPE ENGINE
+ CHARACTER_SETS SYSTEM VIEW MEMORY
+-COLLATIONS SYSTEM VIEW MEMORY
++CLIENT_STATISTICS SYSTEM VIEW MEMORY
+ show tables from information_schema like "T%";
+ Tables_in_information_schema (T%)
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ create database information_schema;
+ ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
+@@ -609,6 +617,7 @@
+ TABLES SYSTEM VIEW
+ TABLE_CONSTRAINTS SYSTEM VIEW
+ TABLE_PRIVILEGES SYSTEM VIEW
++TABLE_STATISTICS SYSTEM VIEW
+ TRIGGERS SYSTEM VIEW
+ create table t1(a int);
+ ERROR 42S02: Unknown table 't1' in information_schema
+@@ -621,6 +630,7 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ select table_name from tables where table_name='user';
+ table_name
+@@ -730,7 +740,7 @@
+ CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
+ CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
+ count(*)
+-102
++106
+ drop view a2, a1;
+ drop table t_crashme;
+ select table_schema,table_name, column_name from
+@@ -790,18 +800,20 @@
+ TABLE_NAME COLUMN_NAME PRIVILEGES
+ COLUMNS TABLE_NAME select
+ COLUMN_PRIVILEGES TABLE_NAME select
++INDEX_STATISTICS TABLE_NAME select
+ KEY_COLUMN_USAGE TABLE_NAME select
+ STATISTICS TABLE_NAME select
+ TABLES TABLE_NAME select
+ TABLE_CONSTRAINTS TABLE_NAME select
+ TABLE_PRIVILEGES TABLE_NAME select
++TABLE_STATISTICS TABLE_NAME select
+ VIEWS TABLE_NAME select
+ delete from mysql.user where user='mysqltest_4';
+ delete from mysql.db where user='mysqltest_4';
+ flush privileges;
+ SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
+ table_schema count(*)
+-information_schema 17
++information_schema 21
+ mysql 17
+ create table t1 (i int, j int);
+ create trigger trg1 before insert on t1 for each row
+@@ -1187,10 +1199,12 @@
+ );
+ table_name column_name
+ CHARACTER_SETS CHARACTER_SET_NAME
++CLIENT_STATISTICS CLIENT
+ COLLATIONS COLLATION_NAME
+ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
+ COLUMNS TABLE_SCHEMA
+ COLUMN_PRIVILEGES TABLE_SCHEMA
++INDEX_STATISTICS TABLE_SCHEMA
+ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+ PROFILING QUERY_ID
+ ROUTINES ROUTINE_SCHEMA
+@@ -1200,8 +1214,10 @@
+ TABLES TABLE_SCHEMA
+ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
+ TABLE_PRIVILEGES TABLE_SCHEMA
++TABLE_STATISTICS TABLE_SCHEMA
+ TRIGGERS TRIGGER_SCHEMA
+ USER_PRIVILEGES GRANTEE
++USER_STATISTICS USER
+ VIEWS TABLE_SCHEMA
+ SELECT t.table_name, c1.column_name
+ FROM information_schema.tables t
+@@ -1219,10 +1235,12 @@
+ );
+ table_name column_name
+ CHARACTER_SETS CHARACTER_SET_NAME
++CLIENT_STATISTICS CLIENT
+ COLLATIONS COLLATION_NAME
+ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
+ COLUMNS TABLE_SCHEMA
+ COLUMN_PRIVILEGES TABLE_SCHEMA
++INDEX_STATISTICS TABLE_SCHEMA
+ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+ PROFILING QUERY_ID
+ ROUTINES ROUTINE_SCHEMA
+@@ -1232,8 +1250,10 @@
+ TABLES TABLE_SCHEMA
+ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
+ TABLE_PRIVILEGES TABLE_SCHEMA
++TABLE_STATISTICS TABLE_SCHEMA
+ TRIGGERS TRIGGER_SCHEMA
+ USER_PRIVILEGES GRANTEE
++USER_STATISTICS USER
+ VIEWS TABLE_SCHEMA
+ SELECT MAX(table_name) FROM information_schema.tables;
+ MAX(table_name)
+@@ -1302,10 +1322,12 @@
+ group by t.table_name order by num1, t.table_name;
+ table_name group_concat(t.table_schema, '.', t.table_name) num1
+ CHARACTER_SETS information_schema.CHARACTER_SETS 1
++CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
+ COLLATIONS information_schema.COLLATIONS 1
+ COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
+ COLUMNS information_schema.COLUMNS 1
+ COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
++INDEX_STATISTICS information_schema.INDEX_STATISTICS 1
+ KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
+ PROFILING information_schema.PROFILING 1
+ ROUTINES information_schema.ROUTINES 1
+@@ -1315,8 +1337,10 @@
+ TABLES information_schema.TABLES 1
+ TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
+ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
++TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
+ TRIGGERS information_schema.TRIGGERS 1
+ USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
++USER_STATISTICS information_schema.USER_STATISTICS 1
+ VIEWS information_schema.VIEWS 1
+ create table t1(f1 int);
+ create view v1 as select f1+1 as a from t1;
+diff -r 592f6c3641ba mysql-test/r/information_schema_db.result
+--- a/mysql-test/r/information_schema_db.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/information_schema_db.result Wed Jul 29 13:34:11 2009 -0700
+@@ -6,10 +6,12 @@
+ show tables;
+ Tables_in_information_schema
+ CHARACTER_SETS
++CLIENT_STATISTICS
+ COLLATIONS
+ COLLATION_CHARACTER_SET_APPLICABILITY
+ COLUMNS
+ COLUMN_PRIVILEGES
++INDEX_STATISTICS
+ KEY_COLUMN_USAGE
+ PROFILING
+ ROUTINES
+@@ -19,14 +21,17 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ USER_PRIVILEGES
++USER_STATISTICS
+ VIEWS
+ show tables from INFORMATION_SCHEMA like 'T%';
+ Tables_in_information_schema (T%)
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ create database `inf%`;
+ create database mbase;
+diff -r 592f6c3641ba mysql-test/r/mysqlshow.result
+--- a/mysql-test/r/mysqlshow.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/mysqlshow.result Wed Jul 29 13:34:11 2009 -0700
+@@ -80,10 +80,12 @@
+ | Tables |
+ +---------------------------------------+
+ | CHARACTER_SETS |
++| CLIENT_STATISTICS |
+ | COLLATIONS |
+ | COLLATION_CHARACTER_SET_APPLICABILITY |
+ | COLUMNS |
+ | COLUMN_PRIVILEGES |
++| INDEX_STATISTICS |
+ | KEY_COLUMN_USAGE |
+ | PROFILING |
+ | ROUTINES |
+@@ -93,8 +95,10 @@
+ | TABLES |
+ | TABLE_CONSTRAINTS |
+ | TABLE_PRIVILEGES |
++| TABLE_STATISTICS |
+ | TRIGGERS |
+ | USER_PRIVILEGES |
++| USER_STATISTICS |
+ | VIEWS |
+ +---------------------------------------+
+ Database: INFORMATION_SCHEMA
+@@ -102,10 +106,12 @@
+ | Tables |
+ +---------------------------------------+
+ | CHARACTER_SETS |
++| CLIENT_STATISTICS |
+ | COLLATIONS |
+ | COLLATION_CHARACTER_SET_APPLICABILITY |
+ | COLUMNS |
+ | COLUMN_PRIVILEGES |
++| INDEX_STATISTICS |
+ | KEY_COLUMN_USAGE |
+ | PROFILING |
+ | ROUTINES |
+@@ -115,8 +121,10 @@
+ | TABLES |
+ | TABLE_CONSTRAINTS |
+ | TABLE_PRIVILEGES |
++| TABLE_STATISTICS |
+ | TRIGGERS |
+ | USER_PRIVILEGES |
++| USER_STATISTICS |
+ | VIEWS |
+ +---------------------------------------+
+ Wildcard: inf_rmation_schema
+diff -r 592f6c3641ba mysys/Makefile.in
+--- a/mysys/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysys/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -228,6 +228,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/Makefile.in
+--- a/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/docs/Makefile.in
+--- a/ndb/docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -149,6 +149,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/include/Makefile.in
+--- a/ndb/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -179,6 +179,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/Makefile.in
+--- a/ndb/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/Makefile.in
+--- a/ndb/src/common/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -174,6 +174,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/debugger/Makefile.in
+--- a/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/debugger/signaldata/Makefile.in
+--- a/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -211,6 +211,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/logger/Makefile.in
+--- a/ndb/src/common/logger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/logger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/mgmcommon/Makefile.in
+--- a/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -211,6 +211,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/portlib/Makefile.in
+--- a/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -222,6 +222,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/transporter/Makefile.in
+--- a/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/util/Makefile.in
+--- a/ndb/src/common/util/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/util/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -217,6 +217,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/cw/Makefile.in
+--- a/ndb/src/cw/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/cw/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/cw/cpcd/Makefile.in
+--- a/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -207,6 +207,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/Makefile.in
+--- a/ndb/src/kernel/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -227,6 +227,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/Makefile.in
+--- a/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/backup/Makefile.in
+--- a/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/cmvmi/Makefile.in
+--- a/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbacc/Makefile.in
+--- a/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdict/Makefile.in
+--- a/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdih/Makefile.in
+--- a/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -203,6 +203,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dblqh/Makefile.in
+--- a/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtc/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtup/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtux/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -199,6 +199,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbutil/Makefile.in
+--- a/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbcntr/Makefile.in
+--- a/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbfs/Makefile.in
+--- a/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/qmgr/Makefile.in
+--- a/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/suma/Makefile.in
+--- a/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/trix/Makefile.in
+--- a/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/error/Makefile.in
+--- a/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/vm/Makefile.in
+--- a/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -207,6 +207,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmapi/Makefile.in
+--- a/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -205,6 +205,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmclient/Makefile.in
+--- a/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -216,6 +216,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmsrv/Makefile.in
+--- a/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -213,6 +213,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/ndbapi/Makefile.in
+--- a/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -215,6 +215,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/Makefile.in
+--- a/ndb/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/ndbapi/Makefile.in
+--- a/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -595,6 +595,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/ndbapi/bank/Makefile.in
+--- a/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -282,6 +282,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/run-test/Makefile.in
+--- a/ndb/test/run-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/run-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -243,6 +243,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/src/Makefile.in
+--- a/ndb/test/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -213,6 +213,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/tools/Makefile.in
+--- a/ndb/test/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -325,6 +325,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/tools/Makefile.in
+--- a/ndb/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -344,6 +344,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba netware/Makefile.in
+--- a/netware/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/netware/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -199,6 +199,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba patch_info/userstats.info
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/patch_info/userstats.info Wed Jul 29 13:34:11 2009 -0700
+@@ -0,0 +1,14 @@
++File=userstatsv2.patch
++Name=SHOW USER/TABLE/INDEX statistics
++Version=V2
++Author=Google
++License=GPL
++Comment=Added INFORMATION_SCHEMA.*_STATISTICS
++2008-12-01
++YK: fix behavior for prepared statements
++
++2008-11-26
++YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
++
++2008-12-09
++YK: fixed "Row_sent: 0" problem at microslow_innodb.patch
+diff -r 592f6c3641ba pstack/Makefile.in
+--- a/pstack/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/pstack/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba pstack/aout/Makefile.in
+--- a/pstack/aout/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/pstack/aout/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -134,6 +134,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba regex/Makefile.in
+--- a/regex/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/regex/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -180,6 +180,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba scripts/Makefile.in
+--- a/scripts/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/scripts/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -176,6 +176,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba server-tools/Makefile.in
+--- a/server-tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/server-tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -155,6 +155,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba server-tools/instance-manager/Makefile.in
+--- a/server-tools/instance-manager/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/server-tools/instance-manager/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -205,6 +205,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/Makefile.in
+--- a/sql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -274,6 +274,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/ha_innodb.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -3341,6 +3341,8 @@
+
+ error = row_insert_for_mysql((byte*) record, prebuilt);
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ if (error == DB_SUCCESS && auto_inc_used) {
+
+ /* Fetch the value that was set in the autoincrement field */
+@@ -3613,6 +3615,8 @@
+ }
+ }
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+@@ -3661,6 +3665,8 @@
+
+ error = row_update_for_mysql((byte*) record, prebuilt);
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+@@ -4092,6 +4098,9 @@
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
++ rows_read++;
++ if (active_index >= 0 && active_index < MAX_KEY)
++ index_rows_read[active_index]++;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+diff -r 592f6c3641ba sql/ha_myisam.cc
+--- a/sql/ha_myisam.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/ha_myisam.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -670,7 +670,9 @@
+ if ((error= update_auto_increment()))
+ return error;
+ }
+- return mi_write(file,buf);
++ int error=mi_write(file,buf);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
+@@ -1521,13 +1523,17 @@
+ statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
+ table->timestamp_field->set_time();
+- return mi_update(file,old_data,new_data);
++ int error=mi_update(file,old_data,new_data);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::delete_row(const byte * buf)
+ {
+ statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
+- return mi_delete(file,buf);
++ int error=mi_delete(file,buf);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::index_read(byte * buf, const byte * key,
+@@ -1538,6 +1544,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1548,6 +1561,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,index, key, key_len, find_flag);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1558,6 +1578,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1568,6 +1595,13 @@
+ &LOCK_status);
+ int error=mi_rnext(file,buf,active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1578,6 +1612,13 @@
+ &LOCK_status);
+ int error=mi_rprev(file,buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1588,6 +1629,13 @@
+ &LOCK_status);
+ int error=mi_rfirst(file, buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1598,6 +1646,13 @@
+ &LOCK_status);
+ int error=mi_rlast(file, buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1614,6 +1669,13 @@
+ error= mi_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1631,6 +1693,7 @@
+ &LOCK_status);
+ int error=mi_scan(file, buf);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) rows_read++;
+ return error;
+ }
+
+@@ -1645,6 +1708,7 @@
+ &LOCK_status);
+ int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) rows_read++;
+ return error;
+ }
+
+diff -r 592f6c3641ba sql/handler.cc
+--- a/sql/handler.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/handler.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -726,6 +726,8 @@
+ if (cookie)
+ tc_log->unlog(cookie, xid);
+ DBUG_EXECUTE_IF("crash_commit_after", abort(););
++ if (is_real_trans)
++ thd->diff_commit_trans++;
+ end:
+ if (is_real_trans)
+ start_waiting_global_read_lock(thd);
+@@ -783,6 +785,7 @@
+ thd->transaction.cleanup();
+ }
+ }
++ thd->diff_rollback_trans++;
+ #endif /* USING_TRANSACTIONS */
+ DBUG_RETURN(error);
+ }
+@@ -1223,6 +1226,7 @@
+ statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status);
+ *ht=0; // keep it conveniently zero-filled
+ }
++ thd->diff_rollback_trans++;
+ DBUG_RETURN(error);
+ }
+
+@@ -1453,6 +1457,8 @@
+ else
+ dupp_ref=ref+ALIGN_SIZE(ref_length);
+ }
++ rows_read = rows_changed = 0;
++ memset(index_rows_read, 0, sizeof(index_rows_read));
+ DBUG_RETURN(error);
+ }
+
+@@ -2287,6 +2293,111 @@
+ return error;
+ }
+
++// Updates the global table stats with the TABLE this handler represents.
++void handler::update_global_table_stats() {
++ if (!opt_userstat_running) {
++ rows_read = rows_changed = 0;
++ return;
++ }
++
++ if (!rows_read && !rows_changed) return; // Nothing to update.
++ // table_cache_key is db_name + '\0' + table_name + '\0'.
++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
++
++ TABLE_STATS* table_stats;
++ char key[NAME_LEN * 2 + 2];
++ // [db] + '.' + [table]
++ sprintf(key, "%s.%s", table->s->table_cache_key, table->s->table_name);
++
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ // Gets the global table stats, creating one if necessary.
++ if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
++ (byte*)key,
++ strlen(key)))) {
++ if (!(table_stats = ((TABLE_STATS*)
++ my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
++ // Out of memory.
++ sql_print_error("Allocating table stats failed.");
++ goto end;
++ }
++ strncpy(table_stats->table, key, sizeof(table_stats->table));
++ table_stats->rows_read = 0;
++ table_stats->rows_changed = 0;
++ table_stats->rows_changed_x_indexes = 0;
++ table_stats->engine_type = (int) ht->db_type;
++
++ if (my_hash_insert(&global_table_stats, (byte*)table_stats)) {
++ // Out of memory.
++ sql_print_error("Inserting table stats failed.");
++ my_free((char*)table_stats, 0);
++ goto end;
++ }
++ }
++ // Updates the global table stats.
++ table_stats->rows_read += rows_read;
++ table_stats->rows_changed += rows_changed;
++ table_stats->rows_changed_x_indexes +=
++ rows_changed * (table->s->keys ? table->s->keys : 1);
++ current_thd->diff_total_read_rows += rows_read;
++ rows_read = rows_changed = 0;
++end:
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++}
++
++// Updates the global index stats with this handler's accumulated index reads.
++void handler::update_global_index_stats() {
++ // table_cache_key is db_name + '\0' + table_name + '\0'.
++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
++
++ if (!opt_userstat_running) {
++ for (int x = 0; x < table->s->keys; x++) {
++ index_rows_read[x] = 0;
++ }
++ return;
++ }
++
++ for (int x = 0; x < table->s->keys; x++) {
++ if (index_rows_read[x]) {
++ // Rows were read using this index.
++ KEY* key_info = &table->key_info[x];
++
++ if (!key_info->name) continue;
++
++ INDEX_STATS* index_stats;
++ char key[NAME_LEN * 3 + 3];
++ // [db] + '.' + [table] + '.' + [index]
++ sprintf(key, "%s.%s.%s", table->s->table_cache_key,
++ table->s->table_name, key_info->name);
++
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ // Gets the global index stats, creating one if necessary.
++ if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
++ (byte*)key,
++ strlen(key)))) {
++ if (!(index_stats = ((INDEX_STATS*)
++ my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
++ // Out of memory.
++ sql_print_error("Allocating index stats failed.");
++ goto end;
++ }
++ strncpy(index_stats->index, key, sizeof(index_stats->index));
++ index_stats->rows_read = 0;
++
++ if (my_hash_insert(&global_index_stats, (byte*)index_stats)) {
++ // Out of memory.
++ sql_print_error("Inserting index stats failed.");
++ my_free((char*)index_stats, 0);
++ goto end;
++ }
++ }
++ // Updates the global index stats.
++ index_stats->rows_read += index_rows_read[x];
++ index_rows_read[x] = 0;
++end:
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ }
++ }
++}
+
+ /****************************************************************************
+ ** Some general functions that isn't in the handler class
+diff -r 592f6c3641ba sql/handler.h
+--- a/sql/handler.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/handler.h Wed Jul 29 13:34:11 2009 -0700
+@@ -32,6 +32,10 @@
+ #define USING_TRANSACTIONS
+ #endif
+
++#if MAX_KEY > 128
++#error MAX_KEY is too large. Values up to 128 are supported.
++#endif
++
+ // the following is for checking tables
+
+ #define HA_ADMIN_ALREADY_DONE 1
+@@ -604,6 +608,9 @@
+ bool auto_increment_column_changed;
+ bool implicit_emptied; /* Can be !=0 only if HEAP */
+ const COND *pushed_cond;
++ ulonglong rows_read;
++ ulonglong rows_changed;
++ ulonglong index_rows_read[MAX_KEY];
+
+ handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
+ ht(ht_arg),
+@@ -615,8 +622,10 @@
+ ref_length(sizeof(my_off_t)), block_size(0),
+ raid_type(0), ft_handler(0), inited(NONE),
+ locked(FALSE), implicit_emptied(0),
+- pushed_cond(NULL)
+- {}
++ pushed_cond(NULL), rows_read(0), rows_changed(0)
++ {
++ memset(index_rows_read, 0, sizeof(index_rows_read));
++ }
+ virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); /* TODO: DBUG_ASSERT(inited == NONE); */ }
+ virtual handler *clone(MEM_ROOT *mem_root);
+ int ha_open(const char *name, int mode, int test_if_locked);
+@@ -625,7 +634,11 @@
+ virtual void print_error(int error, myf errflag);
+ virtual bool get_error_message(int error, String *buf);
+ uint get_dup_key(int error);
+- void change_table_ptr(TABLE *table_arg) { table=table_arg; }
++ void change_table_ptr(TABLE *table_arg) {
++ table=table_arg;
++ rows_read = rows_changed = 0;
++ memset(index_rows_read, 0, sizeof(index_rows_read));
++ }
+ virtual double scan_time()
+ { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+@@ -886,6 +899,9 @@
+ virtual bool is_crashed() const { return 0; }
+ virtual bool auto_repair() const { return 0; }
+
++ void update_global_table_stats();
++ void update_global_index_stats();
++
+ /*
+ default rename_table() and delete_table() rename/delete files with a
+ given name and extensions from bas_ext()
+diff -r 592f6c3641ba sql/lex.h
+--- a/sql/lex.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/lex.h Wed Jul 29 13:34:11 2009 -0700
+@@ -109,6 +109,7 @@
+ { "CHECKSUM", SYM(CHECKSUM_SYM)},
+ { "CIPHER", SYM(CIPHER_SYM)},
+ { "CLIENT", SYM(CLIENT_SYM)},
++ { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)},
+ { "CLOSE", SYM(CLOSE_SYM)},
+ { "CODE", SYM(CODE_SYM)},
+ { "COLLATE", SYM(COLLATE_SYM)},
+@@ -238,6 +239,7 @@
+ { "IN", SYM(IN_SYM)},
+ { "INDEX", SYM(INDEX_SYM)},
+ { "INDEXES", SYM(INDEXES)},
++ { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)},
+ { "INFILE", SYM(INFILE)},
+ { "INNER", SYM(INNER_SYM)},
+ { "INNOBASE", SYM(INNOBASE_SYM)},
+@@ -443,6 +445,7 @@
+ { "SIGNED", SYM(SIGNED_SYM)},
+ { "SIMPLE", SYM(SIMPLE_SYM)},
+ { "SLAVE", SYM(SLAVE)},
++ { "SLOW", SYM(SLOW_SYM)},
+ { "SNAPSHOT", SYM(SNAPSHOT_SYM)},
+ { "SMALLINT", SYM(SMALLINT)},
+ { "SOME", SYM(ANY_SYM)},
+@@ -488,6 +491,7 @@
+ { "TABLE", SYM(TABLE_SYM)},
+ { "TABLES", SYM(TABLES)},
+ { "TABLESPACE", SYM(TABLESPACE)},
++ { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)},
+ { "TEMPORARY", SYM(TEMPORARY)},
+ { "TEMPTABLE", SYM(TEMPTABLE_SYM)},
+ { "TERMINATED", SYM(TERMINATED)},
+@@ -525,6 +529,7 @@
+ { "USE", SYM(USE_SYM)},
+ { "USER", SYM(USER)},
+ { "USER_RESOURCES", SYM(RESOURCES)},
++ { "USER_STATISTICS", SYM(USER_STATS_SYM)},
+ { "USE_FRM", SYM(USE_FRM)},
+ { "USING", SYM(USING)},
+ { "UTC_DATE", SYM(UTC_DATE_SYM)},
+diff -r 592f6c3641ba sql/log.cc
+--- a/sql/log.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/log.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -1958,18 +1958,24 @@
+ thd->current_insert_id);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->rand_used)
+ {
+ Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->user_var_events.elements)
+ {
+@@ -1985,6 +1991,8 @@
+ user_var_event->charset_number);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ }
+ }
+@@ -1995,6 +2003,8 @@
+
+ if (event_info->write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += event_info->data_written;
+
+ if (file == &log_file) // we are writing to the real log (disk)
+ {
+@@ -2117,6 +2127,7 @@
+ */
+ if (qinfo.write(&log_file))
+ goto err;
++ thd->binlog_bytes_written += qinfo.data_written;
+
+ /* Read from the file used to cache the queries .*/
+ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
+@@ -2163,6 +2174,7 @@
+ /* write the first half of the split header */
+ if (my_b_write(&log_file, header, carry))
+ goto err;
++ thd->binlog_bytes_written += carry;
+
+ /*
+ copy fixed second half of header to cache so the correct
+@@ -2231,6 +2243,8 @@
+ /* Write data to the binary log file */
+ if (my_b_write(&log_file, cache->read_pos, length))
+ goto err;
++ thd->binlog_bytes_written += length;
++
+ cache->read_pos=cache->read_end; // Mark buffer used up
+ DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
+ } while ((length=my_b_fill(cache)));
+@@ -2239,6 +2253,8 @@
+
+ if (commit_event->write(&log_file))
+ goto err;
++ thd->binlog_bytes_written += commit_event->data_written;
++
+ #ifndef DBUG_OFF
+ DBUG_skip_commit:
+ #endif
+diff -r 592f6c3641ba sql/mysql_priv.h
+--- a/sql/mysql_priv.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/mysql_priv.h Wed Jul 29 13:34:11 2009 -0700
+@@ -837,7 +837,15 @@
+ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
+ void init_max_user_conn(void);
+ void init_update_queries(void);
++void init_global_user_stats(void);
++void init_global_table_stats(void);
++void init_global_index_stats(void);
++void init_global_client_stats(void);
+ void free_max_user_conn(void);
++void free_global_user_stats(void);
++void free_global_table_stats(void);
++void free_global_index_stats(void);
++void free_global_client_stats(void);
+ pthread_handler_t handle_one_connection(void *arg);
+ pthread_handler_t handle_bootstrap(void *arg);
+ void end_thread(THD *thd,bool put_in_cache);
+@@ -1416,6 +1424,7 @@
+ extern ulong max_connections,max_connect_errors, connect_timeout;
+ extern ulong slave_net_timeout, slave_trans_retries;
+ extern uint max_user_connections;
++extern ulonglong denied_connections;
+ extern ulong what_to_log,flush_time;
+ extern ulong query_buff_size, thread_stack;
+ extern ulong max_prepared_stmt_count, prepared_stmt_count;
+@@ -1446,6 +1455,7 @@
+ extern my_bool opt_safe_show_db, opt_local_infile;
+ extern my_bool opt_slave_compressed_protocol, use_temp_pool;
+ extern my_bool opt_readonly, lower_case_file_system;
++extern my_bool opt_userstat_running;
+ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
+ extern my_bool opt_secure_auth;
+ extern char* opt_secure_file_priv;
+@@ -1493,6 +1503,14 @@
+ extern struct system_variables max_system_variables;
+ extern struct system_status_var global_status_var;
+ extern struct rand_struct sql_rand;
++extern HASH global_user_stats;
++extern HASH global_client_stats;
++extern pthread_mutex_t LOCK_global_user_client_stats;
++extern HASH global_table_stats;
++extern pthread_mutex_t LOCK_global_table_stats;
++extern HASH global_index_stats;
++extern pthread_mutex_t LOCK_global_index_stats;
++extern pthread_mutex_t LOCK_stats;
+
+ extern const char *opt_date_time_formats[];
+ extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
+diff -r 592f6c3641ba sql/mysqld.cc
+--- a/sql/mysqld.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/mysqld.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -417,6 +417,7 @@
+ uint opt_large_page_size= 0;
+ my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
+ char* opt_slow_logname= 0;
++my_bool opt_userstat_running= 0;
+ /*
+ True if there is at least one per-hour limit for some user, so we should
+ check them before each query (and possibly reset counters when hour is
+@@ -453,6 +454,7 @@
+ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
+ ulong max_connections, max_connect_errors;
+ uint max_user_connections= 0;
++ulonglong denied_connections = 0;
+ /*
+ Limit of the total number of prepared statements in the server.
+ Is necessary to protect the server against out-of-memory attacks.
+@@ -555,6 +557,10 @@
+ LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
+ LOCK_global_system_variables,
+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
++pthread_mutex_t LOCK_stats;
++pthread_mutex_t LOCK_global_user_client_stats;
++pthread_mutex_t LOCK_global_table_stats;
++pthread_mutex_t LOCK_global_index_stats;
+ /*
+ The below lock protects access to two global server variables:
+ max_prepared_stmt_count and prepared_stmt_count. These variables
+@@ -1196,6 +1202,10 @@
+ x_free(opt_secure_file_priv);
+ bitmap_free(&temp_pool);
+ free_max_user_conn();
++ free_global_user_stats();
++ free_global_client_stats();
++ free_global_table_stats();
++ free_global_index_stats();
+ #ifdef HAVE_REPLICATION
+ end_slave_list();
+ free_list(&replicate_do_db);
+@@ -1310,6 +1320,10 @@
+ (void) pthread_cond_destroy(&COND_thread_cache);
+ (void) pthread_cond_destroy(&COND_flush_thread_cache);
+ (void) pthread_cond_destroy(&COND_manager);
++ (void) pthread_mutex_destroy(&LOCK_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_table_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_index_stats);
+ }
+
+ #endif /*EMBEDDED_LIBRARY*/
+@@ -3157,6 +3171,10 @@
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
+ #endif
++ (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
+ sp_cache_init();
+ /* Parameter for threads created for connections */
+ (void) pthread_attr_init(&connection_attrib);
+@@ -3428,6 +3446,10 @@
+ sql_print_error("Out of memory");
+ unireg_abort(1);
+ }
++
++ init_global_table_stats();
++ init_global_index_stats();
++
+ if (ha_init())
+ {
+ sql_print_error("Can't init databases");
+@@ -3510,6 +3532,8 @@
+
+ init_max_user_conn();
+ init_update_queries();
++ init_global_user_stats();
++ init_global_client_stats();
+ DBUG_RETURN(0);
+ }
+
+@@ -4236,6 +4260,7 @@
+ {
+ DBUG_PRINT("error",("Too many connections"));
+ close_connection(thd, ER_CON_COUNT_ERROR, 1);
++ statistic_increment(denied_connections, &LOCK_status);
+ delete thd;
+ DBUG_VOID_RETURN;
+ }
+@@ -5056,6 +5081,7 @@
+ OPT_PROFILING_USE_GETRUSAGE,
+ OPT_SLOW_LOG,
+ OPT_SLOW_QUERY_LOG_FILE,
++ OPT_USERSTAT_RUNNING,
+ OPT_USE_GLOBAL_LONG_QUERY_TIME,
+ OPT_INNODB_ROLLBACK_ON_TIMEOUT,
+ OPT_SECURE_FILE_PRIV,
+@@ -6523,6 +6549,10 @@
+ (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
+ 0, 1, 0},
++ {"userstat_running", OPT_USERSTAT_RUNNING,
++ "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
++ (gptr*) &opt_userstat_running, (gptr*) &opt_userstat_running,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+ };
+
+diff -r 592f6c3641ba sql/set_var.cc
+--- a/sql/set_var.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/set_var.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -325,6 +325,7 @@
+ sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
+ &SV::read_buff_size);
+ sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
++sys_var_bool_ptr sys_userstat_running("userstat_running", &opt_userstat_running);
+ sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+ &SV::read_rnd_buff_size);
+ sys_var_thd_ulong sys_div_precincrement("div_precision_increment",
+@@ -837,6 +838,7 @@
+ &sys_trans_alloc_block_size,
+ &sys_trans_prealloc_size,
+ &sys_tx_isolation,
++ &sys_userstat_running,
+ &sys_version,
+ #ifdef HAVE_BERKELEY_DB
+ &sys_version_bdb,
+@@ -1190,6 +1192,7 @@
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+ {sys_updatable_views_with_limit.name,
+ (char*) &sys_updatable_views_with_limit,SHOW_SYS},
++ {sys_userstat_running.name, (char*) &sys_userstat_running, SHOW_SYS},
+ {sys_use_global_long_query_time.name, (char*) &sys_use_global_long_query_time, SHOW_SYS},
+ {sys_version.name, (char*) &sys_version, SHOW_SYS},
+ #ifdef HAVE_BERKELEY_DB
+diff -r 592f6c3641ba sql/share/Makefile.in
+--- a/sql/share/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/share/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/sql_base.cc
+--- a/sql/sql_base.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_base.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -624,6 +624,12 @@
+ DBUG_ENTER("close_thread_table");
+ DBUG_ASSERT(table->key_read == 0);
+ DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
++
++ if(table->file)
++ {
++ table->file->update_global_table_stats();
++ table->file->update_global_index_stats();
++ }
+
+ *table_ptr=table->next;
+ if (table->needs_reopen_or_name_lock() ||
+@@ -670,6 +676,9 @@
+ {
+ DBUG_ENTER("close_temporary");
+ char path[FN_REFLEN];
++
++ table->file->update_global_table_stats();
++ table->file->update_global_index_stats();
+ db_type table_type=table->s->db_type;
+ strmov(path,table->s->path);
+ free_io_cache(table);
+diff -r 592f6c3641ba sql/sql_class.cc
+--- a/sql/sql_class.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_class.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -239,6 +239,13 @@
+ bzero(ha_data, sizeof(ha_data));
+ mysys_var=0;
+ binlog_evt_union.do_union= FALSE;
++ busy_time = 0;
++ cpu_time = 0;
++ bytes_received = 0;
++ bytes_sent = 0;
++ binlog_bytes_written = 0;
++ updated_row_count = 0;
++ sent_row_count_2 = 0;
+ #ifndef DBUG_OFF
+ dbug_sentry=THD_SENTRY_MAGIC;
+ #endif
+@@ -378,6 +385,88 @@
+ total_warn_count= 0;
+ update_charset();
+ bzero((char *) &status_var, sizeof(status_var));
++ reset_stats();
++}
++
++// Resets stats in a THD.
++void THD::reset_stats(void) {
++ current_connect_time = time(NULL);
++ last_global_update_time = current_connect_time;
++ reset_diff_stats();
++}
++
++// Resets the 'diff' stats, which are used to update global stats.
++void THD::reset_diff_stats(void) {
++ diff_total_busy_time = 0;
++ diff_total_cpu_time = 0;
++ diff_total_bytes_received = 0;
++ diff_total_bytes_sent = 0;
++ diff_total_binlog_bytes_written = 0;
++ diff_total_sent_rows = 0;
++ diff_total_updated_rows = 0;
++ diff_total_read_rows = 0;
++ diff_select_commands = 0;
++ diff_update_commands = 0;
++ diff_other_commands = 0;
++ diff_commit_trans = 0;
++ diff_rollback_trans = 0;
++ diff_denied_connections = 0;
++ diff_lost_connections = 0;
++ diff_access_denied_errors = 0;
++ diff_empty_queries = 0;
++}
++
++// Updates 'diff' stats of a THD.
++void THD::update_stats(bool ran_command) {
++ if (opt_userstat_running) {
++ diff_total_busy_time += busy_time;
++ diff_total_cpu_time += cpu_time;
++ diff_total_bytes_received += bytes_received;
++ diff_total_bytes_sent += bytes_sent;
++ diff_total_binlog_bytes_written += binlog_bytes_written;
++ diff_total_sent_rows += sent_row_count_2;
++ diff_total_updated_rows += updated_row_count;
++ // diff_total_read_rows is updated in handler.cc.
++
++ if (ran_command) {
++ // The replication thread has the COM_CONNECT command.
++ if ((old_command == COM_QUERY || command == COM_CONNECT) &&
++ (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
++ // A SQL query.
++ if (lex->sql_command == SQLCOM_SELECT) {
++ if (lex->orig_sql_command == SQLCOM_END) {
++ diff_select_commands++;
++ if (!sent_row_count_2)
++ diff_empty_queries++;
++ } else {
++ // 'SHOW ' commands become SQLCOM_SELECT.
++ diff_other_commands++;
++ // 'SHOW ' commands shouldn't inflate total sent row count.
++ diff_total_sent_rows -= sent_row_count_2;
++ }
++ } else if (is_update_query(lex->sql_command)) {
++ diff_update_commands++;
++ } else {
++ diff_other_commands++;
++ }
++ }
++ }
++ // diff_commit_trans is updated in handler.cc.
++ // diff_rollback_trans is updated in handler.cc.
++ // diff_denied_connections is updated in sql_parse.cc.
++ // diff_lost_connections is updated in sql_parse.cc.
++ // diff_access_denied_errors is updated in sql_parse.cc.
++
++ /* reset counters to zero to avoid double-counting since values
++ are already store in diff_total_*. */
++ }
++ busy_time = 0;
++ cpu_time = 0;
++ bytes_received = 0;
++ bytes_sent = 0;
++ binlog_bytes_written = 0;
++ updated_row_count = 0;
++ sent_row_count_2 = 0;
+ }
+
+
+@@ -907,6 +996,33 @@
+ }
+ #endif
+
++char *THD::get_client_host_port(THD *client)
++{
++ Security_context *client_sctx= client->security_ctx;
++ char *client_host= NULL;
++
++ if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
++ security_ctx->host_or_ip[0])
++ {
++ if ((client_host= this->alloc(LIST_PROCESS_HOST_LEN+1)))
++ my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
++ "%s:%u", client_sctx->host_or_ip, client->peer_port);
++ }
++ else
++ client_host= this->strdup(client_sctx->host_or_ip[0] ?
++ client_sctx->host_or_ip :
++ client_sctx->host ? client_sctx->host : "");
++
++ return client_host;
++}
++
++const char *get_client_host(THD *client)
++{
++ return client->security_ctx->host_or_ip[0] ?
++ client->security_ctx->host_or_ip :
++ client->security_ctx->host ? client->security_ctx->host : "";
++}
++
+
+ struct Item_change_record: public ilink
+ {
+@@ -1082,6 +1198,7 @@
+ buffer.set(buff, sizeof(buff), &my_charset_bin);
+ }
+ thd->sent_row_count++;
++ thd->sent_row_count_2++;
+ if (!thd->vio_ok())
+ DBUG_RETURN(0);
+ if (!thd->net.report_error)
+@@ -1174,6 +1291,7 @@
+ select_export::~select_export()
+ {
+ thd->sent_row_count=row_count;
++ thd->sent_row_count_2=row_count;
+ }
+
+
+@@ -2108,6 +2226,7 @@
+ if (likely(thd != 0))
+ { /* current_thd==0 when close_connection() calls net_send_error() */
+ thd->status_var.bytes_sent+= length;
++ thd->bytes_sent+= length;
+ }
+ }
+
+@@ -2115,6 +2234,7 @@
+ void thd_increment_bytes_received(ulong length)
+ {
+ current_thd->status_var.bytes_received+= length;
++ current_thd->bytes_received+= length;
+ }
+
+
+diff -r 592f6c3641ba sql/sql_class.h
+--- a/sql/sql_class.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_class.h Wed Jul 29 13:34:11 2009 -0700
+@@ -1302,6 +1302,8 @@
+ first byte of the packet in do_command()
+ */
+ enum enum_server_command command;
++ // Used to save the command, before it is set to COM_SLEEP.
++ enum enum_server_command old_command;
+ uint32 server_id;
+ uint32 file_id; // for LOAD DATA INFILE
+ /*
+@@ -1498,6 +1500,8 @@
+ /* variables.transaction_isolation is reset to this after each commit */
+ enum_tx_isolation session_tx_isolation;
+ enum_check_fields count_cuted_fields;
++ ha_rows updated_row_count;
++ ha_rows sent_row_count_2; /* for userstat */
+
+ DYNAMIC_ARRAY user_var_events; /* For user variables replication */
+ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
+@@ -1607,6 +1611,49 @@
+ */
+ LOG_INFO* current_linfo;
+ NET* slave_net; // network connection from slave -> m.
++
++ /*
++ Used to update global user stats. The global user stats are updated
++ occasionally with the 'diff' variables. After the update, the 'diff'
++ variables are reset to 0.
++ */
++ // Time when the current thread connected to MySQL.
++ time_t current_connect_time;
++ // Last time when THD stats were updated in global_user_stats.
++ time_t last_global_update_time;
++ // Busy (non-idle) time for just one command.
++ double busy_time;
++ // Busy time not updated in global_user_stats yet.
++ double diff_total_busy_time;
++ // Cpu (non-idle) time for just one thread.
++ double cpu_time;
++ // Cpu time not updated in global_user_stats yet.
++ double diff_total_cpu_time;
++ /* bytes counting */
++ ulonglong bytes_received;
++ ulonglong diff_total_bytes_received;
++ ulonglong bytes_sent;
++ ulonglong diff_total_bytes_sent;
++ ulonglong binlog_bytes_written;
++ ulonglong diff_total_binlog_bytes_written;
++
++ // Number of rows not reflected in global_user_stats yet.
++ ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
++ // Number of commands not reflected in global_user_stats yet.
++ ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
++ // Number of transactions not reflected in global_user_stats yet.
++ ulonglong diff_commit_trans, diff_rollback_trans;
++ // Number of connection errors not reflected in global_user_stats yet.
++ ulonglong diff_denied_connections, diff_lost_connections;
++ // Number of db access denied, not reflected in global_user_stats yet.
++ ulonglong diff_access_denied_errors;
++ // Number of queries that return 0 rows
++ ulonglong diff_empty_queries;
++
++ // Per account query delay in miliseconds. When not 0, sleep this number of
++ // milliseconds before every SQL command.
++ ulonglong query_delay_millis;
++
+ /* Used by the sys_var class to store temporary values */
+ union
+ {
+@@ -1662,6 +1709,11 @@
+ alloc_root.
+ */
+ void init_for_queries();
++ void reset_stats(void);
++ void reset_diff_stats(void);
++ // ran_command is true when this is called immediately after a
++ // command has been run.
++ void update_stats(bool ran_command);
+ void change_user(void);
+ void cleanup(void);
+ void cleanup_after_query();
+@@ -1891,8 +1943,14 @@
+ if (p_db_length)
+ *p_db_length= db_length;
+ return FALSE;
++
++ // Returns string as 'IP:port' for the client-side of the connnection represented
++ // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
++ // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
+ }
+
++ char *get_client_host_port(THD *client);
++
+ public:
+ /**
+ Add an internal error handler to the thread execution context.
+@@ -1935,6 +1993,10 @@
+ MEM_ROOT main_mem_root;
+ };
+
++// Returns string as 'IP' for the client-side of the connection represented by
++// 'client'. Does not allocate memory. May return "".
++const char *get_client_host(THD *client);
++
+
+ #define tmp_disable_binlog(A) \
+ {ulonglong tmp_disable_binlog__save_options= (A)->options; \
+diff -r 592f6c3641ba sql/sql_delete.cc
+--- a/sql/sql_delete.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_delete.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -358,6 +358,7 @@
+ send_ok(thd,deleted);
+ DBUG_PRINT("info",("%ld records deleted",(long) deleted));
+ }
++ thd->updated_row_count += deleted;
+ DBUG_RETURN(error >= 0 || thd->net.report_error);
+ }
+
+@@ -887,6 +888,7 @@
+ thd->row_count_func= deleted;
+ ::send_ok(thd, deleted);
+ }
++ thd->updated_row_count += deleted;
+ return 0;
+ }
+
+diff -r 592f6c3641ba sql/sql_insert.cc
+--- a/sql/sql_insert.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_insert.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -990,6 +990,7 @@
+ thd->row_count_func= info.copied + info.deleted + updated;
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ }
++ thd->updated_row_count += thd->row_count_func;
+ thd->abort_on_warning= 0;
+ DBUG_RETURN(FALSE);
+
+@@ -3094,6 +3095,7 @@
+ autoinc_value_of_first_inserted_row : thd->insert_id_used ?
+ thd->last_insert_id : 0;
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
++ thd->updated_row_count += thd->row_count_func;
+ DBUG_RETURN(0);
+ }
+
+diff -r 592f6c3641ba sql/sql_lex.h
+--- a/sql/sql_lex.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_lex.h Wed Jul 29 13:34:11 2009 -0700
+@@ -101,6 +101,9 @@
+ When a command is added here, be sure it's also added in mysqld.cc
+ in "struct show_var_st status_vars[]= {" ...
+ */
++ // TODO(mcallaghan): update status_vars in mysqld to export these
++ SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
++ SQLCOM_SHOW_CLIENT_STATS,
+ /* This should be the last !!! */
+ SQLCOM_END
+ };
+diff -r 592f6c3641ba sql/sql_parse.cc
+--- a/sql/sql_parse.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_parse.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -78,6 +78,12 @@
+ const char *table_name);
+ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
+
++// Increments connection count for user.
++static int increment_connection_count(THD* thd, bool use_lock);
++
++// Uses the THD to update the global stats by user name and client IP
++void update_global_user_stats(THD* thd, bool create_user, time_t now);
++
+ const char *any_db="*any*"; // Special symbol for check_access
+
+ const char *command_name[]={
+@@ -146,6 +152,17 @@
+ static bool do_command(THD *thd);
+ #endif // EMBEDDED_LIBRARY
+
++HASH global_user_stats;
++HASH global_client_stats;
++// Protects global_user_stats and global_client_stats
++extern pthread_mutex_t LOCK_global_user_client_stats;
++
++HASH global_table_stats;
++extern pthread_mutex_t LOCK_global_table_stats;
++
++HASH global_index_stats;
++extern pthread_mutex_t LOCK_global_index_stats;
++
+ #ifdef __WIN__
+ extern void win_install_sigabrt_handler(void);
+ #endif
+@@ -504,6 +521,7 @@
+ mysql_log.write(thd,COM_CONNECT,"%s",ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ DBUG_RETURN(-1);
+ }
++ thd->diff_access_denied_errors++;
+ net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+@@ -536,12 +554,190 @@
+ void init_max_user_conn(void)
+ {
+ #ifndef NO_EMBEDDED_ACCESS_CHECKS
+- (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
+- 0,0,
+- (hash_get_key) get_key_conn, (hash_free_key) free_user,
+- 0);
+-#endif
+-}
++ if (hash_init(&hash_user_connections,system_charset_info,max_connections,
++ 0,0,
++ (hash_get_key) get_key_conn, (hash_free_key) free_user,
++ 0)) {
++ sql_print_error("Initializing hash_user_connections failed.");
++ exit(1);
++ }
++#endif
++}
++
++byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(user_stats->user);
++ return (byte*)user_stats->user;
++}
++
++void free_user_stats(USER_STATS* user_stats)
++{
++ my_free((char*)user_stats, MYF(0));
++}
++
++void init_user_stats(USER_STATS *user_stats,
++ const char *user,
++ const char *priv_user,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries)
++{
++ DBUG_ENTER("init_user_stats");
++ DBUG_PRINT("info",
++ ("Add user_stats entry for user %s - priv_user %s",
++ user, priv_user));
++ strncpy(user_stats->user, user, sizeof(user_stats->user));
++ strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
++
++ user_stats->total_connections = total_connections;
++ user_stats->concurrent_connections = concurrent_connections;
++ user_stats->connected_time = connected_time;
++ user_stats->busy_time = busy_time;
++ user_stats->cpu_time = cpu_time;
++ user_stats->bytes_received = bytes_received;
++ user_stats->bytes_sent = bytes_sent;
++ user_stats->binlog_bytes_written = binlog_bytes_written;
++ user_stats->rows_fetched = rows_fetched;
++ user_stats->rows_updated = rows_updated;
++ user_stats->rows_read = rows_read;
++ user_stats->select_commands = select_commands;
++ user_stats->update_commands = update_commands;
++ user_stats->other_commands = other_commands;
++ user_stats->commit_trans = commit_trans;
++ user_stats->rollback_trans = rollback_trans;
++ user_stats->denied_connections = denied_connections;
++ user_stats->lost_connections = lost_connections;
++ user_stats->access_denied_errors = access_denied_errors;
++ user_stats->empty_queries = empty_queries;
++ DBUG_VOID_RETURN;
++}
++
++void add_user_stats(USER_STATS *user_stats,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries)
++{
++ user_stats->total_connections += total_connections;
++ user_stats->concurrent_connections += concurrent_connections;
++ user_stats->connected_time += connected_time;
++ user_stats->busy_time += busy_time;
++ user_stats->cpu_time += cpu_time;
++ user_stats->bytes_received += bytes_received;
++ user_stats->bytes_sent += bytes_sent;
++ user_stats->binlog_bytes_written += binlog_bytes_written;
++ user_stats->rows_fetched += rows_fetched;
++ user_stats->rows_updated += rows_updated;
++ user_stats->rows_read += rows_read;
++ user_stats->select_commands += select_commands;
++ user_stats->update_commands += update_commands;
++ user_stats->other_commands += other_commands;
++ user_stats->commit_trans += commit_trans;
++ user_stats->rollback_trans += rollback_trans;
++ user_stats->denied_connections += denied_connections;
++ user_stats->lost_connections += lost_connections;
++ user_stats->access_denied_errors += access_denied_errors;
++ user_stats->empty_queries += empty_queries;
++}
++
++void init_global_user_stats(void)
++{
++ if (hash_init(&global_user_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0)) {
++ sql_print_error("Initializing global_user_stats failed.");
++ exit(1);
++ }
++}
++
++void init_global_client_stats(void)
++{
++ if (hash_init(&global_client_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0)) {
++ sql_print_error("Initializing global_client_stats failed.");
++ exit(1);
++ }
++}
++
++extern "C" byte *get_key_table_stats(TABLE_STATS *table_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(table_stats->table);
++ return (byte*)table_stats->table;
++}
++
++extern "C" void free_table_stats(TABLE_STATS* table_stats)
++{
++ my_free((char*)table_stats, MYF(0));
++}
++
++void init_global_table_stats(void)
++{
++ if (hash_init(&global_table_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_table_stats,
++ (hash_free_key)free_table_stats, 0)) {
++ sql_print_error("Initializing global_table_stats failed.");
++ exit(1);
++ }
++}
++
++extern "C" byte *get_key_index_stats(INDEX_STATS *index_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(index_stats->index);
++ return (byte*)index_stats->index;
++}
++
++extern "C" void free_index_stats(INDEX_STATS* index_stats)
++{
++ my_free((char*)index_stats, MYF(0));
++}
++
++void init_global_index_stats(void)
++{
++ if (hash_init(&global_index_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_index_stats,
++ (hash_free_key)free_index_stats, 0)) {
++ sql_print_error("Initializing global_index_stats failed.");
++ exit(1);
++ }
++}
++
+
+
+ /*
+@@ -599,7 +795,10 @@
+
+ end:
+ if (error)
++ {
++ statistic_increment(denied_connections, &LOCK_status);
+ uc->connections--; // no need for decrease_user_connections() here
++ }
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ DBUG_RETURN(error);
+ }
+@@ -646,6 +845,25 @@
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ }
+
++void free_global_user_stats(void)
++{
++ hash_free(&global_user_stats);
++}
++
++void free_global_table_stats(void)
++{
++ hash_free(&global_table_stats);
++}
++
++void free_global_index_stats(void)
++{
++ hash_free(&global_index_stats);
++}
++
++void free_global_client_stats(void)
++{
++ hash_free(&global_client_stats);
++}
+
+
+ /*
+@@ -698,6 +916,214 @@
+ return uc_update_queries[command] != 0;
+ }
+
++// 'mysql_system_user' is used for when the user is not defined for a THD.
++static char mysql_system_user[] = "#mysql_system#";
++
++// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise.
++static char* get_valid_user_string(char* user) {
++ return user ? user : mysql_system_user;
++}
++
++// Increments the global stats connection count for an entry from
++// global_client_stats or global_user_stats. Returns 0 on success
++// and 1 on error.
++static int increment_count_by_name(const char *name, const char *role_name,
++ HASH *users_or_clients, THD *thd)
++{
++ USER_STATS* user_stats;
++
++ if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, name,
++ strlen(name))))
++ {
++ // First connection for this user or client
++ if (!(user_stats = ((USER_STATS*)
++ my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
++ {
++ return 1; // Out of memory
++ }
++
++ init_user_stats(user_stats, name, role_name,
++ 0, 0, // connections
++ 0, 0, 0, // time
++ 0, 0, 0, // bytes sent, received and written
++ 0, 0, 0, // rows fetched, updated and read
++ 0, 0, 0, // select, update and other commands
++ 0, 0, // commit and rollback trans
++ thd->diff_denied_connections,
++ 0, // lost connections
++ 0, // access denied errors
++ 0); // empty queries
++
++ if (my_hash_insert(users_or_clients, (byte*)user_stats))
++ {
++ my_free((char*)user_stats, 0);
++ return 1; // Out of memory
++ }
++ }
++ user_stats->total_connections++;
++ return 0;
++}
++
++// Increments the global user and client stats connection count. If 'use_lock'
++// is true, LOCK_global_user_client_stats will be locked/unlocked. Returns
++// 0 on success, 1 on error.
++static int increment_connection_count(THD* thd, bool use_lock)
++{
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ const char* client_string = get_client_host(thd);
++ int return_value = 0;
++
++ if (!opt_userstat_running)
++ return return_value;
++
++ if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
++
++ if (increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd))
++ {
++ return_value = 1;
++ goto end;
++ }
++ if (increment_count_by_name(client_string,
++ user_string,
++ &global_client_stats, thd))
++ {
++ return_value = 1;
++ goto end;
++ }
++
++end:
++ if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ return return_value;
++}
++
++// Used to update the global user and client stats.
++static void update_global_user_stats_with_user(THD* thd,
++ USER_STATS* user_stats,
++ time_t now)
++{
++ user_stats->connected_time += now - thd->last_global_update_time;
++ thd->last_global_update_time = now;
++ user_stats->busy_time += thd->diff_total_busy_time;
++ user_stats->cpu_time += thd->diff_total_cpu_time;
++ user_stats->bytes_received += thd->diff_total_bytes_received;
++ user_stats->bytes_sent += thd->diff_total_bytes_sent;
++ user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
++ user_stats->rows_fetched += thd->diff_total_sent_rows;
++ user_stats->rows_updated += thd->diff_total_updated_rows;
++ user_stats->rows_read += thd->diff_total_read_rows;
++ user_stats->select_commands += thd->diff_select_commands;
++ user_stats->update_commands += thd->diff_update_commands;
++ user_stats->other_commands += thd->diff_other_commands;
++ user_stats->commit_trans += thd->diff_commit_trans;
++ user_stats->rollback_trans += thd->diff_rollback_trans;
++ user_stats->denied_connections += thd->diff_denied_connections;
++ user_stats->lost_connections += thd->diff_lost_connections;
++ user_stats->access_denied_errors += thd->diff_access_denied_errors;
++ user_stats->empty_queries += thd->diff_empty_queries;
++}
++
++// Updates the global stats of a user or client
++void update_global_user_stats(THD* thd, bool create_user, time_t now)
++{
++ if (opt_userstat_running) {
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ const char* client_string = get_client_host(thd);
++
++ USER_STATS* user_stats;
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++
++ // Update by user name
++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
++ (byte*)user_string,
++ strlen(user_string)))) {
++ // Found user.
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Create the entry
++ if (create_user) {
++ increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd);
++ }
++ }
++
++ // Update by client IP
++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
++ (byte*)client_string,
++ strlen(client_string)))) {
++ // Found by client IP
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Create the entry
++ if (create_user) {
++ increment_count_by_name(client_string,
++ user_string,
++ &global_client_stats, thd);
++ }
++ }
++ thd->reset_diff_stats();
++
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ } else {
++ thd->reset_diff_stats();
++ }
++}
++
++// Determines the concurrent number of connections of current threads.
++static void set_connections_stats()
++{
++ USER_STATS* user_stats;
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ pthread_mutex_lock(&LOCK_thread_count);
++
++ // Resets all concurrent connections to 0.
++ for (int i = 0; i < global_user_stats.records; ++i) {
++ user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
++ user_stats->concurrent_connections = 0;
++ }
++ for (int i = 0; i < global_client_stats.records; ++i) {
++ user_stats = (USER_STATS*)hash_element(&global_client_stats, i);
++ user_stats->concurrent_connections = 0;
++ }
++
++ I_List_iterator<THD> it(threads);
++ THD* thd;
++ time_t now = time(NULL);
++ // Iterates through the current threads.
++ while ((thd = it++)) {
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
++ (byte*)user_string,
++ strlen(user_string)))) {
++ // Found user.
++ user_stats->concurrent_connections++;
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // The user name should exist.
++ if (user_string == mysql_system_user) {
++ // Only create the user if it is the mysql_system_user
++ increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd);
++ }
++ }
++
++ const char* client_string = get_client_host(thd);
++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
++ (byte*)client_string,
++ strlen(client_string)))) {
++ // Found user.
++ user_stats->concurrent_connections++;
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Do nothing, unlike what is done for global_user_stats
++ }
++ thd->reset_diff_stats();
++ }
++ pthread_mutex_unlock(&LOCK_thread_count);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++}
++
+ /*
+ Reset per-hour user resource limits when it has been more than
+ an hour since they were last checked
+@@ -1184,6 +1610,8 @@
+ my_net_set_read_timeout(net, connect_timeout);
+ my_net_set_write_timeout(net, connect_timeout);
+
++ bool create_user = true;
++
+ if ((error=check_connection(thd)))
+ { // Wrong permissions
+ if (error > 0)
+@@ -1193,8 +1621,22 @@
+ my_sleep(1000); /* must wait after eof() */
+ #endif
+ statistic_increment(aborted_connects,&LOCK_status);
++ thd->diff_denied_connections++;
++ if (error == -2) {
++ // Do not create statistics for a user who does not exist, or failed
++ // to authenticate.
++ create_user = false;
++ }
+ goto end_thread;
+ }
++
++ thd->reset_stats();
++ // Updates global user connection stats.
++ if (increment_connection_count(thd, true)) {
++ net_send_error(thd, ER_OUTOFMEMORY); // Out of memory
++ goto end_thread;
++ }
++
+ #ifdef __NETWARE__
+ netware_reg_user(sctx->ip, sctx->user, "MySQL");
+ #endif
+@@ -1251,6 +1693,7 @@
+ (net->vio && net->error && net->report_error))
+ {
+ statistic_increment(aborted_threads, &LOCK_status);
++ thd->diff_lost_connections++;
+ }
+
+ if (net->error && net->vio != 0 && net->report_error)
+@@ -1270,6 +1713,8 @@
+
+ end_thread:
+ close_connection(thd, 0, 1);
++ thd->update_stats(false);
++ update_global_user_stats(thd, create_user, time(NULL));
+ end_thread(thd,1);
+ /*
+ If end_thread returns, we are either running with --one-thread
+@@ -1601,6 +2046,13 @@
+
+ thd->clear_error(); // Clear error message
+
++ thd->updated_row_count=0;
++ thd->busy_time=0;
++ thd->cpu_time=0;
++ thd->bytes_received=0;
++ thd->bytes_sent=0;
++ thd->binlog_bytes_written=0;
++
+ net_new_transaction(net);
+
+ packet_length= my_net_read(net);
+@@ -1759,6 +2211,9 @@
+ }
+
+ thd->command=command;
++ // To increment the corrent command counter for user stats, 'command' must
++ // be saved because it is set to COM_SLEEP at the end of this function.
++ thd->old_command = command;
+ /*
+ Commands which always take a long time are logged into
+ the slow log only if opt_log_slow_admin_statements is set.
+@@ -4539,6 +4994,15 @@
+ if (check_global_access(thd,RELOAD_ACL))
+ goto error;
+
++ if(lex->type & REFRESH_SLOW_QUERY_LOG) {
++ /* We are only flushing slow query log */
++ mysql_slow_log.new_file(1);
++
++ send_ok(thd);
++ break;
++ }
++
++
+ /*
+ reload_acl_and_cache() will tell us if we are allowed to write to the
+ binlog or not.
+@@ -4847,6 +5311,7 @@
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ goto create_sp_error;
+ }
+@@ -5691,6 +6156,7 @@
+ if (!no_errors)
+ {
+ const char *db_name= db ? db : thd->db;
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host, db_name);
+ }
+@@ -5726,6 +6192,7 @@
+ { // We can never grant this
+ DBUG_PRINT("error",("No possible access"));
+ if (!no_errors)
++ thd->diff_access_denied_errors++;
+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user,
+ sctx->priv_host,
+@@ -5758,11 +6225,15 @@
+
+ DBUG_PRINT("error",("Access denied"));
+ if (!no_errors)
++ {
++ // increment needs !no_errors condition, otherwise double counting.
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host,
+ (db ? db : (thd->db ?
+ thd->db :
+ "unknown"))); /* purecov: tested */
++ }
+ DBUG_RETURN(TRUE); /* purecov: tested */
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ }
+@@ -5796,6 +6267,7 @@
+ if ((thd->security_ctx->master_access & want_access))
+ return 0;
+ get_privilege_desc(command, sizeof(command), want_access);
++ thd->diff_access_denied_errors++;
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
+ return 1;
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+@@ -5828,6 +6300,7 @@
+
+ if (!thd->col_access && check_grant_db(thd, dst_db_name))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host,
+@@ -5859,6 +6332,12 @@
+ check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
+ }
+
++
++ case SCH_USER_STATS:
++ case SCH_CLIENT_STATS:
++ return check_global_access(thd, SUPER_ACL | PROCESS_ACL);
++ case SCH_TABLE_STATS:
++ case SCH_INDEX_STATS:
+ case SCH_OPEN_TABLES:
+ case SCH_VARIABLES:
+ case SCH_STATUS:
+@@ -5912,8 +6391,8 @@
+ #ifndef NO_EMBEDDED_ACCESS_CHECKS
+ TABLE_LIST *org_tables= tables;
+ #endif
++ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
+ TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
+- Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
+ /*
+ The check that first_not_own_table is not reached is for the case when
+ the given table list refers to the list for prelocking (contains tables
+@@ -5930,9 +6409,12 @@
+ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
+ {
+ if (!no_errors)
++ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host,
+ INFORMATION_SCHEMA_NAME.str);
++ }
+ return TRUE;
+ }
+ /*
+@@ -6442,6 +6924,30 @@
+ lex_start(thd);
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (query_cache_send_result_to_client(thd, (char*) inBuf, length) <= 0)
+ {
+ LEX *lex= thd->lex;
+@@ -6520,6 +7026,43 @@
+ *found_semicolon= NULL;
+ }
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -7531,8 +8074,35 @@
+ pthread_mutex_unlock(&LOCK_active_mi);
+ }
+ #endif
+- if (options & REFRESH_USER_RESOURCES)
+- reset_mqh((LEX_USER *) NULL);
++ if (options & REFRESH_TABLE_STATS)
++ {
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ free_global_table_stats();
++ init_global_table_stats();
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++ }
++ if (options & REFRESH_INDEX_STATS)
++ {
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ free_global_index_stats();
++ init_global_index_stats();
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ }
++ if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS))
++ {
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ if (options & REFRESH_USER_STATS)
++ {
++ free_global_user_stats();
++ init_global_user_stats();
++ }
++ if (options & REFRESH_CLIENT_STATS)
++ {
++ free_global_client_stats();
++ init_global_client_stats();
++ }
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ }
+ *write_to_binlog= tmp_write_to_binlog;
+ return result;
+ }
+diff -r 592f6c3641ba sql/sql_prepare.cc
+--- a/sql/sql_prepare.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_prepare.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -81,6 +81,9 @@
+ #include <mysql_com.h>
+ #endif
+
++// Uses the THD to update the global stats by user name and client IP
++void update_global_user_stats(THD* thd, bool create_user, time_t now);
++
+ /* A result class used to send cursor rows using the binary protocol. */
+
+ class Select_fetch_protocol_prep: public select_send
+@@ -1910,8 +1913,32 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (! (stmt= new Prepared_statement(thd, &thd->protocol_prep)))
+- DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
++ goto end; /* out of memory: error is set in Sql_alloc */
+
+ if (thd->stmt_map.insert(thd, stmt))
+ {
+@@ -1919,7 +1946,7 @@
+ The error is set in the insert. The statement itself
+ will be also deleted there (this is how the hash works).
+ */
+- DBUG_VOID_RETURN;
++ goto end;
+ }
+
+ /* Reset warnings from previous command */
+@@ -1941,6 +1968,44 @@
+ thd->stmt_map.erase(stmt);
+ }
+ /* check_prepared_statemnt sends the metadata packet in case of success */
++end:
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2281,8 +2346,32 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
+- DBUG_VOID_RETURN;
++ goto end;
+
+ #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.set_query_source(stmt->query, stmt->query_length);
+@@ -2325,11 +2414,50 @@
+ test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
+ if (!(specialflag & SPECIAL_NO_PRIOR))
+ my_pthread_setprio(pthread_self(), WAIT_PRIOR);
+- DBUG_VOID_RETURN;
++ goto end;
+
+ set_params_data_err:
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
+ reset_stmt_params(stmt);
++
++end:
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2423,6 +2551,31 @@
+
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
++
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
+ DBUG_VOID_RETURN;
+@@ -2455,6 +2608,43 @@
+ thd->restore_backup_statement(stmt, &stmt_backup);
+ thd->stmt_arena= thd;
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2487,6 +2677,30 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status);
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
+ DBUG_VOID_RETURN;
+@@ -2503,6 +2717,43 @@
+
+ send_ok(thd);
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+diff -r 592f6c3641ba sql/sql_show.cc
+--- a/sql/sql_show.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_show.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -540,6 +540,7 @@
+ sctx->master_access);
+ if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->host_or_ip, dbname);
+ mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
+@@ -1890,6 +1891,300 @@
+ DBUG_RETURN(FALSE);
+ }
+
++/*
++ Aggregate values for mapped_user entries by their role.
++
++ SYNOPSIS
++ aggregate_user_stats
++ all_user_stats - input to aggregate
++ agg_user_stats - returns aggregated values
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++static int
++aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats)
++{
++ DBUG_ENTER("aggregate_user_stats");
++ if (hash_init(agg_user_stats, system_charset_info,
++ max(all_user_stats->records, 1),
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0))
++ {
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++
++ for (int i = 0; i < all_user_stats->records; ++i) {
++ USER_STATS *user = (USER_STATS*)hash_element(all_user_stats, i);
++ USER_STATS *agg_user;
++ if (!(agg_user = (USER_STATS*)hash_search(agg_user_stats,
++ (byte*)user->priv_user,
++ strlen(user->priv_user))))
++ {
++ // First entry for this role.
++ if (!(agg_user =
++ (USER_STATS*) my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL))))
++ {
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++
++ init_user_stats(agg_user, user->priv_user, user->priv_user,
++ user->total_connections, user->concurrent_connections,
++ user->connected_time, user->busy_time, user->cpu_time,
++ user->bytes_received, user->bytes_sent,
++ user->binlog_bytes_written,
++ user->rows_fetched, user->rows_updated, user->rows_read,
++ user->select_commands, user->update_commands,
++ user->other_commands,
++ user->commit_trans, user->rollback_trans,
++ user->denied_connections, user->lost_connections,
++ user->access_denied_errors, user->empty_queries);
++
++ if (my_hash_insert(agg_user_stats, (byte*)agg_user))
++ {
++ // Out of memory.
++ my_free((char*)agg_user, 0);
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++ }
++ else
++ {
++ // Aggregate with existing values for this role.
++ add_user_stats(agg_user,
++ user->total_connections, user->concurrent_connections,
++ user->connected_time, user->busy_time, user->cpu_time,
++ user->bytes_received, user->bytes_sent,
++ user->binlog_bytes_written,
++ user->rows_fetched, user->rows_updated, user->rows_read,
++ user->select_commands, user->update_commands,
++ user->other_commands,
++ user->commit_trans, user->rollback_trans,
++ user->denied_connections, user->lost_connections,
++ user->access_denied_errors, user->empty_queries);
++ }
++ }
++ DBUG_PRINT("exit", ("aggregated %d input into %d output entries",
++ all_user_stats->records, agg_user_stats->records));
++ DBUG_RETURN(0);
++}
++
++/*
++ Write result to network for SHOW USER_STATISTICS
++
++ SYNOPSIS
++ send_user_stats
++ all_user_stats - values to return
++ table - I_S table
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
++{
++ DBUG_ENTER("send_user_stats");
++ for (int i = 0; i < all_user_stats->records; ++i) {
++ restore_record(table, s->default_values);
++ USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
++ table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
++ table->field[1]->store((longlong)user_stats->total_connections);
++ table->field[2]->store((longlong)user_stats->concurrent_connections);
++ table->field[3]->store((longlong)user_stats->connected_time);
++ table->field[4]->store((longlong)user_stats->busy_time);
++ table->field[5]->store((longlong)user_stats->cpu_time);
++ table->field[6]->store((longlong)user_stats->bytes_received);
++ table->field[7]->store((longlong)user_stats->bytes_sent);
++ table->field[8]->store((longlong)user_stats->binlog_bytes_written);
++ table->field[9]->store((longlong)user_stats->rows_fetched);
++ table->field[10]->store((longlong)user_stats->rows_updated);
++ table->field[11]->store((longlong)user_stats->rows_read);
++ table->field[12]->store((longlong)user_stats->select_commands);
++ table->field[13]->store((longlong)user_stats->update_commands);
++ table->field[14]->store((longlong)user_stats->other_commands);
++ table->field[15]->store((longlong)user_stats->commit_trans);
++ table->field[16]->store((longlong)user_stats->rollback_trans);
++ table->field[17]->store((longlong)user_stats->denied_connections);
++ table->field[18]->store((longlong)user_stats->lost_connections);
++ table->field[19]->store((longlong)user_stats->access_denied_errors);
++ table->field[20]->store((longlong)user_stats->empty_queries);
++ if (schema_table_store_record(thd, table))
++ {
++ DBUG_PRINT("error", ("store record error"));
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++/*
++ Process SHOW USER_STATISTICS
++
++ SYNOPSIS
++ mysqld_show_user_stats
++ thd - current thread
++ wild - limit results to the entry for this user
++ with_roles - when true, display role for mapped users
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++
++
++int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_user_stats");
++
++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
++ DBUG_RETURN(1);
++
++ // Iterates through all the global stats and sends them to the client.
++ // Pattern matching on the client IP is supported.
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ int result= send_user_stats(thd, &global_user_stats, table);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ if (result)
++ goto err;
++
++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
++ DBUG_RETURN(0);
++
++ err:
++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
++ DBUG_RETURN(1);
++}
++
++/*
++ Process SHOW CLIENT_STATISTICS
++
++ SYNOPSIS
++ mysqld_show_client_stats
++ thd - current thread
++ wild - limit results to the entry for this client
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++
++
++int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_client_stats");
++
++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
++ DBUG_RETURN(1);
++
++ // Iterates through all the global stats and sends them to the client.
++ // Pattern matching on the client IP is supported.
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ int result= send_user_stats(thd, &global_client_stats, table);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ if (result)
++ goto err;
++
++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
++ DBUG_RETURN(0);
++
++ err:
++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
++ DBUG_RETURN(1);
++}
++
++
++// Sends the global table stats back to the client.
++int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_table_stats");
++ char *table_full_name, *table_schema;
++
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ for (int i = 0; i < global_table_stats.records; ++i) {
++ restore_record(table, s->default_values);
++ TABLE_STATS *table_stats =
++ (TABLE_STATS*)hash_element(&global_table_stats, i);
++
++ table_full_name= thd->strdup(table_stats->table);
++ table_schema= strsep(&table_full_name, ".");
++
++ TABLE_LIST tmp_table;
++ bzero((char*) &tmp_table,sizeof(tmp_table));
++ tmp_table.table_name= table_full_name;
++ tmp_table.db= table_schema;
++ tmp_table.grant.privilege= 0;
++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
++ &tmp_table.grant.privilege, 0, 0,
++ is_schema_db(table_schema)) ||
++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
++ continue;
++
++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
++ table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
++ table->field[2]->store((longlong)table_stats->rows_read, TRUE);
++ table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
++ table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
++
++ if (schema_table_store_record(thd, table))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
++ DBUG_RETURN(1);
++ }
++ }
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++ DBUG_RETURN(0);
++}
++
++// Sends the global index stats back to the client.
++int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_index_stats");
++ char *index_full_name, *table_schema, *table_name;
++
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ for (int i = 0; i < global_index_stats.records; ++i) {
++ restore_record(table, s->default_values);
++ INDEX_STATS *index_stats =
++ (INDEX_STATS*)hash_element(&global_index_stats, i);
++
++ index_full_name= thd->strdup(index_stats->index);
++ table_schema= strsep(&index_full_name, ".");
++ table_name= strsep(&index_full_name, ".");
++
++ TABLE_LIST tmp_table;
++ bzero((char*) &tmp_table,sizeof(tmp_table));
++ tmp_table.table_name= table_name;
++ tmp_table.db= table_schema;
++ tmp_table.grant.privilege= 0;
++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
++ &tmp_table.grant.privilege, 0, 0,
++ is_schema_db(table_schema)) ||
++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
++ continue;
++
++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
++ table->field[1]->store(table_name, strlen(table_name), system_charset_info);
++ table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
++ table->field[3]->store((longlong)index_stats->rows_read, TRUE);
++
++ if (schema_table_store_record(thd, table))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
++ DBUG_RETURN(1);
++ }
++ }
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ DBUG_RETURN(0);
++}
+
+ /* collect status for all running threads */
+
+@@ -4500,6 +4795,77 @@
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+ };
+
++ST_FIELD_INFO user_stats_fields_info[]=
++{
++ {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User"},
++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++ST_FIELD_INFO client_stats_fields_info[]=
++{
++ {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client"},
++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++
++ST_FIELD_INFO table_stats_fields_info[]=
++{
++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
++ {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed"},
++ {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++ST_FIELD_INFO index_stats_fields_info[]=
++{
++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
++ {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name"},
++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
+
+ /*
+ Description of ST_FIELD_INFO in table.h
+@@ -4509,6 +4875,8 @@
+ {
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
++ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
++ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
+ {"COLLATIONS", collation_fields_info, create_schema_table,
+ fill_schema_collation, make_old_format, 0, -1, -1, 0},
+ {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
+@@ -4517,6 +4885,8 @@
+ get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
+ {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
+ fill_schema_column_privileges, 0, 0, -1, -1, 0},
++ {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
++ fill_schema_index_stats, make_old_format, 0, -1, -1, 0},
+ {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
+ get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
+ {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
+@@ -4542,10 +4912,14 @@
+ get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+ {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
+ fill_schema_table_privileges, 0, 0, -1, -1, 0},
++ {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
++ fill_schema_table_stats, make_old_format, 0, -1, -1, 0},
+ {"TRIGGERS", triggers_fields_info, create_schema_table,
+ get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ fill_schema_user_privileges, 0, 0, -1, -1, 0},
++ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
++ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
+ {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
+ make_old_format, 0, -1, -1, 1},
+ {"VIEWS", view_fields_info, create_schema_table,
+diff -r 592f6c3641ba sql/sql_update.cc
+--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -601,7 +601,8 @@
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
+ send_ok(thd, (ulong) thd->row_count_func,
+ thd->insert_id_used ? thd->last_insert_id : 0L,buff);
+- DBUG_PRINT("info",("%ld records updated", (long) updated));
++ thd->updated_row_count += thd->row_count_func;
++ DBUG_PRINT("info",("%d records updated",updated));
+ }
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
+ thd->abort_on_warning= 0;
+@@ -1832,5 +1833,6 @@
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
+ ::send_ok(thd, (ulong) thd->row_count_func,
+ thd->insert_id_used ? thd->last_insert_id : 0L,buff);
++ thd->updated_row_count += thd->row_count_func;
+ return FALSE;
+ }
+diff -r 592f6c3641ba sql/sql_yacc.yy
+--- a/sql/sql_yacc.yy Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_yacc.yy Wed Jul 29 13:34:11 2009 -0700
+@@ -523,6 +523,7 @@
+ %token CHECK_SYM
+ %token CIPHER_SYM
+ %token CLIENT_SYM
++%token CLIENT_STATS_SYM
+ %token CLOSE_SYM
+ %token COALESCE
+ %token CODE_SYM
+@@ -680,6 +681,7 @@
+ %token IMPORT
+ %token INDEXES
+ %token INDEX_SYM
++%token INDEX_STATS_SYM
+ %token INFILE
+ %token INNER_SYM
+ %token INNOBASE_SYM
+@@ -909,6 +911,7 @@
+ %token SIGNED_SYM
+ %token SIMPLE_SYM
+ %token SLAVE
++%token SLOW_SYM
+ %token SMALLINT
+ %token SNAPSHOT_SYM
+ %token SOUNDS_SYM
+@@ -949,6 +952,7 @@
+ %token TABLES
+ %token TABLESPACE
+ %token TABLE_SYM
++%token TABLE_STATS_SYM
+ %token TEMPORARY
+ %token TEMPTABLE_SYM
+ %token TERMINATED
+@@ -991,6 +995,7 @@
+ %token UPGRADE_SYM
+ %token USAGE
+ %token USER
++%token USER_STATS_SYM
+ %token USE_FRM
+ %token USE_SYM
+ %token USING
+@@ -8255,6 +8260,38 @@
+ {
+ Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
+ }
++ | CLIENT_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ Lex->sql_command = SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_CLIENT_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
++ MYSQL_YYABORT;
++ }
++ | USER_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command = SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_USER_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
++ MYSQL_YYABORT;
++ }
++ | TABLE_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command= SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
++ MYSQL_YYABORT;
++ }
++ | INDEX_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command= SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_INDEX_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
++ MYSQL_YYABORT;
++ }
+ | CREATE PROCEDURE sp_name
+ {
+ LEX *lex= Lex;
+@@ -8459,9 +8496,14 @@
+ | LOGS_SYM { Lex->type|= REFRESH_LOG; }
+ | STATUS_SYM { Lex->type|= REFRESH_STATUS; }
+ | SLAVE { Lex->type|= REFRESH_SLAVE; }
++ | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
+ | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
+- | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
++ | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }
++ | CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; }
++ | USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; }
++ | TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; }
++ | INDEX_STATS_SYM { Lex->type|= REFRESH_INDEX_STATS; };
+
+ opt_table_list:
+ /* empty */ {;}
+@@ -9450,6 +9492,7 @@
+ | CHAIN_SYM {}
+ | CHANGED {}
+ | CIPHER_SYM {}
++ | CLIENT_STATS_SYM {}
+ | CLIENT_SYM {}
+ | CODE_SYM {}
+ | COLLATION_SYM {}
+@@ -9502,6 +9545,7 @@
+ | HOSTS_SYM {}
+ | HOUR_SYM {}
+ | IDENTIFIED_SYM {}
++ | INDEX_STATS_SYM {}
+ | INVOKER_SYM {}
+ | IMPORT {}
+ | INDEXES {}
+@@ -9611,6 +9655,7 @@
+ | SIMPLE_SYM {}
+ | SHARE_SYM {}
+ | SHUTDOWN {}
++ | SLOW_SYM {}
+ | SNAPSHOT_SYM {}
+ | SOUNDS_SYM {}
+ | SOURCE_SYM {}
+@@ -9627,6 +9672,7 @@
+ | SUSPEND_SYM {}
+ | SWAPS_SYM {}
+ | SWITCHES_SYM {}
++ | TABLE_STATS_SYM {}
+ | TABLES {}
+ | TABLESPACE {}
+ | TEMPORARY {}
+@@ -9647,6 +9693,7 @@
+ | UNKNOWN_SYM {}
+ | UNTIL_SYM {}
+ | USER {}
++ | USER_STATS_SYM {}
+ | USE_FRM {}
+ | VARIABLES {}
+ | VIEW_SYM {}
+diff -r 592f6c3641ba sql/structs.h
+--- a/sql/structs.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/structs.h Wed Jul 29 13:34:11 2009 -0700
+@@ -273,6 +273,98 @@
+ time_t intime;
+ } USER_CONN;
+
++typedef struct st_user_stats {
++ char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
++ // Account name the user is mapped to when this is a user from mapped_user.
++ // Otherwise, the same value as user.
++ char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
++ uint total_connections;
++ uint concurrent_connections;
++ time_t connected_time; // in seconds
++ double busy_time; // in seconds
++ double cpu_time; // in seconds
++ ulonglong bytes_received;
++ ulonglong bytes_sent;
++ ulonglong binlog_bytes_written;
++ ha_rows rows_fetched, rows_updated, rows_read;
++ ulonglong select_commands, update_commands, other_commands;
++ ulonglong commit_trans, rollback_trans;
++ ulonglong denied_connections, lost_connections;
++ ulonglong access_denied_errors;
++ ulonglong empty_queries;
++} USER_STATS;
++
++/* Lookup function for hash tables with USER_STATS entries */
++extern byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
++ my_bool not_used __attribute__((unused)));
++
++/* Free all memory for a hash table with USER_STATS entries */
++extern void free_user_stats(USER_STATS* user_stats);
++
++/* Intialize an instance of USER_STATS */
++extern void
++init_user_stats(USER_STATS *user_stats,
++ const char *user,
++ const char *priv_user,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries);
++
++/* Increment values of an instance of USER_STATS */
++extern void
++add_user_stats(USER_STATS *user_stats,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries);
++
++typedef struct st_table_stats {
++ char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0'
++ ulonglong rows_read, rows_changed;
++ ulonglong rows_changed_x_indexes;
++ /* Stores enum db_type, but forward declarations cannot be done */
++ int engine_type;
++} TABLE_STATS;
++
++typedef struct st_index_stats {
++ char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0'
++ ulonglong rows_read;
++} INDEX_STATS;
++
++
+ /* Bits in form->update */
+ #define REG_MAKE_DUPP 1 /* Make a copy of record when read */
+ #define REG_NEW_RECORD 2 /* Write a new record if not found */
+diff -r 592f6c3641ba sql/table.h
+--- a/sql/table.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/table.h Wed Jul 29 13:34:11 2009 -0700
+@@ -371,10 +371,12 @@
+ enum enum_schema_tables
+ {
+ SCH_CHARSETS= 0,
++ SCH_CLIENT_STATS,
+ SCH_COLLATIONS,
+ SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
+ SCH_COLUMNS,
+ SCH_COLUMN_PRIVILEGES,
++ SCH_INDEX_STATS,
+ SCH_KEY_COLUMN_USAGE,
+ SCH_OPEN_TABLES,
+ SCH_PROFILES,
+@@ -387,8 +389,10 @@
+ SCH_TABLE_CONSTRAINTS,
+ SCH_TABLE_NAMES,
+ SCH_TABLE_PRIVILEGES,
++ SCH_TABLE_STATS,
+ SCH_TRIGGERS,
+ SCH_USER_PRIVILEGES,
++ SCH_USER_STATS,
+ SCH_VARIABLES,
+ SCH_VIEWS
+ };
+diff -r 592f6c3641ba strings/Makefile.in
+--- a/strings/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/strings/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -342,6 +342,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/MacOSX/Makefile.in
+--- a/support-files/MacOSX/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/MacOSX/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -148,6 +148,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/Makefile.in
+--- a/support-files/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/RHEL4-SElinux/Makefile.in
+--- a/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -146,6 +146,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba tests/Makefile.in
+--- a/tests/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/tests/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -193,6 +193,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba tools/Makefile.in
+--- a/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -167,6 +167,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba vio/Makefile.in
+--- a/vio/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/vio/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -176,6 +176,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba win/Makefile.in
+--- a/win/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/win/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba zlib/Makefile.in
+--- a/zlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/zlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -187,6 +187,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = $(NON_THREADED_LIBS)
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -Nur a/include/mysql_com.h b/include/mysql_com.h
+--- a/include/mysql_com.h 2010-05-22 00:26:45.000000000 -0700
++++ b/include/mysql_com.h 2010-05-22 00:27:14.000000000 -0700
+@@ -228,7 +228,7 @@
+
+ my_bool report_error; /* We should report error (we have unreported error) */
+ my_bool return_errno;
+-#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
++#if defined(MYSQL_SERVER)
+ /*
+ Controls whether a big packet should be skipped.
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 2:04 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 2:04 UTC (permalink / raw
To: gentoo-commits
commit: 0b42f57f3de8d2f8a0c120fc69e284d32e7aaea8
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 02:01:16 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 02:01:16 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0b42f57f
Complete previous commit to update 10030_all_userstatv2-percona patch for the 5.0.92 release.
---
10030_all_userstatv2-percona-5.0.92.patch | 21 ++++++++++++---------
1 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/10030_all_userstatv2-percona-5.0.92.patch b/10030_all_userstatv2-percona-5.0.92.patch
index 7ae1249..a60b7e2 100644
--- a/10030_all_userstatv2-percona-5.0.92.patch
+++ b/10030_all_userstatv2-percona-5.0.92.patch
@@ -3942,11 +3942,11 @@ diff -r 592f6c3641ba sql/sql_show.cc
Description of ST_FIELD_INFO in table.h
@@ -4509,6 +4875,8 @@
{
- {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
+ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
+ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
- {"COLLATIONS", collation_fields_info, create_schema_table,
+ {"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
@@ -4517,6 +4885,8 @@
@@ -3958,21 +3958,24 @@ diff -r 592f6c3641ba sql/sql_show.cc
{"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
-@@ -4542,10 +4912,14 @@
- get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
- {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
- fill_schema_table_privileges, 0, 0, -1, -1, 0},
+@@ -4542,6 +4912,8 @@
+ get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
+ {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
+ get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
+ {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
+ fill_schema_table_stats, make_old_format, 0, -1, -1, 0},
- {"TRIGGERS", triggers_fields_info, create_schema_table,
+ {"TABLE_NAMES", table_names_fields_info, create_schema_table,
+ get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+ {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
+@@ -4550,6 +4920,8 @@
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
- {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0},
+ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
+ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, -1, -1, 1},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
diff -r 592f6c3641ba sql/sql_update.cc
--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
+++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 12:08 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 12:08 UTC (permalink / raw
To: gentoo-commits
commit: 9560b95a0d9e0b4c79296b8409cf7e1667a56883
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 12:06:00 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 12:06:00 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=9560b95a
Fix the missing #endif error by dropping the 07300_all_mysql_embedded_compilefix patch for the 5.0.92 release.
---
00000_index.txt | 5 -----
07300_all_mysql_embedded_compilefix-5.0.92.patch | 11 -----------
2 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 94a582a..ab861dd 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -663,11 +663,6 @@
@pn mysql
@@ Compile fix for bug introduced by upstream in 5.0.91
-@patch 07300_all_mysql_embedded_compilefix-5.0.92.patch
-@ver 5.00.92.00 to 5.00.99.99
-@pn mysql
-@@ Compile fix for bug introduced by upstream in 5.0.91
-
@patch 07310_all_mysql_gcc45-disable-abicheck.patch
@ver 5.01.00.00 to 5.01.49.99
@pn mysql
diff --git a/07300_all_mysql_embedded_compilefix-5.0.92.patch b/07300_all_mysql_embedded_compilefix-5.0.92.patch
deleted file mode 100644
index 26a4c87..0000000
--- a/07300_all_mysql_embedded_compilefix-5.0.92.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Nuar mysql-5.0.91.orig//sql/sql_parse.cc mysql-5.0.91//sql/sql_parse.cc
---- mysql-5.0.91.orig//sql/sql_parse.cc 2010-05-05 14:07:10.000000000 +0000
-+++ mysql-5.0.91//sql/sql_parse.cc 2010-05-21 20:29:16.714903163 +0000
-@@ -499,6 +499,7 @@
- big packets indefinitely, this is a previously established behavior
- that needs to be preserved as to not break backwards compatibility.
- */
-+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
- thd->net.skip_big_packet= TRUE;
- #endif
- /* Ready to handle queries */
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 20:36 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 20:36 UTC (permalink / raw
To: gentoo-commits
commit: 49875a9122b33c48043bdb4e4c0bed1ddcbd6353
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 20:33:44 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 20:33:44 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=49875a91
Updated 10030_all_userstatv2-percona patch for the 5.0.92 release - whitespace.
---
10030_all_userstatv2-percona-5.0.92.patch | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/10030_all_userstatv2-percona-5.0.92.patch b/10030_all_userstatv2-percona-5.0.92.patch
index a60b7e2..2be677f 100644
--- a/10030_all_userstatv2-percona-5.0.92.patch
+++ b/10030_all_userstatv2-percona-5.0.92.patch
@@ -3942,11 +3942,11 @@ diff -r 592f6c3641ba sql/sql_show.cc
Description of ST_FIELD_INFO in table.h
@@ -4509,6 +4875,8 @@
{
- {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
+ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
+ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
- {"COLLATIONS", collation_fields_info, create_schema_table,
+ {"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
@@ -4517,6 +4885,8 @@
@@ -3969,13 +3969,13 @@ diff -r 592f6c3641ba sql/sql_show.cc
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
@@ -4550,6 +4920,8 @@
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
- {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0},
+ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
+ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, -1, -1, 1},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
diff -r 592f6c3641ba sql/sql_update.cc
--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
+++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 20:49 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 20:49 UTC (permalink / raw
To: gentoo-commits
commit: aea21e2809d9523b00a06093730fec41734bac9b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 20:47:15 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 20:47:15 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=aea21e28
Revert "Fix the missing #endif error by dropping the 07300_all_mysql_embedded_compilefix patch for the 5.0.92 release."
This reverts commit 9560b95a0d9e0b4c79296b8409cf7e1667a56883.
---
00000_index.txt | 5 +++++
07300_all_mysql_embedded_compilefix-5.0.92.patch | 11 +++++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index ab861dd..94a582a 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -663,6 +663,11 @@
@pn mysql
@@ Compile fix for bug introduced by upstream in 5.0.91
+@patch 07300_all_mysql_embedded_compilefix-5.0.92.patch
+@ver 5.00.92.00 to 5.00.99.99
+@pn mysql
+@@ Compile fix for bug introduced by upstream in 5.0.91
+
@patch 07310_all_mysql_gcc45-disable-abicheck.patch
@ver 5.01.00.00 to 5.01.49.99
@pn mysql
diff --git a/07300_all_mysql_embedded_compilefix-5.0.92.patch b/07300_all_mysql_embedded_compilefix-5.0.92.patch
new file mode 100644
index 0000000..26a4c87
--- /dev/null
+++ b/07300_all_mysql_embedded_compilefix-5.0.92.patch
@@ -0,0 +1,11 @@
+diff -Nuar mysql-5.0.91.orig//sql/sql_parse.cc mysql-5.0.91//sql/sql_parse.cc
+--- mysql-5.0.91.orig//sql/sql_parse.cc 2010-05-05 14:07:10.000000000 +0000
++++ mysql-5.0.91//sql/sql_parse.cc 2010-05-21 20:29:16.714903163 +0000
+@@ -499,6 +499,7 @@
+ big packets indefinitely, this is a previously established behavior
+ that needs to be preserved as to not break backwards compatibility.
+ */
++#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
+ thd->net.skip_big_packet= TRUE;
+ #endif
+ /* Ready to handle queries */
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 21:05 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 21:05 UTC (permalink / raw
To: gentoo-commits
commit: ab9ab291fee571af524825685ada6fe029e1cd46
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 21:02:20 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 21:02:20 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ab9ab291
Revert "Revert "Fix the missing #endif error by dropping the 07300_all_mysql_embedded_compilefix patch for the 5.0.92 release.""
This reverts commit aea21e2809d9523b00a06093730fec41734bac9b.
---
00000_index.txt | 5 -----
07300_all_mysql_embedded_compilefix-5.0.92.patch | 11 -----------
2 files changed, 0 insertions(+), 16 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 94a582a..ab861dd 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -663,11 +663,6 @@
@pn mysql
@@ Compile fix for bug introduced by upstream in 5.0.91
-@patch 07300_all_mysql_embedded_compilefix-5.0.92.patch
-@ver 5.00.92.00 to 5.00.99.99
-@pn mysql
-@@ Compile fix for bug introduced by upstream in 5.0.91
-
@patch 07310_all_mysql_gcc45-disable-abicheck.patch
@ver 5.01.00.00 to 5.01.49.99
@pn mysql
diff --git a/07300_all_mysql_embedded_compilefix-5.0.92.patch b/07300_all_mysql_embedded_compilefix-5.0.92.patch
deleted file mode 100644
index 26a4c87..0000000
--- a/07300_all_mysql_embedded_compilefix-5.0.92.patch
+++ /dev/null
@@ -1,11 +0,0 @@
-diff -Nuar mysql-5.0.91.orig//sql/sql_parse.cc mysql-5.0.91//sql/sql_parse.cc
---- mysql-5.0.91.orig//sql/sql_parse.cc 2010-05-05 14:07:10.000000000 +0000
-+++ mysql-5.0.91//sql/sql_parse.cc 2010-05-21 20:29:16.714903163 +0000
-@@ -499,6 +499,7 @@
- big packets indefinitely, this is a previously established behavior
- that needs to be preserved as to not break backwards compatibility.
- */
-+#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
- thd->net.skip_big_packet= TRUE;
- #endif
- /* Ready to handle queries */
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-02-17 21:05 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-02-17 21:05 UTC (permalink / raw
To: gentoo-commits
commit: 296028837e403c34b315d282537b42745d1f877e
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 17 21:02:41 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Feb 17 21:02:41 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=29602883
Revert "Updated 10030_all_userstatv2-percona patch for the 5.0.92 release - whitespace."
This reverts commit 49875a9122b33c48043bdb4e4c0bed1ddcbd6353.
---
10030_all_userstatv2-percona-5.0.92.patch | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/10030_all_userstatv2-percona-5.0.92.patch b/10030_all_userstatv2-percona-5.0.92.patch
index 2be677f..a60b7e2 100644
--- a/10030_all_userstatv2-percona-5.0.92.patch
+++ b/10030_all_userstatv2-percona-5.0.92.patch
@@ -3942,11 +3942,11 @@ diff -r 592f6c3641ba sql/sql_show.cc
Description of ST_FIELD_INFO in table.h
@@ -4509,6 +4875,8 @@
{
- {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
+ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
+ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
- {"COLLATIONS", collation_fields_info, create_schema_table,
+ {"COLLATIONS", collation_fields_info, create_schema_table,
fill_schema_collation, make_old_format, 0, -1, -1, 0},
{"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
@@ -4517,6 +4885,8 @@
@@ -3969,13 +3969,13 @@ diff -r 592f6c3641ba sql/sql_show.cc
{"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
@@ -4550,6 +4920,8 @@
get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
- {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
fill_schema_user_privileges, 0, 0, -1, -1, 0},
+ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
+ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
{"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
make_old_format, 0, -1, -1, 1},
- {"VIEWS", view_fields_info, create_schema_table,
+ {"VIEWS", view_fields_info, create_schema_table,
diff -r 592f6c3641ba sql/sql_update.cc
--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
+++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-03-02 19:55 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-03-02 19:55 UTC (permalink / raw
To: gentoo-commits
commit: efff8295e1e36824b88f09da2369db1333effd19
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 2 19:50:43 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Wed Mar 2 19:50:43 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=efff8295
Split the 07340 patches in 2, leaving the removal of the strings.s file on the 07340 patches and moving everything else to the 07341 patches.
Fixes bug 356459.
---
00000_index.txt | 11 +
07340_all_mariadb_hardened_x86_strings.patch | 509 -------------------------
07340_all_mysql_hardened_x86_strings.patch | 509 -------------------------
07341_all_mariadb_hardened_x86_strings.patch | 517 ++++++++++++++++++++++++++
07341_all_mysql_hardened_x86_strings.patch | 517 ++++++++++++++++++++++++++
5 files changed, 1045 insertions(+), 1018 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index ab861dd..8287602 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -691,6 +691,17 @@
@pn mariadb
@@ Gentoo Bug #344031: Fix new TEXTRELs
+@patch 07341_all_mysql_hardened_x86_strings.patch
+@ver 5.01.51.00 to 5.01.99.99
+@pn mysql
+@pn mysql-cluster
+@@ Gentoo Bug #344031: Fix new TEXTRELs
+
+@patch 07341_all_mariadb_hardened_x86_strings.patch
+@ver 5.01.51.00 to 5.01.99.99
+@pn mariadb
+@@ Gentoo Bug #344031: Fix new TEXTRELs
+
@patch 10010_all_show_patches-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
diff --git a/07340_all_mariadb_hardened_x86_strings.patch b/07340_all_mariadb_hardened_x86_strings.patch
index a65234a..b442042 100644
--- a/07340_all_mariadb_hardened_x86_strings.patch
+++ b/07340_all_mariadb_hardened_x86_strings.patch
@@ -6,515 +6,6 @@
* strings/Makefile.in Likewise.
* strings/strings-x86.S Copy of strings-x86.s to support -fPIC
-diff -urN a/configure.in b/configure.in
---- a/configure.in 2010-11-10 00:23:45.287000082 +0100
-+++ b/configure.in 2010-11-10 00:30:47.681000059 +0100
-@@ -698,7 +698,7 @@
-
- AC_MSG_CHECKING(if we should use assembler functions)
- # For now we only support assembler on i386 and sparc systems
--AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
-+AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
- AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
- AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
- AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
-diff -urN a/strings/Makefile.am b/strings/Makefile.am
---- a/strings/Makefile.am 2010-11-10 00:23:45.421000083 +0100
-+++ b/strings/Makefile.am 2010-11-10 00:31:23.489000090 +0100
-@@ -20,7 +20,7 @@
-
- # Exact one of ASSEMBLER_X
- if ASSEMBLER_x86
--ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-+ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
- CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c strmov_overlapp.c
- else
- if ASSEMBLER_sparc32
-@@ -44,7 +44,7 @@
- EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
- ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
- ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
-- xml.c decimal.c strto.c strings-x86.s \
-+ xml.c decimal.c strto.c strings-x86.S \
- longlong2str.c longlong2str-x86.s longlong2str_asm.c \
- my_strtoll10.c my_strtoll10-x86.s \
- strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
-diff -urN a/strings/Makefile.in b/strings/Makefile.in
---- a/strings/Makefile.in 2010-11-10 00:23:45.423000082 +0100
-+++ b/strings/Makefile.in 2010-11-10 00:29:17.547000090 +0100
-@@ -104,7 +104,7 @@
- libmystrings_la_DEPENDENCIES =
- am__libmystrings_la_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
- strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
-- strnmov-sparc.s strstr-sparc.s strings-x86.s \
-+ strnmov-sparc.s strstr-sparc.s strings-x86.S \
- longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
- strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
- strstr.c strinstr.c strmake.c strnmov.c strmov.c \
-@@ -637,7 +637,7 @@
- @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
-
- # Exact one of ASSEMBLER_X
--@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-+@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
- # These file MUST all be on the same line!! Otherwise automake
- # generats a very broken makefile
- @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov_overlapp.c
-@@ -649,7 +649,7 @@
- EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
- ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
- ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
-- xml.c decimal.c strto.c strings-x86.s \
-+ xml.c decimal.c strto.c strings-x86.S \
- longlong2str.c longlong2str-x86.s longlong2str_asm.c \
- my_strtoll10.c my_strtoll10-x86.s \
- strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
-diff -urN a/strings/strings-x86.S b/strings/strings-x86.S
---- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100
-+++ b/strings/strings-x86.S 2010-11-10 00:29:17.547000090 +0100
-@@ -0,0 +1,442 @@
-+# Copyright (C) 2000 MySQL AB
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; version 2 of the License.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+# Optimized string functions Intel 80x86 (gcc/gas syntax)
-+
-+ .file "strings.S"
-+ .version "1.01"
-+
-+.text
-+
-+# Move a alligned, not overlapped, by (long) divided memory area
-+# Args: to,from,length
-+
-+.globl bmove_align
-+ .type bmove_align,@function
-+bmove_align:
-+ movl %edi,%edx
-+ push %esi
-+ movl 4(%esp),%edi # to
-+ movl 8(%esp),%esi # from
-+ movl 12(%esp),%ecx # length
-+ addw $3,%cx # fix if not divisible with long
-+ shrw $2,%cx
-+ jz .ba_20
-+ .p2align 4,,7
-+.ba_10:
-+ movl -4(%esi,%ecx),%eax
-+ movl %eax,-4(%edi,%ecx)
-+ decl %ecx
-+ jnz .ba_10
-+.ba_20: pop %esi
-+ movl %edx,%edi
-+ ret
-+
-+.bmove_align_end:
-+ .size bmove_align,.bmove_align_end-bmove_align
-+
-+ # Move a string from higher to lower
-+ # Arg from_end+1,to_end+1,length
-+
-+.globl bmove_upp
-+ .type bmove_upp,@function
-+bmove_upp:
-+ movl %edi,%edx # Remember %edi
-+ push %esi
-+ movl 8(%esp),%edi # dst
-+ movl 16(%esp),%ecx # length
-+ movl 12(%esp),%esi # source
-+ test %ecx,%ecx
-+ jz .bu_20
-+ subl %ecx,%esi # To start of strings
-+ subl %ecx,%edi
-+
-+ .p2align 4,,7
-+.bu_10: movb -1(%esi,%ecx),%al
-+ movb %al,-1(%edi,%ecx)
-+ decl %ecx
-+ jnz .bu_10
-+.bu_20: pop %esi
-+ movl %edx,%edi
-+ ret
-+
-+.bmove_upp_end:
-+ .size bmove_upp,.bmove_upp_end-bmove_upp
-+
-+ # Append fillchars to string
-+ # Args: dest,len,fill
-+
-+.globl strappend
-+ .type strappend,@function
-+strappend:
-+ pushl %edi
-+ movl 8(%esp),%edi # Memory pointer
-+ movl 12(%esp),%ecx # Length
-+ clrl %eax # Find end of string
-+ repne
-+ scasb
-+ jnz sa_99 # String to long, shorten it
-+ movzb 16(%esp),%eax # Fillchar
-+ decl %edi # Point at end null
-+ incl %ecx # rep made one dec for null-char
-+
-+ movb %al,%ah # (2) Set up a 32 bit pattern.
-+ movw %ax,%dx # (2)
-+ shll $16,%eax # (3)
-+ movw %dx,%ax # (2) %eax has the 32 bit pattern.
-+
-+ movl %ecx,%edx # (2) Save the count of bytes.
-+ shrl $2,%ecx # (2) Number of dwords.
-+ rep
-+ stosl # (5 + 5n)
-+ movb $3,%cl # (2)
-+ and %edx,%ecx # (2) Fill in the odd bytes
-+ rep
-+ stosb # Move last bytes if any
-+
-+sa_99: movb $0,(%edi) # End of string
-+ popl %edi
-+ ret
-+.strappend_end:
-+ .size strappend,.strappend_end-strappend
-+
-+ # Find if string contains any char in another string
-+ # Arg: str,set
-+ # Ret: Pointer to first found char in str
-+
-+.globl strcont
-+ .type strcont,@function
-+strcont:
-+ movl %edi,%edx
-+ pushl %esi
-+ movl 8(%esp),%esi # str
-+ movl 12(%esp),%ecx # set
-+ clrb %ah # For endtest
-+ jmp sc_60
-+
-+sc_10: scasb
-+ jz sc_fo # Found char
-+sc_20: cmp (%edi),%ah # Test if null
-+ jnz sc_10 # Not end of set yet
-+ incl %esi # Next char in str
-+sc_60: movl %ecx,%edi # %edi = Set
-+ movb (%esi),%al # Test if this char exist
-+ andb %al,%al
-+ jnz sc_20 # Not end of string
-+ clrl %esi # Return Null
-+sc_fo: movl %esi,%eax # Char found here
-+ movl %edx,%edi # Restore
-+ popl %esi
-+ ret
-+.strcont_end:
-+ .size strcont,.strcont_end-strcont
-+
-+ # Find end of string
-+ # Arg: str
-+ # ret: Pointer to end null
-+
-+.globl strend
-+ .type strend,@function
-+strend:
-+ movl %edi,%edx # Save
-+ movl 4(%esp),%edi # str
-+ clrl %eax # Find end of string
-+ movl %eax,%ecx
-+ decl %ecx # ECX = -1
-+ repne
-+ scasb
-+ movl %edi,%eax
-+ decl %eax # End of string
-+ movl %edx,%edi # Restore
-+ ret
-+.strend_end:
-+ .size strend,.strend_end-strend
-+
-+ # Make a string with len fill-chars and endnull
-+ # Args: dest,len,fill
-+ # Ret: dest+len
-+
-+.globl strfill
-+ .type strfill,@function
-+strfill:
-+ pushl %edi
-+ movl 8(%esp),%edi # Memory pointer
-+ movl 12(%esp),%ecx # Length
-+ movzb 16(%esp),%eax # Fill
-+
-+ movb %al,%ah # (2) Set up a 32 bit pattern
-+ movw %ax,%dx # (2)
-+ shll $16,%eax # (3)
-+ movw %dx,%ax # (2) %eax has the 32 bit pattern.
-+
-+ movl %ecx,%edx # (2) Save the count of bytes.
-+ shrl $2,%ecx # (2) Number of dwords.
-+ rep
-+ stosl # (5 + 5n)
-+ movb $3,%cl # (2)
-+ and %edx,%ecx # (2) Fill in the odd bytes
-+ rep
-+ stosb # Move last bytes if any
-+
-+ movb %cl,(%edi) # End NULL
-+ movl %edi,%eax # End i %eax
-+ popl %edi
-+ ret
-+.strfill_end:
-+ .size strfill,.strfill_end-strfill
-+
-+
-+ # Find a char in or end of a string
-+ # Arg: str,char
-+ # Ret: pointer to found char or NullS
-+
-+.globl strcend
-+ .type strcend,@function
-+strcend:
-+ movl %edi,%edx
-+ movl 4(%esp),%edi # str
-+ movb 8(%esp),%ah # search
-+ clrb %al # for scasb to find end
-+
-+se_10: cmpb (%edi),%ah
-+ jz se_20 # Found char
-+ scasb
-+ jnz se_10 # Not end
-+ dec %edi # Not found, point at end of string
-+se_20: movl %edi,%eax
-+ movl %edx,%edi # Restore
-+ ret
-+.strcend_end:
-+ .size strcend,.strcend_end-strcend
-+
-+ # Test if string has a given suffix
-+
-+.globl is_prefix
-+ .type is_prefix,@function
-+is_prefix:
-+ movl %edi,%edx # Save %edi
-+ pushl %esi # and %esi
-+ movl 12(%esp),%esi # get suffix
-+ movl 8(%esp),%edi # s1
-+ movl $1,%eax # Ok and zero-test
-+ip_10: cmpb (%esi),%ah
-+ jz suf_ok # End of string/ found suffix
-+ cmpsb # Compare strings
-+ jz ip_10 # Same, possible prefix
-+ xor %eax,%eax # Not suffix
-+suf_ok: popl %esi
-+ movl %edx,%edi
-+ ret
-+.is_prefix_end:
-+ .size is_prefix,.is_prefix_end-is_prefix
-+
-+ # Find a substring in string
-+ # Arg: str,search
-+
-+.globl strstr
-+ .type strstr,@function
-+
-+strstr:
-+ pushl %edi
-+ pushl %esi
-+ movl 12(%esp),%esi # str
-+ movl 16(%esp),%edi # search
-+ movl %edi,%ecx
-+ incl %ecx # %ecx = search+1
-+ movb (%edi),%ah # %ah = First char in search
-+ jmp sf_10
-+
-+sf_00: movl %edx,%esi # si = Current str-pos
-+sf_10: movb (%esi),%al # Test if this char exist
-+ andb %al,%al
-+ jz sf_90 # End of string, didn't find search
-+ incl %esi
-+ cmpb %al,%ah
-+ jnz sf_10 # Didn't find first char, continue
-+ movl %esi,%edx # Save str-pos in %edx
-+ movl %ecx,%edi
-+sf_20: cmpb $0,(%edi)
-+ jz sf_fo # Found substring
-+ cmpsb
-+ jz sf_20 # Char ok
-+ jmp sf_00 # Next str-pos
-+
-+sf_90: movl $1,%edx # Return Null
-+sf_fo: movl %edx,%eax # Char found here
-+ decl %eax # Pointed one after
-+ popl %esi
-+ popl %edi
-+ ret
-+.strstr_end:
-+ .size strstr,.strstr_end-strstr
-+
-+
-+ # Find a substring in string, return index
-+ # Arg: str,search
-+
-+.globl strinstr
-+ .type strinstr,@function
-+
-+strinstr:
-+ pushl %ebp
-+ movl %esp,%ebp
-+#ifdef __PIC__
-+# undef __i686 /* gcc define gets in our way */
-+ pushl %ebx
-+ call __i686.get_pc_thunk.bx
-+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
-+#endif
-+ pushl 12(%ebp) # search
-+ pushl 8(%ebp) # str
-+#ifdef __PIC__
-+ call strstr@PLT /*We need to be sure that ebx point to the got*/
-+#else
-+ call strstr
-+#endif
-+ add $8,%esp
-+ or %eax,%eax
-+ jz si_99 # Not found, return NULL
-+ sub 8(%ebp),%eax # Pos from start
-+ inc %eax # And first pos = 1
-+si_99:
-+#ifdef __PIC__
-+ popl %ebx
-+#endif
-+ popl %ebp
-+ ret
-+.strinstr_end:
-+ .size strinstr,.strinstr_end-strinstr
-+
-+ # Make a string of len length from another string
-+ # Arg: dst,src,length
-+ # ret: end of dst
-+
-+.globl strmake
-+ .type strmake,@function
-+
-+strmake:
-+ pushl %edi
-+ pushl %esi
-+ mov 12(%esp),%edi # dst
-+ movl $0,%edx
-+ movl 20(%esp),%ecx # length
-+ movl 16(%esp),%esi # src
-+ cmpl %edx,%ecx
-+ jz sm_90
-+sm_00: movb (%esi,%edx),%al
-+ cmpb $0,%al
-+ jz sm_90
-+ movb %al,(%edi,%edx)
-+ incl %edx
-+ cmpl %edx,%ecx
-+ jnz sm_00
-+sm_90: movb $0,(%edi,%edx)
-+sm_99: lea (%edi,%edx),%eax # Return pointer to end null
-+ pop %esi
-+ pop %edi
-+ ret
-+.strmake_end:
-+ .size strmake,.strmake_end-strmake
-+
-+ # Move a string with max len chars
-+ # arg: dst,src,len
-+ # ret: pos to first null or dst+len
-+
-+.globl strnmov
-+ .type strnmov,@function
-+strnmov:
-+ pushl %edi
-+ pushl %esi
-+ movl 12(%esp),%edi # dst
-+ movl 16(%esp),%esi # src
-+ movl 20(%esp),%ecx # Length of memory-area
-+ jecxz snm_99 # Nothing to do
-+ clrb %al # For test of end-null
-+
-+snm_10: cmpb (%esi),%al # Next char to move
-+ movsb # move arg
-+ jz snm_20 # last char, fill with null
-+ loop snm_10 # Continue moving
-+ incl %edi # Point two after last
-+snm_20: decl %edi # Point at first null (or last+1)
-+snm_99: movl %edi,%eax # Pointer at last char
-+ popl %esi
-+ popl %edi
-+ ret
-+.strnmov_end:
-+ .size strnmov,.strnmov_end-strnmov
-+
-+
-+.globl strmov
-+ .type strmov,@function
-+strmov:
-+ movl %esi,%ecx # Save old %esi and %edi
-+ movl %edi,%edx
-+ movl 8(%esp),%esi # get source pointer (s2)
-+ movl 4(%esp),%edi # %edi -> s1
-+smo_10: movb (%esi),%al
-+ movsb # move arg
-+ andb %al,%al
-+ jnz smo_10 # Not last
-+ movl %edi,%eax
-+ dec %eax
-+ movl %ecx,%esi # Restore
-+ movl %edx,%edi
-+ ret
-+.strmov_end:
-+ .size strmov,.strmov_end-strmov
-+
-+.globl strxmov
-+ .type strxmov,@function
-+strxmov:
-+ movl %ebx,%edx # Save %ebx, %esi and %edi
-+ mov %esi,%ecx
-+ push %edi
-+ leal 8(%esp),%ebx # Get destination
-+ movl (%ebx),%edi
-+ xorb %al,%al
-+ jmp next_str # Handle source ebx+4
-+
-+start_str:
-+ movsb
-+ cmpb -1(%edi),%al
-+ jne start_str
-+ decl %edi # Don't copy last null
-+
-+next_str:
-+ addl $4,%ebx
-+ movl (%ebx),%esi
-+ orl %esi,%esi
-+ jne start_str
-+ movb %al,0(%edi) # Force last to ASCII 0
-+
-+ movl %edi,%eax # Return ptr to ASCII 0
-+ pop %edi # Restore registers
-+ movl %ecx,%esi
-+ movl %edx,%ebx
-+ ret
-+.strxmov_end:
-+ .size strxmov,.strxmov_end-strxmov
-+
-+#ifdef __PIC__
-+ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
-+ .globl __i686.get_pc_thunk.bx
-+ .hidden __i686.get_pc_thunk.bx
-+ .type __i686.get_pc_thunk.bx,@function
-+__i686.get_pc_thunk.bx:
-+ movl (%esp), %ebx
-+ ret
-+#endif
-+ .section .note.GNU-stack,"",@progbits
-+
diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
+++ b/strings/strings-x86.s 1970-01-01 01:00:00.000000000 +0100
diff --git a/07340_all_mysql_hardened_x86_strings.patch b/07340_all_mysql_hardened_x86_strings.patch
index 9e43d6a..b442042 100644
--- a/07340_all_mysql_hardened_x86_strings.patch
+++ b/07340_all_mysql_hardened_x86_strings.patch
@@ -6,515 +6,6 @@
* strings/Makefile.in Likewise.
* strings/strings-x86.S Copy of strings-x86.s to support -fPIC
-diff -urN a/configure.in b/configure.in
---- a/configure.in 2010-11-09 21:29:31.806000076 +0100
-+++ b/configure.in 2010-11-09 21:31:55.596000072 +0100
-@@ -673,7 +673,7 @@
-
- AC_MSG_CHECKING(if we should use assembler functions)
- # For now we only support assembler on i386 and sparc systems
--AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
-+AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
- AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
- AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
- AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
-diff -urN a/strings/Makefile.am b/strings/Makefile.am
---- a/strings/Makefile.am 2010-11-09 21:29:32.195000076 +0100
-+++ b/strings/Makefile.am 2010-11-09 21:33:18.545000075 +0100
-@@ -20,7 +20,7 @@
-
- # Exact one of ASSEMBLER_X
- if ASSEMBLER_x86
--ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-+ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
- CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c
- else
- if ASSEMBLER_sparc32
-@@ -44,7 +44,7 @@
- EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
- ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
- ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
-- xml.c decimal.c strto.c strings-x86.s \
-+ xml.c decimal.c strto.c strings-x86.S \
- longlong2str.c longlong2str-x86.s longlong2str_asm.c \
- my_strtoll10.c my_strtoll10-x86.s \
- strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
-diff -urN a/strings/Makefile.in b/strings/Makefile.in
---- a/strings/Makefile.in 2010-11-09 21:29:32.197000076 +0100
-+++ b/strings/Makefile.in 2010-11-09 21:33:45.348000075 +0100
-@@ -103,7 +103,7 @@
- libmystrings_la_DEPENDENCIES =
- am__libmystrings_la_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
- strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
-- strnmov-sparc.s strstr-sparc.s strings-x86.s \
-+ strnmov-sparc.s strstr-sparc.s strings-x86.S \
- longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
- strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
- strstr.c strinstr.c strmake.c strnmov.c strmov.c \
-@@ -621,7 +621,7 @@
- @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
-
- # Exact one of ASSEMBLER_X
--@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
-+@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
- # These file MUST all be on the same line!! Otherwise automake
- # generats a very broken makefile
- @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c
-@@ -633,7 +633,7 @@
- EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
- ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
- ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
-- xml.c decimal.c strto.c strings-x86.s \
-+ xml.c decimal.c strto.c strings-x86.S \
- longlong2str.c longlong2str-x86.s longlong2str_asm.c \
- my_strtoll10.c my_strtoll10-x86.s \
- strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
-diff -urN a/strings/strings-x86.S b/strings/strings-x86.S
---- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100
-+++ b/strings/strings-x86.S 2010-11-09 22:05:05.084000076 +0100
-@@ -0,0 +1,442 @@
-+# Copyright (C) 2000 MySQL AB
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; version 2 of the License.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+# GNU General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+
-+# Optimized string functions Intel 80x86 (gcc/gas syntax)
-+
-+ .file "strings.S"
-+ .version "1.01"
-+
-+.text
-+
-+# Move a alligned, not overlapped, by (long) divided memory area
-+# Args: to,from,length
-+
-+.globl bmove_align
-+ .type bmove_align,@function
-+bmove_align:
-+ movl %edi,%edx
-+ push %esi
-+ movl 4(%esp),%edi # to
-+ movl 8(%esp),%esi # from
-+ movl 12(%esp),%ecx # length
-+ addw $3,%cx # fix if not divisible with long
-+ shrw $2,%cx
-+ jz .ba_20
-+ .p2align 4,,7
-+.ba_10:
-+ movl -4(%esi,%ecx),%eax
-+ movl %eax,-4(%edi,%ecx)
-+ decl %ecx
-+ jnz .ba_10
-+.ba_20: pop %esi
-+ movl %edx,%edi
-+ ret
-+
-+.bmove_align_end:
-+ .size bmove_align,.bmove_align_end-bmove_align
-+
-+ # Move a string from higher to lower
-+ # Arg from_end+1,to_end+1,length
-+
-+.globl bmove_upp
-+ .type bmove_upp,@function
-+bmove_upp:
-+ movl %edi,%edx # Remember %edi
-+ push %esi
-+ movl 8(%esp),%edi # dst
-+ movl 16(%esp),%ecx # length
-+ movl 12(%esp),%esi # source
-+ test %ecx,%ecx
-+ jz .bu_20
-+ subl %ecx,%esi # To start of strings
-+ subl %ecx,%edi
-+
-+ .p2align 4,,7
-+.bu_10: movb -1(%esi,%ecx),%al
-+ movb %al,-1(%edi,%ecx)
-+ decl %ecx
-+ jnz .bu_10
-+.bu_20: pop %esi
-+ movl %edx,%edi
-+ ret
-+
-+.bmove_upp_end:
-+ .size bmove_upp,.bmove_upp_end-bmove_upp
-+
-+ # Append fillchars to string
-+ # Args: dest,len,fill
-+
-+.globl strappend
-+ .type strappend,@function
-+strappend:
-+ pushl %edi
-+ movl 8(%esp),%edi # Memory pointer
-+ movl 12(%esp),%ecx # Length
-+ clrl %eax # Find end of string
-+ repne
-+ scasb
-+ jnz sa_99 # String to long, shorten it
-+ movzb 16(%esp),%eax # Fillchar
-+ decl %edi # Point at end null
-+ incl %ecx # rep made one dec for null-char
-+
-+ movb %al,%ah # (2) Set up a 32 bit pattern.
-+ movw %ax,%dx # (2)
-+ shll $16,%eax # (3)
-+ movw %dx,%ax # (2) %eax has the 32 bit pattern.
-+
-+ movl %ecx,%edx # (2) Save the count of bytes.
-+ shrl $2,%ecx # (2) Number of dwords.
-+ rep
-+ stosl # (5 + 5n)
-+ movb $3,%cl # (2)
-+ and %edx,%ecx # (2) Fill in the odd bytes
-+ rep
-+ stosb # Move last bytes if any
-+
-+sa_99: movb $0,(%edi) # End of string
-+ popl %edi
-+ ret
-+.strappend_end:
-+ .size strappend,.strappend_end-strappend
-+
-+ # Find if string contains any char in another string
-+ # Arg: str,set
-+ # Ret: Pointer to first found char in str
-+
-+.globl strcont
-+ .type strcont,@function
-+strcont:
-+ movl %edi,%edx
-+ pushl %esi
-+ movl 8(%esp),%esi # str
-+ movl 12(%esp),%ecx # set
-+ clrb %ah # For endtest
-+ jmp sc_60
-+
-+sc_10: scasb
-+ jz sc_fo # Found char
-+sc_20: cmp (%edi),%ah # Test if null
-+ jnz sc_10 # Not end of set yet
-+ incl %esi # Next char in str
-+sc_60: movl %ecx,%edi # %edi = Set
-+ movb (%esi),%al # Test if this char exist
-+ andb %al,%al
-+ jnz sc_20 # Not end of string
-+ clrl %esi # Return Null
-+sc_fo: movl %esi,%eax # Char found here
-+ movl %edx,%edi # Restore
-+ popl %esi
-+ ret
-+.strcont_end:
-+ .size strcont,.strcont_end-strcont
-+
-+ # Find end of string
-+ # Arg: str
-+ # ret: Pointer to end null
-+
-+.globl strend
-+ .type strend,@function
-+strend:
-+ movl %edi,%edx # Save
-+ movl 4(%esp),%edi # str
-+ clrl %eax # Find end of string
-+ movl %eax,%ecx
-+ decl %ecx # ECX = -1
-+ repne
-+ scasb
-+ movl %edi,%eax
-+ decl %eax # End of string
-+ movl %edx,%edi # Restore
-+ ret
-+.strend_end:
-+ .size strend,.strend_end-strend
-+
-+ # Make a string with len fill-chars and endnull
-+ # Args: dest,len,fill
-+ # Ret: dest+len
-+
-+.globl strfill
-+ .type strfill,@function
-+strfill:
-+ pushl %edi
-+ movl 8(%esp),%edi # Memory pointer
-+ movl 12(%esp),%ecx # Length
-+ movzb 16(%esp),%eax # Fill
-+
-+ movb %al,%ah # (2) Set up a 32 bit pattern
-+ movw %ax,%dx # (2)
-+ shll $16,%eax # (3)
-+ movw %dx,%ax # (2) %eax has the 32 bit pattern.
-+
-+ movl %ecx,%edx # (2) Save the count of bytes.
-+ shrl $2,%ecx # (2) Number of dwords.
-+ rep
-+ stosl # (5 + 5n)
-+ movb $3,%cl # (2)
-+ and %edx,%ecx # (2) Fill in the odd bytes
-+ rep
-+ stosb # Move last bytes if any
-+
-+ movb %cl,(%edi) # End NULL
-+ movl %edi,%eax # End i %eax
-+ popl %edi
-+ ret
-+.strfill_end:
-+ .size strfill,.strfill_end-strfill
-+
-+
-+ # Find a char in or end of a string
-+ # Arg: str,char
-+ # Ret: pointer to found char or NullS
-+
-+.globl strcend
-+ .type strcend,@function
-+strcend:
-+ movl %edi,%edx
-+ movl 4(%esp),%edi # str
-+ movb 8(%esp),%ah # search
-+ clrb %al # for scasb to find end
-+
-+se_10: cmpb (%edi),%ah
-+ jz se_20 # Found char
-+ scasb
-+ jnz se_10 # Not end
-+ dec %edi # Not found, point at end of string
-+se_20: movl %edi,%eax
-+ movl %edx,%edi # Restore
-+ ret
-+.strcend_end:
-+ .size strcend,.strcend_end-strcend
-+
-+ # Test if string has a given suffix
-+
-+.globl is_prefix
-+ .type is_prefix,@function
-+is_prefix:
-+ movl %edi,%edx # Save %edi
-+ pushl %esi # and %esi
-+ movl 12(%esp),%esi # get suffix
-+ movl 8(%esp),%edi # s1
-+ movl $1,%eax # Ok and zero-test
-+ip_10: cmpb (%esi),%ah
-+ jz suf_ok # End of string/ found suffix
-+ cmpsb # Compare strings
-+ jz ip_10 # Same, possible prefix
-+ xor %eax,%eax # Not suffix
-+suf_ok: popl %esi
-+ movl %edx,%edi
-+ ret
-+.is_prefix_end:
-+ .size is_prefix,.is_prefix_end-is_prefix
-+
-+ # Find a substring in string
-+ # Arg: str,search
-+
-+.globl strstr
-+ .type strstr,@function
-+
-+strstr:
-+ pushl %edi
-+ pushl %esi
-+ movl 12(%esp),%esi # str
-+ movl 16(%esp),%edi # search
-+ movl %edi,%ecx
-+ incl %ecx # %ecx = search+1
-+ movb (%edi),%ah # %ah = First char in search
-+ jmp sf_10
-+
-+sf_00: movl %edx,%esi # si = Current str-pos
-+sf_10: movb (%esi),%al # Test if this char exist
-+ andb %al,%al
-+ jz sf_90 # End of string, didn't find search
-+ incl %esi
-+ cmpb %al,%ah
-+ jnz sf_10 # Didn't find first char, continue
-+ movl %esi,%edx # Save str-pos in %edx
-+ movl %ecx,%edi
-+sf_20: cmpb $0,(%edi)
-+ jz sf_fo # Found substring
-+ cmpsb
-+ jz sf_20 # Char ok
-+ jmp sf_00 # Next str-pos
-+
-+sf_90: movl $1,%edx # Return Null
-+sf_fo: movl %edx,%eax # Char found here
-+ decl %eax # Pointed one after
-+ popl %esi
-+ popl %edi
-+ ret
-+.strstr_end:
-+ .size strstr,.strstr_end-strstr
-+
-+
-+ # Find a substring in string, return index
-+ # Arg: str,search
-+
-+.globl strinstr
-+ .type strinstr,@function
-+
-+strinstr:
-+ pushl %ebp
-+ movl %esp,%ebp
-+#ifdef __PIC__
-+# undef __i686 /* gcc define gets in our way */
-+ pushl %ebx
-+ call __i686.get_pc_thunk.bx
-+ addl $_GLOBAL_OFFSET_TABLE_, %ebx
-+#endif
-+ pushl 12(%ebp) # search
-+ pushl 8(%ebp) # str
-+#ifdef __PIC__
-+ call strstr@PLT /*We need to be sure that ebx point to the got*/
-+#else
-+ call strstr
-+#endif
-+ add $8,%esp
-+ or %eax,%eax
-+ jz si_99 # Not found, return NULL
-+ sub 8(%ebp),%eax # Pos from start
-+ inc %eax # And first pos = 1
-+si_99:
-+#ifdef __PIC__
-+ popl %ebx
-+#endif
-+ popl %ebp
-+ ret
-+.strinstr_end:
-+ .size strinstr,.strinstr_end-strinstr
-+
-+ # Make a string of len length from another string
-+ # Arg: dst,src,length
-+ # ret: end of dst
-+
-+.globl strmake
-+ .type strmake,@function
-+
-+strmake:
-+ pushl %edi
-+ pushl %esi
-+ mov 12(%esp),%edi # dst
-+ movl $0,%edx
-+ movl 20(%esp),%ecx # length
-+ movl 16(%esp),%esi # src
-+ cmpl %edx,%ecx
-+ jz sm_90
-+sm_00: movb (%esi,%edx),%al
-+ cmpb $0,%al
-+ jz sm_90
-+ movb %al,(%edi,%edx)
-+ incl %edx
-+ cmpl %edx,%ecx
-+ jnz sm_00
-+sm_90: movb $0,(%edi,%edx)
-+sm_99: lea (%edi,%edx),%eax # Return pointer to end null
-+ pop %esi
-+ pop %edi
-+ ret
-+.strmake_end:
-+ .size strmake,.strmake_end-strmake
-+
-+ # Move a string with max len chars
-+ # arg: dst,src,len
-+ # ret: pos to first null or dst+len
-+
-+.globl strnmov
-+ .type strnmov,@function
-+strnmov:
-+ pushl %edi
-+ pushl %esi
-+ movl 12(%esp),%edi # dst
-+ movl 16(%esp),%esi # src
-+ movl 20(%esp),%ecx # Length of memory-area
-+ jecxz snm_99 # Nothing to do
-+ clrb %al # For test of end-null
-+
-+snm_10: cmpb (%esi),%al # Next char to move
-+ movsb # move arg
-+ jz snm_20 # last char, fill with null
-+ loop snm_10 # Continue moving
-+ incl %edi # Point two after last
-+snm_20: decl %edi # Point at first null (or last+1)
-+snm_99: movl %edi,%eax # Pointer at last char
-+ popl %esi
-+ popl %edi
-+ ret
-+.strnmov_end:
-+ .size strnmov,.strnmov_end-strnmov
-+
-+
-+.globl strmov
-+ .type strmov,@function
-+strmov:
-+ movl %esi,%ecx # Save old %esi and %edi
-+ movl %edi,%edx
-+ movl 8(%esp),%esi # get source pointer (s2)
-+ movl 4(%esp),%edi # %edi -> s1
-+smo_10: movb (%esi),%al
-+ movsb # move arg
-+ andb %al,%al
-+ jnz smo_10 # Not last
-+ movl %edi,%eax
-+ dec %eax
-+ movl %ecx,%esi # Restore
-+ movl %edx,%edi
-+ ret
-+.strmov_end:
-+ .size strmov,.strmov_end-strmov
-+
-+.globl strxmov
-+ .type strxmov,@function
-+strxmov:
-+ movl %ebx,%edx # Save %ebx, %esi and %edi
-+ mov %esi,%ecx
-+ push %edi
-+ leal 8(%esp),%ebx # Get destination
-+ movl (%ebx),%edi
-+ xorb %al,%al
-+ jmp next_str # Handle source ebx+4
-+
-+start_str:
-+ movsb
-+ cmpb -1(%edi),%al
-+ jne start_str
-+ decl %edi # Don't copy last null
-+
-+next_str:
-+ addl $4,%ebx
-+ movl (%ebx),%esi
-+ orl %esi,%esi
-+ jne start_str
-+ movb %al,0(%edi) # Force last to ASCII 0
-+
-+ movl %edi,%eax # Return ptr to ASCII 0
-+ pop %edi # Restore registers
-+ movl %ecx,%esi
-+ movl %edx,%ebx
-+ ret
-+.strxmov_end:
-+ .size strxmov,.strxmov_end-strxmov
-+
-+#ifdef __PIC__
-+ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
-+ .globl __i686.get_pc_thunk.bx
-+ .hidden __i686.get_pc_thunk.bx
-+ .type __i686.get_pc_thunk.bx,@function
-+__i686.get_pc_thunk.bx:
-+ movl (%esp), %ebx
-+ ret
-+#endif
-+ .section .note.GNU-stack,"",@progbits
-+
diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
+++ b/strings/strings-x86.s 1970-01-01 01:00:00.000000000 +0100
diff --git a/07341_all_mariadb_hardened_x86_strings.patch b/07341_all_mariadb_hardened_x86_strings.patch
new file mode 100644
index 0000000..7e86f7f
--- /dev/null
+++ b/07341_all_mariadb_hardened_x86_strings.patch
@@ -0,0 +1,517 @@
+2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
+
+ #344031
+ * configure.in: Rename strings-x86.s to strings-x86.S
+ * strings/Makefile.am Likewise.
+ * strings/Makefile.in Likewise.
+ * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+
+diff -urN a/configure.in b/configure.in
+--- a/configure.in 2010-11-10 00:23:45.287000082 +0100
++++ b/configure.in 2010-11-10 00:30:47.681000059 +0100
+@@ -698,7 +698,7 @@
+
+ AC_MSG_CHECKING(if we should use assembler functions)
+ # For now we only support assembler on i386 and sparc systems
+-AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
++AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
+ AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
+ AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
+ AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
+diff -urN a/strings/Makefile.am b/strings/Makefile.am
+--- a/strings/Makefile.am 2010-11-10 00:23:45.421000083 +0100
++++ b/strings/Makefile.am 2010-11-10 00:31:23.489000090 +0100
+@@ -20,7 +20,7 @@
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+-ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c strmov_overlapp.c
+ else
+ if ASSEMBLER_sparc32
+@@ -44,7 +44,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/Makefile.in b/strings/Makefile.in
+--- a/strings/Makefile.in 2010-11-10 00:23:45.423000082 +0100
++++ b/strings/Makefile.in 2010-11-10 00:29:17.547000090 +0100
+@@ -104,7 +104,7 @@
+ libmystrings_la_DEPENDENCIES =
+ am__libmystrings_la_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
+ strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
+- strnmov-sparc.s strstr-sparc.s strings-x86.s \
++ strnmov-sparc.s strstr-sparc.s strings-x86.S \
+ longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
+ strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
+ strstr.c strinstr.c strmake.c strnmov.c strmov.c \
+@@ -637,7 +637,7 @@
+ @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
+
+ # Exact one of ASSEMBLER_X
+-@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ # These file MUST all be on the same line!! Otherwise automake
+ # generats a very broken makefile
+ @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov_overlapp.c
+@@ -649,7 +649,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/strings-x86.S b/strings/strings-x86.S
+--- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100
++++ b/strings/strings-x86.S 2010-11-10 00:29:17.547000090 +0100
+@@ -0,0 +1,442 @@
++# Copyright (C) 2000 MySQL AB
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; version 2 of the License.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++# Optimized string functions Intel 80x86 (gcc/gas syntax)
++
++ .file "strings.S"
++ .version "1.01"
++
++.text
++
++# Move a alligned, not overlapped, by (long) divided memory area
++# Args: to,from,length
++
++.globl bmove_align
++ .type bmove_align,@function
++bmove_align:
++ movl %edi,%edx
++ push %esi
++ movl 4(%esp),%edi # to
++ movl 8(%esp),%esi # from
++ movl 12(%esp),%ecx # length
++ addw $3,%cx # fix if not divisible with long
++ shrw $2,%cx
++ jz .ba_20
++ .p2align 4,,7
++.ba_10:
++ movl -4(%esi,%ecx),%eax
++ movl %eax,-4(%edi,%ecx)
++ decl %ecx
++ jnz .ba_10
++.ba_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_align_end:
++ .size bmove_align,.bmove_align_end-bmove_align
++
++ # Move a string from higher to lower
++ # Arg from_end+1,to_end+1,length
++
++.globl bmove_upp
++ .type bmove_upp,@function
++bmove_upp:
++ movl %edi,%edx # Remember %edi
++ push %esi
++ movl 8(%esp),%edi # dst
++ movl 16(%esp),%ecx # length
++ movl 12(%esp),%esi # source
++ test %ecx,%ecx
++ jz .bu_20
++ subl %ecx,%esi # To start of strings
++ subl %ecx,%edi
++
++ .p2align 4,,7
++.bu_10: movb -1(%esi,%ecx),%al
++ movb %al,-1(%edi,%ecx)
++ decl %ecx
++ jnz .bu_10
++.bu_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_upp_end:
++ .size bmove_upp,.bmove_upp_end-bmove_upp
++
++ # Append fillchars to string
++ # Args: dest,len,fill
++
++.globl strappend
++ .type strappend,@function
++strappend:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ clrl %eax # Find end of string
++ repne
++ scasb
++ jnz sa_99 # String to long, shorten it
++ movzb 16(%esp),%eax # Fillchar
++ decl %edi # Point at end null
++ incl %ecx # rep made one dec for null-char
++
++ movb %al,%ah # (2) Set up a 32 bit pattern.
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++sa_99: movb $0,(%edi) # End of string
++ popl %edi
++ ret
++.strappend_end:
++ .size strappend,.strappend_end-strappend
++
++ # Find if string contains any char in another string
++ # Arg: str,set
++ # Ret: Pointer to first found char in str
++
++.globl strcont
++ .type strcont,@function
++strcont:
++ movl %edi,%edx
++ pushl %esi
++ movl 8(%esp),%esi # str
++ movl 12(%esp),%ecx # set
++ clrb %ah # For endtest
++ jmp sc_60
++
++sc_10: scasb
++ jz sc_fo # Found char
++sc_20: cmp (%edi),%ah # Test if null
++ jnz sc_10 # Not end of set yet
++ incl %esi # Next char in str
++sc_60: movl %ecx,%edi # %edi = Set
++ movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jnz sc_20 # Not end of string
++ clrl %esi # Return Null
++sc_fo: movl %esi,%eax # Char found here
++ movl %edx,%edi # Restore
++ popl %esi
++ ret
++.strcont_end:
++ .size strcont,.strcont_end-strcont
++
++ # Find end of string
++ # Arg: str
++ # ret: Pointer to end null
++
++.globl strend
++ .type strend,@function
++strend:
++ movl %edi,%edx # Save
++ movl 4(%esp),%edi # str
++ clrl %eax # Find end of string
++ movl %eax,%ecx
++ decl %ecx # ECX = -1
++ repne
++ scasb
++ movl %edi,%eax
++ decl %eax # End of string
++ movl %edx,%edi # Restore
++ ret
++.strend_end:
++ .size strend,.strend_end-strend
++
++ # Make a string with len fill-chars and endnull
++ # Args: dest,len,fill
++ # Ret: dest+len
++
++.globl strfill
++ .type strfill,@function
++strfill:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ movzb 16(%esp),%eax # Fill
++
++ movb %al,%ah # (2) Set up a 32 bit pattern
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++ movb %cl,(%edi) # End NULL
++ movl %edi,%eax # End i %eax
++ popl %edi
++ ret
++.strfill_end:
++ .size strfill,.strfill_end-strfill
++
++
++ # Find a char in or end of a string
++ # Arg: str,char
++ # Ret: pointer to found char or NullS
++
++.globl strcend
++ .type strcend,@function
++strcend:
++ movl %edi,%edx
++ movl 4(%esp),%edi # str
++ movb 8(%esp),%ah # search
++ clrb %al # for scasb to find end
++
++se_10: cmpb (%edi),%ah
++ jz se_20 # Found char
++ scasb
++ jnz se_10 # Not end
++ dec %edi # Not found, point at end of string
++se_20: movl %edi,%eax
++ movl %edx,%edi # Restore
++ ret
++.strcend_end:
++ .size strcend,.strcend_end-strcend
++
++ # Test if string has a given suffix
++
++.globl is_prefix
++ .type is_prefix,@function
++is_prefix:
++ movl %edi,%edx # Save %edi
++ pushl %esi # and %esi
++ movl 12(%esp),%esi # get suffix
++ movl 8(%esp),%edi # s1
++ movl $1,%eax # Ok and zero-test
++ip_10: cmpb (%esi),%ah
++ jz suf_ok # End of string/ found suffix
++ cmpsb # Compare strings
++ jz ip_10 # Same, possible prefix
++ xor %eax,%eax # Not suffix
++suf_ok: popl %esi
++ movl %edx,%edi
++ ret
++.is_prefix_end:
++ .size is_prefix,.is_prefix_end-is_prefix
++
++ # Find a substring in string
++ # Arg: str,search
++
++.globl strstr
++ .type strstr,@function
++
++strstr:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%esi # str
++ movl 16(%esp),%edi # search
++ movl %edi,%ecx
++ incl %ecx # %ecx = search+1
++ movb (%edi),%ah # %ah = First char in search
++ jmp sf_10
++
++sf_00: movl %edx,%esi # si = Current str-pos
++sf_10: movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jz sf_90 # End of string, didn't find search
++ incl %esi
++ cmpb %al,%ah
++ jnz sf_10 # Didn't find first char, continue
++ movl %esi,%edx # Save str-pos in %edx
++ movl %ecx,%edi
++sf_20: cmpb $0,(%edi)
++ jz sf_fo # Found substring
++ cmpsb
++ jz sf_20 # Char ok
++ jmp sf_00 # Next str-pos
++
++sf_90: movl $1,%edx # Return Null
++sf_fo: movl %edx,%eax # Char found here
++ decl %eax # Pointed one after
++ popl %esi
++ popl %edi
++ ret
++.strstr_end:
++ .size strstr,.strstr_end-strstr
++
++
++ # Find a substring in string, return index
++ # Arg: str,search
++
++.globl strinstr
++ .type strinstr,@function
++
++strinstr:
++ pushl %ebp
++ movl %esp,%ebp
++#ifdef __PIC__
++# undef __i686 /* gcc define gets in our way */
++ pushl %ebx
++ call __i686.get_pc_thunk.bx
++ addl $_GLOBAL_OFFSET_TABLE_, %ebx
++#endif
++ pushl 12(%ebp) # search
++ pushl 8(%ebp) # str
++#ifdef __PIC__
++ call strstr@PLT /*We need to be sure that ebx point to the got*/
++#else
++ call strstr
++#endif
++ add $8,%esp
++ or %eax,%eax
++ jz si_99 # Not found, return NULL
++ sub 8(%ebp),%eax # Pos from start
++ inc %eax # And first pos = 1
++si_99:
++#ifdef __PIC__
++ popl %ebx
++#endif
++ popl %ebp
++ ret
++.strinstr_end:
++ .size strinstr,.strinstr_end-strinstr
++
++ # Make a string of len length from another string
++ # Arg: dst,src,length
++ # ret: end of dst
++
++.globl strmake
++ .type strmake,@function
++
++strmake:
++ pushl %edi
++ pushl %esi
++ mov 12(%esp),%edi # dst
++ movl $0,%edx
++ movl 20(%esp),%ecx # length
++ movl 16(%esp),%esi # src
++ cmpl %edx,%ecx
++ jz sm_90
++sm_00: movb (%esi,%edx),%al
++ cmpb $0,%al
++ jz sm_90
++ movb %al,(%edi,%edx)
++ incl %edx
++ cmpl %edx,%ecx
++ jnz sm_00
++sm_90: movb $0,(%edi,%edx)
++sm_99: lea (%edi,%edx),%eax # Return pointer to end null
++ pop %esi
++ pop %edi
++ ret
++.strmake_end:
++ .size strmake,.strmake_end-strmake
++
++ # Move a string with max len chars
++ # arg: dst,src,len
++ # ret: pos to first null or dst+len
++
++.globl strnmov
++ .type strnmov,@function
++strnmov:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%edi # dst
++ movl 16(%esp),%esi # src
++ movl 20(%esp),%ecx # Length of memory-area
++ jecxz snm_99 # Nothing to do
++ clrb %al # For test of end-null
++
++snm_10: cmpb (%esi),%al # Next char to move
++ movsb # move arg
++ jz snm_20 # last char, fill with null
++ loop snm_10 # Continue moving
++ incl %edi # Point two after last
++snm_20: decl %edi # Point at first null (or last+1)
++snm_99: movl %edi,%eax # Pointer at last char
++ popl %esi
++ popl %edi
++ ret
++.strnmov_end:
++ .size strnmov,.strnmov_end-strnmov
++
++
++.globl strmov
++ .type strmov,@function
++strmov:
++ movl %esi,%ecx # Save old %esi and %edi
++ movl %edi,%edx
++ movl 8(%esp),%esi # get source pointer (s2)
++ movl 4(%esp),%edi # %edi -> s1
++smo_10: movb (%esi),%al
++ movsb # move arg
++ andb %al,%al
++ jnz smo_10 # Not last
++ movl %edi,%eax
++ dec %eax
++ movl %ecx,%esi # Restore
++ movl %edx,%edi
++ ret
++.strmov_end:
++ .size strmov,.strmov_end-strmov
++
++.globl strxmov
++ .type strxmov,@function
++strxmov:
++ movl %ebx,%edx # Save %ebx, %esi and %edi
++ mov %esi,%ecx
++ push %edi
++ leal 8(%esp),%ebx # Get destination
++ movl (%ebx),%edi
++ xorb %al,%al
++ jmp next_str # Handle source ebx+4
++
++start_str:
++ movsb
++ cmpb -1(%edi),%al
++ jne start_str
++ decl %edi # Don't copy last null
++
++next_str:
++ addl $4,%ebx
++ movl (%ebx),%esi
++ orl %esi,%esi
++ jne start_str
++ movb %al,0(%edi) # Force last to ASCII 0
++
++ movl %edi,%eax # Return ptr to ASCII 0
++ pop %edi # Restore registers
++ movl %ecx,%esi
++ movl %edx,%ebx
++ ret
++.strxmov_end:
++ .size strxmov,.strxmov_end-strxmov
++
++#ifdef __PIC__
++ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
++ .globl __i686.get_pc_thunk.bx
++ .hidden __i686.get_pc_thunk.bx
++ .type __i686.get_pc_thunk.bx,@function
++__i686.get_pc_thunk.bx:
++ movl (%esp), %ebx
++ ret
++#endif
++ .section .note.GNU-stack,"",@progbits
++
diff --git a/07341_all_mysql_hardened_x86_strings.patch b/07341_all_mysql_hardened_x86_strings.patch
new file mode 100644
index 0000000..f3afb26
--- /dev/null
+++ b/07341_all_mysql_hardened_x86_strings.patch
@@ -0,0 +1,517 @@
+2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
+
+ #344031
+ * configure.in: Rename strings-x86.s to strings-x86.S
+ * strings/Makefile.am Likewise.
+ * strings/Makefile.in Likewise.
+ * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+
+diff -urN a/configure.in b/configure.in
+--- a/configure.in 2010-11-09 21:29:31.806000076 +0100
++++ b/configure.in 2010-11-09 21:31:55.596000072 +0100
+@@ -673,7 +673,7 @@
+
+ AC_MSG_CHECKING(if we should use assembler functions)
+ # For now we only support assembler on i386 and sparc systems
+-AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
++AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
+ AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
+ AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
+ AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
+diff -urN a/strings/Makefile.am b/strings/Makefile.am
+--- a/strings/Makefile.am 2010-11-09 21:29:32.195000076 +0100
++++ b/strings/Makefile.am 2010-11-09 21:33:18.545000075 +0100
+@@ -20,7 +20,7 @@
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+-ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c
+ else
+ if ASSEMBLER_sparc32
+@@ -44,7 +44,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/Makefile.in b/strings/Makefile.in
+--- a/strings/Makefile.in 2010-11-09 21:29:32.197000076 +0100
++++ b/strings/Makefile.in 2010-11-09 21:33:45.348000075 +0100
+@@ -103,7 +103,7 @@
+ libmystrings_la_DEPENDENCIES =
+ am__libmystrings_la_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
+ strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
+- strnmov-sparc.s strstr-sparc.s strings-x86.s \
++ strnmov-sparc.s strstr-sparc.s strings-x86.S \
+ longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
+ strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
+ strstr.c strinstr.c strmake.c strnmov.c strmov.c \
+@@ -621,7 +621,7 @@
+ @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
+
+ # Exact one of ASSEMBLER_X
+-@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ # These file MUST all be on the same line!! Otherwise automake
+ # generats a very broken makefile
+ @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c
+@@ -633,7 +633,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/strings-x86.S b/strings/strings-x86.S
+--- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100
++++ b/strings/strings-x86.S 2010-11-09 22:05:05.084000076 +0100
+@@ -0,0 +1,442 @@
++# Copyright (C) 2000 MySQL AB
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; version 2 of the License.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++# Optimized string functions Intel 80x86 (gcc/gas syntax)
++
++ .file "strings.S"
++ .version "1.01"
++
++.text
++
++# Move a alligned, not overlapped, by (long) divided memory area
++# Args: to,from,length
++
++.globl bmove_align
++ .type bmove_align,@function
++bmove_align:
++ movl %edi,%edx
++ push %esi
++ movl 4(%esp),%edi # to
++ movl 8(%esp),%esi # from
++ movl 12(%esp),%ecx # length
++ addw $3,%cx # fix if not divisible with long
++ shrw $2,%cx
++ jz .ba_20
++ .p2align 4,,7
++.ba_10:
++ movl -4(%esi,%ecx),%eax
++ movl %eax,-4(%edi,%ecx)
++ decl %ecx
++ jnz .ba_10
++.ba_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_align_end:
++ .size bmove_align,.bmove_align_end-bmove_align
++
++ # Move a string from higher to lower
++ # Arg from_end+1,to_end+1,length
++
++.globl bmove_upp
++ .type bmove_upp,@function
++bmove_upp:
++ movl %edi,%edx # Remember %edi
++ push %esi
++ movl 8(%esp),%edi # dst
++ movl 16(%esp),%ecx # length
++ movl 12(%esp),%esi # source
++ test %ecx,%ecx
++ jz .bu_20
++ subl %ecx,%esi # To start of strings
++ subl %ecx,%edi
++
++ .p2align 4,,7
++.bu_10: movb -1(%esi,%ecx),%al
++ movb %al,-1(%edi,%ecx)
++ decl %ecx
++ jnz .bu_10
++.bu_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_upp_end:
++ .size bmove_upp,.bmove_upp_end-bmove_upp
++
++ # Append fillchars to string
++ # Args: dest,len,fill
++
++.globl strappend
++ .type strappend,@function
++strappend:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ clrl %eax # Find end of string
++ repne
++ scasb
++ jnz sa_99 # String to long, shorten it
++ movzb 16(%esp),%eax # Fillchar
++ decl %edi # Point at end null
++ incl %ecx # rep made one dec for null-char
++
++ movb %al,%ah # (2) Set up a 32 bit pattern.
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++sa_99: movb $0,(%edi) # End of string
++ popl %edi
++ ret
++.strappend_end:
++ .size strappend,.strappend_end-strappend
++
++ # Find if string contains any char in another string
++ # Arg: str,set
++ # Ret: Pointer to first found char in str
++
++.globl strcont
++ .type strcont,@function
++strcont:
++ movl %edi,%edx
++ pushl %esi
++ movl 8(%esp),%esi # str
++ movl 12(%esp),%ecx # set
++ clrb %ah # For endtest
++ jmp sc_60
++
++sc_10: scasb
++ jz sc_fo # Found char
++sc_20: cmp (%edi),%ah # Test if null
++ jnz sc_10 # Not end of set yet
++ incl %esi # Next char in str
++sc_60: movl %ecx,%edi # %edi = Set
++ movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jnz sc_20 # Not end of string
++ clrl %esi # Return Null
++sc_fo: movl %esi,%eax # Char found here
++ movl %edx,%edi # Restore
++ popl %esi
++ ret
++.strcont_end:
++ .size strcont,.strcont_end-strcont
++
++ # Find end of string
++ # Arg: str
++ # ret: Pointer to end null
++
++.globl strend
++ .type strend,@function
++strend:
++ movl %edi,%edx # Save
++ movl 4(%esp),%edi # str
++ clrl %eax # Find end of string
++ movl %eax,%ecx
++ decl %ecx # ECX = -1
++ repne
++ scasb
++ movl %edi,%eax
++ decl %eax # End of string
++ movl %edx,%edi # Restore
++ ret
++.strend_end:
++ .size strend,.strend_end-strend
++
++ # Make a string with len fill-chars and endnull
++ # Args: dest,len,fill
++ # Ret: dest+len
++
++.globl strfill
++ .type strfill,@function
++strfill:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ movzb 16(%esp),%eax # Fill
++
++ movb %al,%ah # (2) Set up a 32 bit pattern
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++ movb %cl,(%edi) # End NULL
++ movl %edi,%eax # End i %eax
++ popl %edi
++ ret
++.strfill_end:
++ .size strfill,.strfill_end-strfill
++
++
++ # Find a char in or end of a string
++ # Arg: str,char
++ # Ret: pointer to found char or NullS
++
++.globl strcend
++ .type strcend,@function
++strcend:
++ movl %edi,%edx
++ movl 4(%esp),%edi # str
++ movb 8(%esp),%ah # search
++ clrb %al # for scasb to find end
++
++se_10: cmpb (%edi),%ah
++ jz se_20 # Found char
++ scasb
++ jnz se_10 # Not end
++ dec %edi # Not found, point at end of string
++se_20: movl %edi,%eax
++ movl %edx,%edi # Restore
++ ret
++.strcend_end:
++ .size strcend,.strcend_end-strcend
++
++ # Test if string has a given suffix
++
++.globl is_prefix
++ .type is_prefix,@function
++is_prefix:
++ movl %edi,%edx # Save %edi
++ pushl %esi # and %esi
++ movl 12(%esp),%esi # get suffix
++ movl 8(%esp),%edi # s1
++ movl $1,%eax # Ok and zero-test
++ip_10: cmpb (%esi),%ah
++ jz suf_ok # End of string/ found suffix
++ cmpsb # Compare strings
++ jz ip_10 # Same, possible prefix
++ xor %eax,%eax # Not suffix
++suf_ok: popl %esi
++ movl %edx,%edi
++ ret
++.is_prefix_end:
++ .size is_prefix,.is_prefix_end-is_prefix
++
++ # Find a substring in string
++ # Arg: str,search
++
++.globl strstr
++ .type strstr,@function
++
++strstr:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%esi # str
++ movl 16(%esp),%edi # search
++ movl %edi,%ecx
++ incl %ecx # %ecx = search+1
++ movb (%edi),%ah # %ah = First char in search
++ jmp sf_10
++
++sf_00: movl %edx,%esi # si = Current str-pos
++sf_10: movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jz sf_90 # End of string, didn't find search
++ incl %esi
++ cmpb %al,%ah
++ jnz sf_10 # Didn't find first char, continue
++ movl %esi,%edx # Save str-pos in %edx
++ movl %ecx,%edi
++sf_20: cmpb $0,(%edi)
++ jz sf_fo # Found substring
++ cmpsb
++ jz sf_20 # Char ok
++ jmp sf_00 # Next str-pos
++
++sf_90: movl $1,%edx # Return Null
++sf_fo: movl %edx,%eax # Char found here
++ decl %eax # Pointed one after
++ popl %esi
++ popl %edi
++ ret
++.strstr_end:
++ .size strstr,.strstr_end-strstr
++
++
++ # Find a substring in string, return index
++ # Arg: str,search
++
++.globl strinstr
++ .type strinstr,@function
++
++strinstr:
++ pushl %ebp
++ movl %esp,%ebp
++#ifdef __PIC__
++# undef __i686 /* gcc define gets in our way */
++ pushl %ebx
++ call __i686.get_pc_thunk.bx
++ addl $_GLOBAL_OFFSET_TABLE_, %ebx
++#endif
++ pushl 12(%ebp) # search
++ pushl 8(%ebp) # str
++#ifdef __PIC__
++ call strstr@PLT /*We need to be sure that ebx point to the got*/
++#else
++ call strstr
++#endif
++ add $8,%esp
++ or %eax,%eax
++ jz si_99 # Not found, return NULL
++ sub 8(%ebp),%eax # Pos from start
++ inc %eax # And first pos = 1
++si_99:
++#ifdef __PIC__
++ popl %ebx
++#endif
++ popl %ebp
++ ret
++.strinstr_end:
++ .size strinstr,.strinstr_end-strinstr
++
++ # Make a string of len length from another string
++ # Arg: dst,src,length
++ # ret: end of dst
++
++.globl strmake
++ .type strmake,@function
++
++strmake:
++ pushl %edi
++ pushl %esi
++ mov 12(%esp),%edi # dst
++ movl $0,%edx
++ movl 20(%esp),%ecx # length
++ movl 16(%esp),%esi # src
++ cmpl %edx,%ecx
++ jz sm_90
++sm_00: movb (%esi,%edx),%al
++ cmpb $0,%al
++ jz sm_90
++ movb %al,(%edi,%edx)
++ incl %edx
++ cmpl %edx,%ecx
++ jnz sm_00
++sm_90: movb $0,(%edi,%edx)
++sm_99: lea (%edi,%edx),%eax # Return pointer to end null
++ pop %esi
++ pop %edi
++ ret
++.strmake_end:
++ .size strmake,.strmake_end-strmake
++
++ # Move a string with max len chars
++ # arg: dst,src,len
++ # ret: pos to first null or dst+len
++
++.globl strnmov
++ .type strnmov,@function
++strnmov:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%edi # dst
++ movl 16(%esp),%esi # src
++ movl 20(%esp),%ecx # Length of memory-area
++ jecxz snm_99 # Nothing to do
++ clrb %al # For test of end-null
++
++snm_10: cmpb (%esi),%al # Next char to move
++ movsb # move arg
++ jz snm_20 # last char, fill with null
++ loop snm_10 # Continue moving
++ incl %edi # Point two after last
++snm_20: decl %edi # Point at first null (or last+1)
++snm_99: movl %edi,%eax # Pointer at last char
++ popl %esi
++ popl %edi
++ ret
++.strnmov_end:
++ .size strnmov,.strnmov_end-strnmov
++
++
++.globl strmov
++ .type strmov,@function
++strmov:
++ movl %esi,%ecx # Save old %esi and %edi
++ movl %edi,%edx
++ movl 8(%esp),%esi # get source pointer (s2)
++ movl 4(%esp),%edi # %edi -> s1
++smo_10: movb (%esi),%al
++ movsb # move arg
++ andb %al,%al
++ jnz smo_10 # Not last
++ movl %edi,%eax
++ dec %eax
++ movl %ecx,%esi # Restore
++ movl %edx,%edi
++ ret
++.strmov_end:
++ .size strmov,.strmov_end-strmov
++
++.globl strxmov
++ .type strxmov,@function
++strxmov:
++ movl %ebx,%edx # Save %ebx, %esi and %edi
++ mov %esi,%ecx
++ push %edi
++ leal 8(%esp),%ebx # Get destination
++ movl (%ebx),%edi
++ xorb %al,%al
++ jmp next_str # Handle source ebx+4
++
++start_str:
++ movsb
++ cmpb -1(%edi),%al
++ jne start_str
++ decl %edi # Don't copy last null
++
++next_str:
++ addl $4,%ebx
++ movl (%ebx),%esi
++ orl %esi,%esi
++ jne start_str
++ movb %al,0(%edi) # Force last to ASCII 0
++
++ movl %edi,%eax # Return ptr to ASCII 0
++ pop %edi # Restore registers
++ movl %ecx,%esi
++ movl %edx,%ebx
++ ret
++.strxmov_end:
++ .size strxmov,.strxmov_end-strxmov
++
++#ifdef __PIC__
++ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
++ .globl __i686.get_pc_thunk.bx
++ .hidden __i686.get_pc_thunk.bx
++ .type __i686.get_pc_thunk.bx,@function
++__i686.get_pc_thunk.bx:
++ movl (%esp), %ebx
++ ret
++#endif
++ .section .note.GNU-stack,"",@progbits
++
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-03-04 12:53 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-03-04 12:53 UTC (permalink / raw
To: gentoo-commits
commit: 934534c930fd596131ba09f4fff90a0013dbdf87
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 4 12:51:18 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Fri Mar 4 12:51:18 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=934534c9
Updated 07341 patch for mariadb-5.1.55.
---
00000_index.txt | 7 +-
...1_all_mariadb_5.1.55_hardened_x86_strings.patch | 517 ++++++++++++++++++++
2 files changed, 523 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 8287602..1940250 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -698,7 +698,12 @@
@@ Gentoo Bug #344031: Fix new TEXTRELs
@patch 07341_all_mariadb_hardened_x86_strings.patch
-@ver 5.01.51.00 to 5.01.99.99
+@ver 5.01.51.00 to 5.01.54.99
+@pn mariadb
+@@ Gentoo Bug #344031: Fix new TEXTRELs
+
+@patch 07341_all_mariadb_5.1.55_hardened_x86_strings.patch
+@ver 5.01.55.00 to 5.01.99.99
@pn mariadb
@@ Gentoo Bug #344031: Fix new TEXTRELs
diff --git a/07341_all_mariadb_5.1.55_hardened_x86_strings.patch b/07341_all_mariadb_5.1.55_hardened_x86_strings.patch
new file mode 100644
index 0000000..1dc125a
--- /dev/null
+++ b/07341_all_mariadb_5.1.55_hardened_x86_strings.patch
@@ -0,0 +1,517 @@
+2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
+
+ #344031
+ * configure.in: Rename strings-x86.s to strings-x86.S
+ * strings/Makefile.am Likewise.
+ * strings/Makefile.in Likewise.
+ * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+
+diff -urN a/configure.in b/configure.in
+--- a/configure.in 2010-11-10 00:23:45.287000082 +0100
++++ b/configure.in 2010-11-10 00:30:47.681000059 +0100
+@@ -698,7 +698,7 @@
+
+ AC_MSG_CHECKING(if we should use assembler functions)
+ # For now we only support assembler on i386 and sparc systems
+-AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
++AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $CCAS $CCASFLAGS -c strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
+ AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
+ AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
+ AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
+diff -urN a/strings/Makefile.am b/strings/Makefile.am
+--- a/strings/Makefile.am 2010-11-10 00:23:45.421000083 +0100
++++ b/strings/Makefile.am 2010-11-10 00:31:23.489000090 +0100
+@@ -22,7 +22,7 @@
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+-ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov_overlapp.c
+ else
+ if ASSEMBLER_sparc32
+@@ -46,7 +46,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/Makefile.in b/strings/Makefile.in
+--- a/strings/Makefile.in 2010-11-10 00:23:45.423000082 +0100
++++ b/strings/Makefile.in 2010-11-10 00:29:17.547000090 +0100
+@@ -104,7 +104,7 @@
+ libmystrings_la_DEPENDENCIES =
+ am__libmystrings_la_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
+ strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
+- strnmov-sparc.s strstr-sparc.s strings-x86.s \
++ strnmov-sparc.s strstr-sparc.s strings-x86.S \
+ longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
+ strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
+ strstr.c strinstr.c strmake.c strnmov.c strmov.c \
+@@ -637,7 +637,7 @@
+ @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
+
+ # Exact one of ASSEMBLER_X
+-@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ # These file MUST all be on the same line!! Otherwise automake
+ # generats a very broken makefile
+ @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c bcmp.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c strmov_overlapp.c
+@@ -649,7 +649,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -urN a/strings/strings-x86.S b/strings/strings-x86.S
+--- a/strings/strings-x86.S 1970-01-01 01:00:00.000000000 +0100
++++ b/strings/strings-x86.S 2010-11-10 00:29:17.547000090 +0100
+@@ -0,0 +1,442 @@
++# Copyright (C) 2000 MySQL AB
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; version 2 of the License.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++# Optimized string functions Intel 80x86 (gcc/gas syntax)
++
++ .file "strings.S"
++ .version "1.01"
++
++.text
++
++# Move a alligned, not overlapped, by (long) divided memory area
++# Args: to,from,length
++
++.globl bmove_align
++ .type bmove_align,@function
++bmove_align:
++ movl %edi,%edx
++ push %esi
++ movl 4(%esp),%edi # to
++ movl 8(%esp),%esi # from
++ movl 12(%esp),%ecx # length
++ addw $3,%cx # fix if not divisible with long
++ shrw $2,%cx
++ jz .ba_20
++ .p2align 4,,7
++.ba_10:
++ movl -4(%esi,%ecx),%eax
++ movl %eax,-4(%edi,%ecx)
++ decl %ecx
++ jnz .ba_10
++.ba_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_align_end:
++ .size bmove_align,.bmove_align_end-bmove_align
++
++ # Move a string from higher to lower
++ # Arg from_end+1,to_end+1,length
++
++.globl bmove_upp
++ .type bmove_upp,@function
++bmove_upp:
++ movl %edi,%edx # Remember %edi
++ push %esi
++ movl 8(%esp),%edi # dst
++ movl 16(%esp),%ecx # length
++ movl 12(%esp),%esi # source
++ test %ecx,%ecx
++ jz .bu_20
++ subl %ecx,%esi # To start of strings
++ subl %ecx,%edi
++
++ .p2align 4,,7
++.bu_10: movb -1(%esi,%ecx),%al
++ movb %al,-1(%edi,%ecx)
++ decl %ecx
++ jnz .bu_10
++.bu_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_upp_end:
++ .size bmove_upp,.bmove_upp_end-bmove_upp
++
++ # Append fillchars to string
++ # Args: dest,len,fill
++
++.globl strappend
++ .type strappend,@function
++strappend:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ clrl %eax # Find end of string
++ repne
++ scasb
++ jnz sa_99 # String to long, shorten it
++ movzb 16(%esp),%eax # Fillchar
++ decl %edi # Point at end null
++ incl %ecx # rep made one dec for null-char
++
++ movb %al,%ah # (2) Set up a 32 bit pattern.
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++sa_99: movb $0,(%edi) # End of string
++ popl %edi
++ ret
++.strappend_end:
++ .size strappend,.strappend_end-strappend
++
++ # Find if string contains any char in another string
++ # Arg: str,set
++ # Ret: Pointer to first found char in str
++
++.globl strcont
++ .type strcont,@function
++strcont:
++ movl %edi,%edx
++ pushl %esi
++ movl 8(%esp),%esi # str
++ movl 12(%esp),%ecx # set
++ clrb %ah # For endtest
++ jmp sc_60
++
++sc_10: scasb
++ jz sc_fo # Found char
++sc_20: cmp (%edi),%ah # Test if null
++ jnz sc_10 # Not end of set yet
++ incl %esi # Next char in str
++sc_60: movl %ecx,%edi # %edi = Set
++ movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jnz sc_20 # Not end of string
++ clrl %esi # Return Null
++sc_fo: movl %esi,%eax # Char found here
++ movl %edx,%edi # Restore
++ popl %esi
++ ret
++.strcont_end:
++ .size strcont,.strcont_end-strcont
++
++ # Find end of string
++ # Arg: str
++ # ret: Pointer to end null
++
++.globl strend
++ .type strend,@function
++strend:
++ movl %edi,%edx # Save
++ movl 4(%esp),%edi # str
++ clrl %eax # Find end of string
++ movl %eax,%ecx
++ decl %ecx # ECX = -1
++ repne
++ scasb
++ movl %edi,%eax
++ decl %eax # End of string
++ movl %edx,%edi # Restore
++ ret
++.strend_end:
++ .size strend,.strend_end-strend
++
++ # Make a string with len fill-chars and endnull
++ # Args: dest,len,fill
++ # Ret: dest+len
++
++.globl strfill
++ .type strfill,@function
++strfill:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ movzb 16(%esp),%eax # Fill
++
++ movb %al,%ah # (2) Set up a 32 bit pattern
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++ movb %cl,(%edi) # End NULL
++ movl %edi,%eax # End i %eax
++ popl %edi
++ ret
++.strfill_end:
++ .size strfill,.strfill_end-strfill
++
++
++ # Find a char in or end of a string
++ # Arg: str,char
++ # Ret: pointer to found char or NullS
++
++.globl strcend
++ .type strcend,@function
++strcend:
++ movl %edi,%edx
++ movl 4(%esp),%edi # str
++ movb 8(%esp),%ah # search
++ clrb %al # for scasb to find end
++
++se_10: cmpb (%edi),%ah
++ jz se_20 # Found char
++ scasb
++ jnz se_10 # Not end
++ dec %edi # Not found, point at end of string
++se_20: movl %edi,%eax
++ movl %edx,%edi # Restore
++ ret
++.strcend_end:
++ .size strcend,.strcend_end-strcend
++
++ # Test if string has a given suffix
++
++.globl is_prefix
++ .type is_prefix,@function
++is_prefix:
++ movl %edi,%edx # Save %edi
++ pushl %esi # and %esi
++ movl 12(%esp),%esi # get suffix
++ movl 8(%esp),%edi # s1
++ movl $1,%eax # Ok and zero-test
++ip_10: cmpb (%esi),%ah
++ jz suf_ok # End of string/ found suffix
++ cmpsb # Compare strings
++ jz ip_10 # Same, possible prefix
++ xor %eax,%eax # Not suffix
++suf_ok: popl %esi
++ movl %edx,%edi
++ ret
++.is_prefix_end:
++ .size is_prefix,.is_prefix_end-is_prefix
++
++ # Find a substring in string
++ # Arg: str,search
++
++.globl strstr
++ .type strstr,@function
++
++strstr:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%esi # str
++ movl 16(%esp),%edi # search
++ movl %edi,%ecx
++ incl %ecx # %ecx = search+1
++ movb (%edi),%ah # %ah = First char in search
++ jmp sf_10
++
++sf_00: movl %edx,%esi # si = Current str-pos
++sf_10: movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jz sf_90 # End of string, didn't find search
++ incl %esi
++ cmpb %al,%ah
++ jnz sf_10 # Didn't find first char, continue
++ movl %esi,%edx # Save str-pos in %edx
++ movl %ecx,%edi
++sf_20: cmpb $0,(%edi)
++ jz sf_fo # Found substring
++ cmpsb
++ jz sf_20 # Char ok
++ jmp sf_00 # Next str-pos
++
++sf_90: movl $1,%edx # Return Null
++sf_fo: movl %edx,%eax # Char found here
++ decl %eax # Pointed one after
++ popl %esi
++ popl %edi
++ ret
++.strstr_end:
++ .size strstr,.strstr_end-strstr
++
++
++ # Find a substring in string, return index
++ # Arg: str,search
++
++.globl strinstr
++ .type strinstr,@function
++
++strinstr:
++ pushl %ebp
++ movl %esp,%ebp
++#ifdef __PIC__
++# undef __i686 /* gcc define gets in our way */
++ pushl %ebx
++ call __i686.get_pc_thunk.bx
++ addl $_GLOBAL_OFFSET_TABLE_, %ebx
++#endif
++ pushl 12(%ebp) # search
++ pushl 8(%ebp) # str
++#ifdef __PIC__
++ call strstr@PLT /*We need to be sure that ebx point to the got*/
++#else
++ call strstr
++#endif
++ add $8,%esp
++ or %eax,%eax
++ jz si_99 # Not found, return NULL
++ sub 8(%ebp),%eax # Pos from start
++ inc %eax # And first pos = 1
++si_99:
++#ifdef __PIC__
++ popl %ebx
++#endif
++ popl %ebp
++ ret
++.strinstr_end:
++ .size strinstr,.strinstr_end-strinstr
++
++ # Make a string of len length from another string
++ # Arg: dst,src,length
++ # ret: end of dst
++
++.globl strmake
++ .type strmake,@function
++
++strmake:
++ pushl %edi
++ pushl %esi
++ mov 12(%esp),%edi # dst
++ movl $0,%edx
++ movl 20(%esp),%ecx # length
++ movl 16(%esp),%esi # src
++ cmpl %edx,%ecx
++ jz sm_90
++sm_00: movb (%esi,%edx),%al
++ cmpb $0,%al
++ jz sm_90
++ movb %al,(%edi,%edx)
++ incl %edx
++ cmpl %edx,%ecx
++ jnz sm_00
++sm_90: movb $0,(%edi,%edx)
++sm_99: lea (%edi,%edx),%eax # Return pointer to end null
++ pop %esi
++ pop %edi
++ ret
++.strmake_end:
++ .size strmake,.strmake_end-strmake
++
++ # Move a string with max len chars
++ # arg: dst,src,len
++ # ret: pos to first null or dst+len
++
++.globl strnmov
++ .type strnmov,@function
++strnmov:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%edi # dst
++ movl 16(%esp),%esi # src
++ movl 20(%esp),%ecx # Length of memory-area
++ jecxz snm_99 # Nothing to do
++ clrb %al # For test of end-null
++
++snm_10: cmpb (%esi),%al # Next char to move
++ movsb # move arg
++ jz snm_20 # last char, fill with null
++ loop snm_10 # Continue moving
++ incl %edi # Point two after last
++snm_20: decl %edi # Point at first null (or last+1)
++snm_99: movl %edi,%eax # Pointer at last char
++ popl %esi
++ popl %edi
++ ret
++.strnmov_end:
++ .size strnmov,.strnmov_end-strnmov
++
++
++.globl strmov
++ .type strmov,@function
++strmov:
++ movl %esi,%ecx # Save old %esi and %edi
++ movl %edi,%edx
++ movl 8(%esp),%esi # get source pointer (s2)
++ movl 4(%esp),%edi # %edi -> s1
++smo_10: movb (%esi),%al
++ movsb # move arg
++ andb %al,%al
++ jnz smo_10 # Not last
++ movl %edi,%eax
++ dec %eax
++ movl %ecx,%esi # Restore
++ movl %edx,%edi
++ ret
++.strmov_end:
++ .size strmov,.strmov_end-strmov
++
++.globl strxmov
++ .type strxmov,@function
++strxmov:
++ movl %ebx,%edx # Save %ebx, %esi and %edi
++ mov %esi,%ecx
++ push %edi
++ leal 8(%esp),%ebx # Get destination
++ movl (%ebx),%edi
++ xorb %al,%al
++ jmp next_str # Handle source ebx+4
++
++start_str:
++ movsb
++ cmpb -1(%edi),%al
++ jne start_str
++ decl %edi # Don't copy last null
++
++next_str:
++ addl $4,%ebx
++ movl (%ebx),%esi
++ orl %esi,%esi
++ jne start_str
++ movb %al,0(%edi) # Force last to ASCII 0
++
++ movl %edi,%eax # Return ptr to ASCII 0
++ pop %edi # Restore registers
++ movl %ecx,%esi
++ movl %edx,%ebx
++ ret
++.strxmov_end:
++ .size strxmov,.strxmov_end-strxmov
++
++#ifdef __PIC__
++ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
++ .globl __i686.get_pc_thunk.bx
++ .hidden __i686.get_pc_thunk.bx
++ .type __i686.get_pc_thunk.bx,@function
++__i686.get_pc_thunk.bx:
++ movl (%esp), %ebx
++ ret
++#endif
++ .section .note.GNU-stack,"",@progbits
++
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-03-21 2:23 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-03-21 2:23 UTC (permalink / raw
To: gentoo-commits
commit: f9463d3a4f099e50de509b56ed6aba3c776073d9
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 21 02:22:05 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Mon Mar 21 02:22:05 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f9463d3a
Added a revised patch from upstream ( http://lists.mysql.com/commits/102373 ) to get a shared libmysqld.
This is still not fixed on upstream's tree.
---
00000_index.txt | 5 +++
02040_all_embedded-library-shared-5.5.10.patch | 45 ++++++++++++++++++++++++
2 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1940250..83cb229 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -286,6 +286,11 @@
@pn mysql
@@ Take libmysqld to be a proper shared library.
+@patch 02040_all_embedded-library-shared-5.5.10.patch
+@ver 5.05.10.00 to 5.05.99.99
+@pn mysql
+@@ Take libmysqld to be a proper shared library.
+
@patch 02040_all_embedded-library-shared-maria-5.1.50.patch
@ver 5.01.50.00 to 5.01.52.99
@pn mariadb
diff --git a/02040_all_embedded-library-shared-5.5.10.patch b/02040_all_embedded-library-shared-5.5.10.patch
new file mode 100644
index 0000000..df4a55d
--- /dev/null
+++ b/02040_all_embedded-library-shared-5.5.10.patch
@@ -0,0 +1,45 @@
+=== modified file 'cmake/libutils.cmake'
+--- a/cmake/libutils.cmake 2010-01-26 12:47:34 +0000
++++ b/cmake/libutils.cmake 2010-03-04 21:19:38 +0000
+@@ -268,6 +268,16 @@ MACRO(MERGE_LIBRARIES)
+ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
++
++ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
++ # Do not allow undefined symbols in shared libraries
++ GET_TARGET_PROPERTY(TARGET_LINK_FLAGS ${TARGET} LINK_FLAGS)
++ IF(NOT TARGET_LINK_FLAGS)
++ SET(TARGET_LINK_FLAGS)
++ ENDIF()
++ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS
++ "${TARGET_LINK_FLAGS} ${LINK_FLAG_NO_UNDEFINED}")
++ ENDIF()
+ ENDMACRO()
+
+ FUNCTION(GET_DEPENDEND_OS_LIBS target result)
+
+=== modified file 'libmysqld/CMakeLists.txt'
+--- a/libmysqld/CMakeLists.txt 2010-02-20 19:40:03 +0000
++++ b/libmysqld/CMakeLists.txt 2010-03-04 21:19:38 +0000
+@@ -138,7 +138,17 @@ IF(MSVC)
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+-IF(MSVC AND NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}
+- COMPONENT Embedded)
++IF(NOT DISABLE_SHARED)
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ IF(UNIX)
++ # Name the shared library, handle versioning (provides same api as client library
++ # hence the same version)
++ SET_TARGET_PROPERTIES(libmysqld PROPERTIES
++ OUTPUT_NAME mysqld
++ VERSION "${SHARED_LIB_MAJOR_VERSION}.0.0"
++ SOVERSION "${SHARED_LIB_MAJOR_VERSION}")
++ # Clean direct output flags, as 2 targets have the same base name (libmysqld)
++ SET_TARGET_PROPERTIES(libmysqld PROPERTIES CLEAN_DIRECT_OUTPUT 1)
++ SET_TARGET_PROPERTIES(mysqlserver PROPERTIES CLEAN_DIRECT_OUTPUT 1)
++ ENDIF()
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-03-27 20:58 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-03-27 20:58 UTC (permalink / raw
To: gentoo-commits
commit: 038797f721da1f8b2cadfc57f5ab6a749dbd9b89
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 27 20:55:31 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Mar 27 20:55:31 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=038797f7
Updated the 07110_all_mysql_gcc-4.2 patch for mysql-5.1.56.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.56.patch | 3729 ++++++++++++++++++++++++++++++++++
2 files changed, 3736 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 83cb229..d250ddd 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -508,7 +508,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.51.patch
-@ver 5.01.51.00 to 5.01.99.99
+@ver 5.01.51.00 to 5.01.55.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.56.patch
+@ver 5.01.56.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.56.patch b/07110_all_mysql_gcc-4.2_5.1.56.patch
new file mode 100644
index 0000000..b3aac08
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.56.patch
@@ -0,0 +1,3729 @@
+
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -Nuar mysql.orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql.orig/client/mysqlbinlog.cc 2010-08-03 17:24:30.000000000 +0000
++++ mysql/client/mysqlbinlog.cc 2010-08-20 22:20:26.954731698 +0000
+@@ -1945,7 +1945,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -Nuar mysql.orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql.orig/client/mysql.cc 2010-08-03 17:24:30.000000000 +0000
++++ mysql/client/mysql.cc 2010-08-20 22:20:26.954731698 +0000
+@@ -3336,9 +3336,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3358,7 +3358,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -Nuar mysql.orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql.orig/client/mysqldump.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/client/mysqldump.c 2010-08-20 22:20:26.958065154 +0000
+@@ -830,7 +830,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4517,7 +4517,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -Nuar mysql.orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql.orig/client/mysqltest.cc 2010-08-03 17:24:31.000000000 +0000
++++ mysql/client/mysqltest.cc 2010-08-20 22:20:26.958065154 +0000
+@@ -5652,9 +5652,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -Nuar mysql.orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql.orig/client/mysql_upgrade.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/client/mysql_upgrade.c 2010-08-20 22:20:26.958065154 +0000
+@@ -528,7 +528,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -Nuar mysql.orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql.orig/client/sql_string.cc 2010-08-03 17:24:35.000000000 +0000
++++ mysql/client/sql_string.cc 2010-08-20 22:20:26.961398610 +0000
+@@ -660,7 +660,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -746,7 +746,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -763,7 +763,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -Nuar mysql.orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql.orig/dbug/dbug.c 2010-08-03 17:24:26.000000000 +0000
++++ mysql/dbug/dbug.c 2010-08-20 22:20:26.961398610 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -Nuar mysql.orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql.orig/extra/yassl/src/ssl.cpp 2010-08-03 17:24:35.000000000 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2010-08-20 22:20:26.961398610 +0000
+@@ -38,6 +38,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -113,7 +114,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -Nuar mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp 2010-08-03 17:24:32.000000000 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2010-08-20 22:30:48.830833557 +0000
+@@ -67,7 +67,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -Nuar mysql.orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql.orig/extra/yassl/taocrypt/src/dh.cpp 2010-08-03 17:24:26.000000000 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2010-08-20 22:20:26.961398610 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -Nuar mysql.orig/include/my_global.h mysql/include/my_global.h
+--- mysql.orig/include/my_global.h 2010-08-03 17:24:30.000000000 +0000
++++ mysql/include/my_global.h 2010-08-20 22:31:41.752770815 +0000
+@@ -584,10 +584,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+@@ -1535,6 +1533,8 @@
+ /* Define some useful general macros (should be done after all headers). */
+ #if !defined(max)
+ #define max(a, b) ((a) > (b) ? (a) : (b))
++#endif
++#if !defined(min)
+ #define min(a, b) ((a) < (b) ? (a) : (b))
+ #endif
+ /*
+diff -Nuar mysql.orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql.orig/libmysql/libmysql.c 2010-08-03 17:24:28.000000000 +0000
++++ mysql/libmysql/libmysql.c 2010-08-20 22:20:26.961398610 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -Nuar mysql.orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql.orig/libmysqld/lib_sql.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/libmysqld/lib_sql.cc 2010-08-20 22:20:26.964732066 +0000
+@@ -824,7 +824,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -Nuar mysql.orig/mysys/array.c mysql/mysys/array.c
+--- mysql.orig/mysys/array.c 2010-08-03 17:24:23.000000000 +0000
++++ mysql/mysys/array.c 2010-08-20 22:20:26.964732066 +0000
+@@ -47,7 +47,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -341,7 +341,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -Nuar mysql.orig/mysys/default.c mysql/mysys/default.c
+--- mysql.orig/mysys/default.c 2010-08-03 17:24:26.000000000 +0000
++++ mysql/mysys/default.c 2010-08-20 22:20:26.964732066 +0000
+@@ -793,7 +793,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -Nuar mysql.orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql.orig/mysys/mf_format.c 2010-08-03 17:24:29.000000000 +0000
++++ mysql/mysys/mf_format.c 2010-08-20 22:20:26.964732066 +0000
+@@ -83,7 +83,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -Nuar mysql.orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql.orig/mysys/mf_iocache.c 2010-08-03 17:24:29.000000000 +0000
++++ mysql/mysys/mf_iocache.c 2010-08-20 22:20:26.964732066 +0000
+@@ -1097,7 +1097,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1256,7 +1256,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1365,7 +1365,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1399,7 +1399,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -Nuar mysql.orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql.orig/mysys/my_alloc.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_alloc.c 2010-08-20 22:20:26.964732066 +0000
+@@ -212,7 +212,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -Nuar mysql.orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql.orig/mysys/my_bitmap.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_bitmap.c 2010-08-20 22:20:26.964732066 +0000
+@@ -365,7 +365,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ *map2->last_word_ptr&= ~map2->last_word_mask; /*Clear last bits in map2*/
+ while (to < end)
+ *to++ &= *from++;
+diff -Nuar mysql.orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql.orig/mysys/my_compress.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_compress.c 2010-08-20 22:20:26.964732066 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -Nuar mysql.orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql.orig/mysys/my_conio.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_conio.c 2010-08-20 22:20:26.964732066 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -Nuar mysql.orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql.orig/mysys/my_file.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_file.c 2010-08-20 22:20:26.964732066 +0000
+@@ -75,7 +75,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -97,7 +97,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -107,9 +107,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -Nuar mysql.orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql.orig/mysys/my_getopt.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_getopt.c 2010-08-20 22:20:26.968065522 +0000
+@@ -983,7 +983,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -Nuar mysql.orig/mysys/my_handler.c mysql/mysys/my_handler.c
+--- mysql.orig/mysys/my_handler.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_handler.c 2010-08-20 22:20:26.968065522 +0000
+@@ -38,7 +38,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -166,7 +166,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -Nuar mysql.orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql.orig/mysys/my_static.h 2010-08-03 17:24:30.000000000 +0000
++++ mysql/mysys/my_static.h 2010-08-20 22:31:16.785190193 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -Nuar mysql.orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql.orig/mysys/safemalloc.c 2010-08-03 17:24:33.000000000 +0000
++++ mysql/mysys/safemalloc.c 2010-08-20 22:20:26.968065522 +0000
+@@ -248,7 +248,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -Nuar mysql.orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql.orig/mysys/stacktrace.c 2010-08-03 17:24:19.000000000 +0000
++++ mysql/mysys/stacktrace.c 2010-08-20 22:20:26.968065522 +0000
+@@ -324,7 +324,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) &
+ ~(ulong) 0xFFFF);
+diff -Nuar mysql.orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql.orig/server-tools/instance-manager/buffer.cc 2010-08-03 17:24:24.000000000 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2010-08-20 22:20:26.968065522 +0000
+@@ -83,8 +83,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -Nuar mysql.orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql.orig/server-tools/instance-manager/listener.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2010-08-20 22:20:26.968065522 +0000
+@@ -103,7 +103,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -Nuar mysql.orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql.orig/sql/debug_sync.cc 2010-08-03 17:24:21.000000000 +0000
++++ mysql/sql/debug_sync.cc 2010-08-20 22:26:19.817651899 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -Nuar mysql.orig/sql/field.cc mysql/sql/field.cc
+--- mysql.orig/sql/field.cc 2010-08-03 17:24:26.000000000 +0000
++++ mysql/sql/field.cc 2010-08-20 22:26:12.860730523 +0000
+@@ -54,7 +54,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2072,7 +2072,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2080,7 +2080,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2505,7 +2505,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2521,7 +2521,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3091,7 +3091,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3303,7 +3303,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3520,7 +3520,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3739,7 +3739,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3980,7 +3980,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4203,7 +4203,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6440,13 +6440,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6454,7 +6454,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6712,7 +6712,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7706,7 +7706,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7866,7 +7866,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8062,7 +8062,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9109,7 +9109,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9195,7 +9195,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9323,7 +9323,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9780,7 +9780,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -Nuar mysql.orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql.orig/sql/filesort.cc 2010-08-03 17:24:26.000000000 +0000
++++ mysql/sql/filesort.cc 2010-08-20 22:20:26.971398975 +0000
+@@ -193,7 +193,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -215,12 +215,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+ if ((table_sort.sort_keys=
+ (uchar **) make_char_array((char **) table_sort.sort_keys,
+ param.keys, param.rec_length, MYF(0))))
+@@ -1117,7 +1117,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1380,7 +1380,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -Nuar mysql.orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql.orig/sql/ha_ndbcluster.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/sql/ha_ndbcluster.cc 2010-08-20 22:20:26.974732431 +0000
+@@ -800,7 +800,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -Nuar mysql.orig/sql/handler.h mysql/sql/handler.h
+--- mysql.orig/sql/handler.h 2010-08-03 17:24:27.000000000 +0000
++++ mysql/sql/handler.h 2010-08-20 22:20:26.974732431 +0000
+@@ -1606,15 +1606,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -Nuar mysql.orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql.orig/sql/ha_partition.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/sql/ha_partition.cc 2010-08-20 22:26:27.484599263 +0000
+@@ -5966,7 +5966,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -Nuar mysql.orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql.orig/sql/item_buff.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/item_buff.cc 2010-08-20 22:21:21.480061665 +0000
+@@ -59,7 +59,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -69,7 +69,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -Nuar mysql.orig/sql/item.cc mysql/sql/item.cc
+--- mysql.orig/sql/item.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item.cc 2010-08-20 22:25:24.732301765 +0000
+@@ -74,7 +74,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -442,9 +442,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -750,7 +750,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5400,7 +5400,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5455,7 +5455,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7545,14 +7545,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7583,7 +7583,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7605,7 +7605,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7623,7 +7623,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -Nuar mysql.orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql.orig/sql/item_cmpfunc.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item_cmpfunc.cc 2010-08-20 22:20:26.978065887 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4981,7 +4981,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -5000,7 +5000,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5121,14 +5121,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5152,14 +5152,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -Nuar mysql.orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql.orig/sql/item_func.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/item_func.cc 2010-08-20 22:20:26.981399343 +0000
+@@ -547,7 +547,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1141,10 +1141,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1254,9 +1254,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1304,7 +1304,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1313,7 +1313,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1327,7 +1327,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1458,8 +1458,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1977,7 +1977,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1987,7 +1987,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2004,13 +2004,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2111,7 +2111,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2986,7 +2986,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2995,7 +2995,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -Nuar mysql.orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql.orig/sql/item_func.h 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item_func.h 2010-08-20 22:27:22.543281683 +0000
+@@ -420,7 +420,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -Nuar mysql.orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql.orig/sql/item_strfunc.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item_strfunc.cc 2010-08-20 22:24:51.184406804 +0000
+@@ -388,7 +388,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -747,7 +747,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1248,7 +1248,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1268,7 +1268,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1959,7 +1959,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3111,11 +3111,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3522,7 +3522,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -Nuar mysql.orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql.orig/sql/item_strfunc.h 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item_strfunc.h 2010-08-20 22:27:12.919596025 +0000
+@@ -705,7 +705,7 @@
+ void fix_length_and_dec()
+ {
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ collation.set(args[0]->collation);
+ }
+ };
+diff -Nuar mysql.orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql.orig/sql/item_sum.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/item_sum.cc 2010-08-20 22:20:26.984732799 +0000
+@@ -1143,7 +1143,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1206,16 +1206,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1406,13 +1406,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3349,7 +3349,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -Nuar mysql.orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql.orig/sql/item_timefunc.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/item_timefunc.cc 2010-08-20 22:20:26.984732799 +0000
+@@ -308,14 +308,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -324,7 +324,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -341,15 +341,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -360,14 +360,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -375,7 +375,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -427,7 +427,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -439,7 +439,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -451,7 +451,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -596,7 +596,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1823,7 +1823,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -Nuar mysql.orig/sql/key.cc mysql/sql/key.cc
+--- mysql.orig/sql/key.cc 2010-08-03 17:24:28.000000000 +0000
++++ mysql/sql/key.cc 2010-08-20 22:20:26.984732799 +0000
+@@ -125,13 +125,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -215,7 +215,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -224,7 +224,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -285,7 +285,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -351,7 +351,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -Nuar mysql.orig/sql/log.cc mysql/sql/log.cc
+--- mysql.orig/sql/log.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/log.cc 2010-08-20 22:20:26.984732799 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2429,7 +2429,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5236,7 +5236,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -Nuar mysql.orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql.orig/sql/log_event.cc 2010-08-03 17:24:29.000000000 +0000
++++ mysql/sql/log_event.cc 2010-08-20 22:24:38.123928612 +0000
+@@ -1075,7 +1075,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2671,7 +2671,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5588,7 +5588,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7315,7 +7315,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar mysql.orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql.orig/sql/log_event_old.cc 2010-08-03 17:24:29.000000000 +0000
++++ mysql/sql/log_event_old.cc 2010-08-20 22:26:32.254773908 +0000
+@@ -1420,7 +1420,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar mysql.orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql.orig/sql/mysqld.cc 2010-08-03 17:24:30.000000000 +0000
++++ mysql/sql/mysqld.cc 2010-08-20 22:20:26.991399708 +0000
+@@ -3377,7 +3377,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3389,15 +3389,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -5079,7 +5079,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -Nuar mysql.orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql.orig/sql/net_serv.cc 2010-08-03 17:24:31.000000000 +0000
++++ mysql/sql/net_serv.cc 2010-08-20 22:20:26.991399708 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -Nuar mysql.orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql.orig/sql/opt_range.cc 2010-08-03 17:24:31.000000000 +0000
++++ mysql/sql/opt_range.cc 2010-08-20 22:20:26.994733164 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -Nuar mysql.orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql.orig/sql/opt_range.h 2010-08-03 17:24:31.000000000 +0000
++++ mysql/sql/opt_range.h 2010-08-20 22:27:06.589364267 +0000
+@@ -83,7 +83,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -121,7 +121,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -Nuar mysql.orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql.orig/sql/protocol.cc 2010-08-03 17:24:31.000000000 +0000
++++ mysql/sql/protocol.cc 2010-08-20 22:20:26.998066620 +0000
+@@ -167,7 +167,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -262,7 +262,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -Nuar mysql.orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql.orig/sql/rpl_record.cc 2010-08-03 17:24:33.000000000 +0000
++++ mysql/sql/rpl_record.cc 2010-08-20 22:20:26.998066620 +0000
+@@ -285,7 +285,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -Nuar mysql.orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql.orig/sql/rpl_rli.cc 2010-08-03 17:24:33.000000000 +0000
++++ mysql/sql/rpl_rli.cc 2010-08-20 22:20:26.998066620 +0000
+@@ -686,7 +686,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -696,7 +696,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -Nuar mysql.orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql.orig/sql/rpl_utility.cc 2010-08-03 17:24:33.000000000 +0000
++++ mysql/sql/rpl_utility.cc 2010-08-20 22:20:26.998066620 +0000
+@@ -180,7 +180,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -Nuar mysql.orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql.orig/sql/rpl_utility.h 2010-08-03 17:24:33.000000000 +0000
++++ mysql/sql/rpl_utility.h 2010-08-20 22:26:52.782192108 +0000
+@@ -295,7 +295,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -Nuar mysql.orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql.orig/sql/set_var.cc 2010-08-03 17:24:33.000000000 +0000
++++ mysql/sql/set_var.cc 2010-08-20 22:24:34.027111945 +0000
+@@ -1835,7 +1835,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4020,7 +4020,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -Nuar mysql.orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql.orig/sql/slave.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/slave.cc 2010-08-20 22:20:27.001400076 +0000
+@@ -1737,7 +1737,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2354,7 +2354,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4050,7 +4050,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -Nuar mysql.orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql.orig/sql/spatial.h 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/spatial.h 2010-08-20 22:20:27.001400076 +0000
+@@ -180,8 +180,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -Nuar mysql.orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql.orig/sql/sp_head.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sp_head.cc 2010-08-20 22:20:27.001400076 +0000
+@@ -2453,7 +2453,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2654,7 +2654,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -Nuar mysql.orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql.orig/sql/sql_acl.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_acl.cc 2010-08-20 22:20:27.004733529 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -Nuar mysql.orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql.orig/sql/sql_analyse.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_analyse.cc 2010-08-20 22:20:27.004733529 +0000
+@@ -280,16 +280,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1043,7 +1043,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1068,7 +1068,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1185,7 +1185,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -Nuar mysql.orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql.orig/sql/sql_cache.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_cache.cc 2010-08-20 22:20:27.004733529 +0000
+@@ -1004,7 +1004,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2425,7 +2425,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2480,7 +2480,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2508,7 +2508,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2596,8 +2596,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2629,7 +2629,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2638,7 +2638,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3061,7 +3061,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -Nuar mysql.orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql.orig/sql/sql_class.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_class.cc 2010-08-20 22:24:23.626731145 +0000
+@@ -416,7 +416,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -431,7 +431,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2082,7 +2082,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -Nuar mysql.orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql.orig/sql/sql_client.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_client.cc 2010-08-20 22:20:27.008066985 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -Nuar mysql.orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql.orig/sql/sql_connect.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_connect.cc 2010-08-20 22:20:27.008066985 +0000
+@@ -679,7 +679,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -Nuar mysql.orig/sql/sql_load.cc mysql/sql/sql_load.cc
+--- mysql.orig/sql/sql_load.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/sql_load.cc 2010-08-20 22:20:27.008066985 +0000
+@@ -1109,7 +1109,7 @@
+
+
+ /* Set of a stack for unget if long terminators */
+- uint length=max(field_term_length,line_term_length)+1;
++ uint length=MYSQL_MAX(field_term_length,line_term_length)+1;
+ set_if_bigger(length,line_start.length());
+ stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
+
+diff -Nuar mysql.orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql.orig/sql/sql_parse.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_parse.cc 2010-08-20 22:20:27.011400441 +0000
+@@ -5708,7 +5708,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7212,7 +7212,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -Nuar mysql.orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql.orig/sql/sql_partition.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_partition.cc 2010-08-20 22:20:27.011400441 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -Nuar mysql.orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql.orig/sql/sql_plugin.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_plugin.cc 2010-08-20 22:20:27.011400441 +0000
+@@ -508,7 +508,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2124,7 +2124,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -Nuar mysql.orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql.orig/sql/sql_prepare.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/sql_prepare.cc 2010-08-20 22:20:27.014733897 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -Nuar mysql.orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql.orig/sql/sql_profile.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_profile.cc 2010-08-20 22:26:43.418515961 +0000
+@@ -252,7 +252,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -Nuar mysql.orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql.orig/sql/sql_repl.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_repl.cc 2010-08-20 22:24:15.399763250 +0000
+@@ -1297,12 +1297,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1474,7 +1474,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1745,14 +1745,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1761,7 +1761,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -Nuar mysql.orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql.orig/sql/sql_select.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_select.cc 2010-08-20 22:24:03.355988947 +0000
+@@ -2998,7 +2998,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3934,7 +3934,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3957,7 +3957,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4120,7 +4120,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4440,7 +4440,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4607,7 +4607,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5557,7 +5557,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10473,7 +10473,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13645,7 +13645,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13657,7 +13657,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14355,7 +14355,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14477,7 +14477,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -Nuar mysql.orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql.orig/sql/sql_show.cc 2010-08-03 17:24:34.000000000 +0000
++++ mysql/sql/sql_show.cc 2010-08-20 22:23:46.608709084 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1871,7 +1871,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2002,7 +2002,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3168,7 +3168,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7042,7 +7042,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -Nuar mysql.orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql.orig/sql/sql_string.cc 2010-08-03 17:24:35.000000000 +0000
++++ mysql/sql/sql_string.cc 2010-08-20 22:23:39.628453503 +0000
+@@ -695,7 +695,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -781,7 +781,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -798,7 +798,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -999,7 +999,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1185,7 +1185,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -Nuar mysql.orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql.orig/sql/sql_table.cc 2010-08-03 17:24:19.000000000 +0000
++++ mysql/sql/sql_table.cc 2010-08-20 22:20:27.024734262 +0000
+@@ -3264,7 +3264,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -Nuar mysql.orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql.orig/sql/sql_yacc.cc 2010-08-03 17:42:08.000000000 +0000
++++ mysql/sql/sql_yacc.cc 2010-08-20 22:20:27.038068083 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -Nuar mysql.orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql.orig/sql/sql_yacc.yy 2010-08-03 17:24:35.000000000 +0000
++++ mysql/sql/sql_yacc.yy 2010-08-20 22:20:27.041401539 +0000
+@@ -1805,7 +1805,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1815,7 +1815,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -Nuar mysql.orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql.orig/sql/thr_malloc.cc 2010-08-03 17:24:36.000000000 +0000
++++ mysql/sql/thr_malloc.cc 2010-08-20 22:20:27.041401539 +0000
+@@ -130,7 +130,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -Nuar mysql.orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql.orig/sql/tztime.cc 2010-08-03 17:24:36.000000000 +0000
++++ mysql/sql/tztime.cc 2010-08-20 22:20:27.041401539 +0000
+@@ -167,7 +167,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -396,7 +396,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1823,7 +1823,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -Nuar mysql.orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql.orig/sql/unireg.cc 2010-08-03 17:24:36.000000000 +0000
++++ mysql/sql/unireg.cc 2010-08-20 22:20:27.044734995 +0000
+@@ -496,7 +496,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -715,7 +715,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -Nuar mysql.orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql.orig/sql-common/client.c 2010-08-03 17:24:24.000000000 +0000
++++ mysql/sql-common/client.c 2010-08-20 22:20:27.044734995 +0000
+@@ -728,7 +728,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2102,7 +2102,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -Nuar mysql.orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql.orig/sql-common/my_time.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/sql-common/my_time.c 2010-08-20 22:20:27.044734995 +0000
+@@ -249,7 +249,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -Nuar mysql.orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql.orig/storage/csv/ha_tina.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/csv/ha_tina.cc 2010-08-20 22:20:27.044734995 +0000
+@@ -1193,7 +1193,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1429,7 +1429,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -Nuar mysql.orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql.orig/storage/federated/ha_federated.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/federated/ha_federated.cc 2010-08-20 22:20:27.044734995 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -Nuar mysql.orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql.orig/storage/heap/hp_create.c 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/heap/hp_create.c 2010-08-20 22:20:27.048068451 +0000
+@@ -229,7 +229,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -Nuar mysql.orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql.orig/storage/heap/hp_test2.c 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/heap/hp_test2.c 2010-08-20 22:20:27.048068451 +0000
+@@ -136,7 +136,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -217,7 +217,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -Nuar mysql.orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql.orig/storage/myisam/ha_myisam.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2010-08-20 22:20:27.048068451 +0000
+@@ -1527,7 +1527,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -Nuar mysql.orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql.orig/storage/myisam/mi_cache.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_cache.c 2010-08-20 22:20:27.048068451 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -Nuar mysql.orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql.orig/storage/myisam/mi_check.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_check.c 2010-08-20 22:20:27.048068451 +0000
+@@ -2172,7 +2172,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2328,7 +2328,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2781,7 +2781,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -4330,7 +4330,7 @@
+
+ VOID(mi_close(*org_info));
+ bzero((char*) &create_info,sizeof(create_info));
+- create_info.max_rows=max(max_records,share.base.records);
++ create_info.max_rows=MYSQL_MAX(max_records,share.base.records);
+ create_info.reloc_rows=share.base.reloc;
+ create_info.old_options=(share.options |
+ (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
+diff -Nuar mysql.orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql.orig/storage/myisam/mi_create.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_create.c 2010-08-20 22:20:27.048068451 +0000
+@@ -437,8 +437,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -527,7 +527,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -565,7 +565,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -Nuar mysql.orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql.orig/storage/myisam/mi_dynrec.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2010-08-20 22:20:27.051401907 +0000
+@@ -880,7 +880,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -Nuar mysql.orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql.orig/storage/myisam/mi_extra.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_extra.c 2010-08-20 22:20:27.051401907 +0000
+@@ -99,7 +99,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -Nuar mysql.orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql.orig/storage/myisam/mi_open.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_open.c 2010-08-20 22:20:27.051401907 +0000
+@@ -328,7 +328,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -501,7 +501,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -714,10 +714,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -Nuar mysql.orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql.orig/storage/myisam/mi_packrec.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_packrec.c 2010-08-20 22:20:27.051401907 +0000
+@@ -684,7 +684,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1399,7 +1399,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -Nuar mysql.orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql.orig/storage/myisam/mi_test1.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_test1.c 2010-08-20 22:20:27.051401907 +0000
+@@ -435,7 +435,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -Nuar mysql.orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql.orig/storage/myisam/mi_test2.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/mi_test2.c 2010-08-20 22:20:27.051401907 +0000
+@@ -601,7 +601,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -Nuar mysql.orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql.orig/storage/myisam/myisamlog.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/myisamlog.c 2010-08-20 22:20:27.051401907 +0000
+@@ -90,7 +90,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -Nuar mysql.orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql.orig/storage/myisam/myisampack.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/storage/myisam/myisampack.c 2010-08-20 22:20:27.054735360 +0000
+@@ -1239,7 +1239,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3001,7 +3001,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -Nuar mysql.orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql.orig/storage/myisam/rt_mbr.c 2010-08-03 17:24:33.000000000 +0000
++++ mysql/storage/myisam/rt_mbr.c 2010-08-20 22:20:27.054735360 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -Nuar mysql.orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql.orig/storage/myisam/sort.c 2010-08-03 17:24:34.000000000 +0000
++++ mysql/storage/myisam/sort.c 2010-08-20 22:20:27.054735360 +0000
+@@ -129,7 +129,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -346,7 +346,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -820,7 +820,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -841,7 +841,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -Nuar mysql.orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql.orig/storage/myisammrg/ha_myisammrg.cc 2010-08-03 17:24:27.000000000 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2010-08-20 22:20:27.054735360 +0000
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -Nuar mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2010-08-03 17:24:31.000000000 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2010-08-20 22:20:27.054735360 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -Nuar mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2010-08-03 17:24:26.000000000 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2010-08-20 22:20:27.054735360 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -Nuar mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2010-08-03 17:24:31.000000000 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2010-08-20 22:20:27.054735360 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -Nuar mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2010-08-03 17:24:36.000000000 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2010-08-20 22:20:27.054735360 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -Nuar mysql.orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql.orig/storage/ndb/test/src/getarg.c 2010-08-03 17:24:26.000000000 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2010-08-20 22:20:27.054735360 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -Nuar mysql.orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql.orig/strings/ctype-big5.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-big5.c 2010-08-20 22:20:27.058068816 +0000
+@@ -253,7 +253,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -266,7 +266,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar mysql.orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql.orig/strings/ctype-bin.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-bin.c 2010-08-20 22:20:27.058068816 +0000
+@@ -80,7 +80,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -131,7 +131,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -175,7 +175,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -404,7 +404,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -417,7 +417,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar mysql.orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql.orig/strings/ctype-gbk.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-gbk.c 2010-08-20 22:20:27.061402272 +0000
+@@ -2616,7 +2616,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2627,7 +2627,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar mysql.orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql.orig/strings/ctype-mb.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-mb.c 2010-08-20 22:20:27.064735728 +0000
+@@ -368,7 +368,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -412,7 +412,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -451,7 +451,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar mysql.orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql.orig/strings/ctype-simple.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-simple.c 2010-08-20 22:20:27.064735728 +0000
+@@ -159,7 +159,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -873,7 +873,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -927,7 +927,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1158,7 +1158,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -Nuar mysql.orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql.orig/strings/ctype-tis620.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-tis620.c 2010-08-20 22:20:27.064735728 +0000
+@@ -581,7 +581,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -638,7 +638,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -Nuar mysql.orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql.orig/strings/ctype-uca.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-uca.c 2010-08-20 22:20:27.068069184 +0000
+@@ -7567,7 +7567,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -Nuar mysql.orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql.orig/strings/ctype-ucs2.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-ucs2.c 2010-08-20 22:20:27.068069184 +0000
+@@ -279,7 +279,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1331,7 +1331,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1425,7 +1425,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1472,7 +1472,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar mysql.orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql.orig/strings/ctype-utf8.c 2010-08-03 17:24:25.000000000 +0000
++++ mysql/strings/ctype-utf8.c 2010-08-20 22:20:27.071402637 +0000
+@@ -1937,7 +1937,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -Nuar mysql.orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql.orig/strings/decimal.c 2010-08-03 17:24:26.000000000 +0000
++++ mysql/strings/decimal.c 2010-08-20 22:20:27.071402637 +0000
+@@ -403,7 +403,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -426,7 +426,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1517,8 +1517,8 @@
+
+ if (to != from || intg1>intg0)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg1+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg1+MYSQL_MAX(frac1, frac0);
+
+ while (buf0 < p0)
+ *(--p1) = *(--p0);
+@@ -1529,7 +1529,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1631,7 +1631,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1650,7 +1650,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1699,11 +1699,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1718,7 +1718,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1743,7 +1743,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1772,14 +1772,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... max(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1800,7 +1800,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1875,7 +1875,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1910,7 +1910,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2173,11 +2173,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2301,7 +2301,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2339,7 +2339,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -Nuar mysql.orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql.orig/strings/my_vsnprintf.c 2010-08-03 17:24:30.000000000 +0000
++++ mysql/strings/my_vsnprintf.c 2010-08-20 22:20:27.071402637 +0000
+@@ -141,7 +141,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -Nuar mysql.orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql.orig/strings/str2int.c 2010-08-03 17:24:35.000000000 +0000
++++ mysql/strings/str2int.c 2010-08-20 22:20:27.071402637 +0000
+@@ -82,7 +82,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -Nuar mysql.orig/tests/mysql_client_test.c mysql/tests/mysql_client_test.c
+--- mysql.orig/tests/mysql_client_test.c 2010-08-20 22:18:38.644098669 +0000
++++ mysql/tests/mysql_client_test.c 2010-08-20 22:20:27.074736093 +0000
+@@ -610,7 +610,7 @@
+ return row_count;
+ }
+
+- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
++ field_count= MYSQL_MIN(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+diff -Nuar mysql.orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql.orig/vio/viosocket.c 2010-08-03 17:24:36.000000000 +0000
++++ mysql/vio/viosocket.c 2010-08-20 22:20:27.074736093 +0000
+@@ -69,7 +69,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-03-27 21:02 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-03-27 21:02 UTC (permalink / raw
To: gentoo-commits
commit: 0fed5d5e537a332536344755212e673c0eba150b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 27 21:00:00 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Mar 27 21:00:00 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0fed5d5e
The 07330_all_mysql_itemfunc_stacksize_bug57386.patch patch is no longer required for mysql-5.1.56.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index d250ddd..185cb4e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -685,7 +685,7 @@
@@ my_compiler.h is not installed, but is required.
@patch 07330_all_mysql_itemfunc_stacksize_bug57386.patch
-@ver 5.01.50.00 to 5.01.99.99
+@ver 5.01.50.00 to 5.01.55.99
@pn mysql
@pn maria
@pn mysql-cluster
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-17 3:40 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-04-17 3:40 UTC (permalink / raw
To: gentoo-commits
commit: 3f32777cce99d3295f64851220ae63733116b3b6
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 17 03:37:20 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sun Apr 17 03:37:20 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=3f32777c
Added patch to fix the hardcoded lib paths on mysql ac macros.
Thanks to Jonathan Callen (abcd) for calling our attention.
---
15020_fix_hardcoded_lib_paths.patch | 121 +++++++++++++++++++++++++++++++++++
1 files changed, 121 insertions(+), 0 deletions(-)
diff --git a/15020_fix_hardcoded_lib_paths.patch b/15020_fix_hardcoded_lib_paths.patch
new file mode 100644
index 0000000..f62d1d0
--- /dev/null
+++ b/15020_fix_hardcoded_lib_paths.patch
@@ -0,0 +1,121 @@
+diff -urN mysql-orig//config/ac-macros/ha_ndbcluster.m4 mysql/config/ac-macros/ha_ndbcluster.m4
+--- mysql-orig//config/ac-macros/ha_ndbcluster.m4 2011-04-17 02:29:26.660000016 +0000
++++ mysql/config/ac-macros/ha_ndbcluster.m4 2011-04-17 02:33:40.293333350 +0000
+@@ -24,7 +24,7 @@
+ AC_HELP_STRING([--with-ndb-sci=DIR],
+ [Provide MySQL with a custom location of
+ sci library. Given DIR, sci library is
+- assumed to be in $DIR/lib and header files
++ assumed to be in $DIR/${LIBDIR} and header files
+ in $DIR/include.]),
+ [mysql_sci_dir=${withval}],
+ [mysql_sci_dir=""])
+@@ -35,19 +35,19 @@
+ AC_MSG_RESULT([-- not including sci transporter])
+ ;;
+ * )
+- if test -f "$mysql_sci_dir/lib/libsisci.a" -a \
++ if test -f "$mysql_sci_dir/${LIBDIR}/libsisci.a" -a \
+ -f "$mysql_sci_dir/include/sisci_api.h"; then
+ NDB_SCI_INCLUDES="-I$mysql_sci_dir/include"
+- NDB_SCI_LIBS="$mysql_sci_dir/lib/libsisci.a"
++ NDB_SCI_LIBS="$mysql_sci_dir/${LIBDIR}/libsisci.a"
+ AC_MSG_RESULT([-- including sci transporter])
+ AC_DEFINE([NDB_SCI_TRANSPORTER], [1],
+ [Including Ndb Cluster DB sci transporter])
+ AC_SUBST(NDB_SCI_INCLUDES)
+ AC_SUBST(NDB_SCI_LIBS)
+ have_ndb_sci="yes"
+- AC_MSG_RESULT([found sci transporter in $mysql_sci_dir/{include, lib}])
++ AC_MSG_RESULT([found sci transporter in $mysql_sci_dir/{include, ${LIBDIR}}])
+ else
+- AC_MSG_RESULT([could not find sci transporter in $mysql_sci_dir/{include, lib}])
++ AC_MSG_RESULT([could not find sci transporter in $mysql_sci_dir/{include, {LIBDIR}}])
+ fi
+ ;;
+ esac
+diff -urN mysql-orig//config/ac-macros/ssl.m4 mysql/config/ac-macros/ssl.m4
+--- mysql-orig//config/ac-macros/ssl.m4 2011-04-17 02:29:26.660000016 +0000
++++ mysql/config/ac-macros/ssl.m4 2011-04-17 02:32:26.143333350 +0000
+@@ -111,7 +111,7 @@
+ #
+ # Try to link with openSSL libs in <location>
+ #
+- openssl_libs="-L$location/lib/ -lssl -lcrypto"
++ openssl_libs="-L$location/${LIBDIR}/ -lssl -lcrypto"
+ MYSQL_CHECK_SSL_DIR([$openssl_includes], [$openssl_libs])
+
+ if test "$mysql_ssl_found" == "no"
+@@ -163,7 +163,7 @@
+ dnl bundled along with MySQL sources
+ dnl - ssl location prefix - given location prefix, the macro expects
+ dnl to find the header files in $prefix/include/, and libraries in
+-dnl $prefix/lib. If headers or libraries weren't found at $prefix, the
++dnl $prefix/${LIBDIR}. If headers or libraries weren't found at $prefix, the
+ dnl macro bails out with error.
+ dnl
+ dnl ------------------------------------------------------------------------
+diff -urN mysql-orig//config/ac-macros/zlib.m4 mysql/config/ac-macros/zlib.m4
+--- mysql-orig//config/ac-macros/zlib.m4 2011-04-17 02:29:26.660000016 +0000
++++ mysql/config/ac-macros/zlib.m4 2011-04-17 02:33:10.790000017 +0000
+@@ -51,12 +51,12 @@
+ dnl bundled zlib
+ dnl - zlib location prefix - given location prefix, the macro expects
+ dnl to find the library headers in $prefix/include, and binaries in
+-dnl $prefix/lib. If zlib headers or binaries weren't found at $prefix, the
++dnl $prefix/${LIBDIR}. If zlib headers or binaries weren't found at $prefix, the
+ dnl macro bails out with error.
+ dnl
+ dnl If the library was found, this function #defines HAVE_COMPRESS
+ dnl and configure variables ZLIB_INCLUDES (i.e. -I/path/to/zlib/include),
+-dnl ZLIB_LIBS (i. e. -L/path/to/zlib/lib -lz) and ZLIB_DEPS which is
++dnl ZLIB_LIBS (i. e. -L/path/to/zlib/${LIBDIR} -lz) and ZLIB_DEPS which is
+ dnl used in mysql_config and is always the same as ZLIB_LIBS except to
+ dnl when we use the bundled zlib. In the latter case ZLIB_LIBS points to the
+ dnl build dir ($top_builddir/zlib), while mysql_config must point to the
+@@ -78,7 +78,7 @@
+ AC_HELP_STRING([--with-zlib-dir=no|bundled|DIR],
+ [Provide MySQL with a custom location of
+ compression library. Given DIR, zlib binary is
+- assumed to be in $DIR/lib and header files
++ assumed to be in $DIR/${LIBDIR} and header files
+ in $DIR/include.]),
+ [mysql_zlib_dir=${withval}],
+ [mysql_zlib_dir=""])
+@@ -102,13 +102,13 @@
+ ;;
+ *)
+ # Test for libz using all known library file endings
+- if test \( -f "$mysql_zlib_dir/lib/libz.a" -o \
+- -f "$mysql_zlib_dir/lib/libz.so" -o \
+- -f "$mysql_zlib_dir/lib/libz.sl" -o \
+- -f "$mysql_zlib_dir/lib/libz.dylib" \) \
++ if test \( -f "$mysql_zlib_dir/${LIBDIR}/libz.a" -o \
++ -f "$mysql_zlib_dir/${LIBDIR}/libz.so" -o \
++ -f "$mysql_zlib_dir/${LIBDIR}/libz.sl" -o \
++ -f "$mysql_zlib_dir/${LIBDIR}/libz.dylib" \) \
+ -a -f "$mysql_zlib_dir/include/zlib.h"; then
+ ZLIB_INCLUDES="-I$mysql_zlib_dir/include"
+- ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz"
++ ZLIB_LIBS="-L$mysql_zlib_dir/${LIBDIR} -lz"
+ MYSQL_CHECK_ZLIB_DIR
+ fi
+ if test "x$mysql_cv_compress" != "xyes"; then
+diff -urN mysql-orig//configure.in mysql/configure.in
+--- mysql-orig//configure.in 2011-04-17 02:29:26.650000015 +0000
++++ mysql/configure.in 2011-04-17 02:58:57.133333350 +0000
+@@ -64,6 +64,14 @@
+ MYSQL_TCP_PORT_DEFAULT=3306
+ MYSQL_UNIX_ADDR_DEFAULT="/tmp/mysql.sock"
+
++AC_ARG_WITH(LIBDIR,
++[AS_HELP_STRING([--with-LIBDIR],[base name of the library dirs])],
++[LIBDIR=$withval],
++[LIBDIR=lib]
++)
++
++AC_SUBST([LIBDIR])
++
+ dnl Include m4
+ sinclude(config/ac-macros/maintainer.m4)
+ sinclude(config/ac-macros/alloca.m4)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-17 20:10 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-17 20:10 UTC (permalink / raw
To: gentoo-commits
commit: 9d4751db2d6bf2e53b0874b9fc1a1eaf1269d0fb
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 17 18:59:14 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 17 18:59:14 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=9d4751db
Add the hardcoded libdir name fix to index.
---
00000_index.txt | 5 +++++
...atch => 15020_all_fix_hardcoded_lib_paths.patch | 0
2 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 185cb4e..06335c3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1326,3 +1326,8 @@
@ver 5.00.87.00 to 5.00.99.99
@pn mysql
@@ Fixup of crash caused by Percona code + compile fix for strchr input type.
+
+@patch 15020_all_fix_hardcoded_lib_paths.patch
+@ver 5.01.53.00 to 5.01.99.99
+@pn mysql
+@@ Fix for the hardcoded /lib paths.
diff --git a/15020_fix_hardcoded_lib_paths.patch b/15020_all_fix_hardcoded_lib_paths.patch
similarity index 100%
rename from 15020_fix_hardcoded_lib_paths.patch
rename to 15020_all_fix_hardcoded_lib_paths.patch
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-17 20:10 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-17 20:10 UTC (permalink / raw
To: gentoo-commits
commit: 15998bcb1f584ce485f4899ef32d6ac69886f538
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 17 20:09:49 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 17 20:09:49 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=15998bcb
Document patch.
---
15020_all_fix_hardcoded_lib_paths.patch | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)
diff --git a/15020_all_fix_hardcoded_lib_paths.patch b/15020_all_fix_hardcoded_lib_paths.patch
index f62d1d0..3d2f112 100644
--- a/15020_all_fix_hardcoded_lib_paths.patch
+++ b/15020_all_fix_hardcoded_lib_paths.patch
@@ -1,3 +1,14 @@
+Multilib: Remove hardcoded lib where lib might be lib32, and lib64 is correct.
+
+On a variety of multilib systems, /lib might not exist, or might contain
+(directly or via a symlink) 32-bit library content. If the objective is to
+build a 64-bit MySQL, we need to explicitly tell mysql how to look for external
+libraries. We add an option --with-LIBDIR that takes the basename for the
+library directory to resolve this problem.
+
+Signed-off-by: Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+
diff -urN mysql-orig//config/ac-macros/ha_ndbcluster.m4 mysql/config/ac-macros/ha_ndbcluster.m4
--- mysql-orig//config/ac-macros/ha_ndbcluster.m4 2011-04-17 02:29:26.660000016 +0000
+++ mysql/config/ac-macros/ha_ndbcluster.m4 2011-04-17 02:33:40.293333350 +0000
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-17 20:10 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-17 20:10 UTC (permalink / raw
To: gentoo-commits
commit: 89dad5c2c602aa228d5bd1db720695dbe47d2fb3
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 17 20:10:17 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 17 20:10:17 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=89dad5c2
Add a fix for test-unit due to Perl Test::Harness changes.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
00000_index.txt | 5 ++++
15030_all_fix_perl_test_harness.patch | 35 +++++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 06335c3..1a8e59c 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1331,3 +1331,8 @@
@ver 5.01.53.00 to 5.01.99.99
@pn mysql
@@ Fix for the hardcoded /lib paths.
+
+@patch 15030_all_fix_perl_test_harness.patch
+@ver 5.01.53.00 to 5.01.99.99
+@pn mysql
+@@ Fix Test::Harness usage since the Perl class has changed and no longer execs by default.
diff --git a/15030_all_fix_perl_test_harness.patch b/15030_all_fix_perl_test_harness.patch
new file mode 100644
index 0000000..bd6d845
--- /dev/null
+++ b/15030_all_fix_perl_test_harness.patch
@@ -0,0 +1,35 @@
+Update Test::Harness usage for Test-Harness-3*
+
+Test-Harness-2 and older directly executed testcases that did not end in .t.
+In version 3, this is no longer the case, and Test::Harness is now a thin
+wrapper around TAP::Harness. To make the testcases work again, we introduce a
+subclass of TAP::Harness, that allows direct execution where needed.
+
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+
+--- mysql/unittest/unit.pl.orig 2011-04-17 18:12:47.104981268 +0000
++++ mysql/unittest/unit.pl 2011-04-17 19:05:46.520096987 +0000
+@@ -93,7 +93,23 @@
+ # Removing the first './' from the file names
+ foreach (@files) { s!^\./!! }
+ $ENV{'HARNESS_PERL_SWITCHES'} .= q" -e 'exec @ARGV'";
++ $ENV{'HARNESS_SUBCLASS'} = qw(TAP::Harness::Exec);
+ runtests @files;
+ }
+ }
+
++package TAP::Harness::Exec;
++use base qw(TAP::Harness);
++sub new {
++ my ($class, $arg_for ) = @_;
++ $arg_for ||= {};
++ $arg_for->{exec} = sub {
++ my ( $harness, $test_file ) = @_;
++ return undef if $test_file =~ /[.]t$/;
++ return [ $test_file ] if -x $test_file;
++ # This is a failure now
++ return undef;
++ };
++ return $class->SUPER::new( $arg_for );
++}
++1;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-17 22:42 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-17 22:42 UTC (permalink / raw
To: gentoo-commits
commit: c6231cd21a7fefc28b93774610ed477f8fdb6bf9
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Sun Apr 17 22:42:01 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 17 22:42:01 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c6231cd2
Respin the hardened strings patch to include the CCASFLAGS fix from bug #347796.
---
00000_index.txt | 18 +-
07340_all_mariadb_hardened_x86_strings.patch | 10 +-
07340_all_mysql_hardened_x86_strings.patch | 10 +-
07341_all_mysql-5.1.56-hardened_x86_strings.patch | 955 +++++++++++++++++++++
4 files changed, 973 insertions(+), 20 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1a8e59c..c44b661 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -695,19 +695,25 @@
@ver 5.01.51.00 to 5.01.99.99
@pn mysql
@pn mysql-cluster
-@@ Gentoo Bug #344031: Fix new TEXTRELs
+@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
-@patch 07340_all_mariadb_hardened_x86_strings.patch
-@ver 5.01.51.00 to 5.01.99.99
-@pn mariadb
+@patch 07341_all_mysql_hardened_x86_strings.patch
+@ver 5.01.51.00 to 5.01.55.99
+@pn mysql
+@pn mysql-cluster
@@ Gentoo Bug #344031: Fix new TEXTRELs
-@patch 07341_all_mysql_hardened_x86_strings.patch
-@ver 5.01.51.00 to 5.01.99.99
+@patch 07341_all_mysql-5.1.56_hardened_x86_strings.patch
+@ver 5.01.56.00 to 5.01.99.99
@pn mysql
@pn mysql-cluster
@@ Gentoo Bug #344031: Fix new TEXTRELs
+@patch 07340_all_mariadb_hardened_x86_strings.patch
+@ver 5.01.51.00 to 5.01.99.99
+@pn mariadb
+@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
+
@patch 07341_all_mariadb_hardened_x86_strings.patch
@ver 5.01.51.00 to 5.01.54.99
@pn mariadb
diff --git a/07340_all_mariadb_hardened_x86_strings.patch b/07340_all_mariadb_hardened_x86_strings.patch
index b442042..df0235d 100644
--- a/07340_all_mariadb_hardened_x86_strings.patch
+++ b/07340_all_mariadb_hardened_x86_strings.patch
@@ -1,10 +1,6 @@
-2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
-
- #344031
- * configure.in: Rename strings-x86.s to strings-x86.S
- * strings/Makefile.am Likewise.
- * strings/Makefile.in Likewise.
- * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+As part of fixing the TEXTRELs, we must remove this file seperately because
+applying a move of .s -> .S on a case-insensitive file-system will cause patch
+to break.
diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
diff --git a/07340_all_mysql_hardened_x86_strings.patch b/07340_all_mysql_hardened_x86_strings.patch
index b442042..df0235d 100644
--- a/07340_all_mysql_hardened_x86_strings.patch
+++ b/07340_all_mysql_hardened_x86_strings.patch
@@ -1,10 +1,6 @@
-2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
-
- #344031
- * configure.in: Rename strings-x86.s to strings-x86.S
- * strings/Makefile.am Likewise.
- * strings/Makefile.in Likewise.
- * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+As part of fixing the TEXTRELs, we must remove this file seperately because
+applying a move of .s -> .S on a case-insensitive file-system will cause patch
+to break.
diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
diff --git a/07341_all_mysql-5.1.56-hardened_x86_strings.patch b/07341_all_mysql-5.1.56-hardened_x86_strings.patch
new file mode 100644
index 0000000..1e25fd6
--- /dev/null
+++ b/07341_all_mysql-5.1.56-hardened_x86_strings.patch
@@ -0,0 +1,955 @@
+2010-11-10 Magnus Granberg <zorry@gento.org>, Francisco Blas Izquierdo Riera <franxisco1988@mixmail.com>
+
+ #344031
+ * configure.in: Rename strings-x86.s to strings-x86.S
+ * strings/Makefile.am Likewise.
+ * strings/Makefile.in Likewise.
+ * strings/strings-x86.S Copy of strings-x86.s to support -fPIC
+
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+
+--
+ configure.in | 4
+ strings/Makefile.am | 4
+ strings/Makefile.in | 6
+ strings/strings-x86.S | 442 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ strings/strings-x86.s | 416 -----------------------------------------------
+ 5 files changed, 449 insertions(+), 423 deletions(-)
+diff -Nuar --exclude '*.orig' mysql.orig//configure.in mysql//configure.in
+--- mysql.orig//configure.in 2011-02-11 19:20:19.000000000 +0000
++++ mysql//configure.in 2011-04-17 22:36:09.579371779 +0000
+@@ -526,7 +526,7 @@
+
+ # We need an assembler, too
+ AM_PROG_AS
+-CCASFLAGS="$CCASFLAGS $ASFLAGS"
++CCASFLAGS="$CCASFLAGS $(for flag in $ASFLAGS ; do echo "-Wa,$flag" ; done)"
+
+ # Check if we need noexec stack for assembler
+ AC_CHECK_NOEXECSTACK
+@@ -680,7 +680,7 @@
+
+ AC_MSG_CHECKING(if we should use assembler functions)
+ # For now we only support assembler on i386 and sparc systems
+-AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.s -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
++AM_CONDITIONAL(ASSEMBLER_x86, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "i386" && $AS strings/strings-x86.S -o checkassembler >/dev/null 2>&1 && test -f checkassembler && (rm -f checkassembler; exit 0;))
+ AM_CONDITIONAL(ASSEMBLER_sparc32, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparc")
+ AM_CONDITIONAL(ASSEMBLER_sparc64, test "$ENABLE_ASSEMBLER" = "yes" -a "$BASE_MACHINE_TYPE" = "sparcv9")
+ AM_CONDITIONAL(ASSEMBLER, test "$ASSEMBLER_x86_TRUE" = "" -o "$ASSEMBLER_sparc32_TRUE" = "")
+diff -Nuar --exclude '*.orig' mysql.orig//strings/Makefile.am mysql//strings/Makefile.am
+--- mysql.orig//strings/Makefile.am 2011-02-11 19:20:35.000000000 +0000
++++ mysql//strings/Makefile.am 2011-04-17 22:35:39.803194869 +0000
+@@ -20,7 +20,7 @@
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+-ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ CSRCS = bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c str_alloc.c longlong2str_asm.c my_strchr.c strmov.c
+ else
+ if ASSEMBLER_sparc32
+@@ -44,7 +44,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -Nuar --exclude '*.orig' mysql.orig//strings/Makefile.in mysql//strings/Makefile.in
+--- mysql.orig//strings/Makefile.in 2011-02-11 19:24:24.000000000 +0000
++++ mysql//strings/Makefile.in 2011-04-17 22:35:39.803194869 +0000
+@@ -87,7 +87,7 @@
+ libmystrings_a_DEPENDENCIES =
+ am__libmystrings_a_SOURCES_DIST = bmove_upp-sparc.s strappend-sparc.s \
+ strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s \
+- strnmov-sparc.s strstr-sparc.s strings-x86.s \
++ strnmov-sparc.s strstr-sparc.s strings-x86.S \
+ longlong2str-x86.s my_strtoll10-x86.s strxmov.c bmove_upp.c \
+ strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c \
+ strstr.c strinstr.c strmake.c strnmov.c strmov.c \
+@@ -581,7 +581,7 @@
+ @ASSEMBLER_sparc32_TRUE@@ASSEMBLER_x86_FALSE@ASRCS = bmove_upp-sparc.s strappend-sparc.s strend-sparc.s strinstr-sparc.s strmake-sparc.s strmov-sparc.s strnmov-sparc.s strstr-sparc.s
+
+ # Exact one of ASSEMBLER_X
+-@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.s longlong2str-x86.s my_strtoll10-x86.s
++@ASSEMBLER_x86_TRUE@ASRCS = strings-x86.S longlong2str-x86.s my_strtoll10-x86.s
+ # These file MUST all be on the same line!! Otherwise automake
+ # generats a very broken makefile
+ @ASSEMBLER_sparc32_FALSE@@ASSEMBLER_x86_FALSE@CSRCS = strxmov.c bmove_upp.c strappend.c strcont.c strend.c strfill.c strcend.c is_prefix.c strstr.c strinstr.c strmake.c strnmov.c strmov.c longlong2str.c bfill.c bmove.c bmove512.c bchange.c strxnmov.c int2str.c str2int.c r_strinstr.c strtod.c strtol.c strtoul.c strtoll.c strtoull.c llstr.c strnlen.c ctype.c ctype-simple.c ctype-mb.c ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-tis620.c ctype-ujis.c ctype-utf8.c ctype-ucs2.c ctype-uca.c ctype-win1250ch.c ctype-bin.c ctype-latin1.c my_vsnprintf.c xml.c decimal.c ctype-extra.c my_strtoll10.c str_alloc.c my_strchr.c
+@@ -593,7 +593,7 @@
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+ ctype-gb2312.c ctype-gbk.c ctype-sjis.c ctype-utf8.c \
+ ctype-ucs2.c ctype-uca.c ctype-tis620.c ctype-ujis.c \
+- xml.c decimal.c strto.c strings-x86.s \
++ xml.c decimal.c strto.c strings-x86.S \
+ longlong2str.c longlong2str-x86.s longlong2str_asm.c \
+ my_strtoll10.c my_strtoll10-x86.s \
+ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
+diff -Nuar --exclude '*.orig' mysql.orig//strings/strings-x86.s mysql//strings/strings-x86.s
+--- mysql.orig//strings/strings-x86.s 2011-02-11 19:20:41.000000000 +0000
++++ mysql//strings/strings-x86.s 1970-01-01 00:00:00.000000000 +0000
+@@ -1,416 +0,0 @@
+-# Copyright (C) 2000 MySQL AB
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; version 2 of the License.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-
+-# Optimized string functions Intel 80x86 (gcc/gas syntax)
+-
+- .file "strings.s"
+- .version "1.00"
+-
+-.text
+-
+-# Move a alligned, not overlapped, by (long) divided memory area
+-# Args: to,from,length
+-
+-.globl bmove_align
+- .type bmove_align,@function
+-bmove_align:
+- movl %edi,%edx
+- push %esi
+- movl 4(%esp),%edi # to
+- movl 8(%esp),%esi # from
+- movl 12(%esp),%ecx # length
+- addw $3,%cx # fix if not divisible with long
+- shrw $2,%cx
+- jz .ba_20
+- .p2align 4,,7
+-.ba_10:
+- movl -4(%esi,%ecx),%eax
+- movl %eax,-4(%edi,%ecx)
+- decl %ecx
+- jnz .ba_10
+-.ba_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_align_end:
+- .size bmove_align,.bmove_align_end-bmove_align
+-
+- # Move a string from higher to lower
+- # Arg from_end+1,to_end+1,length
+-
+-.globl bmove_upp
+- .type bmove_upp,@function
+-bmove_upp:
+- movl %edi,%edx # Remember %edi
+- push %esi
+- movl 8(%esp),%edi # dst
+- movl 16(%esp),%ecx # length
+- movl 12(%esp),%esi # source
+- test %ecx,%ecx
+- jz .bu_20
+- subl %ecx,%esi # To start of strings
+- subl %ecx,%edi
+-
+- .p2align 4,,7
+-.bu_10: movb -1(%esi,%ecx),%al
+- movb %al,-1(%edi,%ecx)
+- decl %ecx
+- jnz .bu_10
+-.bu_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_upp_end:
+- .size bmove_upp,.bmove_upp_end-bmove_upp
+-
+- # Append fillchars to string
+- # Args: dest,len,fill
+-
+-.globl strappend
+- .type strappend,@function
+-strappend:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- clrl %eax # Find end of string
+- repne
+- scasb
+- jnz sa_99 # String to long, shorten it
+- movzb 16(%esp),%eax # Fillchar
+- decl %edi # Point at end null
+- incl %ecx # rep made one dec for null-char
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern.
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+-sa_99: movb $0,(%edi) # End of string
+- popl %edi
+- ret
+-.strappend_end:
+- .size strappend,.strappend_end-strappend
+-
+- # Find if string contains any char in another string
+- # Arg: str,set
+- # Ret: Pointer to first found char in str
+-
+-.globl strcont
+- .type strcont,@function
+-strcont:
+- movl %edi,%edx
+- pushl %esi
+- movl 8(%esp),%esi # str
+- movl 12(%esp),%ecx # set
+- clrb %ah # For endtest
+- jmp sc_60
+-
+-sc_10: scasb
+- jz sc_fo # Found char
+-sc_20: cmp (%edi),%ah # Test if null
+- jnz sc_10 # Not end of set yet
+- incl %esi # Next char in str
+-sc_60: movl %ecx,%edi # %edi = Set
+- movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jnz sc_20 # Not end of string
+- clrl %esi # Return Null
+-sc_fo: movl %esi,%eax # Char found here
+- movl %edx,%edi # Restore
+- popl %esi
+- ret
+-.strcont_end:
+- .size strcont,.strcont_end-strcont
+-
+- # Find end of string
+- # Arg: str
+- # ret: Pointer to end null
+-
+-.globl strend
+- .type strend,@function
+-strend:
+- movl %edi,%edx # Save
+- movl 4(%esp),%edi # str
+- clrl %eax # Find end of string
+- movl %eax,%ecx
+- decl %ecx # ECX = -1
+- repne
+- scasb
+- movl %edi,%eax
+- decl %eax # End of string
+- movl %edx,%edi # Restore
+- ret
+-.strend_end:
+- .size strend,.strend_end-strend
+-
+- # Make a string with len fill-chars and endnull
+- # Args: dest,len,fill
+- # Ret: dest+len
+-
+-.globl strfill
+- .type strfill,@function
+-strfill:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- movzb 16(%esp),%eax # Fill
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+- movb %cl,(%edi) # End NULL
+- movl %edi,%eax # End i %eax
+- popl %edi
+- ret
+-.strfill_end:
+- .size strfill,.strfill_end-strfill
+-
+-
+- # Find a char in or end of a string
+- # Arg: str,char
+- # Ret: pointer to found char or NullS
+-
+-.globl strcend
+- .type strcend,@function
+-strcend:
+- movl %edi,%edx
+- movl 4(%esp),%edi # str
+- movb 8(%esp),%ah # search
+- clrb %al # for scasb to find end
+-
+-se_10: cmpb (%edi),%ah
+- jz se_20 # Found char
+- scasb
+- jnz se_10 # Not end
+- dec %edi # Not found, point at end of string
+-se_20: movl %edi,%eax
+- movl %edx,%edi # Restore
+- ret
+-.strcend_end:
+- .size strcend,.strcend_end-strcend
+-
+- # Test if string has a given suffix
+-
+-.globl is_prefix
+- .type is_prefix,@function
+-is_prefix:
+- movl %edi,%edx # Save %edi
+- pushl %esi # and %esi
+- movl 12(%esp),%esi # get suffix
+- movl 8(%esp),%edi # s1
+- movl $1,%eax # Ok and zero-test
+-ip_10: cmpb (%esi),%ah
+- jz suf_ok # End of string/ found suffix
+- cmpsb # Compare strings
+- jz ip_10 # Same, possible prefix
+- xor %eax,%eax # Not suffix
+-suf_ok: popl %esi
+- movl %edx,%edi
+- ret
+-.is_prefix_end:
+- .size is_prefix,.is_prefix_end-is_prefix
+-
+- # Find a substring in string
+- # Arg: str,search
+-
+-.globl strstr
+- .type strstr,@function
+-
+-strstr:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%esi # str
+- movl 16(%esp),%edi # search
+- movl %edi,%ecx
+- incl %ecx # %ecx = search+1
+- movb (%edi),%ah # %ah = First char in search
+- jmp sf_10
+-
+-sf_00: movl %edx,%esi # si = Current str-pos
+-sf_10: movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jz sf_90 # End of string, didn't find search
+- incl %esi
+- cmpb %al,%ah
+- jnz sf_10 # Didn't find first char, continue
+- movl %esi,%edx # Save str-pos in %edx
+- movl %ecx,%edi
+-sf_20: cmpb $0,(%edi)
+- jz sf_fo # Found substring
+- cmpsb
+- jz sf_20 # Char ok
+- jmp sf_00 # Next str-pos
+-
+-sf_90: movl $1,%edx # Return Null
+-sf_fo: movl %edx,%eax # Char found here
+- decl %eax # Pointed one after
+- popl %esi
+- popl %edi
+- ret
+-.strstr_end:
+- .size strstr,.strstr_end-strstr
+-
+-
+- # Find a substring in string, return index
+- # Arg: str,search
+-
+-.globl strinstr
+- .type strinstr,@function
+-
+-strinstr:
+- pushl %ebp
+- movl %esp,%ebp
+- pushl 12(%ebp) # search
+- pushl 8(%ebp) # str
+- call strstr
+- add $8,%esp
+- or %eax,%eax
+- jz si_99 # Not found, return NULL
+- sub 8(%ebp),%eax # Pos from start
+- inc %eax # And first pos = 1
+-si_99: popl %ebp
+- ret
+-.strinstr_end:
+- .size strinstr,.strinstr_end-strinstr
+-
+- # Make a string of len length from another string
+- # Arg: dst,src,length
+- # ret: end of dst
+-
+-.globl strmake
+- .type strmake,@function
+-
+-strmake:
+- pushl %edi
+- pushl %esi
+- mov 12(%esp),%edi # dst
+- movl $0,%edx
+- movl 20(%esp),%ecx # length
+- movl 16(%esp),%esi # src
+- cmpl %edx,%ecx
+- jz sm_90
+-sm_00: movb (%esi,%edx),%al
+- cmpb $0,%al
+- jz sm_90
+- movb %al,(%edi,%edx)
+- incl %edx
+- cmpl %edx,%ecx
+- jnz sm_00
+-sm_90: movb $0,(%edi,%edx)
+-sm_99: lea (%edi,%edx),%eax # Return pointer to end null
+- pop %esi
+- pop %edi
+- ret
+-.strmake_end:
+- .size strmake,.strmake_end-strmake
+-
+- # Move a string with max len chars
+- # arg: dst,src,len
+- # ret: pos to first null or dst+len
+-
+-.globl strnmov
+- .type strnmov,@function
+-strnmov:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%edi # dst
+- movl 16(%esp),%esi # src
+- movl 20(%esp),%ecx # Length of memory-area
+- jecxz snm_99 # Nothing to do
+- clrb %al # For test of end-null
+-
+-snm_10: cmpb (%esi),%al # Next char to move
+- movsb # move arg
+- jz snm_20 # last char, fill with null
+- loop snm_10 # Continue moving
+- incl %edi # Point two after last
+-snm_20: decl %edi # Point at first null (or last+1)
+-snm_99: movl %edi,%eax # Pointer at last char
+- popl %esi
+- popl %edi
+- ret
+-.strnmov_end:
+- .size strnmov,.strnmov_end-strnmov
+-
+-
+-.globl strmov
+- .type strmov,@function
+-strmov:
+- movl %esi,%ecx # Save old %esi and %edi
+- movl %edi,%edx
+- movl 8(%esp),%esi # get source pointer (s2)
+- movl 4(%esp),%edi # %edi -> s1
+-smo_10: movb (%esi),%al
+- movsb # move arg
+- andb %al,%al
+- jnz smo_10 # Not last
+- movl %edi,%eax
+- dec %eax
+- movl %ecx,%esi # Restore
+- movl %edx,%edi
+- ret
+-.strmov_end:
+- .size strmov,.strmov_end-strmov
+-
+-.globl strxmov
+- .type strxmov,@function
+-strxmov:
+- movl %ebx,%edx # Save %ebx, %esi and %edi
+- mov %esi,%ecx
+- push %edi
+- leal 8(%esp),%ebx # Get destination
+- movl (%ebx),%edi
+- xorb %al,%al
+- jmp next_str # Handle source ebx+4
+-
+-start_str:
+- movsb
+- cmpb -1(%edi),%al
+- jne start_str
+- decl %edi # Don't copy last null
+-
+-next_str:
+- addl $4,%ebx
+- movl (%ebx),%esi
+- orl %esi,%esi
+- jne start_str
+- movb %al,0(%edi) # Force last to ASCII 0
+-
+- movl %edi,%eax # Return ptr to ASCII 0
+- pop %edi # Restore registers
+- movl %ecx,%esi
+- movl %edx,%ebx
+- ret
+-.strxmov_end:
+- .size strxmov,.strxmov_end-strxmov
+diff -Nuar --exclude '*.orig' mysql.orig//strings/strings-x86.S mysql//strings/strings-x86.S
+--- mysql.orig//strings/strings-x86.S 1970-01-01 00:00:00.000000000 +0000
++++ mysql//strings/strings-x86.S 2011-04-17 22:35:39.806527767 +0000
+@@ -0,0 +1,442 @@
++# Copyright (C) 2000 MySQL AB
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; version 2 of the License.
++#
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++# GNU General Public License for more details.
++#
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
++
++# Optimized string functions Intel 80x86 (gcc/gas syntax)
++
++ .file "strings.S"
++ .version "1.01"
++
++.text
++
++# Move a alligned, not overlapped, by (long) divided memory area
++# Args: to,from,length
++
++.globl bmove_align
++ .type bmove_align,@function
++bmove_align:
++ movl %edi,%edx
++ push %esi
++ movl 4(%esp),%edi # to
++ movl 8(%esp),%esi # from
++ movl 12(%esp),%ecx # length
++ addw $3,%cx # fix if not divisible with long
++ shrw $2,%cx
++ jz .ba_20
++ .p2align 4,,7
++.ba_10:
++ movl -4(%esi,%ecx),%eax
++ movl %eax,-4(%edi,%ecx)
++ decl %ecx
++ jnz .ba_10
++.ba_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_align_end:
++ .size bmove_align,.bmove_align_end-bmove_align
++
++ # Move a string from higher to lower
++ # Arg from_end+1,to_end+1,length
++
++.globl bmove_upp
++ .type bmove_upp,@function
++bmove_upp:
++ movl %edi,%edx # Remember %edi
++ push %esi
++ movl 8(%esp),%edi # dst
++ movl 16(%esp),%ecx # length
++ movl 12(%esp),%esi # source
++ test %ecx,%ecx
++ jz .bu_20
++ subl %ecx,%esi # To start of strings
++ subl %ecx,%edi
++
++ .p2align 4,,7
++.bu_10: movb -1(%esi,%ecx),%al
++ movb %al,-1(%edi,%ecx)
++ decl %ecx
++ jnz .bu_10
++.bu_20: pop %esi
++ movl %edx,%edi
++ ret
++
++.bmove_upp_end:
++ .size bmove_upp,.bmove_upp_end-bmove_upp
++
++ # Append fillchars to string
++ # Args: dest,len,fill
++
++.globl strappend
++ .type strappend,@function
++strappend:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ clrl %eax # Find end of string
++ repne
++ scasb
++ jnz sa_99 # String to long, shorten it
++ movzb 16(%esp),%eax # Fillchar
++ decl %edi # Point at end null
++ incl %ecx # rep made one dec for null-char
++
++ movb %al,%ah # (2) Set up a 32 bit pattern.
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++sa_99: movb $0,(%edi) # End of string
++ popl %edi
++ ret
++.strappend_end:
++ .size strappend,.strappend_end-strappend
++
++ # Find if string contains any char in another string
++ # Arg: str,set
++ # Ret: Pointer to first found char in str
++
++.globl strcont
++ .type strcont,@function
++strcont:
++ movl %edi,%edx
++ pushl %esi
++ movl 8(%esp),%esi # str
++ movl 12(%esp),%ecx # set
++ clrb %ah # For endtest
++ jmp sc_60
++
++sc_10: scasb
++ jz sc_fo # Found char
++sc_20: cmp (%edi),%ah # Test if null
++ jnz sc_10 # Not end of set yet
++ incl %esi # Next char in str
++sc_60: movl %ecx,%edi # %edi = Set
++ movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jnz sc_20 # Not end of string
++ clrl %esi # Return Null
++sc_fo: movl %esi,%eax # Char found here
++ movl %edx,%edi # Restore
++ popl %esi
++ ret
++.strcont_end:
++ .size strcont,.strcont_end-strcont
++
++ # Find end of string
++ # Arg: str
++ # ret: Pointer to end null
++
++.globl strend
++ .type strend,@function
++strend:
++ movl %edi,%edx # Save
++ movl 4(%esp),%edi # str
++ clrl %eax # Find end of string
++ movl %eax,%ecx
++ decl %ecx # ECX = -1
++ repne
++ scasb
++ movl %edi,%eax
++ decl %eax # End of string
++ movl %edx,%edi # Restore
++ ret
++.strend_end:
++ .size strend,.strend_end-strend
++
++ # Make a string with len fill-chars and endnull
++ # Args: dest,len,fill
++ # Ret: dest+len
++
++.globl strfill
++ .type strfill,@function
++strfill:
++ pushl %edi
++ movl 8(%esp),%edi # Memory pointer
++ movl 12(%esp),%ecx # Length
++ movzb 16(%esp),%eax # Fill
++
++ movb %al,%ah # (2) Set up a 32 bit pattern
++ movw %ax,%dx # (2)
++ shll $16,%eax # (3)
++ movw %dx,%ax # (2) %eax has the 32 bit pattern.
++
++ movl %ecx,%edx # (2) Save the count of bytes.
++ shrl $2,%ecx # (2) Number of dwords.
++ rep
++ stosl # (5 + 5n)
++ movb $3,%cl # (2)
++ and %edx,%ecx # (2) Fill in the odd bytes
++ rep
++ stosb # Move last bytes if any
++
++ movb %cl,(%edi) # End NULL
++ movl %edi,%eax # End i %eax
++ popl %edi
++ ret
++.strfill_end:
++ .size strfill,.strfill_end-strfill
++
++
++ # Find a char in or end of a string
++ # Arg: str,char
++ # Ret: pointer to found char or NullS
++
++.globl strcend
++ .type strcend,@function
++strcend:
++ movl %edi,%edx
++ movl 4(%esp),%edi # str
++ movb 8(%esp),%ah # search
++ clrb %al # for scasb to find end
++
++se_10: cmpb (%edi),%ah
++ jz se_20 # Found char
++ scasb
++ jnz se_10 # Not end
++ dec %edi # Not found, point at end of string
++se_20: movl %edi,%eax
++ movl %edx,%edi # Restore
++ ret
++.strcend_end:
++ .size strcend,.strcend_end-strcend
++
++ # Test if string has a given suffix
++
++.globl is_prefix
++ .type is_prefix,@function
++is_prefix:
++ movl %edi,%edx # Save %edi
++ pushl %esi # and %esi
++ movl 12(%esp),%esi # get suffix
++ movl 8(%esp),%edi # s1
++ movl $1,%eax # Ok and zero-test
++ip_10: cmpb (%esi),%ah
++ jz suf_ok # End of string/ found suffix
++ cmpsb # Compare strings
++ jz ip_10 # Same, possible prefix
++ xor %eax,%eax # Not suffix
++suf_ok: popl %esi
++ movl %edx,%edi
++ ret
++.is_prefix_end:
++ .size is_prefix,.is_prefix_end-is_prefix
++
++ # Find a substring in string
++ # Arg: str,search
++
++.globl strstr
++ .type strstr,@function
++
++strstr:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%esi # str
++ movl 16(%esp),%edi # search
++ movl %edi,%ecx
++ incl %ecx # %ecx = search+1
++ movb (%edi),%ah # %ah = First char in search
++ jmp sf_10
++
++sf_00: movl %edx,%esi # si = Current str-pos
++sf_10: movb (%esi),%al # Test if this char exist
++ andb %al,%al
++ jz sf_90 # End of string, didn't find search
++ incl %esi
++ cmpb %al,%ah
++ jnz sf_10 # Didn't find first char, continue
++ movl %esi,%edx # Save str-pos in %edx
++ movl %ecx,%edi
++sf_20: cmpb $0,(%edi)
++ jz sf_fo # Found substring
++ cmpsb
++ jz sf_20 # Char ok
++ jmp sf_00 # Next str-pos
++
++sf_90: movl $1,%edx # Return Null
++sf_fo: movl %edx,%eax # Char found here
++ decl %eax # Pointed one after
++ popl %esi
++ popl %edi
++ ret
++.strstr_end:
++ .size strstr,.strstr_end-strstr
++
++
++ # Find a substring in string, return index
++ # Arg: str,search
++
++.globl strinstr
++ .type strinstr,@function
++
++strinstr:
++ pushl %ebp
++ movl %esp,%ebp
++#ifdef __PIC__
++# undef __i686 /* gcc define gets in our way */
++ pushl %ebx
++ call __i686.get_pc_thunk.bx
++ addl $_GLOBAL_OFFSET_TABLE_, %ebx
++#endif
++ pushl 12(%ebp) # search
++ pushl 8(%ebp) # str
++#ifdef __PIC__
++ call strstr@PLT /*We need to be sure that ebx point to the got*/
++#else
++ call strstr
++#endif
++ add $8,%esp
++ or %eax,%eax
++ jz si_99 # Not found, return NULL
++ sub 8(%ebp),%eax # Pos from start
++ inc %eax # And first pos = 1
++si_99:
++#ifdef __PIC__
++ popl %ebx
++#endif
++ popl %ebp
++ ret
++.strinstr_end:
++ .size strinstr,.strinstr_end-strinstr
++
++ # Make a string of len length from another string
++ # Arg: dst,src,length
++ # ret: end of dst
++
++.globl strmake
++ .type strmake,@function
++
++strmake:
++ pushl %edi
++ pushl %esi
++ mov 12(%esp),%edi # dst
++ movl $0,%edx
++ movl 20(%esp),%ecx # length
++ movl 16(%esp),%esi # src
++ cmpl %edx,%ecx
++ jz sm_90
++sm_00: movb (%esi,%edx),%al
++ cmpb $0,%al
++ jz sm_90
++ movb %al,(%edi,%edx)
++ incl %edx
++ cmpl %edx,%ecx
++ jnz sm_00
++sm_90: movb $0,(%edi,%edx)
++sm_99: lea (%edi,%edx),%eax # Return pointer to end null
++ pop %esi
++ pop %edi
++ ret
++.strmake_end:
++ .size strmake,.strmake_end-strmake
++
++ # Move a string with max len chars
++ # arg: dst,src,len
++ # ret: pos to first null or dst+len
++
++.globl strnmov
++ .type strnmov,@function
++strnmov:
++ pushl %edi
++ pushl %esi
++ movl 12(%esp),%edi # dst
++ movl 16(%esp),%esi # src
++ movl 20(%esp),%ecx # Length of memory-area
++ jecxz snm_99 # Nothing to do
++ clrb %al # For test of end-null
++
++snm_10: cmpb (%esi),%al # Next char to move
++ movsb # move arg
++ jz snm_20 # last char, fill with null
++ loop snm_10 # Continue moving
++ incl %edi # Point two after last
++snm_20: decl %edi # Point at first null (or last+1)
++snm_99: movl %edi,%eax # Pointer at last char
++ popl %esi
++ popl %edi
++ ret
++.strnmov_end:
++ .size strnmov,.strnmov_end-strnmov
++
++
++.globl strmov
++ .type strmov,@function
++strmov:
++ movl %esi,%ecx # Save old %esi and %edi
++ movl %edi,%edx
++ movl 8(%esp),%esi # get source pointer (s2)
++ movl 4(%esp),%edi # %edi -> s1
++smo_10: movb (%esi),%al
++ movsb # move arg
++ andb %al,%al
++ jnz smo_10 # Not last
++ movl %edi,%eax
++ dec %eax
++ movl %ecx,%esi # Restore
++ movl %edx,%edi
++ ret
++.strmov_end:
++ .size strmov,.strmov_end-strmov
++
++.globl strxmov
++ .type strxmov,@function
++strxmov:
++ movl %ebx,%edx # Save %ebx, %esi and %edi
++ mov %esi,%ecx
++ push %edi
++ leal 8(%esp),%ebx # Get destination
++ movl (%ebx),%edi
++ xorb %al,%al
++ jmp next_str # Handle source ebx+4
++
++start_str:
++ movsb
++ cmpb -1(%edi),%al
++ jne start_str
++ decl %edi # Don't copy last null
++
++next_str:
++ addl $4,%ebx
++ movl (%ebx),%esi
++ orl %esi,%esi
++ jne start_str
++ movb %al,0(%edi) # Force last to ASCII 0
++
++ movl %edi,%eax # Return ptr to ASCII 0
++ pop %edi # Restore registers
++ movl %ecx,%esi
++ movl %edx,%ebx
++ ret
++.strxmov_end:
++ .size strxmov,.strxmov_end-strxmov
++
++#ifdef __PIC__
++ .section .gnu.linkonce.t.__i686.get_pc_thunk.bx,"ax",@progbits
++ .globl __i686.get_pc_thunk.bx
++ .hidden __i686.get_pc_thunk.bx
++ .type __i686.get_pc_thunk.bx,@function
++__i686.get_pc_thunk.bx:
++ movl (%esp), %ebx
++ ret
++#endif
++ .section .note.GNU-stack,"",@progbits
++
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-26 9:15 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-26 9:15 UTC (permalink / raw
To: gentoo-commits
commit: c2ea737a926b3e6070a739ba42c810f5b3d21ca7
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 26 09:15:45 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Apr 26 09:15:45 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c2ea737a
Fix typos in patch naming
---
00000_index.txt | 2 +-
...341_all_mysql-5.1.56_hardened_x86_strings.patch | 0
2 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index c44b661..9a4b2ce 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -226,7 +226,7 @@
@pn mysql
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-@patch 01050_all_mariadb_config_cleanup-5.1.41.patch
+@patch 01050_all_mariadb_mysql_config_cleanup-5.1.41.patch
@ver 5.01.39.00 to 5.01.99.99
@pn mariadb
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
diff --git a/07341_all_mysql-5.1.56-hardened_x86_strings.patch b/07341_all_mysql-5.1.56_hardened_x86_strings.patch
similarity index 100%
rename from 07341_all_mysql-5.1.56-hardened_x86_strings.patch
rename to 07341_all_mysql-5.1.56_hardened_x86_strings.patch
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-26 9:23 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-26 9:23 UTC (permalink / raw
To: gentoo-commits
commit: 6e9e461ef3fd1917a0bd9cf54c5c2d668e20acdb
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 26 09:23:44 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Apr 26 09:23:44 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=6e9e461e
Bug #364451 cleanup of strings patching.
---
00000_index.txt | 11 ++++++++++-
00350_x86_asm-pic-fixes-5.1.56.patch | 20 ++++++++++++++++++++
2 files changed, 30 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 9a4b2ce..4f13f3d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -101,7 +101,16 @@
@@ _many_ thanks to pageexec@freemail.hu
@patch 00350_x86_asm-pic-fixes-5.1.41.patch
-@ver 5.01.39.00 to 5.01.99.99
+@ver 5.01.39.00 to 5.01.55.99
+@pn mysql
+@pn mariadb
+@@ remove page relocations
+@@ Most of the original patch has already been accepted by MysQL,
+@@ here is the remaining.
+@@ _many_ thanks to pageexec@freemail.hu
+
+@patch 00350_x86_asm-pic-fixes-5.1.41.patch
+@ver 5.01.56.00 to 5.01.99.99
@pn mysql
@pn mariadb
@@ remove page relocations
diff --git a/00350_x86_asm-pic-fixes-5.1.56.patch b/00350_x86_asm-pic-fixes-5.1.56.patch
new file mode 100644
index 0000000..747f140
--- /dev/null
+++ b/00350_x86_asm-pic-fixes-5.1.56.patch
@@ -0,0 +1,20 @@
+diff -Naur mysql.old/strings/longlong2str-x86.s mysql.new/strings/longlong2str-x86.s
+--- mysql.old/strings/longlong2str-x86.s 2005-08-27 22:33:11.000000000 +0200
++++ mysql.new/strings/longlong2str-x86.s 2005-09-05 18:46:04.000000000 +0200
+@@ -214,3 +214,6 @@
+
+ .L10end:
+ .size longlong10_to_str,.L10end-longlong10_to_str
++
++ .section .note.GNU-stack,"",@progbits
++
+diff -Naur mysql.old/strings/my_strtoll10-x86.s mysql.new/strings/my_strtoll10-x86.s
+--- mysql.old/strings/my_strtoll10-x86.s 2005-08-27 22:33:19.000000000 +0200
++++ mysql.new/strings/my_strtoll10-x86.s 2005-09-05 18:46:10.000000000 +0200
+@@ -416,3 +416,6 @@
+ .comm end_ptr,120,32
+ .comm error,120,32
+ .ident "Monty"
++
++ .section .note.GNU-stack,"",@progbits
++
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-26 9:48 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-26 9:48 UTC (permalink / raw
To: gentoo-commits
commit: dbe92bef0e499e7c9148a7f5d32a43075c574c94
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 26 09:48:23 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Apr 26 09:48:23 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=dbe92bef
One more patchup.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 4f13f3d..cc6549f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -109,7 +109,7 @@
@@ here is the remaining.
@@ _many_ thanks to pageexec@freemail.hu
-@patch 00350_x86_asm-pic-fixes-5.1.41.patch
+@patch 00350_x86_asm-pic-fixes-5.1.56.patch
@ver 5.01.56.00 to 5.01.99.99
@pn mysql
@pn mariadb
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-04-26 9:51 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-04-26 9:51 UTC (permalink / raw
To: gentoo-commits
commit: 0a625e604209ffa117ca42c91a70cc2f722c15c1
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 26 09:51:49 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Apr 26 09:51:49 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0a625e60
Avoiding more patch problems with case insensitive systems.
---
07341_all_mysql-5.1.56_hardened_x86_strings.patch | 420 ---------------------
1 files changed, 0 insertions(+), 420 deletions(-)
diff --git a/07341_all_mysql-5.1.56_hardened_x86_strings.patch b/07341_all_mysql-5.1.56_hardened_x86_strings.patch
index 1e25fd6..4bf44ae 100644
--- a/07341_all_mysql-5.1.56_hardened_x86_strings.patch
+++ b/07341_all_mysql-5.1.56_hardened_x86_strings.patch
@@ -87,426 +87,6 @@ diff -Nuar --exclude '*.orig' mysql.orig//strings/Makefile.in mysql//strings/Mak
longlong2str.c longlong2str-x86.s longlong2str_asm.c \
my_strtoll10.c my_strtoll10-x86.s \
strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
-diff -Nuar --exclude '*.orig' mysql.orig//strings/strings-x86.s mysql//strings/strings-x86.s
---- mysql.orig//strings/strings-x86.s 2011-02-11 19:20:41.000000000 +0000
-+++ mysql//strings/strings-x86.s 1970-01-01 00:00:00.000000000 +0000
-@@ -1,416 +0,0 @@
--# Copyright (C) 2000 MySQL AB
--# This program is free software; you can redistribute it and/or modify
--# it under the terms of the GNU General Public License as published by
--# the Free Software Foundation; version 2 of the License.
--#
--# This program is distributed in the hope that it will be useful,
--# but WITHOUT ANY WARRANTY; without even the implied warranty of
--# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--# GNU General Public License for more details.
--#
--# You should have received a copy of the GNU General Public License
--# along with this program; if not, write to the Free Software
--# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--
--# Optimized string functions Intel 80x86 (gcc/gas syntax)
--
-- .file "strings.s"
-- .version "1.00"
--
--.text
--
--# Move a alligned, not overlapped, by (long) divided memory area
--# Args: to,from,length
--
--.globl bmove_align
-- .type bmove_align,@function
--bmove_align:
-- movl %edi,%edx
-- push %esi
-- movl 4(%esp),%edi # to
-- movl 8(%esp),%esi # from
-- movl 12(%esp),%ecx # length
-- addw $3,%cx # fix if not divisible with long
-- shrw $2,%cx
-- jz .ba_20
-- .p2align 4,,7
--.ba_10:
-- movl -4(%esi,%ecx),%eax
-- movl %eax,-4(%edi,%ecx)
-- decl %ecx
-- jnz .ba_10
--.ba_20: pop %esi
-- movl %edx,%edi
-- ret
--
--.bmove_align_end:
-- .size bmove_align,.bmove_align_end-bmove_align
--
-- # Move a string from higher to lower
-- # Arg from_end+1,to_end+1,length
--
--.globl bmove_upp
-- .type bmove_upp,@function
--bmove_upp:
-- movl %edi,%edx # Remember %edi
-- push %esi
-- movl 8(%esp),%edi # dst
-- movl 16(%esp),%ecx # length
-- movl 12(%esp),%esi # source
-- test %ecx,%ecx
-- jz .bu_20
-- subl %ecx,%esi # To start of strings
-- subl %ecx,%edi
--
-- .p2align 4,,7
--.bu_10: movb -1(%esi,%ecx),%al
-- movb %al,-1(%edi,%ecx)
-- decl %ecx
-- jnz .bu_10
--.bu_20: pop %esi
-- movl %edx,%edi
-- ret
--
--.bmove_upp_end:
-- .size bmove_upp,.bmove_upp_end-bmove_upp
--
-- # Append fillchars to string
-- # Args: dest,len,fill
--
--.globl strappend
-- .type strappend,@function
--strappend:
-- pushl %edi
-- movl 8(%esp),%edi # Memory pointer
-- movl 12(%esp),%ecx # Length
-- clrl %eax # Find end of string
-- repne
-- scasb
-- jnz sa_99 # String to long, shorten it
-- movzb 16(%esp),%eax # Fillchar
-- decl %edi # Point at end null
-- incl %ecx # rep made one dec for null-char
--
-- movb %al,%ah # (2) Set up a 32 bit pattern.
-- movw %ax,%dx # (2)
-- shll $16,%eax # (3)
-- movw %dx,%ax # (2) %eax has the 32 bit pattern.
--
-- movl %ecx,%edx # (2) Save the count of bytes.
-- shrl $2,%ecx # (2) Number of dwords.
-- rep
-- stosl # (5 + 5n)
-- movb $3,%cl # (2)
-- and %edx,%ecx # (2) Fill in the odd bytes
-- rep
-- stosb # Move last bytes if any
--
--sa_99: movb $0,(%edi) # End of string
-- popl %edi
-- ret
--.strappend_end:
-- .size strappend,.strappend_end-strappend
--
-- # Find if string contains any char in another string
-- # Arg: str,set
-- # Ret: Pointer to first found char in str
--
--.globl strcont
-- .type strcont,@function
--strcont:
-- movl %edi,%edx
-- pushl %esi
-- movl 8(%esp),%esi # str
-- movl 12(%esp),%ecx # set
-- clrb %ah # For endtest
-- jmp sc_60
--
--sc_10: scasb
-- jz sc_fo # Found char
--sc_20: cmp (%edi),%ah # Test if null
-- jnz sc_10 # Not end of set yet
-- incl %esi # Next char in str
--sc_60: movl %ecx,%edi # %edi = Set
-- movb (%esi),%al # Test if this char exist
-- andb %al,%al
-- jnz sc_20 # Not end of string
-- clrl %esi # Return Null
--sc_fo: movl %esi,%eax # Char found here
-- movl %edx,%edi # Restore
-- popl %esi
-- ret
--.strcont_end:
-- .size strcont,.strcont_end-strcont
--
-- # Find end of string
-- # Arg: str
-- # ret: Pointer to end null
--
--.globl strend
-- .type strend,@function
--strend:
-- movl %edi,%edx # Save
-- movl 4(%esp),%edi # str
-- clrl %eax # Find end of string
-- movl %eax,%ecx
-- decl %ecx # ECX = -1
-- repne
-- scasb
-- movl %edi,%eax
-- decl %eax # End of string
-- movl %edx,%edi # Restore
-- ret
--.strend_end:
-- .size strend,.strend_end-strend
--
-- # Make a string with len fill-chars and endnull
-- # Args: dest,len,fill
-- # Ret: dest+len
--
--.globl strfill
-- .type strfill,@function
--strfill:
-- pushl %edi
-- movl 8(%esp),%edi # Memory pointer
-- movl 12(%esp),%ecx # Length
-- movzb 16(%esp),%eax # Fill
--
-- movb %al,%ah # (2) Set up a 32 bit pattern
-- movw %ax,%dx # (2)
-- shll $16,%eax # (3)
-- movw %dx,%ax # (2) %eax has the 32 bit pattern.
--
-- movl %ecx,%edx # (2) Save the count of bytes.
-- shrl $2,%ecx # (2) Number of dwords.
-- rep
-- stosl # (5 + 5n)
-- movb $3,%cl # (2)
-- and %edx,%ecx # (2) Fill in the odd bytes
-- rep
-- stosb # Move last bytes if any
--
-- movb %cl,(%edi) # End NULL
-- movl %edi,%eax # End i %eax
-- popl %edi
-- ret
--.strfill_end:
-- .size strfill,.strfill_end-strfill
--
--
-- # Find a char in or end of a string
-- # Arg: str,char
-- # Ret: pointer to found char or NullS
--
--.globl strcend
-- .type strcend,@function
--strcend:
-- movl %edi,%edx
-- movl 4(%esp),%edi # str
-- movb 8(%esp),%ah # search
-- clrb %al # for scasb to find end
--
--se_10: cmpb (%edi),%ah
-- jz se_20 # Found char
-- scasb
-- jnz se_10 # Not end
-- dec %edi # Not found, point at end of string
--se_20: movl %edi,%eax
-- movl %edx,%edi # Restore
-- ret
--.strcend_end:
-- .size strcend,.strcend_end-strcend
--
-- # Test if string has a given suffix
--
--.globl is_prefix
-- .type is_prefix,@function
--is_prefix:
-- movl %edi,%edx # Save %edi
-- pushl %esi # and %esi
-- movl 12(%esp),%esi # get suffix
-- movl 8(%esp),%edi # s1
-- movl $1,%eax # Ok and zero-test
--ip_10: cmpb (%esi),%ah
-- jz suf_ok # End of string/ found suffix
-- cmpsb # Compare strings
-- jz ip_10 # Same, possible prefix
-- xor %eax,%eax # Not suffix
--suf_ok: popl %esi
-- movl %edx,%edi
-- ret
--.is_prefix_end:
-- .size is_prefix,.is_prefix_end-is_prefix
--
-- # Find a substring in string
-- # Arg: str,search
--
--.globl strstr
-- .type strstr,@function
--
--strstr:
-- pushl %edi
-- pushl %esi
-- movl 12(%esp),%esi # str
-- movl 16(%esp),%edi # search
-- movl %edi,%ecx
-- incl %ecx # %ecx = search+1
-- movb (%edi),%ah # %ah = First char in search
-- jmp sf_10
--
--sf_00: movl %edx,%esi # si = Current str-pos
--sf_10: movb (%esi),%al # Test if this char exist
-- andb %al,%al
-- jz sf_90 # End of string, didn't find search
-- incl %esi
-- cmpb %al,%ah
-- jnz sf_10 # Didn't find first char, continue
-- movl %esi,%edx # Save str-pos in %edx
-- movl %ecx,%edi
--sf_20: cmpb $0,(%edi)
-- jz sf_fo # Found substring
-- cmpsb
-- jz sf_20 # Char ok
-- jmp sf_00 # Next str-pos
--
--sf_90: movl $1,%edx # Return Null
--sf_fo: movl %edx,%eax # Char found here
-- decl %eax # Pointed one after
-- popl %esi
-- popl %edi
-- ret
--.strstr_end:
-- .size strstr,.strstr_end-strstr
--
--
-- # Find a substring in string, return index
-- # Arg: str,search
--
--.globl strinstr
-- .type strinstr,@function
--
--strinstr:
-- pushl %ebp
-- movl %esp,%ebp
-- pushl 12(%ebp) # search
-- pushl 8(%ebp) # str
-- call strstr
-- add $8,%esp
-- or %eax,%eax
-- jz si_99 # Not found, return NULL
-- sub 8(%ebp),%eax # Pos from start
-- inc %eax # And first pos = 1
--si_99: popl %ebp
-- ret
--.strinstr_end:
-- .size strinstr,.strinstr_end-strinstr
--
-- # Make a string of len length from another string
-- # Arg: dst,src,length
-- # ret: end of dst
--
--.globl strmake
-- .type strmake,@function
--
--strmake:
-- pushl %edi
-- pushl %esi
-- mov 12(%esp),%edi # dst
-- movl $0,%edx
-- movl 20(%esp),%ecx # length
-- movl 16(%esp),%esi # src
-- cmpl %edx,%ecx
-- jz sm_90
--sm_00: movb (%esi,%edx),%al
-- cmpb $0,%al
-- jz sm_90
-- movb %al,(%edi,%edx)
-- incl %edx
-- cmpl %edx,%ecx
-- jnz sm_00
--sm_90: movb $0,(%edi,%edx)
--sm_99: lea (%edi,%edx),%eax # Return pointer to end null
-- pop %esi
-- pop %edi
-- ret
--.strmake_end:
-- .size strmake,.strmake_end-strmake
--
-- # Move a string with max len chars
-- # arg: dst,src,len
-- # ret: pos to first null or dst+len
--
--.globl strnmov
-- .type strnmov,@function
--strnmov:
-- pushl %edi
-- pushl %esi
-- movl 12(%esp),%edi # dst
-- movl 16(%esp),%esi # src
-- movl 20(%esp),%ecx # Length of memory-area
-- jecxz snm_99 # Nothing to do
-- clrb %al # For test of end-null
--
--snm_10: cmpb (%esi),%al # Next char to move
-- movsb # move arg
-- jz snm_20 # last char, fill with null
-- loop snm_10 # Continue moving
-- incl %edi # Point two after last
--snm_20: decl %edi # Point at first null (or last+1)
--snm_99: movl %edi,%eax # Pointer at last char
-- popl %esi
-- popl %edi
-- ret
--.strnmov_end:
-- .size strnmov,.strnmov_end-strnmov
--
--
--.globl strmov
-- .type strmov,@function
--strmov:
-- movl %esi,%ecx # Save old %esi and %edi
-- movl %edi,%edx
-- movl 8(%esp),%esi # get source pointer (s2)
-- movl 4(%esp),%edi # %edi -> s1
--smo_10: movb (%esi),%al
-- movsb # move arg
-- andb %al,%al
-- jnz smo_10 # Not last
-- movl %edi,%eax
-- dec %eax
-- movl %ecx,%esi # Restore
-- movl %edx,%edi
-- ret
--.strmov_end:
-- .size strmov,.strmov_end-strmov
--
--.globl strxmov
-- .type strxmov,@function
--strxmov:
-- movl %ebx,%edx # Save %ebx, %esi and %edi
-- mov %esi,%ecx
-- push %edi
-- leal 8(%esp),%ebx # Get destination
-- movl (%ebx),%edi
-- xorb %al,%al
-- jmp next_str # Handle source ebx+4
--
--start_str:
-- movsb
-- cmpb -1(%edi),%al
-- jne start_str
-- decl %edi # Don't copy last null
--
--next_str:
-- addl $4,%ebx
-- movl (%ebx),%esi
-- orl %esi,%esi
-- jne start_str
-- movb %al,0(%edi) # Force last to ASCII 0
--
-- movl %edi,%eax # Return ptr to ASCII 0
-- pop %edi # Restore registers
-- movl %ecx,%esi
-- movl %edx,%ebx
-- ret
--.strxmov_end:
-- .size strxmov,.strxmov_end-strxmov
diff -Nuar --exclude '*.orig' mysql.orig//strings/strings-x86.S mysql//strings/strings-x86.S
--- mysql.orig//strings/strings-x86.S 1970-01-01 00:00:00.000000000 +0000
+++ mysql//strings/strings-x86.S 2011-04-17 22:35:39.806527767 +0000
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-05-10 18:05 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-05-10 18:05 UTC (permalink / raw
To: gentoo-commits
commit: 950710a56e02503b2e08400853d4365f4a297dea
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Tue May 10 18:00:36 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Tue May 10 18:00:36 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=950710a5
Updated the 07110_all_mysql_gcc-4.2 patch for mysql-5.1.57.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.57.patch |70130 ++++++++++++++++++++++++++++++++++
2 files changed, 70137 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index cc6549f..a65a9c9 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -523,7 +523,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.56.patch
-@ver 5.01.56.00 to 5.01.99.99
+@ver 5.01.56.00 to 5.01.56.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.57.patch
+@ver 5.01.57.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.57.patch b/07110_all_mysql_gcc-4.2_5.1.57.patch
new file mode 100644
index 0000000..7265c94
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.57.patch
@@ -0,0 +1,70130 @@
+diff -urN mysql-old/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql-old/client/mysqlbinlog.cc 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/mysqlbinlog.cc 2011-05-10 17:56:01.266682376 +0000
+@@ -1953,7 +1953,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -urN mysql-old/client/mysql.cc mysql/client/mysql.cc
+--- mysql-old/client/mysql.cc 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/mysql.cc 2011-05-10 17:56:01.270015709 +0000
+@@ -3336,9 +3336,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3358,7 +3358,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -urN mysql-old/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql-old/client/mysqldump.c 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/mysqldump.c 2011-05-10 17:56:01.273349042 +0000
+@@ -830,7 +830,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4523,7 +4523,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -urN mysql-old/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql-old/client/mysqltest.cc 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/mysqltest.cc 2011-05-10 17:56:01.293349043 +0000
+@@ -5652,9 +5652,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -urN mysql-old/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql-old/client/mysql_upgrade.c 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/mysql_upgrade.c 2011-05-10 17:56:01.296682376 +0000
+@@ -528,7 +528,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -urN mysql-old/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql-old/client/sql_string.cc 2011-05-10 17:45:45.693349043 +0000
++++ mysql/client/sql_string.cc 2011-05-10 17:56:01.296682376 +0000
+@@ -660,7 +660,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -746,7 +746,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -763,7 +763,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -urN mysql-old/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql-old/dbug/dbug.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/dbug/dbug.c 2011-05-10 17:56:01.296682376 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -urN mysql-old/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql-old/extra/yassl/src/ssl.cpp 2011-05-10 17:45:45.696682376 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2011-05-10 17:56:01.300015709 +0000
+@@ -38,6 +38,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -113,7 +114,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -urN mysql-old/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-old/extra/yassl/taocrypt/include/pwdbased.hpp 2011-05-10 17:45:45.696682376 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2011-05-10 17:56:01.300015709 +0000
+@@ -67,7 +67,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -urN mysql-old/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-old/extra/yassl/taocrypt/src/dh.cpp 2011-05-10 17:45:45.696682376 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2011-05-10 17:56:01.300015709 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -urN mysql-old/include/my_global.h mysql/include/my_global.h
+--- mysql-old/include/my_global.h 2011-05-10 17:45:45.726682376 +0000
++++ mysql/include/my_global.h 2011-05-10 17:56:01.300015709 +0000
+@@ -584,10 +584,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+@@ -1535,6 +1533,8 @@
+ /* Define some useful general macros (should be done after all headers). */
+ #if !defined(max)
+ #define max(a, b) ((a) > (b) ? (a) : (b))
++#endif
++#if !defined(min)
+ #define min(a, b) ((a) < (b) ? (a) : (b))
+ #endif
+ /*
+diff -urN mysql-old/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql-old/libmysql/libmysql.c 2011-05-10 17:45:45.693349043 +0000
++++ mysql/libmysql/libmysql.c 2011-05-10 17:56:01.303349042 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -urN mysql-old/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql-old/libmysqld/lib_sql.cc 2011-05-10 17:45:45.620015710 +0000
++++ mysql/libmysqld/lib_sql.cc 2011-05-10 17:56:01.303349042 +0000
+@@ -824,7 +824,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -urN mysql-old/mysys/array.c mysql/mysys/array.c
+--- mysql-old/mysys/array.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/array.c 2011-05-10 17:56:01.306682376 +0000
+@@ -47,7 +47,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -341,7 +341,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -urN mysql-old/mysys/default.c mysql/mysys/default.c
+--- mysql-old/mysys/default.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/default.c 2011-05-10 17:56:01.306682376 +0000
+@@ -793,7 +793,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -urN mysql-old/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql-old/mysys/mf_format.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/mf_format.c 2011-05-10 17:56:01.306682376 +0000
+@@ -83,7 +83,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -urN mysql-old/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql-old/mysys/mf_iocache.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/mf_iocache.c 2011-05-10 17:56:01.306682376 +0000
+@@ -1097,7 +1097,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1256,7 +1256,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1365,7 +1365,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1399,7 +1399,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -urN mysql-old/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql-old/mysys/my_alloc.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/my_alloc.c 2011-05-10 17:56:01.310015710 +0000
+@@ -212,7 +212,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -urN mysql-old/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql-old/mysys/my_bitmap.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/my_bitmap.c 2011-05-10 17:56:01.310015710 +0000
+@@ -423,7 +423,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -urN mysql-old/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql-old/mysys/my_compress.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/my_compress.c 2011-05-10 17:56:01.310015710 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -urN mysql-old/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql-old/mysys/my_conio.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/my_conio.c 2011-05-10 17:56:01.310015710 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -urN mysql-old/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql-old/mysys/my_file.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/mysys/my_file.c 2011-05-10 17:56:01.310015710 +0000
+@@ -75,7 +75,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -97,7 +97,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -107,9 +107,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -urN mysql-old/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql-old/mysys/my_getopt.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/my_getopt.c 2011-05-10 17:56:01.310015710 +0000
+@@ -983,7 +983,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -urN mysql-old/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql-old/mysys/my_static.h 2011-05-10 17:45:45.703349042 +0000
++++ mysql/mysys/my_static.h 2011-05-10 17:56:01.310015710 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -urN mysql-old/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql-old/mysys/safemalloc.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/safemalloc.c 2011-05-10 17:56:01.313349044 +0000
+@@ -248,7 +248,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -urN mysql-old/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql-old/mysys/stacktrace.c 2011-05-10 17:45:45.700015709 +0000
++++ mysql/mysys/stacktrace.c 2011-05-10 17:56:01.313349044 +0000
+@@ -324,7 +324,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) &
+ ~(ulong) 0xFFFF);
+diff -urN mysql-old/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql-old/server-tools/instance-manager/buffer.cc 2011-05-10 17:45:45.436682376 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2011-05-10 17:56:01.313349044 +0000
+@@ -83,8 +83,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -urN mysql-old/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql-old/server-tools/instance-manager/listener.cc 2011-05-10 17:45:45.436682376 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2011-05-10 17:56:01.313349044 +0000
+@@ -103,7 +103,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -urN mysql-old/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql-old/sql/debug_sync.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/debug_sync.cc 2011-05-10 17:56:01.313349044 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -urN mysql-old/sql/field.cc mysql/sql/field.cc
+--- mysql-old/sql/field.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/field.cc 2011-05-10 17:56:01.316682377 +0000
+@@ -54,7 +54,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2072,7 +2072,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2080,7 +2080,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2505,7 +2505,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2521,7 +2521,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3091,7 +3091,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3303,7 +3303,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3520,7 +3520,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3739,7 +3739,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3980,7 +3980,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4203,7 +4203,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6440,13 +6440,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6454,7 +6454,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6712,7 +6712,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7706,7 +7706,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7866,7 +7866,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8062,7 +8062,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9109,7 +9109,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9195,7 +9195,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9323,7 +9323,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9780,7 +9780,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -urN mysql-old/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql-old/sql/filesort.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/filesort.cc 2011-05-10 17:56:01.320015710 +0000
+@@ -193,7 +193,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -215,12 +215,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+ if ((table_sort.sort_keys=
+ (uchar **) make_char_array((char **) table_sort.sort_keys,
+ param.keys, param.rec_length, MYF(0))))
+@@ -1117,7 +1117,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1380,7 +1380,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -urN mysql-old/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql-old/sql/ha_ndbcluster.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/ha_ndbcluster.cc 2011-05-10 17:56:01.323349043 +0000
+@@ -800,7 +800,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -urN mysql-old/sql/handler.h mysql/sql/handler.h
+--- mysql-old/sql/handler.h 2011-05-10 17:45:45.640015709 +0000
++++ mysql/sql/handler.h 2011-05-10 17:56:01.330015709 +0000
+@@ -1605,15 +1605,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -urN mysql-old/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql-old/sql/ha_partition.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/ha_partition.cc 2011-05-10 17:56:01.330015709 +0000
+@@ -5968,7 +5968,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -urN mysql-old/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql-old/sql/item_buff.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/item_buff.cc 2011-05-10 17:56:01.333349042 +0000
+@@ -59,7 +59,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -69,7 +69,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -urN mysql-old/sql/item.cc mysql/sql/item.cc
+--- mysql-old/sql/item.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/item.cc 2011-05-10 17:56:01.336682376 +0000
+@@ -74,7 +74,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -442,9 +442,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -750,7 +750,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5414,7 +5414,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5469,7 +5469,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7559,14 +7559,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7597,7 +7597,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7619,7 +7619,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7637,7 +7637,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -urN mysql-old/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql-old/sql/item_cmpfunc.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/item_cmpfunc.cc 2011-05-10 17:56:01.340015710 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4981,7 +4981,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -5000,7 +5000,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5121,14 +5121,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5152,14 +5152,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -urN mysql-old/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql-old/sql/item_func.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/item_func.cc 2011-05-10 17:56:01.346682377 +0000
+@@ -550,7 +550,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1144,10 +1144,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1257,9 +1257,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1307,7 +1307,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1316,7 +1316,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1330,7 +1330,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1461,8 +1461,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1981,7 +1981,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1991,7 +1991,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2008,13 +2008,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2115,7 +2115,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2990,7 +2990,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2999,7 +2999,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -urN mysql-old/sql/item_func.cc.orig mysql/sql/item_func.cc.orig
+--- mysql-old/sql/item_func.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/item_func.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,6160 @@
++/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++
++/**
++ @file
++
++ @brief
++ This file defines all numerical functions
++*/
++
++#ifdef USE_PRAGMA_IMPLEMENTATION
++#pragma implementation // gcc: Class implementation
++#endif
++
++#include "mysql_priv.h"
++#include "slave.h" // for wait_for_master_pos
++#include "rpl_mi.h"
++#include <m_ctype.h>
++#include <hash.h>
++#include <time.h>
++#include <ft_global.h>
++#include <my_bit.h>
++
++#include "sp_head.h"
++#include "sp_rcontext.h"
++#include "sp.h"
++
++#ifdef NO_EMBEDDED_ACCESS_CHECKS
++#define sp_restore_security_context(A,B) while (0) {}
++#endif
++
++bool check_reserved_words(LEX_STRING *name)
++{
++ if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
++ !my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
++ !my_strcasecmp(system_charset_info, name->str, "SESSION"))
++ return TRUE;
++ return FALSE;
++}
++
++
++/**
++ @return
++ TRUE if item is a constant
++*/
++
++bool
++eval_const_cond(COND *cond)
++{
++ return ((Item_func*) cond)->val_int() ? TRUE : FALSE;
++}
++
++
++void Item_func::set_arguments(List<Item> &list)
++{
++ allowed_arg_cols= 1;
++ arg_count=list.elements;
++ args= tmp_arg; // If 2 arguments
++ if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
++ {
++ List_iterator_fast<Item> li(list);
++ Item *item;
++ Item **save_args= args;
++
++ while ((item=li++))
++ {
++ *(save_args++)= item;
++ with_sum_func|=item->with_sum_func;
++ }
++ }
++ list.empty(); // Fields are used
++}
++
++Item_func::Item_func(List<Item> &list)
++ :allowed_arg_cols(1)
++{
++ set_arguments(list);
++}
++
++Item_func::Item_func(THD *thd, Item_func *item)
++ :Item_result_field(thd, item),
++ allowed_arg_cols(item->allowed_arg_cols),
++ arg_count(item->arg_count),
++ used_tables_cache(item->used_tables_cache),
++ not_null_tables_cache(item->not_null_tables_cache),
++ const_item_cache(item->const_item_cache)
++{
++ if (arg_count)
++ {
++ if (arg_count <=2)
++ args= tmp_arg;
++ else
++ {
++ if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
++ return;
++ }
++ memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count);
++ }
++}
++
++
++/*
++ Resolve references to table column for a function and its argument
++
++ SYNOPSIS:
++ fix_fields()
++ thd Thread object
++ ref Pointer to where this object is used. This reference
++ is used if we want to replace this object with another
++ one (for example in the summary functions).
++
++ DESCRIPTION
++ Call fix_fields() for all arguments to the function. The main intention
++ is to allow all Item_field() objects to setup pointers to the table fields.
++
++ Sets as a side effect the following class variables:
++ maybe_null Set if any argument may return NULL
++ with_sum_func Set if any of the arguments contains a sum function
++ used_tables_cache Set to union of the tables used by arguments
++
++ str_value.charset If this is a string function, set this to the
++ character set for the first argument.
++ If any argument is binary, this is set to binary
++
++ If for any item any of the defaults are wrong, then this can
++ be fixed in the fix_length_and_dec() function that is called
++ after this one or by writing a specialized fix_fields() for the
++ item.
++
++ RETURN VALUES
++ FALSE ok
++ TRUE Got error. Stored with my_error().
++*/
++
++bool
++Item_func::fix_fields(THD *thd, Item **ref)
++{
++ DBUG_ASSERT(fixed == 0);
++ Item **arg,**arg_end;
++#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
++ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
++#endif
++
++ used_tables_cache= not_null_tables_cache= 0;
++ const_item_cache=1;
++
++ /*
++ Use stack limit of STACK_MIN_SIZE * 2 since
++ on some platforms a recursive call to fix_fields
++ requires more than STACK_MIN_SIZE bytes (e.g. for
++ MIPS, it takes about 22kB to make one recursive
++ call to Item_func::fix_fields())
++ */
++ if (check_stack_overrun(thd, STACK_MIN_SIZE * 2, buff))
++ return TRUE; // Fatal error if flag is set!
++ if (arg_count)
++ { // Print purify happy
++ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
++ {
++ Item *item;
++ /*
++ We can't yet set item to *arg as fix_fields may change *arg
++ We shouldn't call fix_fields() twice, so check 'fixed' field first
++ */
++ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
++ return TRUE; /* purecov: inspected */
++ item= *arg;
++
++ if (allowed_arg_cols)
++ {
++ if (item->check_cols(allowed_arg_cols))
++ return 1;
++ }
++ else
++ {
++ /* we have to fetch allowed_arg_cols from first argument */
++ DBUG_ASSERT(arg == args); // it is first argument
++ allowed_arg_cols= item->cols();
++ DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more
++ }
++
++ if (item->maybe_null)
++ maybe_null=1;
++
++ with_sum_func= with_sum_func || item->with_sum_func;
++ used_tables_cache|= item->used_tables();
++ not_null_tables_cache|= item->not_null_tables();
++ const_item_cache&= item->const_item();
++ with_subselect|= item->with_subselect;
++ }
++ }
++ fix_length_and_dec();
++ if (thd->is_error()) // An error inside fix_length_and_dec occured
++ return TRUE;
++ fixed= 1;
++ return FALSE;
++}
++
++
++bool Item_func::walk(Item_processor processor, bool walk_subquery,
++ uchar *argument)
++{
++ if (arg_count)
++ {
++ Item **arg,**arg_end;
++ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
++ {
++ if ((*arg)->walk(processor, walk_subquery, argument))
++ return 1;
++ }
++ }
++ return (this->*processor)(argument);
++}
++
++void Item_func::traverse_cond(Cond_traverser traverser,
++ void *argument, traverse_order order)
++{
++ if (arg_count)
++ {
++ Item **arg,**arg_end;
++
++ switch (order) {
++ case(PREFIX):
++ (*traverser)(this, argument);
++ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
++ {
++ (*arg)->traverse_cond(traverser, argument, order);
++ }
++ break;
++ case (POSTFIX):
++ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
++ {
++ (*arg)->traverse_cond(traverser, argument, order);
++ }
++ (*traverser)(this, argument);
++ }
++ }
++ else
++ (*traverser)(this, argument);
++}
++
++
++/**
++ Transform an Item_func object with a transformer callback function.
++
++ The function recursively applies the transform method to each
++ argument of the Item_func node.
++ If the call of the method for an argument item returns a new item
++ the old item is substituted for a new one.
++ After this the transformer is applied to the root node
++ of the Item_func object.
++ @param transformer the transformer callback function to be applied to
++ the nodes of the tree of the object
++ @param argument parameter to be passed to the transformer
++
++ @return
++ Item returned as the result of transformation of the root node
++*/
++
++Item *Item_func::transform(Item_transformer transformer, uchar *argument)
++{
++ DBUG_ASSERT(!current_thd->is_stmt_prepare());
++
++ if (arg_count)
++ {
++ Item **arg,**arg_end;
++ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
++ {
++ Item *new_item= (*arg)->transform(transformer, argument);
++ if (!new_item)
++ return 0;
++
++ /*
++ THD::change_item_tree() should be called only if the tree was
++ really transformed, i.e. when a new item has been created.
++ Otherwise we'll be allocating a lot of unnecessary memory for
++ change records at each execution.
++ */
++ if (*arg != new_item)
++ current_thd->change_item_tree(arg, new_item);
++ }
++ }
++ return (this->*transformer)(argument);
++}
++
++
++/**
++ Compile Item_func object with a processor and a transformer
++ callback functions.
++
++ First the function applies the analyzer to the root node of
++ the Item_func object. Then if the analizer succeeeds (returns TRUE)
++ the function recursively applies the compile method to each argument
++ of the Item_func node.
++ If the call of the method for an argument item returns a new item
++ the old item is substituted for a new one.
++ After this the transformer is applied to the root node
++ of the Item_func object.
++
++ @param analyzer the analyzer callback function to be applied to the
++ nodes of the tree of the object
++ @param[in,out] arg_p parameter to be passed to the processor
++ @param transformer the transformer callback function to be applied to the
++ nodes of the tree of the object
++ @param arg_t parameter to be passed to the transformer
++
++ @return
++ Item returned as the result of transformation of the root node
++*/
++
++Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
++ Item_transformer transformer, uchar *arg_t)
++{
++ if (!(this->*analyzer)(arg_p))
++ return 0;
++ if (arg_count)
++ {
++ Item **arg,**arg_end;
++ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
++ {
++ /*
++ The same parameter value of arg_p must be passed
++ to analyze any argument of the condition formula.
++ */
++ uchar *arg_v= *arg_p;
++ Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
++ if (new_item && *arg != new_item)
++ current_thd->change_item_tree(arg, new_item);
++ }
++ }
++ return (this->*transformer)(arg_t);
++}
++
++/**
++ See comments in Item_cmp_func::split_sum_func()
++*/
++
++void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
++ List<Item> &fields)
++{
++ Item **arg, **arg_end;
++ for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
++ (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, TRUE);
++}
++
++
++void Item_func::update_used_tables()
++{
++ used_tables_cache=0;
++ const_item_cache=1;
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ args[i]->update_used_tables();
++ used_tables_cache|=args[i]->used_tables();
++ const_item_cache&=args[i]->const_item();
++ }
++}
++
++
++table_map Item_func::used_tables() const
++{
++ return used_tables_cache;
++}
++
++
++table_map Item_func::not_null_tables() const
++{
++ return not_null_tables_cache;
++}
++
++
++void Item_func::print(String *str, enum_query_type query_type)
++{
++ str->append(func_name());
++ str->append('(');
++ print_args(str, 0, query_type);
++ str->append(')');
++}
++
++
++void Item_func::print_args(String *str, uint from, enum_query_type query_type)
++{
++ for (uint i=from ; i < arg_count ; i++)
++ {
++ if (i != from)
++ str->append(',');
++ args[i]->print(str, query_type);
++ }
++}
++
++
++void Item_func::print_op(String *str, enum_query_type query_type)
++{
++ str->append('(');
++ for (uint i=0 ; i < arg_count-1 ; i++)
++ {
++ args[i]->print(str, query_type);
++ str->append(' ');
++ str->append(func_name());
++ str->append(' ');
++ }
++ args[arg_count-1]->print(str, query_type);
++ str->append(')');
++}
++
++
++bool Item_func::eq(const Item *item, bool binary_cmp) const
++{
++ /* Assume we don't have rtti */
++ if (this == item)
++ return 1;
++ if (item->type() != FUNC_ITEM)
++ return 0;
++ Item_func *item_func=(Item_func*) item;
++ Item_func::Functype func_type;
++ if ((func_type= functype()) != item_func->functype() ||
++ arg_count != item_func->arg_count ||
++ (func_type != Item_func::FUNC_SP &&
++ func_name() != item_func->func_name()) ||
++ (func_type == Item_func::FUNC_SP &&
++ my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
++ return 0;
++ for (uint i=0; i < arg_count ; i++)
++ if (!args[i]->eq(item_func->args[i], binary_cmp))
++ return 0;
++ return 1;
++}
++
++
++Field *Item_func::tmp_table_field(TABLE *table)
++{
++ Field *field= NULL;
++
++ switch (result_type()) {
++ case INT_RESULT:
++ if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
++ field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
++ else
++ field= new Field_long(max_length, maybe_null, name, unsigned_flag);
++ break;
++ case REAL_RESULT:
++ field= new Field_double(max_length, maybe_null, name, decimals);
++ break;
++ case STRING_RESULT:
++ return make_string_field(table);
++ break;
++ case DECIMAL_RESULT:
++ field= Field_new_decimal::create_from_item(this);
++ break;
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ field= 0;
++ break;
++ }
++ if (field)
++ field->init(table);
++ return field;
++}
++
++
++bool Item_func::is_expensive_processor(uchar *arg)
++{
++ return is_expensive();
++}
++
++
++my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
++{
++ DBUG_ASSERT(fixed);
++ longlong nr= val_int();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value);
++ return decimal_value;
++}
++
++
++String *Item_real_func::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ double nr= val_real();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ str->set_real(nr,decimals, &my_charset_bin);
++ return str;
++}
++
++
++my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
++{
++ DBUG_ASSERT(fixed);
++ double nr= val_real();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
++ return decimal_value;
++}
++
++
++void Item_func::fix_num_length_and_dec()
++{
++ uint fl_length= 0;
++ decimals=0;
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ set_if_bigger(decimals,args[i]->decimals);
++ set_if_bigger(fl_length, args[i]->max_length);
++ }
++ max_length=float_length(decimals);
++ if (fl_length > max_length)
++ {
++ decimals= NOT_FIXED_DEC;
++ max_length= float_length(NOT_FIXED_DEC);
++ }
++}
++
++
++void Item_func_numhybrid::fix_num_length_and_dec()
++{}
++
++
++/**
++ Set max_length/decimals of function if function is fixed point and
++ result length/precision depends on argument ones.
++*/
++
++void Item_func::count_decimal_length()
++{
++ int max_int_part= 0;
++ decimals= 0;
++ unsigned_flag= 1;
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ set_if_bigger(decimals, args[i]->decimals);
++ set_if_bigger(max_int_part, args[i]->decimal_int_part());
++ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
++ }
++ int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
++ unsigned_flag);
++}
++
++
++/**
++ Set max_length of if it is maximum length of its arguments.
++*/
++
++void Item_func::count_only_length()
++{
++ max_length= 0;
++ unsigned_flag= 0;
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ set_if_bigger(max_length, args[i]->max_length);
++ set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
++ }
++}
++
++
++/**
++ Set max_length/decimals of function if function is floating point and
++ result length/precision depends on argument ones.
++*/
++
++void Item_func::count_real_length()
++{
++ uint32 length= 0;
++ decimals= 0;
++ max_length= 0;
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ if (decimals != NOT_FIXED_DEC)
++ {
++ set_if_bigger(decimals, args[i]->decimals);
++ set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
++ }
++ set_if_bigger(max_length, args[i]->max_length);
++ }
++ if (decimals != NOT_FIXED_DEC)
++ {
++ max_length= length;
++ length+= decimals;
++ if (length < max_length) // If previous operation gave overflow
++ max_length= UINT_MAX32;
++ else
++ max_length= length;
++ }
++}
++
++
++
++void Item_func::signal_divide_by_null()
++{
++ THD *thd= current_thd;
++ if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO)
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO,
++ ER(ER_DIVISION_BY_ZERO));
++ null_value= 1;
++}
++
++
++Item *Item_func::get_tmp_table_item(THD *thd)
++{
++ if (!with_sum_func && !const_item())
++ return new Item_field(result_field);
++ return copy_or_same(thd);
++}
++
++double Item_int_func::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++
++ return unsigned_flag ? (double) ((ulonglong) val_int()) : (double) val_int();
++}
++
++
++String *Item_int_func::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong nr=val_int();
++ if (null_value)
++ return 0;
++ str->set_int(nr, unsigned_flag, &my_charset_bin);
++ return str;
++}
++
++
++void Item_func_connection_id::fix_length_and_dec()
++{
++ Item_int_func::fix_length_and_dec();
++ max_length= 10;
++}
++
++
++bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
++{
++ if (Item_int_func::fix_fields(thd, ref))
++ return TRUE;
++ thd->thread_specific_used= TRUE;
++ value= thd->variables.pseudo_thread_id;
++ return FALSE;
++}
++
++
++/**
++ Check arguments here to determine result's type for a numeric
++ function of two arguments.
++*/
++
++void Item_num_op::find_num_type(void)
++{
++ DBUG_ENTER("Item_num_op::find_num_type");
++ DBUG_PRINT("info", ("name %s", func_name()));
++ DBUG_ASSERT(arg_count == 2);
++ Item_result r0= args[0]->result_type();
++ Item_result r1= args[1]->result_type();
++
++ if (r0 == REAL_RESULT || r1 == REAL_RESULT ||
++ r0 == STRING_RESULT || r1 ==STRING_RESULT)
++ {
++ count_real_length();
++ max_length= float_length(decimals);
++ hybrid_type= REAL_RESULT;
++ }
++ else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT)
++ {
++ hybrid_type= DECIMAL_RESULT;
++ result_precision();
++ }
++ else
++ {
++ DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT);
++ decimals= 0;
++ hybrid_type=INT_RESULT;
++ result_precision();
++ }
++ DBUG_PRINT("info", ("Type: %s",
++ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
++ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
++ hybrid_type == INT_RESULT ? "INT_RESULT" :
++ "--ILLEGAL!!!--")));
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ 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)
++*/
++
++void Item_func_num1::find_num_type()
++{
++ DBUG_ENTER("Item_func_num1::find_num_type");
++ DBUG_PRINT("info", ("name %s", func_name()));
++ switch (hybrid_type= args[0]->result_type()) {
++ case INT_RESULT:
++ unsigned_flag= args[0]->unsigned_flag;
++ break;
++ case STRING_RESULT:
++ case REAL_RESULT:
++ hybrid_type= REAL_RESULT;
++ max_length= float_length(decimals);
++ break;
++ case DECIMAL_RESULT:
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ DBUG_PRINT("info", ("Type: %s",
++ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
++ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
++ hybrid_type == INT_RESULT ? "INT_RESULT" :
++ "--ILLEGAL!!!--")));
++ DBUG_VOID_RETURN;
++}
++
++
++void Item_func_num1::fix_num_length_and_dec()
++{
++ decimals= args[0]->decimals;
++ max_length= args[0]->max_length;
++}
++
++
++void Item_func_numhybrid::fix_length_and_dec()
++{
++ fix_num_length_and_dec();
++ find_num_type();
++}
++
++
++String *Item_func_numhybrid::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ switch (hybrid_type) {
++ case DECIMAL_RESULT:
++ {
++ my_decimal decimal_value, *val;
++ if (!(val= decimal_op(&decimal_value)))
++ return 0; // null is set
++ my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
++ my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
++ break;
++ }
++ case INT_RESULT:
++ {
++ longlong nr= int_op();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ str->set_int(nr, unsigned_flag, &my_charset_bin);
++ break;
++ }
++ case REAL_RESULT:
++ {
++ double nr= real_op();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ str->set_real(nr,decimals,&my_charset_bin);
++ break;
++ }
++ case STRING_RESULT:
++ return str_op(&str_value);
++ default:
++ DBUG_ASSERT(0);
++ }
++ return str;
++}
++
++
++double Item_func_numhybrid::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ switch (hybrid_type) {
++ case DECIMAL_RESULT:
++ {
++ my_decimal decimal_value, *val;
++ double result;
++ if (!(val= decimal_op(&decimal_value)))
++ return 0.0; // null is set
++ my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
++ return result;
++ }
++ case INT_RESULT:
++ {
++ longlong result= int_op();
++ return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
++ }
++ 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);
++ }
++ return 0.0;
++}
++
++
++longlong Item_func_numhybrid::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ switch (hybrid_type) {
++ case DECIMAL_RESULT:
++ {
++ my_decimal decimal_value, *val;
++ if (!(val= decimal_op(&decimal_value)))
++ return 0; // null is set
++ longlong result;
++ my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
++ return result;
++ }
++ case INT_RESULT:
++ return int_op();
++ case REAL_RESULT:
++ return (longlong) rint(real_op());
++ case STRING_RESULT:
++ {
++ int err_not_used;
++ String *res;
++ if (!(res= str_op(&str_value)))
++ return 0;
++
++ char *end= (char*) res->ptr() + res->length();
++ CHARSET_INFO *cs= res->charset();
++ return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
++ }
++ default:
++ DBUG_ASSERT(0);
++ }
++ return 0;
++}
++
++
++my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
++{
++ my_decimal *val= decimal_value;
++ DBUG_ASSERT(fixed == 1);
++ switch (hybrid_type) {
++ case DECIMAL_RESULT:
++ val= decimal_op(decimal_value);
++ break;
++ case INT_RESULT:
++ {
++ longlong result= int_op();
++ int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
++ break;
++ }
++ case REAL_RESULT:
++ {
++ double result= (double)real_op();
++ double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
++ break;
++ }
++ case STRING_RESULT:
++ {
++ String *res;
++ if (!(res= str_op(&str_value)))
++ return NULL;
++
++ str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
++ res->length(), res->charset(), decimal_value);
++ break;
++ }
++ case ROW_RESULT:
++ default:
++ DBUG_ASSERT(0);
++ }
++ return val;
++}
++
++
++void Item_func_signed::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("cast("));
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" as signed)"));
++
++}
++
++
++longlong Item_func_signed::val_int_from_str(int *error)
++{
++ char buff[MAX_FIELD_WIDTH], *end, *start;
++ uint32 length;
++ String tmp(buff,sizeof(buff), &my_charset_bin), *res;
++ longlong value;
++
++ /*
++ For a string result, we must first get the string and then convert it
++ to a longlong
++ */
++
++ if (!(res= args[0]->val_str(&tmp)))
++ {
++ null_value= 1;
++ *error= 0;
++ return 0;
++ }
++ null_value= 0;
++ start= (char *)res->ptr();
++ length= res->length();
++
++ end= start + length;
++ value= my_strtoll10(start, &end, error);
++ if (*error > 0 || end != start+ length)
++ {
++ char err_buff[128];
++ String err_tmp(err_buff,(uint32) sizeof(err_buff), system_charset_info);
++ err_tmp.copy(start, length, system_charset_info);
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_TRUNCATED_WRONG_VALUE,
++ ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
++ err_tmp.c_ptr());
++ }
++ return value;
++}
++
++
++longlong Item_func_signed::val_int()
++{
++ longlong value;
++ int error;
++
++ if (args[0]->cast_to_int_type() != STRING_RESULT ||
++ args[0]->result_as_longlong())
++ {
++ value= args[0]->val_int();
++ null_value= args[0]->null_value;
++ return value;
++ }
++
++ value= val_int_from_str(&error);
++ if (value < 0 && error == 0)
++ {
++ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
++ "Cast to signed converted positive out-of-range integer to "
++ "it's negative complement");
++ }
++ return value;
++}
++
++
++void Item_func_unsigned::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("cast("));
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" as unsigned)"));
++
++}
++
++
++longlong Item_func_unsigned::val_int()
++{
++ longlong value;
++ int error;
++
++ if (args[0]->cast_to_int_type() == DECIMAL_RESULT)
++ {
++ my_decimal tmp, *dec= args[0]->val_decimal(&tmp);
++ if (!(null_value= args[0]->null_value))
++ my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
++ else
++ value= 0;
++ return value;
++ }
++ else if (args[0]->cast_to_int_type() != STRING_RESULT ||
++ args[0]->result_as_longlong())
++ {
++ value= args[0]->val_int();
++ null_value= args[0]->null_value;
++ return value;
++ }
++
++ value= val_int_from_str(&error);
++ if (error < 0)
++ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
++ "Cast to unsigned converted negative integer to it's "
++ "positive complement");
++ return value;
++}
++
++
++String *Item_decimal_typecast::val_str(String *str)
++{
++ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
++ if (null_value)
++ return NULL;
++ my_decimal2string(E_DEC_FATAL_ERROR, tmp, 0, 0, 0, str);
++ return str;
++}
++
++
++double Item_decimal_typecast::val_real()
++{
++ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
++ double res;
++ if (null_value)
++ return 0.0;
++ my_decimal2double(E_DEC_FATAL_ERROR, tmp, &res);
++ return res;
++}
++
++
++longlong Item_decimal_typecast::val_int()
++{
++ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
++ longlong res;
++ if (null_value)
++ return 0;
++ my_decimal2int(E_DEC_FATAL_ERROR, tmp, unsigned_flag, &res);
++ return res;
++}
++
++
++my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
++{
++ my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
++ bool sign;
++ uint precision;
++
++ if ((null_value= args[0]->null_value))
++ return NULL;
++ my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
++ sign= dec->sign();
++ if (unsigned_flag)
++ {
++ if (sign)
++ {
++ my_decimal_set_zero(dec);
++ goto err;
++ }
++ }
++ precision= my_decimal_length_to_precision(max_length,
++ decimals, unsigned_flag);
++ if (precision - decimals < (uint) my_decimal_intg(dec))
++ {
++ max_my_decimal(dec, precision, decimals);
++ dec->sign(sign);
++ goto err;
++ }
++ return dec;
++
++err:
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_WARN_DATA_OUT_OF_RANGE,
++ ER(ER_WARN_DATA_OUT_OF_RANGE),
++ name, 1);
++ return dec;
++}
++
++
++void Item_decimal_typecast::print(String *str, enum_query_type query_type)
++{
++ char len_buf[20*3 + 1];
++ char *end;
++
++ uint precision= my_decimal_length_to_precision(max_length, decimals,
++ unsigned_flag);
++ str->append(STRING_WITH_LEN("cast("));
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" as decimal("));
++
++ end=int10_to_str(precision, len_buf,10);
++ str->append(len_buf, (uint32) (end - len_buf));
++
++ str->append(',');
++
++ end=int10_to_str(decimals, len_buf,10);
++ str->append(len_buf, (uint32) (end - len_buf));
++
++ str->append(')');
++ str->append(')');
++}
++
++
++double Item_func_plus::real_op()
++{
++ double value= args[0]->val_real() + args[1]->val_real();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0.0;
++ return fix_result(value);
++}
++
++
++longlong Item_func_plus::int_op()
++{
++ longlong value=args[0]->val_int()+args[1]->val_int();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0;
++ return value;
++}
++
++
++/**
++ Calculate plus of two decimals.
++
++ @param decimal_value Buffer that can be used to store result
++
++ @retval
++ 0 Value was NULL; In this case null_value is set
++ @retval
++ \# Value of operation as a decimal
++*/
++
++my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal value1, *val1;
++ my_decimal value2, *val2;
++ val1= args[0]->val_decimal(&value1);
++ if ((null_value= args[0]->null_value))
++ return 0;
++ val2= args[1]->val_decimal(&value2);
++ if (!(null_value= (args[1]->null_value ||
++ (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
++ val2) > 3))))
++ return decimal_value;
++ return 0;
++}
++
++/**
++ Set precision of results for additive operations (+ and -)
++*/
++void Item_func_additive_op::result_precision()
++{
++ decimals= max(args[0]->decimals, args[1]->decimals);
++ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
++ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
++ int precision= max(arg1_int, arg2_int) + 1 + decimals;
++
++ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
++ if (result_type() == INT_RESULT)
++ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
++ else
++ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
++ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
++ unsigned_flag);
++}
++
++
++/**
++ The following function is here to allow the user to force
++ subtraction of UNSIGNED BIGINT to return negative values.
++*/
++
++void Item_func_minus::fix_length_and_dec()
++{
++ Item_num_op::fix_length_and_dec();
++ if (unsigned_flag &&
++ (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
++ unsigned_flag=0;
++}
++
++
++double Item_func_minus::real_op()
++{
++ double value= args[0]->val_real() - args[1]->val_real();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0.0;
++ return fix_result(value);
++}
++
++
++longlong Item_func_minus::int_op()
++{
++ longlong value=args[0]->val_int() - args[1]->val_int();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0;
++ return value;
++}
++
++
++/**
++ See Item_func_plus::decimal_op for comments.
++*/
++
++my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal value1, *val1;
++ my_decimal value2, *val2=
++
++ val1= args[0]->val_decimal(&value1);
++ if ((null_value= args[0]->null_value))
++ return 0;
++ val2= args[1]->val_decimal(&value2);
++ if (!(null_value= (args[1]->null_value ||
++ (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
++ val2) > 3))))
++ return decimal_value;
++ return 0;
++}
++
++
++double Item_func_mul::real_op()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real() * args[1]->val_real();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0.0;
++ return fix_result(value);
++}
++
++
++longlong Item_func_mul::int_op()
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong value=args[0]->val_int()*args[1]->val_int();
++ if ((null_value=args[0]->null_value || args[1]->null_value))
++ return 0;
++ return value;
++}
++
++
++/** See Item_func_plus::decimal_op for comments. */
++
++my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal value1, *val1;
++ my_decimal value2, *val2;
++ val1= args[0]->val_decimal(&value1);
++ if ((null_value= args[0]->null_value))
++ return 0;
++ val2= args[1]->val_decimal(&value2);
++ if (!(null_value= (args[1]->null_value ||
++ (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
++ val2) > 3))))
++ return decimal_value;
++ return 0;
++}
++
++
++void Item_func_mul::result_precision()
++{
++ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
++ if (result_type() == INT_RESULT)
++ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
++ else
++ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
++ decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
++ uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
++ unsigned_flag);
++}
++
++
++double Item_func_div::real_op()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ double val2= args[1]->val_real();
++ if ((null_value= args[0]->null_value || args[1]->null_value))
++ return 0.0;
++ if (val2 == 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return fix_result(value/val2);
++}
++
++
++my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal value1, *val1;
++ my_decimal value2, *val2;
++ int err;
++
++ val1= args[0]->val_decimal(&value1);
++ if ((null_value= args[0]->null_value))
++ return 0;
++ val2= args[1]->val_decimal(&value2);
++ if ((null_value= args[1]->null_value))
++ return 0;
++ if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
++ val1, val2, prec_increment)) > 3)
++ {
++ if (err == E_DEC_DIV_ZERO)
++ signal_divide_by_null();
++ null_value= 1;
++ return 0;
++ }
++ return decimal_value;
++}
++
++
++void Item_func_div::result_precision()
++{
++ uint precision=min(args[0]->decimal_precision() +
++ args[1]->decimals + prec_increment,
++ DECIMAL_MAX_PRECISION);
++
++ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
++ if (result_type() == INT_RESULT)
++ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
++ else
++ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
++ decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
++ unsigned_flag);
++}
++
++
++void Item_func_div::fix_length_and_dec()
++{
++ DBUG_ENTER("Item_func_div::fix_length_and_dec");
++ prec_increment= current_thd->variables.div_precincrement;
++ Item_num_op::fix_length_and_dec();
++ switch(hybrid_type) {
++ case REAL_RESULT:
++ {
++ decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ set_if_smaller(decimals, NOT_FIXED_DEC);
++ uint tmp=float_length(decimals);
++ if (decimals == NOT_FIXED_DEC)
++ max_length= tmp;
++ else
++ {
++ max_length=args[0]->max_length - args[0]->decimals + decimals;
++ set_if_smaller(max_length,tmp);
++ }
++ break;
++ }
++ case INT_RESULT:
++ hybrid_type= DECIMAL_RESULT;
++ DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
++ result_precision();
++ break;
++ case DECIMAL_RESULT:
++ result_precision();
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ maybe_null= 1; // devision by zero
++ DBUG_VOID_RETURN;
++}
++
++
++/* Integer division */
++longlong Item_func_int_div::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong value=args[0]->val_int();
++ longlong val2=args[1]->val_int();
++ if ((null_value= (args[0]->null_value || args[1]->null_value)))
++ return 0;
++ if (val2 == 0)
++ {
++ signal_divide_by_null();
++ return 0;
++ }
++
++ if (unsigned_flag)
++ return ((ulonglong) value / (ulonglong) val2);
++ else if (value == LONGLONG_MIN && val2 == -1)
++ return LONGLONG_MIN;
++ else
++ return value / val2;
++}
++
++
++void Item_func_int_div::fix_length_and_dec()
++{
++ Item_result argtype= args[0]->result_type();
++ /* use precision ony for the data type it is applicable for and valid */
++ max_length=args[0]->max_length -
++ (argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
++ args[0]->decimals : 0);
++ maybe_null=1;
++ unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
++}
++
++
++longlong Item_func_mod::int_op()
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong value= args[0]->val_int();
++ longlong val2= args[1]->val_int();
++ longlong result;
++
++ if ((null_value= args[0]->null_value || args[1]->null_value))
++ return 0; /* purecov: inspected */
++ if (val2 == 0)
++ {
++ signal_divide_by_null();
++ return 0;
++ }
++
++ if (args[0]->unsigned_flag)
++ result= args[1]->unsigned_flag ?
++ ((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2;
++ else result= args[1]->unsigned_flag ?
++ value % ((ulonglong) val2) :
++ (val2 == -1) ? 0 : value % val2;
++
++ return result;
++}
++
++double Item_func_mod::real_op()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ double val2= args[1]->val_real();
++ if ((null_value= args[0]->null_value || args[1]->null_value))
++ return 0.0; /* purecov: inspected */
++ if (val2 == 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return fmod(value,val2);
++}
++
++
++my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal value1, *val1;
++ my_decimal value2, *val2;
++
++ val1= args[0]->val_decimal(&value1);
++ if ((null_value= args[0]->null_value))
++ return 0;
++ val2= args[1]->val_decimal(&value2);
++ if ((null_value= args[1]->null_value))
++ return 0;
++ switch (my_decimal_mod(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
++ val1, val2)) {
++ case E_DEC_TRUNCATED:
++ case E_DEC_OK:
++ return decimal_value;
++ case E_DEC_DIV_ZERO:
++ signal_divide_by_null();
++ default:
++ null_value= 1;
++ return 0;
++ }
++}
++
++
++void Item_func_mod::result_precision()
++{
++ decimals= max(args[0]->decimals, args[1]->decimals);
++ max_length= max(args[0]->max_length, args[1]->max_length);
++}
++
++
++void Item_func_mod::fix_length_and_dec()
++{
++ Item_num_op::fix_length_and_dec();
++ maybe_null= 1;
++ unsigned_flag= args[0]->unsigned_flag;
++}
++
++
++double Item_func_neg::real_op()
++{
++ double value= args[0]->val_real();
++ null_value= args[0]->null_value;
++ return -value;
++}
++
++
++longlong Item_func_neg::int_op()
++{
++ longlong value= args[0]->val_int();
++ null_value= args[0]->null_value;
++ return -value;
++}
++
++
++my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal val, *value= args[0]->val_decimal(&val);
++ if (!(null_value= args[0]->null_value))
++ {
++ my_decimal2decimal(value, decimal_value);
++ my_decimal_neg(decimal_value);
++ return decimal_value;
++ }
++ return 0;
++}
++
++
++void Item_func_neg::fix_num_length_and_dec()
++{
++ decimals= args[0]->decimals;
++ /* 1 add because sign can appear */
++ max_length= args[0]->max_length + 1;
++}
++
++
++void Item_func_neg::fix_length_and_dec()
++{
++ DBUG_ENTER("Item_func_neg::fix_length_and_dec");
++ Item_func_num1::fix_length_and_dec();
++
++ /*
++ If this is in integer context keep the context as integer if possible
++ (This is how multiplication and other integer functions works)
++ Use val() to get value as arg_type doesn't mean that item is
++ Item_int or Item_real due to existence of Item_param.
++ */
++ if (hybrid_type == INT_RESULT && args[0]->const_item())
++ {
++ longlong val= args[0]->val_int();
++ if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
++ ((ulonglong) val != (ulonglong) LONGLONG_MIN ||
++ args[0]->type() != INT_ITEM))
++ {
++ /*
++ Ensure that result is converted to DECIMAL, as longlong can't hold
++ the negated number
++ */
++ hybrid_type= DECIMAL_RESULT;
++ DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
++ }
++ }
++ unsigned_flag= 0;
++ DBUG_VOID_RETURN;
++}
++
++
++double Item_func_abs::real_op()
++{
++ double value= args[0]->val_real();
++ null_value= args[0]->null_value;
++ return fabs(value);
++}
++
++
++longlong Item_func_abs::int_op()
++{
++ longlong value= args[0]->val_int();
++ if ((null_value= args[0]->null_value))
++ return 0;
++ return (value >= 0) || unsigned_flag ? value : -value;
++}
++
++
++my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal val, *value= args[0]->val_decimal(&val);
++ if (!(null_value= args[0]->null_value))
++ {
++ my_decimal2decimal(value, decimal_value);
++ if (decimal_value->sign())
++ my_decimal_neg(decimal_value);
++ return decimal_value;
++ }
++ return 0;
++}
++
++
++void Item_func_abs::fix_length_and_dec()
++{
++ Item_func_num1::fix_length_and_dec();
++ unsigned_flag= args[0]->unsigned_flag;
++}
++
++
++/** Gateway to natural LOG function. */
++double Item_func_ln::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value= args[0]->null_value))
++ return 0.0;
++ if (value <= 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return log(value);
++}
++
++/**
++ Extended but so slower LOG function.
++
++ We have to check if all values are > zero and first one is not one
++ as these are the cases then result is not a number.
++*/
++double Item_func_log::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value= args[0]->null_value))
++ return 0.0;
++ if (value <= 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ if (arg_count == 2)
++ {
++ double value2= args[1]->val_real();
++ if ((null_value= args[1]->null_value))
++ return 0.0;
++ if (value2 <= 0.0 || value == 1.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return log(value2) / log(value);
++ }
++ return log(value);
++}
++
++double Item_func_log2::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++
++ if ((null_value=args[0]->null_value))
++ return 0.0;
++ if (value <= 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return log(value) / M_LN2;
++}
++
++double Item_func_log10::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value= args[0]->null_value))
++ return 0.0;
++ if (value <= 0.0)
++ {
++ signal_divide_by_null();
++ return 0.0;
++ }
++ return log10(value);
++}
++
++double Item_func_exp::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0.0; /* purecov: inspected */
++ return fix_result(exp(value));
++}
++
++double Item_func_sqrt::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=(args[0]->null_value || value < 0)))
++ return 0.0; /* purecov: inspected */
++ return sqrt(value);
++}
++
++double Item_func_pow::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ double val2= args[1]->val_real();
++ if ((null_value=(args[0]->null_value || args[1]->null_value)))
++ return 0.0; /* purecov: inspected */
++ return fix_result(pow(value,val2));
++}
++
++// Trigonometric functions
++
++double Item_func_acos::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
++ volatile double value= args[0]->val_real();
++ if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
++ return 0.0;
++ return acos(value);
++}
++
++double Item_func_asin::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
++ volatile double value= args[0]->val_real();
++ if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
++ return 0.0;
++ return asin(value);
++}
++
++double Item_func_atan::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0.0;
++ if (arg_count == 2)
++ {
++ double val2= args[1]->val_real();
++ if ((null_value=args[1]->null_value))
++ return 0.0;
++ return fix_result(atan2(value,val2));
++ }
++ return atan(value);
++}
++
++double Item_func_cos::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0.0;
++ return cos(value);
++}
++
++double Item_func_sin::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0.0;
++ return sin(value);
++}
++
++double Item_func_tan::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0.0;
++ return fix_result(tan(value));
++}
++
++
++// Shift-functions, same as << and >> in C/C++
++
++
++longlong Item_func_shift_left::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ uint shift;
++ ulonglong res= ((ulonglong) args[0]->val_int() <<
++ (shift=(uint) args[1]->val_int()));
++ if (args[0]->null_value || args[1]->null_value)
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0));
++}
++
++longlong Item_func_shift_right::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ uint shift;
++ ulonglong res= (ulonglong) args[0]->val_int() >>
++ (shift=(uint) args[1]->val_int());
++ if (args[0]->null_value || args[1]->null_value)
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0));
++}
++
++
++longlong Item_func_bit_neg::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ ulonglong res= (ulonglong) args[0]->val_int();
++ if ((null_value=args[0]->null_value))
++ return 0;
++ return ~res;
++}
++
++
++// Conversion functions
++
++void Item_func_integer::fix_length_and_dec()
++{
++ max_length=args[0]->max_length - args[0]->decimals+1;
++ uint tmp=float_length(decimals);
++ set_if_smaller(max_length,tmp);
++ decimals=0;
++}
++
++void Item_func_int_val::fix_num_length_and_dec()
++{
++ ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
++ (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
++ max_length= tmp_max_length > (ulonglong) max_field_size ?
++ max_field_size : (uint32) tmp_max_length;
++ uint tmp= float_length(decimals);
++ set_if_smaller(max_length,tmp);
++ decimals= 0;
++}
++
++
++void Item_func_int_val::find_num_type()
++{
++ DBUG_ENTER("Item_func_int_val::find_num_type");
++ DBUG_PRINT("info", ("name %s", func_name()));
++ switch(hybrid_type= args[0]->result_type())
++ {
++ case STRING_RESULT:
++ case REAL_RESULT:
++ hybrid_type= REAL_RESULT;
++ max_length= float_length(decimals);
++ break;
++ case INT_RESULT:
++ case DECIMAL_RESULT:
++ /*
++ -2 because in most high position can't be used any digit for longlong
++ and one position for increasing value during operation
++ */
++ if ((args[0]->max_length - args[0]->decimals) >=
++ (DECIMAL_LONGLONG_DIGITS - 2))
++ {
++ hybrid_type= DECIMAL_RESULT;
++ }
++ else
++ {
++ unsigned_flag= args[0]->unsigned_flag;
++ hybrid_type= INT_RESULT;
++ }
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ DBUG_PRINT("info", ("Type: %s",
++ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
++ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
++ hybrid_type == INT_RESULT ? "INT_RESULT" :
++ "--ILLEGAL!!!--")));
++
++ DBUG_VOID_RETURN;
++}
++
++
++longlong Item_func_ceiling::int_op()
++{
++ longlong result;
++ switch (args[0]->result_type()) {
++ case INT_RESULT:
++ result= args[0]->val_int();
++ null_value= args[0]->null_value;
++ break;
++ case DECIMAL_RESULT:
++ {
++ my_decimal dec_buf, *dec;
++ if ((dec= Item_func_ceiling::decimal_op(&dec_buf)))
++ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
++ else
++ result= 0;
++ break;
++ }
++ default:
++ result= (longlong)Item_func_ceiling::real_op();
++ };
++ return result;
++}
++
++
++double Item_func_ceiling::real_op()
++{
++ /*
++ the volatile's for BUG #3051 to calm optimizer down (because of gcc's
++ bug)
++ */
++ volatile double value= args[0]->val_real();
++ null_value= args[0]->null_value;
++ return ceil(value);
++}
++
++
++my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal val, *value= args[0]->val_decimal(&val);
++ if (!(null_value= (args[0]->null_value ||
++ my_decimal_ceiling(E_DEC_FATAL_ERROR, value,
++ decimal_value) > 1)))
++ return decimal_value;
++ return 0;
++}
++
++
++longlong Item_func_floor::int_op()
++{
++ longlong result;
++ switch (args[0]->result_type()) {
++ case INT_RESULT:
++ result= args[0]->val_int();
++ null_value= args[0]->null_value;
++ break;
++ case DECIMAL_RESULT:
++ {
++ my_decimal dec_buf, *dec;
++ if ((dec= Item_func_floor::decimal_op(&dec_buf)))
++ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
++ else
++ result= 0;
++ break;
++ }
++ default:
++ result= (longlong)Item_func_floor::real_op();
++ };
++ return result;
++}
++
++
++double Item_func_floor::real_op()
++{
++ /*
++ the volatile's for BUG #3051 to calm optimizer down (because of gcc's
++ bug)
++ */
++ volatile double value= args[0]->val_real();
++ null_value= args[0]->null_value;
++ return floor(value);
++}
++
++
++my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal val, *value= args[0]->val_decimal(&val);
++ if (!(null_value= (args[0]->null_value ||
++ my_decimal_floor(E_DEC_FATAL_ERROR, value,
++ decimal_value) > 1)))
++ return decimal_value;
++ return 0;
++}
++
++
++void Item_func_round::fix_length_and_dec()
++{
++ int decimals_to_set;
++ longlong val1;
++ bool val1_unsigned;
++
++ unsigned_flag= args[0]->unsigned_flag;
++ if (!args[1]->const_item())
++ {
++ decimals= args[0]->decimals;
++ max_length= float_length(decimals);
++ if (args[0]->result_type() == DECIMAL_RESULT)
++ {
++ max_length++;
++ hybrid_type= DECIMAL_RESULT;
++ }
++ else
++ hybrid_type= REAL_RESULT;
++ return;
++ }
++
++ val1= args[1]->val_int();
++ val1_unsigned= args[1]->unsigned_flag;
++ if (val1 < 0)
++ decimals_to_set= val1_unsigned ? INT_MAX : 0;
++ else
++ decimals_to_set= (val1 > INT_MAX) ? INT_MAX : (int) val1;
++
++ if (args[0]->decimals == NOT_FIXED_DEC)
++ {
++ decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ max_length= float_length(decimals);
++ hybrid_type= REAL_RESULT;
++ return;
++ }
++
++ switch (args[0]->result_type()) {
++ case REAL_RESULT:
++ case STRING_RESULT:
++ hybrid_type= REAL_RESULT;
++ decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ max_length= float_length(decimals);
++ break;
++ case INT_RESULT:
++ if ((!decimals_to_set && truncate) || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS))
++ {
++ int length_can_increase= test(!truncate && (val1 < 0) && !val1_unsigned);
++ max_length= args[0]->max_length + length_can_increase;
++ /* Here we can keep INT_RESULT */
++ hybrid_type= INT_RESULT;
++ decimals= 0;
++ break;
++ }
++ /* fall through */
++ case DECIMAL_RESULT:
++ {
++ hybrid_type= DECIMAL_RESULT;
++ decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ int decimals_delta= args[0]->decimals - decimals_to_set;
++ int precision= args[0]->decimal_precision();
++ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
++
++ precision-= decimals_delta - length_increase;
++ decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ max_length= my_decimal_precision_to_length_no_truncation(precision,
++ decimals,
++ unsigned_flag);
++ break;
++ }
++ default:
++ DBUG_ASSERT(0); /* This result type isn't handled */
++ }
++}
++
++double my_double_round(double value, longlong dec, bool dec_unsigned,
++ bool truncate)
++{
++ double tmp;
++ bool dec_negative= (dec < 0) && !dec_unsigned;
++ ulonglong abs_dec= dec_negative ? -dec : dec;
++ /*
++ tmp2 is here to avoid return the value with 80 bit precision
++ This will fix that the test round(0.1,1) = round(0.1,1) is true
++ */
++ volatile double tmp2;
++
++ tmp=(abs_dec < array_elements(log_10) ?
++ log_10[abs_dec] : pow(10.0,(double) abs_dec));
++
++ if (dec_negative && my_isinf(tmp))
++ tmp2= 0;
++ else if (!dec_negative && my_isinf(value * tmp))
++ tmp2= value;
++ else if (truncate)
++ {
++ if (value >= 0)
++ tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
++ else
++ tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
++ }
++ else
++ tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
++ return tmp2;
++}
++
++
++double Item_func_round::real_op()
++{
++ double value= args[0]->val_real();
++
++ if (!(null_value= args[0]->null_value || args[1]->null_value))
++ return my_double_round(value, args[1]->val_int(), args[1]->unsigned_flag,
++ truncate);
++
++ return 0.0;
++}
++
++/*
++ Rounds a given value to a power of 10 specified as the 'to' argument,
++ avoiding overflows when the value is close to the ulonglong range boundary.
++*/
++
++static inline ulonglong my_unsigned_round(ulonglong value, ulonglong to)
++{
++ ulonglong tmp= value / to * to;
++ return (value - tmp < (to >> 1)) ? tmp : tmp + to;
++}
++
++
++longlong Item_func_round::int_op()
++{
++ longlong value= args[0]->val_int();
++ longlong dec= args[1]->val_int();
++ decimals= 0;
++ ulonglong abs_dec;
++ if ((null_value= args[0]->null_value || args[1]->null_value))
++ return 0;
++ if ((dec >= 0) || args[1]->unsigned_flag)
++ return value; // integer have not digits after point
++
++ abs_dec= -dec;
++ longlong tmp;
++
++ if(abs_dec >= array_elements(log_10_int))
++ return 0;
++
++ tmp= log_10_int[abs_dec];
++
++ if (truncate)
++ value= (unsigned_flag) ?
++ ((ulonglong) value / tmp) * tmp : (value / tmp) * tmp;
++ else
++ value= (unsigned_flag || value >= 0) ?
++ my_unsigned_round((ulonglong) value, tmp) :
++ -(longlong) my_unsigned_round((ulonglong) -value, tmp);
++ return value;
++}
++
++
++my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
++{
++ my_decimal val, *value= args[0]->val_decimal(&val);
++ longlong dec= args[1]->val_int();
++ if (dec >= 0 || args[1]->unsigned_flag)
++ dec= min((ulonglong) dec, decimals);
++ else if (dec < INT_MIN)
++ dec= INT_MIN;
++
++ if (!(null_value= (args[0]->null_value || args[1]->null_value ||
++ my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
++ truncate, decimal_value) > 1)))
++ {
++ decimal_value->frac= decimals;
++ return decimal_value;
++ }
++ return 0;
++}
++
++
++void Item_func_rand::seed_random(Item *arg)
++{
++ /*
++ TODO: do not do reinit 'rand' for every execute of PS/SP if
++ args[0] is a constant.
++ */
++ uint32 tmp= (uint32) arg->val_int();
++ randominit(rand, (uint32) (tmp*0x10001L+55555555L),
++ (uint32) (tmp*0x10000001L));
++}
++
++
++bool Item_func_rand::fix_fields(THD *thd,Item **ref)
++{
++ if (Item_real_func::fix_fields(thd, ref))
++ return TRUE;
++ used_tables_cache|= RAND_TABLE_BIT;
++ if (arg_count)
++ { // Only use argument once in query
++ /*
++ Allocate rand structure once: we must use thd->stmt_arena
++ to create rand in proper mem_root if it's a prepared statement or
++ stored procedure.
++
++ No need to send a Rand log event if seed was given eg: RAND(seed),
++ as it will be replicated in the query as such.
++ */
++ if (!rand && !(rand= (struct rand_struct*)
++ thd->stmt_arena->alloc(sizeof(*rand))))
++ return TRUE;
++ }
++ else
++ {
++ /*
++ Save the seed only the first time RAND() is used in the query
++ Once events are forwarded rather than recreated,
++ the following can be skipped if inside the slave thread
++ */
++ if (!thd->rand_used)
++ {
++ thd->rand_used= 1;
++ thd->rand_saved_seed1= thd->rand.seed1;
++ thd->rand_saved_seed2= thd->rand.seed2;
++ }
++ rand= &thd->rand;
++ }
++ return FALSE;
++}
++
++void Item_func_rand::update_used_tables()
++{
++ Item_real_func::update_used_tables();
++ used_tables_cache|= RAND_TABLE_BIT;
++}
++
++
++double Item_func_rand::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ if (arg_count)
++ {
++ if (!args[0]->const_item())
++ seed_random(args[0]);
++ else if (first_eval)
++ {
++ /*
++ Constantness of args[0] may be set during JOIN::optimize(), if arg[0]
++ is a field item of "constant" table. Thus, we have to evaluate
++ seed_random() for constant arg there but not at the fix_fields method.
++ */
++ first_eval= FALSE;
++ seed_random(args[0]);
++ }
++ }
++ return my_rnd(rand);
++}
++
++longlong Item_func_sign::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ null_value=args[0]->null_value;
++ return value < 0.0 ? -1 : (value > 0 ? 1 : 0);
++}
++
++
++double Item_func_units::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0;
++ return value*mul+add;
++}
++
++
++void Item_func_min_max::fix_length_and_dec()
++{
++ int max_int_part=0;
++ bool datetime_found= FALSE;
++ decimals=0;
++ max_length=0;
++ maybe_null=0;
++ cmp_type=args[0]->result_type();
++
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ set_if_bigger(max_length, args[i]->max_length);
++ set_if_bigger(decimals, args[i]->decimals);
++ set_if_bigger(max_int_part, args[i]->decimal_int_part());
++ if (args[i]->maybe_null)
++ maybe_null=1;
++ cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
++ if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime())
++ {
++ datetime_found= TRUE;
++ if (!datetime_item || args[i]->field_type() == MYSQL_TYPE_DATETIME)
++ datetime_item= args[i];
++ }
++ }
++ if (cmp_type == STRING_RESULT)
++ {
++ agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
++ if (datetime_found)
++ {
++ thd= current_thd;
++ compare_as_dates= TRUE;
++ }
++ }
++ else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
++ max_length= my_decimal_precision_to_length_no_truncation(max_int_part +
++ decimals, decimals,
++ unsigned_flag);
++ else if (cmp_type == REAL_RESULT)
++ max_length= float_length(decimals);
++ cached_field_type= agg_field_type(args, arg_count);
++}
++
++
++/*
++ Compare item arguments in the DATETIME context.
++
++ SYNOPSIS
++ cmp_datetimes()
++ value [out] found least/greatest DATE/DATETIME value
++
++ DESCRIPTION
++ Compare item arguments as DATETIME values and return the index of the
++ least/greatest argument in the arguments array.
++ The correct integer DATE/DATETIME value of the found argument is
++ stored to the value pointer, if latter is provided.
++
++ RETURN
++ 0 If one of arguments is NULL or there was a execution error
++ # index of the least/greatest argument
++*/
++
++uint Item_func_min_max::cmp_datetimes(ulonglong *value)
++{
++ longlong UNINIT_VAR(min_max);
++ uint min_max_idx= 0;
++
++ for (uint i=0; i < arg_count ; i++)
++ {
++ Item **arg= args + i;
++ bool is_null;
++ longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
++
++ /* Check if we need to stop (because of error or KILL) and stop the loop */
++ if (thd->is_error())
++ {
++ null_value= 1;
++ return 0;
++ }
++
++ if ((null_value= args[i]->null_value))
++ return 0;
++ if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
++ {
++ min_max= res;
++ min_max_idx= i;
++ }
++ }
++ if (value)
++ {
++ *value= min_max;
++ if (datetime_item->field_type() == MYSQL_TYPE_DATE)
++ *value/= 1000000L;
++ }
++ return min_max_idx;
++}
++
++
++String *Item_func_min_max::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ if (compare_as_dates)
++ {
++ String *str_res;
++ uint min_max_idx= cmp_datetimes(NULL);
++ if (null_value)
++ return 0;
++ str_res= args[min_max_idx]->val_str(str);
++ if (args[min_max_idx]->null_value)
++ {
++ // check if the call to val_str() above returns a NULL value
++ null_value= 1;
++ return NULL;
++ }
++ str_res->set_charset(collation.collation);
++ return str_res;
++ }
++ switch (cmp_type) {
++ case INT_RESULT:
++ {
++ longlong nr=val_int();
++ if (null_value)
++ return 0;
++ str->set_int(nr, unsigned_flag, &my_charset_bin);
++ return str;
++ }
++ case DECIMAL_RESULT:
++ {
++ my_decimal dec_buf, *dec_val= val_decimal(&dec_buf);
++ if (null_value)
++ return 0;
++ my_decimal2string(E_DEC_FATAL_ERROR, dec_val, 0, 0, 0, str);
++ return str;
++ }
++ case REAL_RESULT:
++ {
++ double nr= val_real();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ str->set_real(nr,decimals,&my_charset_bin);
++ return str;
++ }
++ case STRING_RESULT:
++ {
++ String *UNINIT_VAR(res);
++ for (uint i=0; i < arg_count ; i++)
++ {
++ if (i == 0)
++ res=args[i]->val_str(str);
++ else
++ {
++ String *res2;
++ res2= args[i]->val_str(res == str ? &tmp_value : str);
++ if (res2)
++ {
++ int cmp= sortcmp(res,res2,collation.collation);
++ if ((cmp_sign < 0 ? cmp : -cmp) < 0)
++ res=res2;
++ }
++ }
++ if ((null_value= args[i]->null_value))
++ return 0;
++ }
++ res->set_charset(collation.collation);
++ return res;
++ }
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ return 0;
++ }
++ return 0; // Keep compiler happy
++}
++
++
++double Item_func_min_max::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ double value=0.0;
++ if (compare_as_dates)
++ {
++ ulonglong result= 0;
++ (void)cmp_datetimes(&result);
++ return (double)result;
++ }
++ for (uint i=0; i < arg_count ; i++)
++ {
++ if (i == 0)
++ value= args[i]->val_real();
++ else
++ {
++ double tmp= args[i]->val_real();
++ if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
++ value=tmp;
++ }
++ if ((null_value= args[i]->null_value))
++ break;
++ }
++ return value;
++}
++
++
++longlong Item_func_min_max::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong value=0;
++ if (compare_as_dates)
++ {
++ ulonglong result= 0;
++ (void)cmp_datetimes(&result);
++ return (longlong)result;
++ }
++ for (uint i=0; i < arg_count ; i++)
++ {
++ if (i == 0)
++ value=args[i]->val_int();
++ else
++ {
++ longlong tmp=args[i]->val_int();
++ if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
++ value=tmp;
++ }
++ if ((null_value= args[i]->null_value))
++ break;
++ }
++ return value;
++}
++
++
++my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
++{
++ DBUG_ASSERT(fixed == 1);
++ my_decimal tmp_buf, *tmp, *UNINIT_VAR(res);
++
++ if (compare_as_dates)
++ {
++ ulonglong value= 0;
++ (void)cmp_datetimes(&value);
++ ulonglong2decimal(value, dec);
++ return dec;
++ }
++ for (uint i=0; i < arg_count ; i++)
++ {
++ if (i == 0)
++ res= args[i]->val_decimal(dec);
++ else
++ {
++ tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
++ if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0)
++ {
++ if (tmp == &tmp_buf)
++ {
++ /* Move value out of tmp_buf as this will be reused on next loop */
++ my_decimal2decimal(tmp, dec);
++ res= dec;
++ }
++ else
++ res= tmp;
++ }
++ }
++ if ((null_value= args[i]->null_value))
++ {
++ res= 0;
++ break;
++ }
++ }
++ return res;
++}
++
++
++longlong Item_func_length::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ return (longlong) res->length();
++}
++
++
++longlong Item_func_char_length::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ return (longlong) res->numchars();
++}
++
++
++longlong Item_func_coercibility::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ null_value= 0;
++ return (longlong) args[0]->collation.derivation;
++}
++
++
++void Item_func_locate::fix_length_and_dec()
++{
++ max_length= MY_INT32_NUM_DECIMAL_DIGITS;
++ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
++}
++
++
++longlong Item_func_locate::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *a=args[0]->val_str(&value1);
++ String *b=args[1]->val_str(&value2);
++ if (!a || !b)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ /* must be longlong to avoid truncation */
++ longlong start= 0;
++ longlong start0= 0;
++ my_match_t match;
++
++ if (arg_count == 3)
++ {
++ start0= start= args[2]->val_int() - 1;
++
++ if ((start < 0) || (start > a->length()))
++ return 0;
++
++ /* start is now sufficiently valid to pass to charpos function */
++ start= a->charpos((int) start);
++
++ if (start + b->length() > a->length())
++ return 0;
++ }
++
++ if (!b->length()) // Found empty string at start
++ return start + 1;
++
++ if (!cmp_collation.collation->coll->instr(cmp_collation.collation,
++ a->ptr()+start,
++ (uint) (a->length()-start),
++ b->ptr(), b->length(),
++ &match, 1))
++ return 0;
++ return (longlong) match.mb_len + start0 + 1;
++}
++
++
++void Item_func_locate::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("locate("));
++ args[1]->print(str, query_type);
++ str->append(',');
++ args[0]->print(str, query_type);
++ if (arg_count == 3)
++ {
++ str->append(',');
++ args[2]->print(str, query_type);
++ }
++ str->append(')');
++}
++
++
++longlong Item_func_field::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++
++ if (cmp_type == STRING_RESULT)
++ {
++ String *field;
++ if (!(field= args[0]->val_str(&value)))
++ return 0;
++ for (uint i=1 ; i < arg_count ; i++)
++ {
++ String *tmp_value=args[i]->val_str(&tmp);
++ if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation))
++ return (longlong) (i);
++ }
++ }
++ 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 (val == args[i]->val_int() && !args[i]->null_value)
++ return (longlong) (i);
++ }
++ }
++ else if (cmp_type == DECIMAL_RESULT)
++ {
++ 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);
++ if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
++ return (longlong) (i);
++ }
++ }
++ else
++ {
++ double val= args[0]->val_real();
++ if (args[0]->null_value)
++ return 0;
++ for (uint i=1; i < arg_count ; i++)
++ {
++ if (val == args[i]->val_real() && !args[i]->null_value)
++ return (longlong) (i);
++ }
++ }
++ return 0;
++}
++
++
++void Item_func_field::fix_length_and_dec()
++{
++ maybe_null=0; max_length=3;
++ cmp_type= args[0]->result_type();
++ for (uint i=1; i < arg_count ; i++)
++ cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
++ if (cmp_type == STRING_RESULT)
++ agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1);
++}
++
++
++longlong Item_func_ascii::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ return (longlong) (res->length() ? (uchar) (*res)[0] : (uchar) 0);
++}
++
++longlong Item_func_ord::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ if (!res->length()) return 0;
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ register const char *str=res->ptr();
++ register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length());
++ if (!l)
++ return (longlong)((uchar) *str);
++ while (l--)
++ n=(n<<8)|(uint32)((uchar) *str++);
++ return (longlong) n;
++ }
++#endif
++ return (longlong) ((uchar) (*res)[0]);
++}
++
++ /* Search after a string in a string of strings separated by ',' */
++ /* Returns number of found type >= 1 or 0 if not found */
++ /* This optimizes searching in enums to bit testing! */
++
++void Item_func_find_in_set::fix_length_and_dec()
++{
++ decimals=0;
++ max_length=3; // 1-999
++ if (args[0]->const_item() && args[1]->type() == FIELD_ITEM)
++ {
++ Field *field= ((Item_field*) args[1])->field;
++ if (field->real_type() == MYSQL_TYPE_SET)
++ {
++ String *find=args[0]->val_str(&value);
++ if (find)
++ {
++ enum_value= find_type(((Field_enum*) field)->typelib,find->ptr(),
++ find->length(), 0);
++ enum_bit=0;
++ if (enum_value)
++ enum_bit=LL(1) << (enum_value-1);
++ }
++ }
++ }
++ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
++}
++
++static const char separator=',';
++
++longlong Item_func_find_in_set::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ if (enum_value)
++ {
++ ulonglong tmp=(ulonglong) args[1]->val_int();
++ if (!(null_value=args[1]->null_value || args[0]->null_value))
++ {
++ if (tmp & enum_bit)
++ return enum_value;
++ }
++ return 0L;
++ }
++
++ String *find=args[0]->val_str(&value);
++ String *buffer=args[1]->val_str(&value2);
++ if (!find || !buffer)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++
++ int diff;
++ if ((diff=buffer->length() - find->length()) >= 0)
++ {
++ my_wc_t wc= 0;
++ CHARSET_INFO *cs= cmp_collation.collation;
++ const char *str_begin= buffer->ptr();
++ const char *str_end= buffer->ptr();
++ const char *real_end= str_end+buffer->length();
++ const uchar *find_str= (const uchar *) find->ptr();
++ uint find_str_len= find->length();
++ int position= 0;
++ while (1)
++ {
++ int symbol_len;
++ if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end,
++ (uchar*) real_end)) > 0)
++ {
++ const char *substr_end= str_end + symbol_len;
++ bool is_last_item= (substr_end == real_end);
++ bool is_separator= (wc == (my_wc_t) separator);
++ if (is_separator || is_last_item)
++ {
++ position++;
++ if (is_last_item && !is_separator)
++ str_end= substr_end;
++ if (!my_strnncoll(cs, (const uchar *) str_begin,
++ (uint) (str_end - str_begin),
++ find_str, find_str_len))
++ return (longlong) position;
++ else
++ str_begin= substr_end;
++ }
++ str_end= substr_end;
++ }
++ else if (str_end - str_begin == 0 &&
++ find_str_len == 0 &&
++ wc == (my_wc_t) separator)
++ return (longlong) ++position;
++ else
++ return LL(0);
++ }
++ }
++ return 0;
++}
++
++longlong Item_func_bit_count::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ ulonglong value= (ulonglong) args[0]->val_int();
++ if ((null_value= args[0]->null_value))
++ return 0; /* purecov: inspected */
++ return (longlong) my_count_bits(value);
++}
++
++
++/****************************************************************************
++** Functions to handle dynamic loadable functions
++** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
++** Rewritten by monty.
++****************************************************************************/
++
++#ifdef HAVE_DLOPEN
++
++void udf_handler::cleanup()
++{
++ if (!not_original)
++ {
++ if (initialized)
++ {
++ if (u_d->func_deinit != NULL)
++ {
++ Udf_func_deinit deinit= u_d->func_deinit;
++ (*deinit)(&initid);
++ }
++ free_udf(u_d);
++ initialized= FALSE;
++ }
++ if (buffers) // Because of bug in ecc
++ delete [] buffers;
++ buffers= 0;
++ }
++}
++
++
++bool
++udf_handler::fix_fields(THD *thd, Item_result_field *func,
++ uint arg_count, Item **arguments)
++{
++#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
++ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
++#endif
++ DBUG_ENTER("Item_udf_func::fix_fields");
++
++ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
++ DBUG_RETURN(TRUE); // Fatal error flag is set!
++
++ udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1);
++
++ if (!tmp_udf)
++ {
++ my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno);
++ DBUG_RETURN(TRUE);
++ }
++ u_d=tmp_udf;
++ args=arguments;
++
++ /* Fix all arguments */
++ func->maybe_null=0;
++ used_tables_cache=0;
++ const_item_cache=1;
++
++ if ((f_args.arg_count=arg_count))
++ {
++ if (!(f_args.arg_type= (Item_result*)
++ sql_alloc(f_args.arg_count*sizeof(Item_result))))
++
++ {
++ free_udf(u_d);
++ DBUG_RETURN(TRUE);
++ }
++ uint i;
++ Item **arg,**arg_end;
++ for (i=0, arg=arguments, arg_end=arguments+arg_count;
++ arg != arg_end ;
++ arg++,i++)
++ {
++ if (!(*arg)->fixed &&
++ (*arg)->fix_fields(thd, arg))
++ DBUG_RETURN(1);
++ // we can't assign 'item' before, because fix_fields() can change arg
++ Item *item= *arg;
++ if (item->check_cols(1))
++ DBUG_RETURN(TRUE);
++ /*
++ TODO: We should think about this. It is not always
++ right way just to set an UDF result to return my_charset_bin
++ if one argument has binary sorting order.
++ The result collation should be calculated according to arguments
++ derivations in some cases and should not in other cases.
++ Moreover, some arguments can represent a numeric input
++ which doesn't effect the result character set and collation.
++ There is no a general rule for UDF. Everything depends on
++ the particular user defined function.
++ */
++ if (item->collation.collation->state & MY_CS_BINSORT)
++ func->collation.set(&my_charset_bin);
++ if (item->maybe_null)
++ func->maybe_null=1;
++ func->with_sum_func= func->with_sum_func || item->with_sum_func;
++ used_tables_cache|=item->used_tables();
++ const_item_cache&=item->const_item();
++ f_args.arg_type[i]=item->result_type();
++ }
++ //TODO: why all following memory is not allocated with 1 call of sql_alloc?
++ if (!(buffers=new String[arg_count]) ||
++ !(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) ||
++ !(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) ||
++ !(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) ||
++ !(num_buffer= (char*) sql_alloc(arg_count *
++ ALIGN_SIZE(sizeof(double)))) ||
++ !(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) ||
++ !(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count *
++ sizeof(long))))
++ {
++ free_udf(u_d);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ func->fix_length_and_dec();
++ initid.max_length=func->max_length;
++ initid.maybe_null=func->maybe_null;
++ initid.const_item=const_item_cache;
++ initid.decimals=func->decimals;
++ initid.ptr=0;
++
++ if (u_d->func_init)
++ {
++ char init_msg_buff[MYSQL_ERRMSG_SIZE];
++ char *to=num_buffer;
++ for (uint i=0; i < arg_count; i++)
++ {
++ /*
++ For a constant argument i, args->args[i] points to the argument value.
++ For non-constant, args->args[i] is NULL.
++ */
++ f_args.args[i]= NULL; /* Non-const unless updated below. */
++
++ f_args.lengths[i]= arguments[i]->max_length;
++ f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
++ f_args.attributes[i]= arguments[i]->name;
++ f_args.attribute_lengths[i]= arguments[i]->name_length;
++
++ if (arguments[i]->const_item())
++ {
++ switch (arguments[i]->result_type())
++ {
++ case STRING_RESULT:
++ case DECIMAL_RESULT:
++ {
++ String *res= arguments[i]->val_str(&buffers[i]);
++ if (arguments[i]->null_value)
++ continue;
++ f_args.args[i]= (char*) res->c_ptr();
++ f_args.lengths[i]= res->length();
++ break;
++ }
++ case INT_RESULT:
++ *((longlong*) to)= arguments[i]->val_int();
++ if (arguments[i]->null_value)
++ continue;
++ f_args.args[i]= to;
++ to+= ALIGN_SIZE(sizeof(longlong));
++ break;
++ case REAL_RESULT:
++ *((double*) to)= arguments[i]->val_real();
++ if (arguments[i]->null_value)
++ continue;
++ f_args.args[i]= to;
++ to+= ALIGN_SIZE(sizeof(double));
++ break;
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ break;
++ }
++ }
++ }
++ Udf_func_init init= u_d->func_init;
++ if ((error=(uchar) init(&initid, &f_args, init_msg_buff)))
++ {
++ my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
++ u_d->name.str, init_msg_buff);
++ free_udf(u_d);
++ DBUG_RETURN(TRUE);
++ }
++ func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->maybe_null=initid.maybe_null;
++ const_item_cache=initid.const_item;
++ /*
++ Keep used_tables_cache in sync with const_item_cache.
++ See the comment in Item_udf_func::update_used tables.
++ */
++ if (!const_item_cache && !used_tables_cache)
++ used_tables_cache= RAND_TABLE_BIT;
++ func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ }
++ initialized=1;
++ if (error)
++ {
++ my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
++ u_d->name.str, ER(ER_UNKNOWN_ERROR));
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++bool udf_handler::get_arguments()
++{
++ if (error)
++ return 1; // Got an error earlier
++ char *to= num_buffer;
++ uint str_count=0;
++ for (uint i=0; i < f_args.arg_count; i++)
++ {
++ f_args.args[i]=0;
++ switch (f_args.arg_type[i]) {
++ case STRING_RESULT:
++ case DECIMAL_RESULT:
++ {
++ String *res=args[i]->val_str(&buffers[str_count++]);
++ if (!(args[i]->null_value))
++ {
++ f_args.args[i]= (char*) res->ptr();
++ f_args.lengths[i]= res->length();
++ break;
++ }
++ }
++ case INT_RESULT:
++ *((longlong*) to) = args[i]->val_int();
++ if (!args[i]->null_value)
++ {
++ f_args.args[i]=to;
++ to+= ALIGN_SIZE(sizeof(longlong));
++ }
++ break;
++ case REAL_RESULT:
++ *((double*) to)= args[i]->val_real();
++ if (!args[i]->null_value)
++ {
++ f_args.args[i]=to;
++ to+= ALIGN_SIZE(sizeof(double));
++ }
++ break;
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ break;
++ }
++ }
++ return 0;
++}
++
++/**
++ @return
++ (String*)NULL in case of NULL values
++*/
++String *udf_handler::val_str(String *str,String *save_str)
++{
++ uchar is_null_tmp=0;
++ ulong res_length;
++ DBUG_ENTER("udf_handler::val_str");
++
++ if (get_arguments())
++ DBUG_RETURN(0);
++ char * (*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
++ (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
++ u_d->func;
++
++ if ((res_length=str->alloced_length()) < MAX_FIELD_WIDTH)
++ { // This happens VERY seldom
++ if (str->alloc(MAX_FIELD_WIDTH))
++ {
++ error=1;
++ DBUG_RETURN(0);
++ }
++ }
++ char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length,
++ &is_null_tmp, &error);
++ DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length));
++ if (is_null_tmp || !res || error) // The !res is for safety
++ {
++ DBUG_PRINT("info", ("Null or error"));
++ DBUG_RETURN(0);
++ }
++ if (res == str->ptr())
++ {
++ str->length(res_length);
++ DBUG_PRINT("exit", ("str: %s", str->ptr()));
++ DBUG_RETURN(str);
++ }
++ save_str->set(res, res_length, str->charset());
++ DBUG_PRINT("exit", ("save_str: %s", save_str->ptr()));
++ DBUG_RETURN(save_str);
++}
++
++
++/*
++ For the moment, UDF functions are returning DECIMAL values as strings
++*/
++
++my_decimal *udf_handler::val_decimal(my_bool *null_value, my_decimal *dec_buf)
++{
++ char buf[DECIMAL_MAX_STR_LENGTH+1], *end;
++ ulong res_length= DECIMAL_MAX_STR_LENGTH;
++
++ if (get_arguments())
++ {
++ *null_value=1;
++ return 0;
++ }
++ char *(*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
++ (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
++ u_d->func;
++
++ char *res= func(&initid, &f_args, buf, &res_length, &is_null, &error);
++ if (is_null || error)
++ {
++ *null_value= 1;
++ return 0;
++ }
++ end= res+ res_length;
++ str2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf, &end);
++ return dec_buf;
++}
++
++
++void Item_udf_func::cleanup()
++{
++ udf.cleanup();
++ Item_func::cleanup();
++}
++
++
++void Item_udf_func::print(String *str, enum_query_type query_type)
++{
++ str->append(func_name());
++ str->append('(');
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ if (i != 0)
++ str->append(',');
++ args[i]->print_item_w_name(str, query_type);
++ }
++ str->append(')');
++}
++
++
++double Item_func_udf_float::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ DBUG_ENTER("Item_func_udf_float::val");
++ DBUG_PRINT("info",("result_type: %d arg_count: %d",
++ args[0]->result_type(), arg_count));
++ DBUG_RETURN(udf.val(&null_value));
++}
++
++
++String *Item_func_udf_float::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ double nr= val_real();
++ if (null_value)
++ return 0; /* purecov: inspected */
++ str->set_real(nr,decimals,&my_charset_bin);
++ return str;
++}
++
++
++longlong Item_func_udf_int::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ DBUG_ENTER("Item_func_udf_int::val_int");
++ DBUG_RETURN(udf.val_int(&null_value));
++}
++
++
++String *Item_func_udf_int::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ longlong nr=val_int();
++ if (null_value)
++ return 0;
++ str->set_int(nr, unsigned_flag, &my_charset_bin);
++ return str;
++}
++
++
++longlong Item_func_udf_decimal::val_int()
++{
++ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
++ longlong result;
++ if (null_value)
++ return 0;
++ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
++ return result;
++}
++
++
++double Item_func_udf_decimal::val_real()
++{
++ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
++ double result;
++ if (null_value)
++ return 0.0;
++ my_decimal2double(E_DEC_FATAL_ERROR, dec, &result);
++ return result;
++}
++
++
++my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf)
++{
++ DBUG_ASSERT(fixed == 1);
++ DBUG_ENTER("Item_func_udf_decimal::val_decimal");
++ DBUG_PRINT("info",("result_type: %d arg_count: %d",
++ args[0]->result_type(), arg_count));
++
++ DBUG_RETURN(udf.val_decimal(&null_value, dec_buf));
++}
++
++
++String *Item_func_udf_decimal::val_str(String *str)
++{
++ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
++ if (null_value)
++ return 0;
++ if (str->length() < DECIMAL_MAX_STR_LENGTH)
++ str->length(DECIMAL_MAX_STR_LENGTH);
++ my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
++ my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, '0', str);
++ return str;
++}
++
++
++void Item_func_udf_decimal::fix_length_and_dec()
++{
++ fix_num_length_and_dec();
++}
++
++
++/* Default max_length is max argument length */
++
++void Item_func_udf_str::fix_length_and_dec()
++{
++ DBUG_ENTER("Item_func_udf_str::fix_length_and_dec");
++ max_length=0;
++ for (uint i = 0; i < arg_count; i++)
++ set_if_bigger(max_length,args[i]->max_length);
++ DBUG_VOID_RETURN;
++}
++
++String *Item_func_udf_str::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=udf.val_str(str,&str_value);
++ null_value = !res;
++ return res;
++}
++
++
++/**
++ @note
++ This has to come last in the udf_handler methods, or C for AIX
++ version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
++*/
++
++udf_handler::~udf_handler()
++{
++ /* Everything should be properly cleaned up by this moment. */
++ DBUG_ASSERT(not_original || !(initialized || buffers));
++}
++
++#else
++bool udf_handler::get_arguments() { return 0; }
++#endif /* HAVE_DLOPEN */
++
++/*
++** User level locks
++*/
++
++pthread_mutex_t LOCK_user_locks;
++static HASH hash_user_locks;
++
++class User_level_lock
++{
++ uchar *key;
++ size_t key_length;
++
++public:
++ int count;
++ bool locked;
++ pthread_cond_t cond;
++ my_thread_id thread_id;
++ void set_thread(THD *thd) { thread_id= thd->thread_id; }
++
++ User_level_lock(const uchar *key_arg,uint length, ulong id)
++ :key_length(length),count(1),locked(1), thread_id(id)
++ {
++ key= (uchar*) my_memdup(key_arg,length,MYF(0));
++ pthread_cond_init(&cond,NULL);
++ if (key)
++ {
++ if (my_hash_insert(&hash_user_locks,(uchar*) this))
++ {
++ my_free(key,MYF(0));
++ key=0;
++ }
++ }
++ }
++ ~User_level_lock()
++ {
++ if (key)
++ {
++ hash_delete(&hash_user_locks,(uchar*) this);
++ my_free(key, MYF(0));
++ }
++ pthread_cond_destroy(&cond);
++ }
++ inline bool initialized() { return key != 0; }
++ friend void item_user_lock_release(User_level_lock *ull);
++ friend uchar *ull_get_key(const User_level_lock *ull, size_t *length,
++ my_bool not_used);
++};
++
++uchar *ull_get_key(const User_level_lock *ull, size_t *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length= ull->key_length;
++ return ull->key;
++}
++
++
++static bool item_user_lock_inited= 0;
++
++void item_user_lock_init(void)
++{
++ pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
++ hash_init(&hash_user_locks,system_charset_info,
++ 16,0,0,(hash_get_key) ull_get_key,NULL,0);
++ item_user_lock_inited= 1;
++}
++
++void item_user_lock_free(void)
++{
++ if (item_user_lock_inited)
++ {
++ item_user_lock_inited= 0;
++ hash_free(&hash_user_locks);
++ pthread_mutex_destroy(&LOCK_user_locks);
++ }
++}
++
++void item_user_lock_release(User_level_lock *ull)
++{
++ ull->locked=0;
++ ull->thread_id= 0;
++ if (--ull->count)
++ pthread_cond_signal(&ull->cond);
++ else
++ delete ull;
++}
++
++/**
++ Wait until we are at or past the given position in the master binlog
++ on the slave.
++*/
++
++longlong Item_master_pos_wait::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ THD* thd = current_thd;
++ String *log_name = args[0]->val_str(&value);
++ int event_count= 0;
++
++ null_value=0;
++ if (thd->slave_thread || !log_name || !log_name->length())
++ {
++ null_value = 1;
++ return 0;
++ }
++#ifdef HAVE_REPLICATION
++ longlong pos = (ulong)args[1]->val_int();
++ longlong timeout = (arg_count==3) ? args[2]->val_int() : 0 ;
++ if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
++ {
++ null_value = 1;
++ event_count=0;
++ }
++#endif
++ return event_count;
++}
++
++
++/**
++ Get a user level lock. If the thread has an old lock this is first released.
++
++ @retval
++ 1 : Got lock
++ @retval
++ 0 : Timeout
++ @retval
++ NULL : Error
++*/
++
++longlong Item_func_get_lock::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ longlong timeout=args[1]->val_int();
++ struct timespec abstime;
++ THD *thd=current_thd;
++ User_level_lock *ull;
++ int error;
++ DBUG_ENTER("Item_func_get_lock::val_int");
++
++ /*
++ In slave thread no need to get locks, everything is serialized. Anyway
++ there is no way to make GET_LOCK() work on slave like it did on master
++ (i.e. make it return exactly the same value) because we don't have the
++ same other concurrent threads environment. No matter what we return here,
++ it's not guaranteed to be same as on master.
++ */
++ if (thd->slave_thread)
++ DBUG_RETURN(1);
++
++ pthread_mutex_lock(&LOCK_user_locks);
++
++ if (!res || !res->length())
++ {
++ pthread_mutex_unlock(&LOCK_user_locks);
++ null_value=1;
++ DBUG_RETURN(0);
++ }
++ DBUG_PRINT("info", ("lock %.*s, thd=%ld", res->length(), res->ptr(),
++ (long) thd->real_id));
++ null_value=0;
++
++ if (thd->ull)
++ {
++ item_user_lock_release(thd->ull);
++ thd->ull=0;
++ }
++
++ if (!(ull= ((User_level_lock *) hash_search(&hash_user_locks,
++ (uchar*) res->ptr(),
++ (size_t) res->length()))))
++ {
++ ull= new User_level_lock((uchar*) res->ptr(), (size_t) res->length(),
++ thd->thread_id);
++ if (!ull || !ull->initialized())
++ {
++ delete ull;
++ pthread_mutex_unlock(&LOCK_user_locks);
++ null_value=1; // Probably out of memory
++ DBUG_RETURN(0);
++ }
++ ull->set_thread(thd);
++ thd->ull=ull;
++ pthread_mutex_unlock(&LOCK_user_locks);
++ DBUG_PRINT("info", ("made new lock"));
++ DBUG_RETURN(1); // Got new lock
++ }
++ ull->count++;
++ DBUG_PRINT("info", ("ull->count=%d", ull->count));
++
++ /*
++ Structure is now initialized. Try to get the lock.
++ Set up control struct to allow others to abort locks.
++ */
++ thd_proc_info(thd, "User lock");
++ thd->mysys_var->current_mutex= &LOCK_user_locks;
++ thd->mysys_var->current_cond= &ull->cond;
++
++ set_timespec(abstime,timeout);
++ error= 0;
++ while (ull->locked && !thd->killed)
++ {
++ DBUG_PRINT("info", ("waiting on lock"));
++ error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
++ if (error == ETIMEDOUT || error == ETIME)
++ {
++ DBUG_PRINT("info", ("lock wait timeout"));
++ break;
++ }
++ error= 0;
++ }
++
++ if (ull->locked)
++ {
++ if (!--ull->count)
++ {
++ DBUG_ASSERT(0);
++ delete ull; // Should never happen
++ }
++ if (!error) // Killed (thd->killed != 0)
++ {
++ error=1;
++ null_value=1; // Return NULL
++ }
++ }
++ else // We got the lock
++ {
++ ull->locked=1;
++ ull->set_thread(thd);
++ ull->thread_id= thd->thread_id;
++ thd->ull=ull;
++ error=0;
++ DBUG_PRINT("info", ("got the lock"));
++ }
++ pthread_mutex_unlock(&LOCK_user_locks);
++
++ pthread_mutex_lock(&thd->mysys_var->mutex);
++ thd_proc_info(thd, 0);
++ thd->mysys_var->current_mutex= 0;
++ thd->mysys_var->current_cond= 0;
++ pthread_mutex_unlock(&thd->mysys_var->mutex);
++
++ DBUG_RETURN(!error ? 1 : 0);
++}
++
++
++/**
++ Release a user level lock.
++ @return
++ - 1 if lock released
++ - 0 if lock wasn't held
++ - (SQL) NULL if no such lock
++*/
++
++longlong Item_func_release_lock::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ User_level_lock *ull;
++ longlong result;
++ THD *thd=current_thd;
++ DBUG_ENTER("Item_func_release_lock::val_int");
++ if (!res || !res->length())
++ {
++ null_value=1;
++ DBUG_RETURN(0);
++ }
++ DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr()));
++ null_value=0;
++
++ result=0;
++ pthread_mutex_lock(&LOCK_user_locks);
++ if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks,
++ (const uchar*) res->ptr(),
++ (size_t) res->length()))))
++ {
++ null_value=1;
++ }
++ else
++ {
++ DBUG_PRINT("info", ("ull->locked=%d ull->thread=%lu thd=%lu",
++ (int) ull->locked,
++ (long)ull->thread_id,
++ (long)thd->thread_id));
++ if (ull->locked && current_thd->thread_id == ull->thread_id)
++ {
++ DBUG_PRINT("info", ("release lock"));
++ result=1; // Release is ok
++ item_user_lock_release(ull);
++ thd->ull=0;
++ }
++ }
++ pthread_mutex_unlock(&LOCK_user_locks);
++ DBUG_RETURN(result);
++}
++
++
++longlong Item_func_last_insert_id::val_int()
++{
++ THD *thd= current_thd;
++ DBUG_ASSERT(fixed == 1);
++ if (arg_count)
++ {
++ longlong value= args[0]->val_int();
++ null_value= args[0]->null_value;
++ /*
++ LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as
++ documented in the manual. We don't want to touch
++ first_successful_insert_id_in_cur_stmt because it would make
++ LAST_INSERT_ID(X) take precedence over an generated auto_increment
++ value for this row.
++ */
++ thd->arg_of_last_insert_id_function= TRUE;
++ thd->first_successful_insert_id_in_prev_stmt= value;
++ return value;
++ }
++ return thd->read_first_successful_insert_id_in_prev_stmt();
++}
++
++
++bool Item_func_last_insert_id::fix_fields(THD *thd, Item **ref)
++{
++ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
++ return Item_int_func::fix_fields(thd, ref);
++}
++
++
++/* This function is just used to test speed of different functions */
++
++longlong Item_func_benchmark::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ char buff[MAX_FIELD_WIDTH];
++ String tmp(buff,sizeof(buff), &my_charset_bin);
++ my_decimal tmp_decimal;
++ THD *thd=current_thd;
++ ulonglong loop_count;
++
++ loop_count= (ulonglong) args[0]->val_int();
++
++ if (args[0]->null_value ||
++ (!args[0]->unsigned_flag && (((longlong) loop_count) < 0)))
++ {
++ if (!args[0]->null_value)
++ {
++ char buff[22];
++ llstr(((longlong) loop_count), buff);
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
++ "count", buff, "benchmark");
++ }
++
++ null_value= 1;
++ return 0;
++ }
++
++ null_value=0;
++ for (ulonglong loop=0 ; loop < loop_count && !thd->killed; loop++)
++ {
++ switch (args[1]->result_type()) {
++ case REAL_RESULT:
++ (void) args[1]->val_real();
++ break;
++ case INT_RESULT:
++ (void) args[1]->val_int();
++ break;
++ case STRING_RESULT:
++ (void) args[1]->val_str(&tmp);
++ break;
++ case DECIMAL_RESULT:
++ (void) args[1]->val_decimal(&tmp_decimal);
++ break;
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ return 0;
++ }
++ }
++ return 0;
++}
++
++
++void Item_func_benchmark::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("benchmark("));
++ args[0]->print(str, query_type);
++ str->append(',');
++ args[1]->print(str, query_type);
++ str->append(')');
++}
++
++
++/** This function is just used to create tests with time gaps. */
++
++longlong Item_func_sleep::val_int()
++{
++ THD *thd= current_thd;
++ struct timespec abstime;
++ pthread_cond_t cond;
++ int error;
++
++ DBUG_ASSERT(fixed == 1);
++
++ double time= args[0]->val_real();
++ /*
++ On 64-bit OSX pthread_cond_timedwait() waits forever
++ if passed abstime time has already been exceeded by
++ the system time.
++ When given a very short timeout (< 10 mcs) just return
++ immediately.
++ We assume that the lines between this test and the call
++ to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
++ */
++ if (time < 0.00001)
++ return 0;
++
++ set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000)));
++
++ pthread_cond_init(&cond, NULL);
++ pthread_mutex_lock(&LOCK_user_locks);
++
++ thd_proc_info(thd, "User sleep");
++ thd->mysys_var->current_mutex= &LOCK_user_locks;
++ thd->mysys_var->current_cond= &cond;
++
++ error= 0;
++ while (!thd->killed)
++ {
++ error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
++ if (error == ETIMEDOUT || error == ETIME)
++ break;
++ error= 0;
++ }
++ thd_proc_info(thd, 0);
++ pthread_mutex_unlock(&LOCK_user_locks);
++ pthread_mutex_lock(&thd->mysys_var->mutex);
++ thd->mysys_var->current_mutex= 0;
++ thd->mysys_var->current_cond= 0;
++ pthread_mutex_unlock(&thd->mysys_var->mutex);
++
++ pthread_cond_destroy(&cond);
++
++ return test(!error); // Return 1 killed
++}
++
++
++#define extra_size sizeof(double)
++
++static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
++ bool create_if_not_exists)
++{
++ user_var_entry *entry;
++
++ if (!(entry = (user_var_entry*) hash_search(hash, (uchar*) name.str,
++ name.length)) &&
++ create_if_not_exists)
++ {
++ uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
++ if (!hash_inited(hash))
++ return 0;
++ if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME))))
++ return 0;
++ entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
++ extra_size;
++ entry->name.length=name.length;
++ entry->value=0;
++ entry->length=0;
++ entry->update_query_id=0;
++ entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
++ entry->unsigned_flag= 0;
++ /*
++ If we are here, we were called from a SET or a query which sets a
++ variable. Imagine it is this:
++ INSERT INTO t SELECT @a:=10, @a:=@a+1.
++ Then when we have a Item_func_get_user_var (because of the @a+1) so we
++ think we have to write the value of @a to the binlog. But before that,
++ we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
++ the variable as "already logged" (line below) so that it won't be logged
++ by Item_func_get_user_var (because that's not necessary).
++ */
++ entry->used_query_id=current_thd->query_id;
++ entry->type=STRING_RESULT;
++ memcpy(entry->name.str, name.str, name.length+1);
++ if (my_hash_insert(hash,(uchar*) entry))
++ {
++ my_free((char*) entry,MYF(0));
++ return 0;
++ }
++ }
++ return entry;
++}
++
++
++void Item_func_set_user_var::cleanup()
++{
++ Item_func::cleanup();
++ entry= NULL;
++}
++
++
++bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists)
++{
++ if (entry && thd->thread_id == entry_thread_id)
++ goto end; // update entry->update_query_id for PS
++ if (!(entry= get_variable(&thd->user_vars, name, create_if_not_exists)))
++ {
++ entry_thread_id= 0;
++ return TRUE;
++ }
++ entry_thread_id= thd->thread_id;
++ /*
++ Remember the last query which updated it, this way a query can later know
++ if this variable is a constant item in the query (it is if update_query_id
++ is different from query_id).
++ */
++end:
++ entry->update_query_id= thd->query_id;
++ return FALSE;
++}
++
++
++/*
++ When a user variable is updated (in a SET command or a query like
++ SELECT @a:= ).
++*/
++
++bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
++{
++ DBUG_ASSERT(fixed == 0);
++ /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
++ if (Item_func::fix_fields(thd, ref) || set_entry(thd, TRUE))
++ return TRUE;
++ /*
++ As it is wrong and confusing to associate any
++ character set with NULL, @a should be latin2
++ after this query sequence:
++
++ SET @a=_latin2'string';
++ SET @a=NULL;
++
++ I.e. the second query should not change the charset
++ to the current default value, but should keep the
++ original value assigned during the first query.
++ In order to do it, we don't copy charset
++ from the argument if the argument is NULL
++ and the variable has previously been initialized.
++ */
++ null_item= (args[0]->type() == NULL_ITEM);
++ if (!entry->collation.collation || !null_item)
++ entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
++ collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
++ cached_result_type= args[0]->result_type();
++ return FALSE;
++}
++
++
++void
++Item_func_set_user_var::fix_length_and_dec()
++{
++ maybe_null=args[0]->maybe_null;
++ max_length=args[0]->max_length;
++ decimals=args[0]->decimals;
++ unsigned_flag= args[0]->unsigned_flag;
++ collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
++}
++
++
++/*
++ Mark field in read_map
++
++ NOTES
++ This is used by filesort to register used fields in a a temporary
++ column read set or to register used fields in a view
++*/
++
++bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
++{
++ if (result_field)
++ {
++ TABLE *table= (TABLE *) arg;
++ if (result_field->table == table || !table)
++ bitmap_set_bit(result_field->table->read_set, result_field->field_index);
++ }
++ return 0;
++}
++
++
++/**
++ Set value to user variable.
++
++ @param entry pointer to structure representing variable
++ @param set_null should we set NULL value ?
++ @param ptr pointer to buffer with new value
++ @param length length of new value
++ @param type type of new value
++ @param cs charset info for new value
++ @param dv derivation for new value
++ @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
++
++ @retval
++ false success
++ @retval
++ true failure
++*/
++
++static bool
++update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
++ Item_result type, CHARSET_INFO *cs, Derivation dv,
++ bool unsigned_arg)
++{
++ if (set_null)
++ {
++ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
++ if (entry->value && entry->value != pos)
++ my_free(entry->value,MYF(0));
++ entry->value= 0;
++ entry->length= 0;
++ }
++ else
++ {
++ if (type == STRING_RESULT)
++ length++; // Store strings with end \0
++ if (length <= extra_size)
++ {
++ /* Save value in value struct */
++ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
++ if (entry->value != pos)
++ {
++ if (entry->value)
++ my_free(entry->value,MYF(0));
++ entry->value=pos;
++ }
++ }
++ else
++ {
++ /* Allocate variable */
++ if (entry->length != length)
++ {
++ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
++ if (entry->value == pos)
++ entry->value=0;
++ entry->value= (char*) my_realloc(entry->value, length,
++ MYF(MY_ALLOW_ZERO_PTR | MY_WME));
++ if (!entry->value)
++ return 1;
++ }
++ }
++ if (type == STRING_RESULT)
++ {
++ length--; // Fix length change above
++ entry->value[length]= 0; // Store end \0
++ }
++ memmove(entry->value, ptr, length);
++ if (type == DECIMAL_RESULT)
++ ((my_decimal*)entry->value)->fix_buffer_pointer();
++ entry->length= length;
++ entry->collation.set(cs, dv);
++ entry->unsigned_flag= unsigned_arg;
++ }
++ entry->type=type;
++ return 0;
++}
++
++
++bool
++Item_func_set_user_var::update_hash(void *ptr, uint length,
++ Item_result res_type,
++ CHARSET_INFO *cs, Derivation dv,
++ bool unsigned_arg)
++{
++ /*
++ If we set a variable explicitely to NULL then keep the old
++ result type of the variable
++ */
++ if ((null_value= args[0]->null_value) && null_item)
++ res_type= entry->type; // Don't change type of item
++ if (::update_hash(entry, (null_value= args[0]->null_value),
++ ptr, length, res_type, cs, dv, unsigned_arg))
++ {
++ current_thd->fatal_error(); // Probably end of memory
++ null_value= 1;
++ return 1;
++ }
++ return 0;
++}
++
++
++/** Get the value of a variable as a double. */
++
++double user_var_entry::val_real(my_bool *null_value)
++{
++ if ((*null_value= (value == 0)))
++ return 0.0;
++
++ switch (type) {
++ case REAL_RESULT:
++ return *(double*) value;
++ case INT_RESULT:
++ return (double) *(longlong*) value;
++ case DECIMAL_RESULT:
++ {
++ double result;
++ my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
++ return result;
++ }
++ case STRING_RESULT:
++ return my_atof(value); // This is null terminated
++ case ROW_RESULT:
++ DBUG_ASSERT(1); // Impossible
++ break;
++ }
++ return 0.0; // Impossible
++}
++
++
++/** Get the value of a variable as an integer. */
++
++longlong user_var_entry::val_int(my_bool *null_value) const
++{
++ if ((*null_value= (value == 0)))
++ return LL(0);
++
++ switch (type) {
++ case REAL_RESULT:
++ return (longlong) *(double*) value;
++ case INT_RESULT:
++ return *(longlong*) value;
++ case DECIMAL_RESULT:
++ {
++ longlong result;
++ my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
++ return result;
++ }
++ case STRING_RESULT:
++ {
++ int error;
++ return my_strtoll10(value, (char**) 0, &error);// String is null terminated
++ }
++ case ROW_RESULT:
++ DBUG_ASSERT(1); // Impossible
++ break;
++ }
++ return LL(0); // Impossible
++}
++
++
++/** Get the value of a variable as a string. */
++
++String *user_var_entry::val_str(my_bool *null_value, String *str,
++ uint decimals)
++{
++ if ((*null_value= (value == 0)))
++ return (String*) 0;
++
++ switch (type) {
++ case REAL_RESULT:
++ str->set_real(*(double*) value, decimals, &my_charset_bin);
++ break;
++ case INT_RESULT:
++ if (!unsigned_flag)
++ str->set(*(longlong*) value, &my_charset_bin);
++ else
++ str->set(*(ulonglong*) value, &my_charset_bin);
++ break;
++ case DECIMAL_RESULT:
++ my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str);
++ break;
++ case STRING_RESULT:
++ if (str->copy(value, length, collation.collation))
++ str= 0; // EOM error
++ case ROW_RESULT:
++ DBUG_ASSERT(1); // Impossible
++ break;
++ }
++ return(str);
++}
++
++/** Get the value of a variable as a decimal. */
++
++my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
++{
++ if ((*null_value= (value == 0)))
++ return 0;
++
++ switch (type) {
++ case REAL_RESULT:
++ double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
++ break;
++ case INT_RESULT:
++ int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val);
++ break;
++ case DECIMAL_RESULT:
++ my_decimal2decimal((my_decimal *) value, val);
++ break;
++ case STRING_RESULT:
++ str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
++ break;
++ case ROW_RESULT:
++ DBUG_ASSERT(1); // Impossible
++ break;
++ }
++ return(val);
++}
++
++/**
++ This functions is invoked on SET \@variable or
++ \@variable:= expression.
++
++ Evaluate (and check expression), store results.
++
++ @note
++ For now it always return OK. All problem with value evaluating
++ will be caught by thd->is_error() check in sql_set_variables().
++
++ @retval
++ FALSE OK.
++*/
++
++bool
++Item_func_set_user_var::check(bool use_result_field)
++{
++ DBUG_ENTER("Item_func_set_user_var::check");
++ if (use_result_field && !result_field)
++ use_result_field= FALSE;
++
++ switch (cached_result_type) {
++ case REAL_RESULT:
++ {
++ save_result.vreal= use_result_field ? result_field->val_real() :
++ args[0]->val_real();
++ break;
++ }
++ case INT_RESULT:
++ {
++ save_result.vint= use_result_field ? result_field->val_int() :
++ args[0]->val_int();
++ unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
++ args[0]->unsigned_flag;
++ break;
++ }
++ case STRING_RESULT:
++ {
++ save_result.vstr= use_result_field ? result_field->val_str(&value) :
++ args[0]->val_str(&value);
++ break;
++ }
++ case DECIMAL_RESULT:
++ {
++ save_result.vdec= use_result_field ?
++ result_field->val_decimal(&decimal_buff) :
++ args[0]->val_decimal(&decimal_buff);
++ break;
++ }
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ break;
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ @brief Evaluate and store item's result.
++ This function is invoked on "SELECT ... INTO @var ...".
++
++ @param item An item to get value from.
++*/
++
++void Item_func_set_user_var::save_item_result(Item *item)
++{
++ DBUG_ENTER("Item_func_set_user_var::save_item_result");
++
++ switch (cached_result_type) {
++ case REAL_RESULT:
++ save_result.vreal= item->val_result();
++ break;
++ case INT_RESULT:
++ save_result.vint= item->val_int_result();
++ unsigned_flag= item->unsigned_flag;
++ break;
++ case STRING_RESULT:
++ save_result.vstr= item->str_result(&value);
++ break;
++ case DECIMAL_RESULT:
++ save_result.vdec= item->val_decimal_result(&decimal_buff);
++ break;
++ case ROW_RESULT:
++ default:
++ // Should never happen
++ DBUG_ASSERT(0);
++ break;
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ This functions is invoked on
++ SET \@variable or \@variable:= expression.
++
++ @note
++ We have to store the expression as such in the variable, independent of
++ the value method used by the user
++
++ @retval
++ 0 OK
++ @retval
++ 1 EOM Error
++
++*/
++
++bool
++Item_func_set_user_var::update()
++{
++ bool res= 0;
++ DBUG_ENTER("Item_func_set_user_var::update");
++
++ switch (cached_result_type) {
++ case REAL_RESULT:
++ {
++ res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
++ REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
++ break;
++ }
++ case INT_RESULT:
++ {
++ res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
++ INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
++ unsigned_flag);
++ break;
++ }
++ case STRING_RESULT:
++ {
++ if (!save_result.vstr) // Null value
++ res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
++ DERIVATION_IMPLICIT, 0);
++ else
++ res= update_hash((void*) save_result.vstr->ptr(),
++ save_result.vstr->length(), STRING_RESULT,
++ save_result.vstr->charset(),
++ DERIVATION_IMPLICIT, 0);
++ break;
++ }
++ case DECIMAL_RESULT:
++ {
++ if (!save_result.vdec) // Null value
++ res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
++ DERIVATION_IMPLICIT, 0);
++ else
++ res= update_hash((void*) save_result.vdec,
++ sizeof(my_decimal), DECIMAL_RESULT,
++ &my_charset_bin, DERIVATION_IMPLICIT, 0);
++ break;
++ }
++ case ROW_RESULT:
++ default:
++ // This case should never be chosen
++ DBUG_ASSERT(0);
++ break;
++ }
++ DBUG_RETURN(res);
++}
++
++
++double Item_func_set_user_var::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(0);
++ update(); // Store expression
++ return entry->val_real(&null_value);
++}
++
++longlong Item_func_set_user_var::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(0);
++ update(); // Store expression
++ return entry->val_int(&null_value);
++}
++
++String *Item_func_set_user_var::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ check(0);
++ update(); // Store expression
++ return entry->val_str(&null_value, str, decimals);
++}
++
++
++my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
++{
++ DBUG_ASSERT(fixed == 1);
++ check(0);
++ update(); // Store expression
++ return entry->val_decimal(&null_value, val);
++}
++
++
++double Item_func_set_user_var::val_result()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return entry->val_real(&null_value);
++}
++
++longlong Item_func_set_user_var::val_int_result()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return entry->val_int(&null_value);
++}
++
++bool Item_func_set_user_var::val_bool_result()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return entry->val_int(&null_value) != 0;
++}
++
++String *Item_func_set_user_var::str_result(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return entry->val_str(&null_value, str, decimals);
++}
++
++
++my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return entry->val_decimal(&null_value, val);
++}
++
++
++bool Item_func_set_user_var::is_null_result()
++{
++ DBUG_ASSERT(fixed == 1);
++ check(TRUE);
++ update(); // Store expression
++ return is_null();
++}
++
++
++void Item_func_set_user_var::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("(@"));
++ str->append(name.str, name.length);
++ str->append(STRING_WITH_LEN(":="));
++ args[0]->print(str, query_type);
++ str->append(')');
++}
++
++
++void Item_func_set_user_var::print_as_stmt(String *str,
++ enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("set @"));
++ str->append(name.str, name.length);
++ str->append(STRING_WITH_LEN(":="));
++ args[0]->print(str, query_type);
++ str->append(')');
++}
++
++bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
++{
++ if (result_field)
++ {
++ check(1);
++ update();
++ return protocol->store(result_field);
++ }
++ return Item::send(protocol, str_arg);
++}
++
++void Item_func_set_user_var::make_field(Send_field *tmp_field)
++{
++ if (result_field)
++ {
++ result_field->make_field(tmp_field);
++ DBUG_ASSERT(tmp_field->table_name != 0);
++ if (Item::name)
++ tmp_field->col_name=Item::name; // Use user supplied name
++ }
++ else
++ Item::make_field(tmp_field);
++}
++
++
++/*
++ Save the value of a user variable into a field
++
++ SYNOPSIS
++ save_in_field()
++ field target field to save the value to
++ no_conversion flag indicating whether conversions are allowed
++
++ DESCRIPTION
++ Save the function value into a field and update the user variable
++ accordingly. If a result field is defined and the target field doesn't
++ coincide with it then the value from the result field will be used as
++ the new value of the user variable.
++
++ The reason to have this method rather than simply using the result
++ field in the val_xxx() methods is that the value from the result field
++ not always can be used when the result field is defined.
++ Let's consider the following cases:
++ 1) when filling a tmp table the result field is defined but the value of it
++ is undefined because it has to be produced yet. Thus we can't use it.
++ 2) on execution of an INSERT ... SELECT statement the save_in_field()
++ function will be called to fill the data in the new record. If the SELECT
++ part uses a tmp table then the result field is defined and should be
++ used in order to get the correct result.
++
++ The difference between the SET_USER_VAR function and regular functions
++ like CONCAT is that the Item_func objects for the regular functions are
++ replaced by Item_field objects after the values of these functions have
++ been stored in a tmp table. Yet an object of the Item_field class cannot
++ be used to update a user variable.
++ Due to this we have to handle the result field in a special way here and
++ in the Item_func_set_user_var::send() function.
++
++ RETURN VALUES
++ FALSE Ok
++ TRUE Error
++*/
++
++int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
++ bool can_use_result_field)
++{
++ bool use_result_field= (!can_use_result_field ? 0 :
++ (result_field && result_field != field));
++ int error;
++
++ /* Update the value of the user variable */
++ check(use_result_field);
++ update();
++
++ if (result_type() == STRING_RESULT ||
++ (result_type() == REAL_RESULT &&
++ field->result_type() == STRING_RESULT))
++ {
++ String *result;
++ CHARSET_INFO *cs= collation.collation;
++ char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
++ str_value.set_quick(buff, sizeof(buff), cs);
++ result= entry->val_str(&null_value, &str_value, decimals);
++
++ if (null_value)
++ {
++ str_value.set_quick(0, 0, cs);
++ return set_field_to_null_with_conversions(field, no_conversions);
++ }
++
++ /* NOTE: If null_value == FALSE, "result" must be not NULL. */
++
++ field->set_notnull();
++ error=field->store(result->ptr(),result->length(),cs);
++ str_value.set_quick(0, 0, cs);
++ }
++ else if (result_type() == REAL_RESULT)
++ {
++ double nr= entry->val_real(&null_value);
++ if (null_value)
++ return set_field_to_null(field);
++ field->set_notnull();
++ error=field->store(nr);
++ }
++ else if (result_type() == DECIMAL_RESULT)
++ {
++ my_decimal decimal_value;
++ my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
++ if (null_value)
++ return set_field_to_null(field);
++ field->set_notnull();
++ error=field->store_decimal(val);
++ }
++ else
++ {
++ longlong nr= entry->val_int(&null_value);
++ if (null_value)
++ return set_field_to_null_with_conversions(field, no_conversions);
++ field->set_notnull();
++ error=field->store(nr, unsigned_flag);
++ }
++ return error;
++}
++
++
++String *
++Item_func_get_user_var::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ DBUG_ENTER("Item_func_get_user_var::val_str");
++ if (!var_entry)
++ DBUG_RETURN((String*) 0); // No such variable
++ DBUG_RETURN(var_entry->val_str(&null_value, str, decimals));
++}
++
++
++double Item_func_get_user_var::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ if (!var_entry)
++ return 0.0; // No such variable
++ return (var_entry->val_real(&null_value));
++}
++
++
++my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
++{
++ DBUG_ASSERT(fixed == 1);
++ if (!var_entry)
++ return 0;
++ return var_entry->val_decimal(&null_value, dec);
++}
++
++
++longlong Item_func_get_user_var::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ if (!var_entry)
++ return LL(0); // No such variable
++ return (var_entry->val_int(&null_value));
++}
++
++
++/**
++ Get variable by name and, if necessary, put the record of variable
++ use into the binary log.
++
++ When a user variable is invoked from an update query (INSERT, UPDATE etc),
++ stores this variable and its value in thd->user_var_events, so that it can be
++ written to the binlog (will be written just before the query is written, see
++ log.cc).
++
++ @param thd Current thread
++ @param name Variable name
++ @param[out] out_entry variable structure or NULL. The pointer is set
++ regardless of whether function succeeded or not.
++
++ @retval
++ 0 OK
++ @retval
++ 1 Failed to put appropriate record into binary log
++
++*/
++
++int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
++ LEX_STRING &name, user_var_entry **out_entry)
++{
++ BINLOG_USER_VAR_EVENT *user_var_event;
++ user_var_entry *var_entry;
++ var_entry= get_variable(&thd->user_vars, name, 0);
++
++ /*
++ Any reference to user-defined variable which is done from stored
++ function or trigger affects their execution and the execution of the
++ calling statement. We must log all such variables even if they are
++ not involved in table-updating statements.
++ */
++ if (!(opt_bin_log &&
++ (is_update_query(sql_command) || thd->in_sub_stmt)))
++ {
++ *out_entry= var_entry;
++ return 0;
++ }
++
++ if (!var_entry)
++ {
++ /*
++ If the variable does not exist, it's NULL, but we want to create it so
++ that it gets into the binlog (if it didn't, the slave could be
++ influenced by a variable of the same name previously set by another
++ thread).
++ We create it like if it had been explicitly set with SET before.
++ The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
++ sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
++ in dispatch_command()). Instead of building a one-element list to pass to
++ sql_set_variables(), we could instead manually call check() and update();
++ this would save memory and time; but calling sql_set_variables() makes
++ one unique place to maintain (sql_set_variables()).
++
++ Manipulation with lex is necessary since free_underlaid_joins
++ is going to release memory belonging to the main query.
++ */
++
++ List<set_var_base> tmp_var_list;
++ LEX *sav_lex= thd->lex, lex_tmp;
++ thd->lex= &lex_tmp;
++ lex_start(thd);
++ tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
++ new Item_null())));
++ /* Create the variable */
++ if (sql_set_variables(thd, &tmp_var_list))
++ {
++ thd->lex= sav_lex;
++ goto err;
++ }
++ thd->lex= sav_lex;
++ if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
++ goto err;
++ }
++ else if (var_entry->used_query_id == thd->query_id ||
++ mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id))
++ {
++ /*
++ If this variable was already stored in user_var_events by this query
++ (because it's used in more than one place in the query), don't store
++ it.
++ */
++ *out_entry= var_entry;
++ return 0;
++ }
++
++ uint size;
++ /*
++ First we need to store value of var_entry, when the next situation
++ appears:
++ > set @a:=1;
++ > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
++ We have to write to binlog value @a= 1.
++
++ We allocate the user_var_event on user_var_events_alloc pool, not on
++ the this-statement-execution pool because in SPs user_var_event objects
++ may need to be valid after current [SP] statement execution pool is
++ destroyed.
++ */
++ size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
++ if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
++ alloc_root(thd->user_var_events_alloc, size)))
++ goto err;
++
++ user_var_event->value= (char*) user_var_event +
++ ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
++ user_var_event->user_var_event= var_entry;
++ user_var_event->type= var_entry->type;
++ user_var_event->charset_number= var_entry->collation.collation->number;
++ if (!var_entry->value)
++ {
++ /* NULL value*/
++ user_var_event->length= 0;
++ user_var_event->value= 0;
++ }
++ else
++ {
++ user_var_event->length= var_entry->length;
++ memcpy(user_var_event->value, var_entry->value,
++ var_entry->length);
++ }
++ /* Mark that this variable has been used by this query */
++ var_entry->used_query_id= thd->query_id;
++ if (insert_dynamic(&thd->user_var_events, (uchar*) &user_var_event))
++ goto err;
++
++ *out_entry= var_entry;
++ return 0;
++
++err:
++ *out_entry= var_entry;
++ return 1;
++}
++
++void Item_func_get_user_var::fix_length_and_dec()
++{
++ THD *thd=current_thd;
++ int error;
++ maybe_null=1;
++ decimals=NOT_FIXED_DEC;
++ max_length=MAX_BLOB_WIDTH;
++
++ error= get_var_with_binlog(thd, thd->lex->sql_command, name, &var_entry);
++
++ /*
++ If the variable didn't exist it has been created as a STRING-type.
++ 'var_entry' is NULL only if there occured an error during the call to
++ get_var_with_binlog.
++ */
++ if (var_entry)
++ {
++ m_cached_result_type= var_entry->type;
++ unsigned_flag= var_entry->unsigned_flag;
++ max_length= var_entry->length;
++
++ collation.set(var_entry->collation);
++ switch(m_cached_result_type) {
++ case REAL_RESULT:
++ max_length= DBL_DIG + 8;
++ break;
++ case INT_RESULT:
++ max_length= MAX_BIGINT_WIDTH;
++ decimals=0;
++ break;
++ case STRING_RESULT:
++ max_length= MAX_BLOB_WIDTH - 1;
++ break;
++ case DECIMAL_RESULT:
++ max_length= DECIMAL_MAX_STR_LENGTH;
++ decimals= DECIMAL_MAX_SCALE;
++ break;
++ case ROW_RESULT: // Keep compiler happy
++ default:
++ DBUG_ASSERT(0);
++ break;
++ }
++ }
++ else
++ {
++ collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
++ null_value= 1;
++ m_cached_result_type= STRING_RESULT;
++ max_length= MAX_BLOB_WIDTH;
++ }
++
++ if (error)
++ thd->fatal_error();
++
++ return;
++}
++
++
++bool Item_func_get_user_var::const_item() const
++{
++ return (!var_entry || current_thd->query_id != var_entry->update_query_id);
++}
++
++
++enum Item_result Item_func_get_user_var::result_type() const
++{
++ return m_cached_result_type;
++}
++
++
++void Item_func_get_user_var::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("(@"));
++ str->append(name.str,name.length);
++ str->append(')');
++}
++
++
++bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
++{
++ /* Assume we don't have rtti */
++ if (this == item)
++ return 1; // Same item is same.
++ /* Check if other type is also a get_user_var() object */
++ if (item->type() != FUNC_ITEM ||
++ ((Item_func*) item)->functype() != functype())
++ return 0;
++ Item_func_get_user_var *other=(Item_func_get_user_var*) item;
++ return (name.length == other->name.length &&
++ !memcmp(name.str, other->name.str, name.length));
++}
++
++
++bool Item_func_get_user_var::set_value(THD *thd,
++ sp_rcontext * /*ctx*/, Item **it)
++{
++ Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it);
++ /*
++ Item_func_set_user_var is not fixed after construction, call
++ fix_fields().
++ */
++ return (!suv || suv->fix_fields(thd, it) || suv->check(0) || suv->update());
++}
++
++
++bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
++{
++ DBUG_ASSERT(fixed == 0);
++ DBUG_ASSERT(thd->lex->exchange);
++ if (Item::fix_fields(thd, ref) ||
++ !(entry= get_variable(&thd->user_vars, name, 1)))
++ return TRUE;
++ entry->type= STRING_RESULT;
++ /*
++ Let us set the same collation which is used for loading
++ of fields in LOAD DATA INFILE.
++ (Since Item_user_var_as_out_param is used only there).
++ */
++ entry->collation.set(thd->lex->exchange->cs ?
++ thd->lex->exchange->cs :
++ thd->variables.collation_database);
++ entry->update_query_id= thd->query_id;
++ return FALSE;
++}
++
++
++void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
++{
++ if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
++ DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
++ current_thd->fatal_error(); // Probably end of memory
++}
++
++
++void Item_user_var_as_out_param::set_value(const char *str, uint length,
++ CHARSET_INFO* cs)
++{
++ if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
++ DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
++ current_thd->fatal_error(); // Probably end of memory
++}
++
++
++double Item_user_var_as_out_param::val_real()
++{
++ DBUG_ASSERT(0);
++ return 0.0;
++}
++
++
++longlong Item_user_var_as_out_param::val_int()
++{
++ DBUG_ASSERT(0);
++ return 0;
++}
++
++
++String* Item_user_var_as_out_param::val_str(String *str)
++{
++ DBUG_ASSERT(0);
++ return 0;
++}
++
++
++my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
++{
++ DBUG_ASSERT(0);
++ return 0;
++}
++
++
++void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
++{
++ str->append('@');
++ str->append(name.str,name.length);
++}
++
++
++Item_func_get_system_var::
++Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
++ LEX_STRING *component_arg, const char *name_arg,
++ size_t name_len_arg)
++ :var(var_arg), var_type(var_type_arg), orig_var_type(var_type_arg),
++ component(*component_arg), cache_present(0)
++{
++ /* set_name() will allocate the name */
++ set_name(name_arg, (uint) name_len_arg, system_charset_info);
++}
++
++
++bool Item_func_get_system_var::is_written_to_binlog()
++{
++ return var->is_written_to_binlog(var_type);
++}
++
++
++void Item_func_get_system_var::update_null_value()
++{
++ THD *thd= current_thd;
++ int save_no_errors= thd->no_errors;
++ thd->no_errors= TRUE;
++ Item::update_null_value();
++ thd->no_errors= save_no_errors;
++}
++
++
++void Item_func_get_system_var::fix_length_and_dec()
++{
++ char *cptr;
++ maybe_null= TRUE;
++ max_length= 0;
++
++ if (var->check_type(var_type))
++ {
++ if (var_type != OPT_DEFAULT)
++ {
++ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
++ var->name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
++ return;
++ }
++ /* As there was no local variable, return the global value */
++ var_type= OPT_GLOBAL;
++ }
++
++ switch (var->show_type())
++ {
++ case SHOW_LONG:
++ case SHOW_INT:
++ case SHOW_HA_ROWS:
++ unsigned_flag= TRUE;
++ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
++ decimals=0;
++ break;
++ case SHOW_LONGLONG:
++ unsigned_flag= TRUE;
++ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
++ decimals=0;
++ break;
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ cptr= var->show_type() == SHOW_CHAR_PTR ?
++ *(char**) var->value_ptr(current_thd, var_type, &component) :
++ (char*) var->value_ptr(current_thd, var_type, &component);
++ if (cptr)
++ max_length= strlen(cptr) * system_charset_info->mbmaxlen;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ collation.set(system_charset_info, DERIVATION_SYSCONST);
++ decimals=NOT_FIXED_DEC;
++ break;
++ case SHOW_BOOL:
++ case SHOW_MY_BOOL:
++ unsigned_flag= FALSE;
++ max_length= 1;
++ decimals=0;
++ break;
++ case SHOW_DOUBLE:
++ unsigned_flag= FALSE;
++ decimals= 6;
++ max_length= DBL_DIG + 6;
++ break;
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ break;
++ }
++}
++
++
++void Item_func_get_system_var::print(String *str, enum_query_type query_type)
++{
++ str->append(name, name_length);
++}
++
++
++enum Item_result Item_func_get_system_var::result_type() const
++{
++ switch (var->show_type())
++ {
++ case SHOW_BOOL:
++ case SHOW_MY_BOOL:
++ case SHOW_INT:
++ case SHOW_LONG:
++ case SHOW_LONGLONG:
++ case SHOW_HA_ROWS:
++ return INT_RESULT;
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ return STRING_RESULT;
++ case SHOW_DOUBLE:
++ return REAL_RESULT;
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ return STRING_RESULT; // keep the compiler happy
++ }
++}
++
++
++enum_field_types Item_func_get_system_var::field_type() const
++{
++ switch (var->show_type())
++ {
++ case SHOW_BOOL:
++ case SHOW_MY_BOOL:
++ case SHOW_INT:
++ case SHOW_LONG:
++ case SHOW_LONGLONG:
++ case SHOW_HA_ROWS:
++ return MYSQL_TYPE_LONGLONG;
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ return MYSQL_TYPE_VARCHAR;
++ case SHOW_DOUBLE:
++ return MYSQL_TYPE_DOUBLE;
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ return MYSQL_TYPE_VARCHAR; // keep the compiler happy
++ }
++}
++
++
++/*
++ Uses var, var_type, component, cache_present, used_query_id, thd,
++ cached_llval, null_value, cached_null_value
++*/
++#define get_sys_var_safe(type) \
++do { \
++ type value; \
++ pthread_mutex_lock(&LOCK_global_system_variables); \
++ value= *(type*) var->value_ptr(thd, var_type, &component); \
++ pthread_mutex_unlock(&LOCK_global_system_variables); \
++ cache_present |= GET_SYS_VAR_CACHE_LONG; \
++ used_query_id= thd->query_id; \
++ cached_llval= null_value ? 0 : (longlong) value; \
++ cached_null_value= null_value; \
++ return cached_llval; \
++} while (0)
++
++
++longlong Item_func_get_system_var::val_int()
++{
++ THD *thd= current_thd;
++
++ if (cache_present && thd->query_id == used_query_id)
++ {
++ if (cache_present & GET_SYS_VAR_CACHE_LONG)
++ {
++ null_value= cached_null_value;
++ return cached_llval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
++ {
++ null_value= cached_null_value;
++ cached_llval= (longlong) cached_dval;
++ cache_present|= GET_SYS_VAR_CACHE_LONG;
++ return cached_llval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_STRING)
++ {
++ null_value= cached_null_value;
++ if (!null_value)
++ cached_llval= longlong_from_string_with_check (cached_strval.charset(),
++ cached_strval.c_ptr(),
++ cached_strval.c_ptr() +
++ cached_strval.length());
++ else
++ cached_llval= 0;
++ cache_present|= GET_SYS_VAR_CACHE_LONG;
++ return cached_llval;
++ }
++ }
++
++ switch (var->show_type())
++ {
++ case SHOW_INT: get_sys_var_safe (uint);
++ case SHOW_LONG: get_sys_var_safe (ulong);
++ case SHOW_LONGLONG: get_sys_var_safe (ulonglong);
++ case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
++ case SHOW_BOOL: get_sys_var_safe (bool);
++ case SHOW_MY_BOOL: get_sys_var_safe (my_bool);
++ case SHOW_DOUBLE:
++ {
++ double dval= val_real();
++
++ used_query_id= thd->query_id;
++ cached_llval= (longlong) dval;
++ cache_present|= GET_SYS_VAR_CACHE_LONG;
++ return cached_llval;
++ }
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ {
++ String *str_val= val_str(NULL);
++
++ if (str_val && str_val->length())
++ cached_llval= longlong_from_string_with_check (system_charset_info,
++ str_val->c_ptr(),
++ str_val->c_ptr() +
++ str_val->length());
++ else
++ {
++ null_value= TRUE;
++ cached_llval= 0;
++ }
++
++ cache_present|= GET_SYS_VAR_CACHE_LONG;
++ return cached_llval;
++ }
++
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ return 0; // keep the compiler happy
++ }
++}
++
++
++String* Item_func_get_system_var::val_str(String* str)
++{
++ THD *thd= current_thd;
++
++ if (cache_present && thd->query_id == used_query_id)
++ {
++ if (cache_present & GET_SYS_VAR_CACHE_STRING)
++ {
++ null_value= cached_null_value;
++ return null_value ? NULL : &cached_strval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_LONG)
++ {
++ null_value= cached_null_value;
++ if (!null_value)
++ cached_strval.set (cached_llval, collation.collation);
++ cache_present|= GET_SYS_VAR_CACHE_STRING;
++ return null_value ? NULL : &cached_strval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
++ {
++ null_value= cached_null_value;
++ if (!null_value)
++ cached_strval.set_real (cached_dval, decimals, collation.collation);
++ cache_present|= GET_SYS_VAR_CACHE_STRING;
++ return null_value ? NULL : &cached_strval;
++ }
++ }
++
++ str= &cached_strval;
++ switch (var->show_type())
++ {
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ {
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ char *cptr= var->show_type() == SHOW_CHAR_PTR ?
++ *(char**) var->value_ptr(thd, var_type, &component) :
++ (char*) var->value_ptr(thd, var_type, &component);
++ if (cptr)
++ {
++ if (str->copy(cptr, strlen(cptr), collation.collation))
++ {
++ null_value= TRUE;
++ str= NULL;
++ }
++ }
++ else
++ {
++ null_value= TRUE;
++ str= NULL;
++ }
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ break;
++ }
++
++ case SHOW_INT:
++ case SHOW_LONG:
++ case SHOW_LONGLONG:
++ case SHOW_HA_ROWS:
++ case SHOW_BOOL:
++ case SHOW_MY_BOOL:
++ str->set (val_int(), collation.collation);
++ break;
++ case SHOW_DOUBLE:
++ str->set_real (val_real(), decimals, collation.collation);
++ break;
++
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ str= NULL;
++ break;
++ }
++
++ cache_present|= GET_SYS_VAR_CACHE_STRING;
++ used_query_id= thd->query_id;
++ cached_null_value= null_value;
++ return str;
++}
++
++
++double Item_func_get_system_var::val_real()
++{
++ THD *thd= current_thd;
++
++ if (cache_present && thd->query_id == used_query_id)
++ {
++ if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
++ {
++ null_value= cached_null_value;
++ return cached_dval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_LONG)
++ {
++ null_value= cached_null_value;
++ cached_dval= (double)cached_llval;
++ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
++ return cached_dval;
++ }
++ else if (cache_present & GET_SYS_VAR_CACHE_STRING)
++ {
++ null_value= cached_null_value;
++ if (!null_value)
++ cached_dval= double_from_string_with_check (cached_strval.charset(),
++ cached_strval.c_ptr(),
++ cached_strval.c_ptr() +
++ cached_strval.length());
++ else
++ cached_dval= 0;
++ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
++ return cached_dval;
++ }
++ }
++
++ switch (var->show_type())
++ {
++ case SHOW_DOUBLE:
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ cached_dval= *(double*) var->value_ptr(thd, var_type, &component);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ used_query_id= thd->query_id;
++ cached_null_value= null_value;
++ if (null_value)
++ cached_dval= 0;
++ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
++ return cached_dval;
++ case SHOW_CHAR:
++ case SHOW_CHAR_PTR:
++ {
++ char *cptr;
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ cptr= var->show_type() == SHOW_CHAR ?
++ (char*) var->value_ptr(thd, var_type, &component) :
++ *(char**) var->value_ptr(thd, var_type, &component);
++ if (cptr)
++ cached_dval= double_from_string_with_check (system_charset_info,
++ cptr, cptr + strlen (cptr));
++ else
++ {
++ null_value= TRUE;
++ cached_dval= 0;
++ }
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ used_query_id= thd->query_id;
++ cached_null_value= null_value;
++ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
++ return cached_dval;
++ }
++ case SHOW_INT:
++ case SHOW_LONG:
++ case SHOW_LONGLONG:
++ case SHOW_HA_ROWS:
++ case SHOW_BOOL:
++ case SHOW_MY_BOOL:
++ cached_dval= (double) val_int();
++ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
++ used_query_id= thd->query_id;
++ cached_null_value= null_value;
++ return cached_dval;
++ default:
++ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
++ return 0;
++ }
++}
++
++
++bool Item_func_get_system_var::eq(const Item *item, bool binary_cmp) const
++{
++ /* Assume we don't have rtti */
++ if (this == item)
++ return 1; // Same item is same.
++ /* Check if other type is also a get_user_var() object */
++ if (item->type() != FUNC_ITEM ||
++ ((Item_func*) item)->functype() != functype())
++ return 0;
++ Item_func_get_system_var *other=(Item_func_get_system_var*) item;
++ return (var == other->var && var_type == other->var_type);
++}
++
++
++void Item_func_get_system_var::cleanup()
++{
++ Item_func::cleanup();
++ cache_present= 0;
++ var_type= orig_var_type;
++ cached_strval.free();
++}
++
++
++longlong Item_func_inet_aton::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ uint byte_result = 0;
++ ulonglong result = 0; // We are ready for 64 bit addresses
++ const char *p,* end;
++ char c = '.'; // we mark c to indicate invalid IP in case length is 0
++ char buff[36];
++ int dot_count= 0;
++
++ String *s,tmp(buff,sizeof(buff),&my_charset_bin);
++ if (!(s = args[0]->val_str(&tmp))) // If null value
++ goto err;
++ null_value=0;
++
++ end= (p = s->ptr()) + s->length();
++ while (p < end)
++ {
++ c = *p++;
++ int digit = (int) (c - '0'); // Assume ascii
++ if (digit >= 0 && digit <= 9)
++ {
++ if ((byte_result = byte_result * 10 + digit) > 255)
++ goto err; // Wrong address
++ }
++ else if (c == '.')
++ {
++ dot_count++;
++ result= (result << 8) + (ulonglong) byte_result;
++ byte_result = 0;
++ }
++ else
++ goto err; // Invalid character
++ }
++ if (c != '.') // IP number can't end on '.'
++ {
++ /*
++ Handle short-forms addresses according to standard. Examples:
++ 127 -> 0.0.0.127
++ 127.1 -> 127.0.0.1
++ 127.2.1 -> 127.2.0.1
++ */
++ switch (dot_count) {
++ case 1: result<<= 8; /* Fall through */
++ case 2: result<<= 8; /* Fall through */
++ }
++ return (result << 8) + (ulonglong) byte_result;
++ }
++
++err:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_match::init_search(bool no_order)
++{
++ DBUG_ENTER("Item_func_match::init_search");
++
++ /* Check if init_search() has been called before */
++ if (ft_handler)
++ {
++ /*
++ We should reset ft_handler as it is cleaned up
++ on destruction of FT_SELECT object
++ (necessary in case of re-execution of subquery).
++ TODO: FT_SELECT should not clean up ft_handler.
++ */
++ if (join_key)
++ table->file->ft_handler= ft_handler;
++ DBUG_VOID_RETURN;
++ }
++
++ if (key == NO_SUCH_KEY)
++ {
++ List<Item> fields;
++ fields.push_back(new Item_string(" ",1, cmp_collation.collation));
++ for (uint i=1; i < arg_count; i++)
++ fields.push_back(args[i]);
++ concat_ws=new Item_func_concat_ws(fields);
++ /*
++ Above function used only to get value and do not need fix_fields for it:
++ Item_string - basic constant
++ fields - fix_fields() was already called for this arguments
++ Item_func_concat_ws - do not need fix_fields() to produce value
++ */
++ concat_ws->quick_fix_field();
++ }
++
++ if (master)
++ {
++ join_key=master->join_key=join_key|master->join_key;
++ master->init_search(no_order);
++ ft_handler=master->ft_handler;
++ join_key=master->join_key;
++ DBUG_VOID_RETURN;
++ }
++
++ String *ft_tmp= 0;
++
++ // MATCH ... AGAINST (NULL) is meaningless, but possible
++ if (!(ft_tmp=key_item()->val_str(&value)))
++ {
++ ft_tmp= &value;
++ value.set("",0,cmp_collation.collation);
++ }
++
++ if (ft_tmp->charset() != cmp_collation.collation)
++ {
++ uint dummy_errors;
++ search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
++ cmp_collation.collation, &dummy_errors);
++ ft_tmp= &search_value;
++ }
++
++ if (join_key && !no_order)
++ flags|=FT_SORTED;
++ ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
++
++ if (join_key)
++ table->file->ft_handler=ft_handler;
++
++ DBUG_VOID_RETURN;
++}
++
++
++bool Item_func_match::fix_fields(THD *thd, Item **ref)
++{
++ DBUG_ASSERT(fixed == 0);
++ Item *UNINIT_VAR(item); // Safe as arg_count is > 1
++
++ maybe_null=1;
++ join_key=0;
++
++ /*
++ const_item is assumed in quite a bit of places, so it would be difficult
++ to remove; If it would ever to be removed, this should include
++ modifications to find_best and auto_close as complement to auto_init code
++ above.
++ */
++ if (Item_func::fix_fields(thd, ref) ||
++ !args[0]->const_during_execution())
++ {
++ my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
++ return TRUE;
++ }
++
++ const_item_cache=0;
++ for (uint i=1 ; i < arg_count ; i++)
++ {
++ item=args[i];
++ if (item->type() == Item::REF_ITEM)
++ args[i]= item= *((Item_ref *)item)->ref;
++ if (item->type() != Item::FIELD_ITEM)
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST");
++ return TRUE;
++ }
++ }
++ /*
++ Check that all columns come from the same table.
++ We've already checked that columns in MATCH are fields so
++ PARAM_TABLE_BIT can only appear from AGAINST argument.
++ */
++ if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
++ key=NO_SUCH_KEY;
++
++ if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
++ {
++ my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
++ return TRUE;
++ }
++ table=((Item_field *)item)->field->table;
++ if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT))
++ {
++ my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
++ return 1;
++ }
++ table->fulltext_searched=1;
++ return agg_arg_collations_for_comparison(cmp_collation,
++ args+1, arg_count-1, 0);
++}
++
++bool Item_func_match::fix_index()
++{
++ Item_field *item;
++ uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr;
++ uint max_cnt=0, mkeys=0, i;
++
++ if (key == NO_SUCH_KEY)
++ return 0;
++
++ if (!table)
++ goto err;
++
++ for (keynr=0 ; keynr < table->s->keys ; keynr++)
++ {
++ if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
++ (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
++ table->s->keys_in_use.is_set(keynr)))
++
++ {
++ ft_to_key[fts]=keynr;
++ ft_cnt[fts]=0;
++ fts++;
++ }
++ }
++
++ if (!fts)
++ goto err;
++
++ for (i=1; i < arg_count; i++)
++ {
++ item=(Item_field*)args[i];
++ for (keynr=0 ; keynr < fts ; keynr++)
++ {
++ KEY *ft_key=&table->key_info[ft_to_key[keynr]];
++ uint key_parts=ft_key->key_parts;
++
++ for (uint part=0 ; part < key_parts ; part++)
++ {
++ if (item->field->eq(ft_key->key_part[part].field))
++ ft_cnt[keynr]++;
++ }
++ }
++ }
++
++ for (keynr=0 ; keynr < fts ; keynr++)
++ {
++ if (ft_cnt[keynr] > max_cnt)
++ {
++ mkeys=0;
++ max_cnt=ft_cnt[mkeys]=ft_cnt[keynr];
++ ft_to_key[mkeys]=ft_to_key[keynr];
++ continue;
++ }
++ if (max_cnt && ft_cnt[keynr] == max_cnt)
++ {
++ mkeys++;
++ ft_cnt[mkeys]=ft_cnt[keynr];
++ ft_to_key[mkeys]=ft_to_key[keynr];
++ continue;
++ }
++ }
++
++ for (keynr=0 ; keynr <= mkeys ; keynr++)
++ {
++ // partial keys doesn't work
++ if (max_cnt < arg_count-1 ||
++ max_cnt < table->key_info[ft_to_key[keynr]].key_parts)
++ continue;
++
++ key=ft_to_key[keynr];
++
++ return 0;
++ }
++
++err:
++ if (flags & FT_BOOL)
++ {
++ key=NO_SUCH_KEY;
++ return 0;
++ }
++ my_message(ER_FT_MATCHING_KEY_NOT_FOUND,
++ ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0));
++ return 1;
++}
++
++
++bool Item_func_match::eq(const Item *item, bool binary_cmp) const
++{
++ if (item->type() != FUNC_ITEM ||
++ ((Item_func*)item)->functype() != FT_FUNC ||
++ flags != ((Item_func_match*)item)->flags)
++ return 0;
++
++ Item_func_match *ifm=(Item_func_match*) item;
++
++ if (key == ifm->key && table == ifm->table &&
++ key_item()->eq(ifm->key_item(), binary_cmp))
++ return 1;
++
++ return 0;
++}
++
++
++double Item_func_match::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ DBUG_ENTER("Item_func_match::val");
++ if (ft_handler == NULL)
++ DBUG_RETURN(-1.0);
++
++ if (key != NO_SUCH_KEY && table->null_row) /* NULL row from an outer join */
++ DBUG_RETURN(0.0);
++
++ if (join_key)
++ {
++ if (table->file->ft_handler)
++ DBUG_RETURN(ft_handler->please->get_relevance(ft_handler));
++ join_key=0;
++ }
++
++ if (key == NO_SUCH_KEY)
++ {
++ String *a= concat_ws->val_str(&value);
++ if ((null_value= (a == 0)) || !a->length())
++ DBUG_RETURN(0);
++ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
++ (uchar *)a->ptr(), a->length()));
++ }
++ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
++ table->record[0], 0));
++}
++
++void Item_func_match::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("(match "));
++ print_args(str, 1, query_type);
++ str->append(STRING_WITH_LEN(" against ("));
++ args[0]->print(str, query_type);
++ if (flags & FT_BOOL)
++ str->append(STRING_WITH_LEN(" in boolean mode"));
++ else if (flags & FT_EXPAND)
++ str->append(STRING_WITH_LEN(" with query expansion"));
++ str->append(STRING_WITH_LEN("))"));
++}
++
++longlong Item_func_bit_xor::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ ulonglong arg1= (ulonglong) args[0]->val_int();
++ ulonglong arg2= (ulonglong) args[1]->val_int();
++ if ((null_value= (args[0]->null_value || args[1]->null_value)))
++ return 0;
++ return (longlong) (arg1 ^ arg2);
++}
++
++
++/***************************************************************************
++ System variables
++****************************************************************************/
++
++/**
++ Return value of an system variable base[.name] as a constant item.
++
++ @param thd Thread handler
++ @param var_type global / session
++ @param name Name of base or system variable
++ @param component Component.
++
++ @note
++ If component.str = 0 then the variable name is in 'name'
++
++ @return
++ - 0 : error
++ - # : constant item
++*/
++
++
++Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
++ LEX_STRING component)
++{
++ sys_var *var;
++ LEX_STRING *base_name, *component_name;
++
++ if (component.str)
++ {
++ base_name= &component;
++ component_name= &name;
++ }
++ else
++ {
++ base_name= &name;
++ component_name= &component; // Empty string
++ }
++
++ if (!(var= find_sys_var(thd, base_name->str, base_name->length)))
++ return 0;
++ if (component.str)
++ {
++ if (!var->is_struct())
++ {
++ my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str);
++ return 0;
++ }
++ }
++ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
++
++ set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH);
++
++ return new Item_func_get_system_var(var, var_type, component_name,
++ NULL, 0);
++}
++
++
++/**
++ Check a user level lock.
++
++ Sets null_value=TRUE on error.
++
++ @retval
++ 1 Available
++ @retval
++ 0 Already taken, or error
++*/
++
++longlong Item_func_is_free_lock::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ User_level_lock *ull;
++
++ null_value=0;
++ if (!res || !res->length())
++ {
++ null_value=1;
++ return 0;
++ }
++
++ pthread_mutex_lock(&LOCK_user_locks);
++ ull= (User_level_lock *) hash_search(&hash_user_locks, (uchar*) res->ptr(),
++ (size_t) res->length());
++ pthread_mutex_unlock(&LOCK_user_locks);
++ if (!ull || !ull->locked)
++ return 1;
++ return 0;
++}
++
++longlong Item_func_is_used_lock::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ User_level_lock *ull;
++
++ null_value=1;
++ if (!res || !res->length())
++ return 0;
++
++ pthread_mutex_lock(&LOCK_user_locks);
++ ull= (User_level_lock *) hash_search(&hash_user_locks, (uchar*) res->ptr(),
++ (size_t) res->length());
++ pthread_mutex_unlock(&LOCK_user_locks);
++ if (!ull || !ull->locked)
++ return 0;
++
++ null_value=0;
++ return ull->thread_id;
++}
++
++
++longlong Item_func_row_count::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ THD *thd= current_thd;
++
++ return thd->row_count_func;
++}
++
++
++
++
++Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name)
++ :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
++{
++ maybe_null= 1;
++ m_name->init_qname(current_thd);
++ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
++ dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
++}
++
++
++Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
++ sp_name *name, List<Item> &list)
++ :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL)
++{
++ maybe_null= 1;
++ m_name->init_qname(current_thd);
++ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
++ dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
++}
++
++
++void
++Item_func_sp::cleanup()
++{
++ if (sp_result_field)
++ {
++ delete sp_result_field;
++ sp_result_field= NULL;
++ }
++ m_sp= NULL;
++ dummy_table->alias= NULL;
++ Item_func::cleanup();
++}
++
++const char *
++Item_func_sp::func_name() const
++{
++ THD *thd= current_thd;
++ /* Calculate length to avoid reallocation of string for sure */
++ uint len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
++ m_name->m_name.length)*2 + //characters*quoting
++ 2 + // ` and `
++ (m_name->m_explicit_name ?
++ 3 : 0) + // '`', '`' and '.' for the db
++ 1 + // end of string
++ ALIGN_SIZE(1)); // to avoid String reallocation
++ String qname((char *)alloc_root(thd->mem_root, len), len,
++ system_charset_info);
++
++ qname.length(0);
++ if (m_name->m_explicit_name)
++ {
++ append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length);
++ qname.append('.');
++ }
++ append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length);
++ return qname.ptr();
++}
++
++
++int my_missing_function_error(const LEX_STRING &token, const char *func_name)
++{
++ if (token.length && is_lex_native_function (&token))
++ return my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name);
++ else
++ return my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name);
++}
++
++
++/**
++ @brief Initialize the result field by creating a temporary dummy table
++ and assign it to a newly created field object. Meta data used to
++ create the field is fetched from the sp_head belonging to the stored
++ proceedure found in the stored procedure functon cache.
++
++ @note This function should be called from fix_fields to init the result
++ field. It is some what related to Item_field.
++
++ @see Item_field
++
++ @param thd A pointer to the session and thread context.
++
++ @return Function return error status.
++ @retval TRUE is returned on an error
++ @retval FALSE is returned on success.
++*/
++
++bool
++Item_func_sp::init_result_field(THD *thd)
++{
++ LEX_STRING empty_name= { C_STRING_WITH_LEN("") };
++ TABLE_SHARE *share;
++ DBUG_ENTER("Item_func_sp::init_result_field");
++
++ DBUG_ASSERT(m_sp == NULL);
++ DBUG_ASSERT(sp_result_field == NULL);
++
++ if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
++ &thd->sp_func_cache, TRUE)))
++ {
++ my_missing_function_error (m_name->m_name, m_name->m_qname.str);
++ context->process_error(thd);
++ DBUG_RETURN(TRUE);
++ }
++
++ /*
++ A Field need to be attached to a Table.
++ Below we "create" a dummy table by initializing
++ the needed pointers.
++ */
++
++ share= dummy_table->s;
++ dummy_table->alias = "";
++ dummy_table->maybe_null = maybe_null;
++ dummy_table->in_use= thd;
++ dummy_table->copy_blobs= TRUE;
++ share->table_cache_key = empty_name;
++ share->table_name = empty_name;
++
++ if (!(sp_result_field= m_sp->create_result_field(max_length, name,
++ dummy_table)))
++ {
++ DBUG_RETURN(TRUE);
++ }
++
++ if (sp_result_field->pack_length() > sizeof(result_buf))
++ {
++ void *tmp;
++ if (!(tmp= sql_alloc(sp_result_field->pack_length())))
++ DBUG_RETURN(TRUE);
++ sp_result_field->move_field((uchar*) tmp);
++ }
++ else
++ sp_result_field->move_field(result_buf);
++
++ sp_result_field->null_ptr= (uchar *) &null_value;
++ sp_result_field->null_bit= 1;
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ @brief Initialize local members with values from the Field interface.
++
++ @note called from Item::fix_fields.
++*/
++
++void Item_func_sp::fix_length_and_dec()
++{
++ DBUG_ENTER("Item_func_sp::fix_length_and_dec");
++
++ DBUG_ASSERT(sp_result_field);
++ decimals= sp_result_field->decimals();
++ max_length= sp_result_field->field_length;
++ collation.set(sp_result_field->charset());
++ maybe_null= 1;
++ unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG);
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ @brief Execute function & store value in field.
++
++ @return Function returns error status.
++ @retval FALSE on success.
++ @retval TRUE if an error occurred.
++*/
++
++bool
++Item_func_sp::execute()
++{
++ THD *thd= current_thd;
++
++ /* Execute function and store the return value in the field. */
++
++ if (execute_impl(thd))
++ {
++ null_value= 1;
++ context->process_error(thd);
++ if (thd->killed)
++ thd->send_kill_message();
++ return TRUE;
++ }
++
++ /* Check that the field (the value) is not NULL. */
++
++ null_value= sp_result_field->is_null();
++
++ return null_value;
++}
++
++
++/**
++ @brief Execute function and store the return value in the field.
++
++ @note This function was intended to be the concrete implementation of
++ the interface function execute. This was never realized.
++
++ @return The error state.
++ @retval FALSE on success
++ @retval TRUE if an error occurred.
++*/
++bool
++Item_func_sp::execute_impl(THD *thd)
++{
++ bool err_status= TRUE;
++ Sub_statement_state statement_state;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ Security_context *save_security_ctx= thd->security_ctx;
++#endif
++ enum enum_sp_data_access access=
++ (m_sp->m_chistics->daccess == SP_DEFAULT_ACCESS) ?
++ SP_DEFAULT_ACCESS_MAPPING : m_sp->m_chistics->daccess;
++
++ DBUG_ENTER("Item_func_sp::execute_impl");
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (context->security_ctx)
++ {
++ /* Set view definer security context */
++ thd->security_ctx= context->security_ctx;
++ }
++#endif
++ if (sp_check_access(thd))
++ goto error;
++
++ /*
++ Throw an error if a non-deterministic function is called while
++ statement-based replication (SBR) is active.
++ */
++
++ if (!m_sp->m_chistics->detistic && !trust_function_creators &&
++ (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) &&
++ (mysql_bin_log.is_open() &&
++ thd->variables.binlog_format == BINLOG_FORMAT_STMT))
++ {
++ my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0));
++ goto error;
++ }
++
++ /*
++ Disable the binlogging if this is not a SELECT statement. If this is a
++ SELECT, leave binlogging on, so execute_function() code writes the
++ function call into binlog.
++ */
++ thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
++ err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field);
++ thd->restore_sub_statement_state(&statement_state);
++
++error:
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ thd->security_ctx= save_security_ctx;
++#endif
++
++ DBUG_RETURN(err_status);
++}
++
++
++void
++Item_func_sp::make_field(Send_field *tmp_field)
++{
++ DBUG_ENTER("Item_func_sp::make_field");
++ DBUG_ASSERT(sp_result_field);
++ sp_result_field->make_field(tmp_field);
++ if (name)
++ tmp_field->col_name= name;
++ DBUG_VOID_RETURN;
++}
++
++
++enum enum_field_types
++Item_func_sp::field_type() const
++{
++ DBUG_ENTER("Item_func_sp::field_type");
++ DBUG_ASSERT(sp_result_field);
++ DBUG_RETURN(sp_result_field->type());
++}
++
++Item_result
++Item_func_sp::result_type() const
++{
++ DBUG_ENTER("Item_func_sp::result_type");
++ DBUG_PRINT("info", ("m_sp = %p", (void *) m_sp));
++ DBUG_ASSERT(sp_result_field);
++ DBUG_RETURN(sp_result_field->result_type());
++}
++
++longlong Item_func_found_rows::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ return current_thd->found_rows();
++}
++
++
++Field *
++Item_func_sp::tmp_table_field(TABLE *t_arg)
++{
++ DBUG_ENTER("Item_func_sp::tmp_table_field");
++
++ DBUG_ASSERT(sp_result_field);
++ DBUG_RETURN(sp_result_field);
++}
++
++
++/**
++ @brief Checks if requested access to function can be granted to user.
++ If function isn't found yet, it searches function first.
++ If function can't be found or user don't have requested access
++ error is raised.
++
++ @param thd thread handler
++
++ @return Indication if the access was granted or not.
++ @retval FALSE Access is granted.
++ @retval TRUE Requested access can't be granted or function doesn't exists.
++
++*/
++
++bool
++Item_func_sp::sp_check_access(THD *thd)
++{
++ DBUG_ENTER("Item_func_sp::sp_check_access");
++ DBUG_ASSERT(m_sp);
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (check_routine_access(thd, EXECUTE_ACL,
++ m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
++ DBUG_RETURN(TRUE);
++#endif
++
++ DBUG_RETURN(FALSE);
++}
++
++
++bool
++Item_func_sp::fix_fields(THD *thd, Item **ref)
++{
++ bool res;
++ DBUG_ENTER("Item_func_sp::fix_fields");
++ DBUG_ASSERT(fixed == 0);
++
++ /*
++ We must call init_result_field before Item_func::fix_fields()
++ to make m_sp and result_field members available to fix_length_and_dec(),
++ which is called from Item_func::fix_fields().
++ */
++ res= init_result_field(thd);
++
++ if (res)
++ DBUG_RETURN(res);
++
++ res= Item_func::fix_fields(thd, ref);
++
++ if (res)
++ DBUG_RETURN(res);
++
++ if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
++ {
++ /*
++ Here we check privileges of the stored routine only during view
++ creation, in order to validate the view. A runtime check is
++ perfomed in Item_func_sp::execute(), and this method is not
++ called during context analysis. Notice, that during view
++ creation we do not infer into stored routine bodies and do not
++ check privileges of its statements, which would probably be a
++ good idea especially if the view has SQL SECURITY DEFINER and
++ the used stored procedure has SQL SECURITY DEFINER.
++ */
++ res= sp_check_access(thd);
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ /*
++ Try to set and restore the security context to see whether it's valid
++ */
++ Security_context *save_secutiry_ctx;
++ res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx);
++ if (!res)
++ m_sp->m_security_ctx.restore_security_context(thd, save_secutiry_ctx);
++
++#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
++ }
++
++ if (!m_sp->m_chistics->detistic)
++ {
++ used_tables_cache |= RAND_TABLE_BIT;
++ const_item_cache= FALSE;
++ }
++
++ DBUG_RETURN(res);
++}
++
++
++void Item_func_sp::update_used_tables()
++{
++ Item_func::update_used_tables();
++
++ if (!m_sp->m_chistics->detistic)
++ {
++ used_tables_cache |= RAND_TABLE_BIT;
++ const_item_cache= FALSE;
++ }
++}
++
++
++/*
++ uuid_short handling.
++
++ The short uuid is defined as a longlong that contains the following bytes:
++
++ Bytes Comment
++ 1 Server_id & 255
++ 4 Startup time of server in seconds
++ 3 Incrementor
++
++ This means that an uuid is guaranteed to be unique
++ even in a replication environment if the following holds:
++
++ - The last byte of the server id is unique
++ - If you between two shutdown of the server don't get more than
++ an average of 2^24 = 16M calls to uuid_short() per second.
++*/
++
++ulonglong uuid_value;
++
++void uuid_short_init()
++{
++ uuid_value= ((((ulonglong) server_id) << 56) +
++ (((ulonglong) server_start_time) << 24));
++}
++
++
++longlong Item_func_uuid_short::val_int()
++{
++ ulonglong val;
++ pthread_mutex_lock(&LOCK_uuid_generator);
++ val= uuid_value++;
++ pthread_mutex_unlock(&LOCK_uuid_generator);
++ return (longlong) val;
++}
+diff -urN mysql-old/sql/item_func.h mysql/sql/item_func.h
+--- mysql-old/sql/item_func.h 2011-05-10 17:45:45.640015709 +0000
++++ mysql/sql/item_func.h 2011-05-10 17:56:01.346682377 +0000
+@@ -420,7 +420,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -urN mysql-old/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql-old/sql/item_strfunc.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/item_strfunc.cc 2011-05-10 17:56:01.350015710 +0000
+@@ -388,7 +388,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -749,7 +749,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1250,7 +1250,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1270,7 +1270,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1961,7 +1961,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3113,11 +3113,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3580,7 +3580,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -urN mysql-old/sql/item_strfunc.cc.orig mysql/sql/item_strfunc.cc.orig
+--- mysql-old/sql/item_strfunc.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/item_strfunc.cc.orig 2011-04-12 12:11:38.000000000 +0000
+@@ -0,0 +1,3643 @@
++/* Copyright (C) 2000-2006 MySQL AB
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++
++/**
++ @file
++
++ @brief
++ This file defines all string functions
++
++ @warning
++ Some string functions don't always put and end-null on a String.
++ (This shouldn't be needed)
++*/
++
++#ifdef USE_PRAGMA_IMPLEMENTATION
++#pragma implementation // gcc: Class implementation
++#endif
++
++#include "mysql_priv.h"
++#include <m_ctype.h>
++#include "my_md5.h"
++#include "sha1.h"
++#include "my_aes.h"
++#include <zlib.h>
++C_MODE_START
++#include "../mysys/my_static.h" // For soundex_map
++C_MODE_END
++
++/**
++ @todo Remove this. It is not safe to use a shared String object.
++ */
++String my_empty_string("",default_charset_info);
++
++
++/*
++ Convert an array of bytes to a hexadecimal representation.
++
++ Used to generate a hexadecimal representation of a message digest.
++*/
++static void array_to_hex(char *to, const char *str, uint len)
++{
++ const char *str_end= str + len;
++ for (; str != str_end; ++str)
++ {
++ *to++= _dig_vec_lower[((uchar) *str) >> 4];
++ *to++= _dig_vec_lower[((uchar) *str) & 0x0F];
++ }
++}
++
++
++bool Item_str_func::fix_fields(THD *thd, Item **ref)
++{
++ bool res= Item_func::fix_fields(thd, ref);
++ /*
++ In Item_str_func::check_well_formed_result() we may set null_value
++ flag on the same condition as in test() below.
++ */
++ maybe_null= (maybe_null ||
++ test(thd->variables.sql_mode &
++ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)));
++ return res;
++}
++
++
++my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value)
++{
++ DBUG_ASSERT(fixed == 1);
++ char buff[64];
++ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
++ res= val_str(&tmp);
++ if (!res)
++ return 0;
++ (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
++ res->length(), res->charset(), decimal_value);
++ return decimal_value;
++}
++
++
++double Item_str_func::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ int err_not_used;
++ char *end_not_used, buff[64];
++ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
++ res= val_str(&tmp);
++ return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
++ &end_not_used, &err_not_used) : 0.0;
++}
++
++
++longlong Item_str_func::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ int err;
++ char buff[22];
++ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
++ res= val_str(&tmp);
++ return (res ?
++ my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
++ &err) :
++ (longlong) 0);
++}
++
++
++String *Item_func_md5::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String * sptr= args[0]->val_str(str);
++ str->set_charset(&my_charset_bin);
++ if (sptr)
++ {
++ uchar digest[16];
++
++ null_value=0;
++ MY_MD5_HASH(digest,(uchar *) sptr->ptr(), sptr->length());
++ if (str->alloc(32)) // Ensure that memory is free
++ {
++ null_value=1;
++ return 0;
++ }
++ array_to_hex((char *) str->ptr(), (const char*) digest, 16);
++ str->length((uint) 32);
++ return str;
++ }
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_md5::fix_length_and_dec()
++{
++ max_length=32;
++ /*
++ The MD5() function treats its parameter as being a case sensitive. Thus
++ we set binary collation on it so different instances of MD5() will be
++ compared properly.
++ */
++ args[0]->collation.set(
++ get_charset_by_csname(args[0]->collation.collation->csname,
++ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
++}
++
++
++String *Item_func_sha::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String * sptr= args[0]->val_str(str);
++ str->set_charset(&my_charset_bin);
++ if (sptr) /* If we got value different from NULL */
++ {
++ SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
++ /* Temporary buffer to store 160bit digest */
++ uint8 digest[SHA1_HASH_SIZE];
++ mysql_sha1_reset(&context); /* We do not have to check for error here */
++ /* No need to check error as the only case would be too long message */
++ mysql_sha1_input(&context,
++ (const uchar *) sptr->ptr(), sptr->length());
++ /* Ensure that memory is free and we got result */
++ if (!( str->alloc(SHA1_HASH_SIZE*2) ||
++ (mysql_sha1_result(&context,digest))))
++ {
++ array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
++ str->length((uint) SHA1_HASH_SIZE*2);
++ null_value=0;
++ return str;
++ }
++ }
++ null_value=1;
++ return 0;
++}
++
++void Item_func_sha::fix_length_and_dec()
++{
++ max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
++ /*
++ The SHA() function treats its parameter as being a case sensitive. Thus
++ we set binary collation on it so different instances of MD5() will be
++ compared properly.
++ */
++ args[0]->collation.set(
++ get_charset_by_csname(args[0]->collation.collation->csname,
++ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
++}
++
++
++/* Implementation of AES encryption routines */
++
++String *Item_func_aes_encrypt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char key_buff[80];
++ String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
++ String *sptr= args[0]->val_str(str); // String to encrypt
++ String *key= args[1]->val_str(&tmp_key_value); // key
++ int aes_length;
++ if (sptr && key) // we need both arguments to be not NULL
++ {
++ null_value=0;
++ aes_length=my_aes_get_size(sptr->length()); // Calculate result length
++
++ if (!str_value.alloc(aes_length)) // Ensure that memory is free
++ {
++ // finally encrypt directly to allocated buffer.
++ if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
++ key->ptr(), key->length()) == aes_length)
++ {
++ // We got the expected result length
++ str_value.length((uint) aes_length);
++ return &str_value;
++ }
++ }
++ }
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_aes_encrypt::fix_length_and_dec()
++{
++ max_length=my_aes_get_size(args[0]->max_length);
++}
++
++
++String *Item_func_aes_decrypt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char key_buff[80];
++ String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
++ String *sptr, *key;
++ DBUG_ENTER("Item_func_aes_decrypt::val_str");
++
++ sptr= args[0]->val_str(str); // String to decrypt
++ key= args[1]->val_str(&tmp_key_value); // Key
++ if (sptr && key) // Need to have both arguments not NULL
++ {
++ null_value=0;
++ if (!str_value.alloc(sptr->length())) // Ensure that memory is free
++ {
++ // finally decrypt directly to allocated buffer.
++ int length;
++ length=my_aes_decrypt(sptr->ptr(), sptr->length(),
++ (char*) str_value.ptr(),
++ key->ptr(), key->length());
++ if (length >= 0) // if we got correct data data
++ {
++ str_value.length((uint) length);
++ DBUG_RETURN(&str_value);
++ }
++ }
++ }
++ // Bad parameters. No memory or bad data will all go here
++ null_value=1;
++ DBUG_RETURN(0);
++}
++
++
++void Item_func_aes_decrypt::fix_length_and_dec()
++{
++ max_length=args[0]->max_length;
++ maybe_null= 1;
++}
++
++
++/**
++ Concatenate args with the following premises:
++ If only one arg (which is ok), return value of arg;
++ Don't reallocate val_str() if not absolute necessary.
++*/
++
++String *Item_func_concat::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res,*res2,*use_as_buff;
++ uint i;
++ bool is_const= 0;
++
++ null_value=0;
++ if (!(res=args[0]->val_str(str)))
++ goto null;
++ use_as_buff= &tmp_value;
++ /* Item_subselect in --ps-protocol mode will state it as a non-const */
++ is_const= args[0]->const_item() || !args[0]->used_tables();
++ for (i=1 ; i < arg_count ; i++)
++ {
++ if (res->length() == 0)
++ {
++ if (!(res=args[i]->val_str(str)))
++ goto null;
++ /*
++ CONCAT accumulates its result in the result of its the first
++ non-empty argument. Because of this we need is_const to be
++ evaluated only for it.
++ */
++ is_const= args[i]->const_item() || !args[i]->used_tables();
++ }
++ else
++ {
++ if (!(res2=args[i]->val_str(use_as_buff)))
++ goto null;
++ if (res2->length() == 0)
++ continue;
++ if (res->length()+res2->length() >
++ current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
++ current_thd->variables.max_allowed_packet);
++ goto null;
++ }
++ if (!is_const && res->alloced_length() >= res->length()+res2->length())
++ { // Use old buffer
++ res->append(*res2);
++ }
++ else if (str->alloced_length() >= res->length()+res2->length())
++ {
++ if (str->ptr() == res2->ptr())
++ str->replace(0,0,*res);
++ else
++ {
++ str->copy(*res);
++ str->append(*res2);
++ }
++ res= str;
++ use_as_buff= &tmp_value;
++ }
++ else if (res == &tmp_value)
++ {
++ if (res->append(*res2)) // Must be a blob
++ goto null;
++ }
++ else if (res2 == &tmp_value)
++ { // This can happend only 1 time
++ if (tmp_value.replace(0,0,*res))
++ goto null;
++ res= &tmp_value;
++ use_as_buff=str; // Put next arg here
++ }
++ else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
++ res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
++ {
++ /*
++ This happens really seldom:
++ In this case res2 is sub string of tmp_value. We will
++ now work in place in tmp_value to set it to res | res2
++ */
++ /* Chop the last characters in tmp_value that isn't in res2 */
++ tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
++ res2->length());
++ /* Place res2 at start of tmp_value, remove chars before res2 */
++ if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
++ *res))
++ goto null;
++ res= &tmp_value;
++ use_as_buff=str; // Put next arg here
++ }
++ else
++ { // Two big const strings
++ /*
++ NOTE: We should be prudent in the initial allocation unit -- the
++ size of the arguments is a function of data distribution, which
++ can be any. Instead of overcommitting at the first row, we grow
++ the allocated amount by the factor of 2. This ensures that no
++ more than 25% of memory will be overcommitted on average.
++ */
++
++ uint concat_len= res->length() + res2->length();
++
++ if (tmp_value.alloced_length() < concat_len)
++ {
++ if (tmp_value.alloced_length() == 0)
++ {
++ if (tmp_value.alloc(concat_len))
++ goto null;
++ }
++ else
++ {
++ uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++
++ if (tmp_value.realloc(new_len))
++ goto null;
++ }
++ }
++
++ if (tmp_value.copy(*res) || tmp_value.append(*res2))
++ goto null;
++
++ res= &tmp_value;
++ use_as_buff=str;
++ }
++ is_const= 0;
++ }
++ }
++ res->set_charset(collation.collation);
++ return res;
++
++null:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_concat::fix_length_and_dec()
++{
++ ulonglong max_result_length= 0;
++
++ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
++ return;
++
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
++ max_result_length+= (args[i]->max_length /
++ args[i]->collation.collation->mbmaxlen) *
++ collation.collation->mbmaxlen;
++ else
++ max_result_length+= args[i]->max_length;
++ }
++
++ if (max_result_length >= MAX_BLOB_WIDTH)
++ {
++ max_result_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) max_result_length;
++}
++
++/**
++ @details
++ Function des_encrypt() by tonu@spam.ee & monty
++ Works only if compiled with OpenSSL library support.
++ @return
++ A binary string where first character is CHAR(128 | key-number).
++ If one uses a string key key_number is 127.
++ Encryption result is longer than original by formula:
++ @code new_length= org_length + (8-(org_length % 8))+1 @endcode
++*/
++
++String *Item_func_des_encrypt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++#ifdef HAVE_OPENSSL
++ uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
++ DES_cblock ivec;
++ struct st_des_keyblock keyblock;
++ struct st_des_keyschedule keyschedule;
++ const char *append_str="********";
++ uint key_number, res_length, tail;
++ String *res= args[0]->val_str(str);
++
++ if ((null_value= args[0]->null_value))
++ return 0; // ENCRYPT(NULL) == NULL
++ if ((res_length=res->length()) == 0)
++ return make_empty_result();
++
++ if (arg_count == 1)
++ {
++ /* Protect against someone doing FLUSH DES_KEY_FILE */
++ VOID(pthread_mutex_lock(&LOCK_des_key_file));
++ keyschedule= des_keyschedule[key_number=des_default_key];
++ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
++ }
++ else if (args[1]->result_type() == INT_RESULT)
++ {
++ key_number= (uint) args[1]->val_int();
++ if (key_number > 9)
++ goto error;
++ VOID(pthread_mutex_lock(&LOCK_des_key_file));
++ keyschedule= des_keyschedule[key_number];
++ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
++ }
++ else
++ {
++ String *keystr=args[1]->val_str(&tmp_value);
++ if (!keystr)
++ goto error;
++ key_number=127; // User key string
++
++ /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
++ bzero((char*) &ivec,sizeof(ivec));
++ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
++ (uchar*) keystr->ptr(), (int) keystr->length(),
++ 1, (uchar*) &keyblock,ivec);
++ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
++ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
++ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
++ }
++
++ /*
++ The problem: DES algorithm requires original data to be in 8-bytes
++ chunks. Missing bytes get filled with '*'s and result of encryption
++ can be up to 8 bytes longer than original string. When decrypted,
++ we do not know the size of original string :(
++ We add one byte with value 0x1..0x8 as the last byte of the padded
++ string marking change of string length.
++ */
++
++ tail= 8 - (res_length % 8); // 1..8 marking extra length
++ res_length+=tail;
++ tmp_arg.realloc(res_length);
++ tmp_arg.length(0);
++ tmp_arg.append(res->ptr(), res->length());
++ code= ER_OUT_OF_RESOURCES;
++ if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1))
++ goto error;
++ tmp_arg[res_length-1]=tail; // save extra length
++ tmp_value.realloc(res_length+1);
++ tmp_value.length(res_length+1);
++ tmp_value.set_charset(&my_charset_bin);
++ tmp_value[0]=(char) (128 | key_number);
++ // Real encryption
++ bzero((char*) &ivec,sizeof(ivec));
++ DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()),
++ (uchar*) (tmp_value.ptr()+1),
++ res_length,
++ &keyschedule.ks1,
++ &keyschedule.ks2,
++ &keyschedule.ks3,
++ &ivec, TRUE);
++ return &tmp_value;
++
++error:
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ code, ER(code),
++ "des_encrypt");
++#else
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
++ "des_encrypt","--with-openssl");
++#endif /* HAVE_OPENSSL */
++ null_value=1;
++ return 0;
++}
++
++
++String *Item_func_des_decrypt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++#ifdef HAVE_OPENSSL
++ uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
++ DES_cblock ivec;
++ struct st_des_keyblock keyblock;
++ struct st_des_keyschedule keyschedule;
++ String *res= args[0]->val_str(str);
++ uint length,tail;
++
++ if ((null_value= args[0]->null_value))
++ return 0;
++ length= res->length();
++ if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
++ return res; // Skip decryption if not encrypted
++
++ if (arg_count == 1) // If automatic uncompression
++ {
++ uint key_number=(uint) (*res)[0] & 127;
++ // Check if automatic key and that we have privilege to uncompress using it
++ if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
++ key_number > 9)
++ goto error;
++
++ VOID(pthread_mutex_lock(&LOCK_des_key_file));
++ keyschedule= des_keyschedule[key_number];
++ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
++ }
++ else
++ {
++ // We make good 24-byte (168 bit) key from given plaintext key with MD5
++ String *keystr=args[1]->val_str(&tmp_value);
++ if (!keystr)
++ goto error;
++
++ bzero((char*) &ivec,sizeof(ivec));
++ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
++ (uchar*) keystr->ptr(),(int) keystr->length(),
++ 1,(uchar*) &keyblock,ivec);
++ // Here we set all 64-bit keys (56 effective) one by one
++ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
++ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
++ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
++ }
++ code= ER_OUT_OF_RESOURCES;
++ if (tmp_value.alloc(length-1))
++ goto error;
++
++ bzero((char*) &ivec,sizeof(ivec));
++ DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
++ (uchar*) (tmp_value.ptr()),
++ length-1,
++ &keyschedule.ks1,
++ &keyschedule.ks2,
++ &keyschedule.ks3,
++ &ivec, FALSE);
++ /* Restore old length of key */
++ if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
++ goto wrong_key; // Wrong key
++ tmp_value.length(length-1-tail);
++ tmp_value.set_charset(&my_charset_bin);
++ return &tmp_value;
++
++error:
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ code, ER(code),
++ "des_decrypt");
++wrong_key:
++#else
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
++ "des_decrypt","--with-openssl");
++#endif /* HAVE_OPENSSL */
++ null_value=1;
++ return 0;
++}
++
++
++/**
++ concat with separator. First arg is the separator
++ concat_ws takes at least two arguments.
++*/
++
++String *Item_func_concat_ws::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char tmp_str_buff[10];
++ String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
++ *sep_str, *res, *res2,*use_as_buff;
++ uint i;
++ bool is_const= 0;
++
++ null_value=0;
++ if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
++ goto null;
++
++ use_as_buff= &tmp_value;
++ str->length(0); // QQ; Should be removed
++ res=str;
++
++ // Skip until non-null argument is found.
++ // If not, return the empty string
++ for (i=1; i < arg_count; i++)
++ if ((res= args[i]->val_str(str)))
++ {
++ is_const= args[i]->const_item() || !args[i]->used_tables();
++ break;
++ }
++
++ if (i == arg_count)
++ return make_empty_result();
++
++ for (i++; i < arg_count ; i++)
++ {
++ if (!(res2= args[i]->val_str(use_as_buff)))
++ continue; // Skip NULL
++
++ if (res->length() + sep_str->length() + res2->length() >
++ current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
++ current_thd->variables.max_allowed_packet);
++ goto null;
++ }
++ if (!is_const && res->alloced_length() >=
++ res->length() + sep_str->length() + res2->length())
++ { // Use old buffer
++ res->append(*sep_str); // res->length() > 0 always
++ res->append(*res2);
++ }
++ else if (str->alloced_length() >=
++ res->length() + sep_str->length() + res2->length())
++ {
++ /* We have room in str; We can't get any errors here */
++ if (str->ptr() == res2->ptr())
++ { // This is quite uncommon!
++ str->replace(0,0,*sep_str);
++ str->replace(0,0,*res);
++ }
++ else
++ {
++ str->copy(*res);
++ str->append(*sep_str);
++ str->append(*res2);
++ }
++ res=str;
++ use_as_buff= &tmp_value;
++ }
++ else if (res == &tmp_value)
++ {
++ if (res->append(*sep_str) || res->append(*res2))
++ goto null; // Must be a blob
++ }
++ else if (res2 == &tmp_value)
++ { // This can happend only 1 time
++ if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
++ goto null;
++ res= &tmp_value;
++ use_as_buff=str; // Put next arg here
++ }
++ else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
++ res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
++ {
++ /*
++ This happens really seldom:
++ In this case res2 is sub string of tmp_value. We will
++ now work in place in tmp_value to set it to res | sep_str | res2
++ */
++ /* Chop the last characters in tmp_value that isn't in res2 */
++ tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
++ res2->length());
++ /* Place res2 at start of tmp_value, remove chars before res2 */
++ if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
++ *res) ||
++ tmp_value.replace(res->length(),0, *sep_str))
++ goto null;
++ res= &tmp_value;
++ use_as_buff=str; // Put next arg here
++ }
++ else
++ { // Two big const strings
++ /*
++ NOTE: We should be prudent in the initial allocation unit -- the
++ size of the arguments is a function of data distribution, which can
++ be any. Instead of overcommitting at the first row, we grow the
++ allocated amount by the factor of 2. This ensures that no more than
++ 25% of memory will be overcommitted on average.
++ */
++
++ uint concat_len= res->length() + sep_str->length() + res2->length();
++
++ if (tmp_value.alloced_length() < concat_len)
++ {
++ if (tmp_value.alloced_length() == 0)
++ {
++ if (tmp_value.alloc(concat_len))
++ goto null;
++ }
++ else
++ {
++ uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++
++ if (tmp_value.realloc(new_len))
++ goto null;
++ }
++ }
++
++ if (tmp_value.copy(*res) ||
++ tmp_value.append(*sep_str) ||
++ tmp_value.append(*res2))
++ goto null;
++ res= &tmp_value;
++ use_as_buff=str;
++ }
++ }
++ res->set_charset(collation.collation);
++ return res;
++
++null:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_concat_ws::fix_length_and_dec()
++{
++ ulonglong max_result_length;
++
++ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
++ return;
++
++ /*
++ arg_count cannot be less than 2,
++ it is done on parser level in sql_yacc.yy
++ so, (arg_count - 2) is safe here.
++ */
++ max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2);
++ for (uint i=1 ; i < arg_count ; i++)
++ max_result_length+=args[i]->max_length;
++
++ if (max_result_length >= MAX_BLOB_WIDTH)
++ {
++ max_result_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) max_result_length;
++}
++
++
++String *Item_func_reverse::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res = args[0]->val_str(str);
++ char *ptr, *end, *tmp;
++
++ if ((null_value=args[0]->null_value))
++ return 0;
++ /* An empty string is a special case as the string pointer may be null */
++ if (!res->length())
++ return make_empty_result();
++ if (tmp_value.alloced_length() < res->length() &&
++ tmp_value.realloc(res->length()))
++ {
++ null_value= 1;
++ return 0;
++ }
++ tmp_value.length(res->length());
++ tmp_value.set_charset(res->charset());
++ ptr= (char *) res->ptr();
++ end= ptr + res->length();
++ tmp= (char *) tmp_value.ptr() + tmp_value.length();
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ register uint32 l;
++ while (ptr < end)
++ {
++ if ((l= my_ismbchar(res->charset(),ptr,end)))
++ {
++ tmp-= l;
++ memcpy(tmp,ptr,l);
++ ptr+= l;
++ }
++ else
++ *--tmp= *ptr++;
++ }
++ }
++ else
++#endif /* USE_MB */
++ {
++ while (ptr < end)
++ *--tmp= *ptr++;
++ }
++ return &tmp_value;
++}
++
++
++void Item_func_reverse::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ max_length = args[0]->max_length;
++}
++
++/**
++ Replace all occurences of string2 in string1 with string3.
++
++ Don't reallocate val_str() if not needed.
++
++ @todo
++ Fix that this works with binary strings when using USE_MB
++*/
++
++String *Item_func_replace::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res,*res2,*res3;
++ int offset;
++ uint from_length,to_length;
++ bool alloced=0;
++#ifdef USE_MB
++ const char *ptr,*end,*strend,*search,*search_end;
++ register uint32 l;
++ bool binary_cmp;
++#endif
++
++ null_value=0;
++ res=args[0]->val_str(str);
++ if (args[0]->null_value)
++ goto null;
++ res2=args[1]->val_str(&tmp_value);
++ if (args[1]->null_value)
++ goto null;
++
++ res->set_charset(collation.collation);
++
++#ifdef USE_MB
++ binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
++#endif
++
++ if (res2->length() == 0)
++ return res;
++#ifndef USE_MB
++ if ((offset=res->strstr(*res2)) < 0)
++ return res;
++#else
++ offset=0;
++ if (binary_cmp && (offset=res->strstr(*res2)) < 0)
++ return res;
++#endif
++ if (!(res3=args[2]->val_str(&tmp_value2)))
++ goto null;
++ from_length= res2->length();
++ to_length= res3->length();
++
++#ifdef USE_MB
++ if (!binary_cmp)
++ {
++ search=res2->ptr();
++ search_end=search+from_length;
++redo:
++ DBUG_ASSERT(res->ptr() || !offset);
++ ptr=res->ptr()+offset;
++ strend=res->ptr()+res->length();
++ /*
++ In some cases val_str() can return empty string
++ with ptr() == NULL and length() == 0.
++ Let's check strend to avoid overflow.
++ */
++ end= strend ? strend - from_length + 1 : NULL;
++ while (ptr < end)
++ {
++ if (*ptr == *search)
++ {
++ register char *i,*j;
++ i=(char*) ptr+1; j=(char*) search+1;
++ while (j != search_end)
++ if (*i++ != *j++) goto skip;
++ offset= (int) (ptr-res->ptr());
++ if (res->length()-from_length + to_length >
++ current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(),
++ current_thd->variables.max_allowed_packet);
++
++ goto null;
++ }
++ if (!alloced)
++ {
++ alloced=1;
++ res=copy_if_not_alloced(str,res,res->length()+to_length);
++ }
++ res->replace((uint) offset,from_length,*res3);
++ offset+=(int) to_length;
++ goto redo;
++ }
++skip:
++ if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
++ else ++ptr;
++ }
++ }
++ else
++#endif /* USE_MB */
++ do
++ {
++ if (res->length()-from_length + to_length >
++ current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
++ current_thd->variables.max_allowed_packet);
++ goto null;
++ }
++ if (!alloced)
++ {
++ alloced=1;
++ res=copy_if_not_alloced(str,res,res->length()+to_length);
++ }
++ res->replace((uint) offset,from_length,*res3);
++ offset+=(int) to_length;
++ }
++ while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
++ return res;
++
++null:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_replace::fix_length_and_dec()
++{
++ ulonglong max_result_length= args[0]->max_length;
++ int diff=(int) (args[2]->max_length - args[1]->max_length);
++ if (diff > 0 && args[1]->max_length)
++ { // Calculate of maxreplaces
++ ulonglong max_substrs= max_result_length/args[1]->max_length;
++ max_result_length+= max_substrs * (uint) diff;
++ }
++ if (max_result_length >= MAX_BLOB_WIDTH)
++ {
++ max_result_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) max_result_length;
++
++ if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1))
++ return;
++}
++
++
++String *Item_func_insert::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res,*res2;
++ longlong start, length; /* must be longlong to avoid truncation */
++
++ null_value=0;
++ res=args[0]->val_str(str);
++ res2=args[3]->val_str(&tmp_value);
++ start= args[1]->val_int() - 1;
++ length= args[2]->val_int();
++
++ if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
++ args[3]->null_value)
++ goto null; /* purecov: inspected */
++
++ if ((start < 0) || (start > res->length()))
++ return res; // Wrong param; skip insert
++ if ((length < 0) || (length > res->length()))
++ length= res->length();
++
++ /*
++ There is one exception not handled (intentionaly) by the character set
++ aggregation code. If one string is strong side and is binary, and
++ another one is weak side and is a multi-byte character string,
++ then we need to operate on the second string in terms on bytes when
++ calling ::numchars() and ::charpos(), rather than in terms of characters.
++ Lets substitute its character set to binary.
++ */
++ if (collation.collation == &my_charset_bin)
++ {
++ res->set_charset(&my_charset_bin);
++ res2->set_charset(&my_charset_bin);
++ }
++
++ /* start and length are now sufficiently valid to pass to charpos function */
++ start= res->charpos((int) start);
++ length= res->charpos((int) length, (uint32) start);
++
++ /* Re-testing with corrected params */
++ if (start > res->length())
++ return res; /* purecov: inspected */ // Wrong param; skip insert
++ if (length > res->length() - start)
++ length= res->length() - start;
++
++ if ((ulonglong) (res->length() - length + res2->length()) >
++ (ulonglong) current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(), current_thd->variables.max_allowed_packet);
++ goto null;
++ }
++ res=copy_if_not_alloced(str,res,res->length());
++ res->replace((uint32) start,(uint32) length,*res2);
++ return res;
++null:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_insert::fix_length_and_dec()
++{
++ ulonglong max_result_length;
++
++ // Handle character set for args[0] and args[3].
++ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3))
++ return;
++ max_result_length= ((ulonglong) args[0]->max_length+
++ (ulonglong) args[3]->max_length);
++ if (max_result_length >= MAX_BLOB_WIDTH)
++ {
++ max_result_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) max_result_length;
++}
++
++
++String *Item_str_conv::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res;
++ if (!(res=args[0]->val_str(str)))
++ {
++ null_value=1; /* purecov: inspected */
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ if (multiply == 1)
++ {
++ uint len;
++ res= copy_if_not_alloced(str,res,res->length());
++ len= converter(collation.collation, (char*) res->ptr(), res->length(),
++ (char*) res->ptr(), res->length());
++ DBUG_ASSERT(len <= res->length());
++ res->length(len);
++ }
++ else
++ {
++ uint len= res->length() * multiply;
++ tmp_value.alloc(len);
++ tmp_value.set_charset(collation.collation);
++ len= converter(collation.collation, (char*) res->ptr(), res->length(),
++ (char*) tmp_value.ptr(), len);
++ tmp_value.length(len);
++ res= &tmp_value;
++ }
++ return res;
++}
++
++
++void Item_func_lcase::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ multiply= collation.collation->casedn_multiply;
++ converter= collation.collation->cset->casedn;
++ max_length= args[0]->max_length * multiply;
++}
++
++void Item_func_ucase::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ multiply= collation.collation->caseup_multiply;
++ converter= collation.collation->cset->caseup;
++ max_length= args[0]->max_length * multiply;
++}
++
++
++String *Item_func_left::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++
++ /* must be longlong to avoid truncation */
++ longlong length= args[1]->val_int();
++ uint char_pos;
++
++ if ((null_value=(args[0]->null_value || args[1]->null_value)))
++ return 0;
++
++ /* if "unsigned_flag" is set, we have a *huge* positive number. */
++ if ((length <= 0) && (!args[1]->unsigned_flag))
++ return make_empty_result();
++ if ((res->length() <= (ulonglong) length) ||
++ (res->length() <= (char_pos= res->charpos((int) length))))
++ return res;
++
++ tmp_value.set(*res, 0, char_pos);
++ return &tmp_value;
++}
++
++
++void Item_str_func::left_right_max_length()
++{
++ max_length=args[0]->max_length;
++ if (args[1]->const_item())
++ {
++ int length=(int) args[1]->val_int()*collation.collation->mbmaxlen;
++ if (length <= 0)
++ max_length=0;
++ else
++ set_if_smaller(max_length,(uint) length);
++ }
++}
++
++
++void Item_func_left::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ left_right_max_length();
++}
++
++
++String *Item_func_right::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ /* must be longlong to avoid truncation */
++ longlong length= args[1]->val_int();
++
++ if ((null_value=(args[0]->null_value || args[1]->null_value)))
++ return 0; /* purecov: inspected */
++
++ /* if "unsigned_flag" is set, we have a *huge* positive number. */
++ if ((length <= 0) && (!args[1]->unsigned_flag))
++ return make_empty_result(); /* purecov: inspected */
++
++ if (res->length() <= (ulonglong) length)
++ return res; /* purecov: inspected */
++
++ uint start=res->numchars();
++ if (start <= (uint) length)
++ return res;
++ start=res->charpos(start - (uint) length);
++ tmp_value.set(*res,start,res->length()-start);
++ return &tmp_value;
++}
++
++
++void Item_func_right::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ left_right_max_length();
++}
++
++
++String *Item_func_substr::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res = args[0]->val_str(str);
++ /* must be longlong to avoid truncation */
++ longlong start= args[1]->val_int();
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Limit so that code sees out-of-bound value properly. */
++ longlong length= arg_count == 3 ? args[2]->val_int() : INT_MAX32;
++ longlong tmp_length;
++
++ if ((null_value=(args[0]->null_value || args[1]->null_value ||
++ (arg_count == 3 && args[2]->null_value))))
++ return 0; /* purecov: inspected */
++
++ /* Negative or zero length, will return empty string. */
++ if ((arg_count == 3) && (length <= 0) &&
++ (length == 0 || !args[2]->unsigned_flag))
++ return make_empty_result();
++
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if ((length <= 0) || (length > INT_MAX32))
++ length= INT_MAX32;
++
++ /* if "unsigned_flag" is set, we have a *huge* positive number. */
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
++ (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
++ return make_empty_result();
++
++ start= ((start < 0) ? res->numchars() + start : start - 1);
++ start= res->charpos((int) start);
++ if ((start < 0) || ((uint) start + 1 > res->length()))
++ return make_empty_result();
++
++ length= res->charpos((int) length, (uint32) start);
++ tmp_length= res->length() - start;
++ length= min(length, tmp_length);
++
++ if (!start && (longlong) res->length() == length)
++ return res;
++ tmp_value.set(*res, (uint32) start, (uint32) length);
++ return &tmp_value;
++}
++
++
++void Item_func_substr::fix_length_and_dec()
++{
++ max_length=args[0]->max_length;
++
++ collation.set(args[0]->collation);
++ if (args[1]->const_item())
++ {
++ int32 start= (int32) args[1]->val_int();
++ if (start < 0)
++ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
++ else
++ max_length-= min((uint)(start - 1), max_length);
++ }
++ if (arg_count == 3 && args[2]->const_item())
++ {
++ int32 length= (int32) args[2]->val_int();
++ if (length <= 0)
++ max_length=0; /* purecov: inspected */
++ else
++ set_if_smaller(max_length,(uint) length);
++ }
++ max_length*= collation.collation->mbmaxlen;
++}
++
++
++void Item_func_substr_index::fix_length_and_dec()
++{
++ max_length= args[0]->max_length;
++
++ if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV, 1))
++ return;
++}
++
++
++String *Item_func_substr_index::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ String *delimiter= args[1]->val_str(&tmp_value);
++ int32 count= (int32) args[2]->val_int();
++ uint offset;
++
++ if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
++ { // string and/or delim are null
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ uint delimiter_length= delimiter->length();
++ if (!res->length() || !delimiter_length || !count)
++ return make_empty_result(); // Wrong parameters
++
++ res->set_charset(collation.collation);
++
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ const char *ptr= res->ptr();
++ const char *strend= ptr+res->length();
++ const char *end= strend-delimiter_length+1;
++ const char *search= delimiter->ptr();
++ const char *search_end= search+delimiter_length;
++ int32 n=0,c=count,pass;
++ register uint32 l;
++ for (pass=(count>0);pass<2;++pass)
++ {
++ while (ptr < end)
++ {
++ if (*ptr == *search)
++ {
++ register char *i,*j;
++ i=(char*) ptr+1; j=(char*) search+1;
++ while (j != search_end)
++ if (*i++ != *j++) goto skip;
++ if (pass==0) ++n;
++ else if (!--c) break;
++ ptr+= delimiter_length;
++ continue;
++ }
++ skip:
++ if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
++ else ++ptr;
++ } /* either not found or got total number when count<0 */
++ if (pass == 0) /* count<0 */
++ {
++ c+=n+1;
++ if (c<=0) return res; /* not found, return original string */
++ ptr=res->ptr();
++ }
++ else
++ {
++ if (c) return res; /* Not found, return original string */
++ if (count>0) /* return left part */
++ {
++ tmp_value.set(*res,0,(ulong) (ptr-res->ptr()));
++ }
++ else /* return right part */
++ {
++ ptr+= delimiter_length;
++ tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
++ }
++ }
++ }
++ }
++ else
++#endif /* USE_MB */
++ {
++ if (count > 0)
++ { // start counting from the beginning
++ for (offset=0; ; offset+= delimiter_length)
++ {
++ if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
++ return res; // Didn't find, return org string
++ if (!--count)
++ {
++ tmp_value.set(*res,0,offset);
++ break;
++ }
++ }
++ }
++ else
++ {
++ /*
++ Negative index, start counting at the end
++ */
++ for (offset=res->length(); offset ;)
++ {
++ /*
++ this call will result in finding the position pointing to one
++ address space less than where the found substring is located
++ in res
++ */
++ if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
++ return res; // Didn't find, return org string
++ /*
++ At this point, we've searched for the substring
++ the number of times as supplied by the index value
++ */
++ if (!++count)
++ {
++ offset+= delimiter_length;
++ tmp_value.set(*res,offset,res->length()- offset);
++ break;
++ }
++ }
++ }
++ }
++ /*
++ We always mark tmp_value as const so that if val_str() is called again
++ on this object, we don't disrupt the contents of tmp_value when it was
++ derived from another String.
++ */
++ tmp_value.mark_as_const();
++ return (&tmp_value);
++}
++
++/*
++** The trim functions are extension to ANSI SQL because they trim substrings
++** They ltrim() and rtrim() functions are optimized for 1 byte strings
++** They also return the original string if possible, else they return
++** a substring that points at the original string.
++*/
++
++
++String *Item_func_ltrim::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char buff[MAX_FIELD_WIDTH], *ptr, *end;
++ String tmp(buff,sizeof(buff),system_charset_info);
++ String *res, *remove_str;
++ uint remove_length;
++ LINT_INIT(remove_length);
++
++ res= args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ remove_str= &remove; /* Default value. */
++ if (arg_count == 2)
++ {
++ remove_str= args[1]->val_str(&tmp);
++ if ((null_value= args[1]->null_value))
++ return 0;
++ }
++
++ if ((remove_length= remove_str->length()) == 0 ||
++ remove_length > res->length())
++ return res;
++
++ ptr= (char*) res->ptr();
++ end= ptr+res->length();
++ if (remove_length == 1)
++ {
++ char chr=(*remove_str)[0];
++ while (ptr != end && *ptr == chr)
++ ptr++;
++ }
++ else
++ {
++ const char *r_ptr=remove_str->ptr();
++ end-=remove_length;
++ while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
++ ptr+=remove_length;
++ end+=remove_length;
++ }
++ if (ptr == res->ptr())
++ return res;
++ tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
++ return &tmp_value;
++}
++
++
++String *Item_func_rtrim::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char buff[MAX_FIELD_WIDTH], *ptr, *end;
++ String tmp(buff, sizeof(buff), system_charset_info);
++ String *res, *remove_str;
++ uint remove_length;
++ LINT_INIT(remove_length);
++
++ res= args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ remove_str= &remove; /* Default value. */
++ if (arg_count == 2)
++ {
++ remove_str= args[1]->val_str(&tmp);
++ if ((null_value= args[1]->null_value))
++ return 0;
++ }
++
++ if ((remove_length= remove_str->length()) == 0 ||
++ remove_length > res->length())
++ return res;
++
++ ptr= (char*) res->ptr();
++ end= ptr+res->length();
++#ifdef USE_MB
++ char *p=ptr;
++ register uint32 l;
++#endif
++ if (remove_length == 1)
++ {
++ char chr=(*remove_str)[0];
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ while (ptr < end)
++ {
++ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
++ else ++ptr;
++ }
++ ptr=p;
++ }
++#endif
++ while (ptr != end && end[-1] == chr)
++ end--;
++ }
++ else
++ {
++ const char *r_ptr=remove_str->ptr();
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ loop:
++ while (ptr + remove_length < end)
++ {
++ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
++ else ++ptr;
++ }
++ if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
++ {
++ end-=remove_length;
++ ptr=p;
++ goto loop;
++ }
++ }
++ else
++#endif /* USE_MB */
++ {
++ while (ptr + remove_length <= end &&
++ !memcmp(end-remove_length, r_ptr, remove_length))
++ end-=remove_length;
++ }
++ }
++ if (end == res->ptr()+res->length())
++ return res;
++ tmp_value.set(*res,0,(uint) (end-res->ptr()));
++ return &tmp_value;
++}
++
++
++String *Item_func_trim::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char buff[MAX_FIELD_WIDTH], *ptr, *end;
++ const char *r_ptr;
++ String tmp(buff, sizeof(buff), system_charset_info);
++ String *res, *remove_str;
++ uint remove_length;
++ LINT_INIT(remove_length);
++
++ res= args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ remove_str= &remove; /* Default value. */
++ if (arg_count == 2)
++ {
++ remove_str= args[1]->val_str(&tmp);
++ if ((null_value= args[1]->null_value))
++ return 0;
++ }
++
++ if ((remove_length= remove_str->length()) == 0 ||
++ remove_length > res->length())
++ return res;
++
++ ptr= (char*) res->ptr();
++ end= ptr+res->length();
++ r_ptr= remove_str->ptr();
++ while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
++ ptr+=remove_length;
++#ifdef USE_MB
++ if (use_mb(res->charset()))
++ {
++ char *p=ptr;
++ register uint32 l;
++ loop:
++ while (ptr + remove_length < end)
++ {
++ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
++ else ++ptr;
++ }
++ if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
++ {
++ end-=remove_length;
++ ptr=p;
++ goto loop;
++ }
++ ptr=p;
++ }
++ else
++#endif /* USE_MB */
++ {
++ while (ptr + remove_length <= end &&
++ !memcmp(end-remove_length,r_ptr,remove_length))
++ end-=remove_length;
++ }
++ if (ptr == res->ptr() && end == ptr+res->length())
++ return res;
++ tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
++ return &tmp_value;
++}
++
++void Item_func_trim::fix_length_and_dec()
++{
++ max_length= args[0]->max_length;
++ if (arg_count == 1)
++ {
++ collation.set(args[0]->collation);
++ remove.set_charset(collation.collation);
++ remove.set_ascii(" ",1);
++ }
++ else
++ {
++ // Handle character set for args[1] and args[0].
++ // Note that we pass args[1] as the first item, and args[0] as the second.
++ if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1))
++ return;
++ }
++}
++
++void Item_func_trim::print(String *str, enum_query_type query_type)
++{
++ if (arg_count == 1)
++ {
++ Item_func::print(str, query_type);
++ return;
++ }
++ str->append(Item_func_trim::func_name());
++ str->append('(');
++ str->append(mode_name());
++ str->append(' ');
++ args[1]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" from "));
++ args[0]->print(str, query_type);
++ str->append(')');
++}
++
++
++/* Item_func_password */
++
++String *Item_func_password::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ if (res->length() == 0)
++ return make_empty_result();
++ my_make_scrambled_password(tmp_value, res->ptr(), res->length());
++ str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset());
++ return str;
++}
++
++char *Item_func_password::alloc(THD *thd, const char *password,
++ size_t pass_len)
++{
++ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
++ if (buff)
++ my_make_scrambled_password(buff, password, pass_len);
++ return buff;
++}
++
++/* Item_func_old_password */
++
++String *Item_func_old_password::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ if (res->length() == 0)
++ return make_empty_result();
++ my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
++ str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset());
++ return str;
++}
++
++char *Item_func_old_password::alloc(THD *thd, const char *password,
++ size_t pass_len)
++{
++ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
++ if (buff)
++ my_make_scrambled_password_323(buff, password, pass_len);
++ return buff;
++}
++
++
++#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
++
++String *Item_func_encrypt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res =args[0]->val_str(str);
++
++#ifdef HAVE_CRYPT
++ char salt[3],*salt_ptr;
++ if ((null_value=args[0]->null_value))
++ return 0;
++ if (res->length() == 0)
++ return make_empty_result();
++ if (arg_count == 1)
++ { // generate random salt
++ time_t timestamp=current_thd->query_start();
++ salt[0] = bin_to_ascii( (ulong) timestamp & 0x3f);
++ salt[1] = bin_to_ascii(( (ulong) timestamp >> 5) & 0x3f);
++ salt[2] = 0;
++ salt_ptr=salt;
++ }
++ else
++ { // obtain salt from the first two bytes
++ String *salt_str=args[1]->val_str(&tmp_value);
++ if ((null_value= (args[1]->null_value || salt_str->length() < 2)))
++ return 0;
++ salt_ptr= salt_str->c_ptr_safe();
++ }
++ pthread_mutex_lock(&LOCK_crypt);
++ char *tmp= crypt(res->c_ptr_safe(),salt_ptr);
++ if (!tmp)
++ {
++ pthread_mutex_unlock(&LOCK_crypt);
++ null_value= 1;
++ return 0;
++ }
++ str->set(tmp, (uint) strlen(tmp), &my_charset_bin);
++ str->copy();
++ pthread_mutex_unlock(&LOCK_crypt);
++ return str;
++#else
++ null_value=1;
++ return 0;
++#endif /* HAVE_CRYPT */
++}
++
++bool Item_func_encode::seed()
++{
++ char buf[80];
++ ulong rand_nr[2];
++ String *key, tmp(buf, sizeof(buf), system_charset_info);
++
++ if (!(key= args[1]->val_str(&tmp)))
++ return TRUE;
++
++ hash_password(rand_nr, key->ptr(), key->length());
++ sql_crypt.init(rand_nr);
++
++ return FALSE;
++}
++
++void Item_func_encode::fix_length_and_dec()
++{
++ max_length=args[0]->max_length;
++ maybe_null=args[0]->maybe_null || args[1]->maybe_null;
++ collation.set(&my_charset_bin);
++ /* Precompute the seed state if the item is constant. */
++ seeded= args[1]->const_item() &&
++ (args[1]->result_type() == STRING_RESULT) && !seed();
++}
++
++String *Item_func_encode::val_str(String *str)
++{
++ String *res;
++ DBUG_ASSERT(fixed == 1);
++
++ if (!(res=args[0]->val_str(str)))
++ {
++ null_value= 1;
++ return NULL;
++ }
++
++ if (!seeded && seed())
++ {
++ null_value= 1;
++ return NULL;
++ }
++
++ null_value= 0;
++ res= copy_if_not_alloced(str, res, res->length());
++ crypto_transform(res);
++ sql_crypt.reinit();
++
++ return res;
++}
++
++void Item_func_encode::crypto_transform(String *res)
++{
++ sql_crypt.encode((char*) res->ptr(),res->length());
++ res->set_charset(&my_charset_bin);
++}
++
++void Item_func_decode::crypto_transform(String *res)
++{
++ sql_crypt.decode((char*) res->ptr(),res->length());
++}
++
++
++Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs)
++{
++ Item_string *conv;
++ uint conv_errors;
++ String tmp, cstr, *ostr= val_str(&tmp);
++ if (null_value)
++ {
++ Item *null_item= new Item_null((char *) fully_qualified_func_name());
++ null_item->collation.set (tocs);
++ return null_item;
++ }
++ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
++ if (conv_errors ||
++ !(conv= new Item_static_string_func(fully_qualified_func_name(),
++ cstr.ptr(), cstr.length(),
++ cstr.charset(),
++ collation.derivation)))
++ {
++ return NULL;
++ }
++ conv->str_value.copy();
++ conv->str_value.mark_as_const();
++ return conv;
++}
++
++
++String *Item_func_database::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ THD *thd= current_thd;
++ if (thd->db == NULL)
++ {
++ null_value= 1;
++ return 0;
++ }
++ else
++ str->copy(thd->db, thd->db_length, system_charset_info);
++ return str;
++}
++
++
++/**
++ @note USER() is replicated correctly if binlog_format=ROW or (as of
++ BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
++ if binlog_format=STATEMENT.
++*/
++bool Item_func_user::init(const char *user, const char *host)
++{
++ DBUG_ASSERT(fixed == 1);
++
++ // For system threads (e.g. replication SQL thread) user may be empty
++ if (user)
++ {
++ CHARSET_INFO *cs= str_value.charset();
++ size_t res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
++
++ if (str_value.alloc((uint) res_length))
++ {
++ null_value=1;
++ return TRUE;
++ }
++
++ res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), (uint) res_length,
++ "%s@%s", user, host);
++ str_value.length((uint) res_length);
++ str_value.mark_as_const();
++ }
++ return FALSE;
++}
++
++
++bool Item_func_user::fix_fields(THD *thd, Item **ref)
++{
++ return (Item_func_sysconst::fix_fields(thd, ref) ||
++ init(thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip));
++}
++
++
++bool Item_func_current_user::fix_fields(THD *thd, Item **ref)
++{
++ if (Item_func_sysconst::fix_fields(thd, ref))
++ return TRUE;
++
++ Security_context *ctx=
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ (context->security_ctx
++ ? context->security_ctx : thd->security_ctx);
++#else
++ thd->security_ctx;
++#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
++ return init(ctx->priv_user, ctx->priv_host);
++}
++
++
++void Item_func_soundex::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ max_length=args[0]->max_length;
++ set_if_bigger(max_length, 4 * collation.collation->mbminlen);
++ tmp_value.set_charset(collation.collation);
++}
++
++
++/**
++ If alpha, map input letter to soundex code.
++ If not alpha and remove_garbage is set then skip to next char
++ else return 0
++*/
++
++static int soundex_toupper(int ch)
++{
++ return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
++}
++
++
++static char get_scode(int wc)
++{
++ int ch= soundex_toupper(wc);
++ if (ch < 'A' || ch > 'Z')
++ {
++ // Thread extended alfa (country spec)
++ return '0'; // as vokal
++ }
++ return(soundex_map[ch-'A']);
++}
++
++
++static bool my_uni_isalpha(int wc)
++{
++ /*
++ Return true for all Basic Latin letters: a..z A..Z.
++ Return true for all Unicode characters with code higher than U+00C0:
++ - characters between 'z' and U+00C0 are controls and punctuations.
++ - "U+00C0 LATIN CAPITAL LETTER A WITH GRAVE" is the first letter after 'z'.
++ */
++ return (wc >= 'a' && wc <= 'z') ||
++ (wc >= 'A' && wc <= 'Z') ||
++ (wc >= 0xC0);
++}
++
++
++String *Item_func_soundex::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res =args[0]->val_str(str);
++ char last_ch,ch;
++ CHARSET_INFO *cs= collation.collation;
++ my_wc_t wc;
++ uint nchars;
++ int rc;
++
++ if ((null_value= args[0]->null_value))
++ return 0; /* purecov: inspected */
++
++ if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ return str; /* purecov: inspected */
++ char *to= (char *) tmp_value.ptr();
++ char *to_end= to + tmp_value.alloced_length();
++ char *from= (char *) res->ptr(), *end= from + res->length();
++
++ for ( ; ; ) /* Skip pre-space */
++ {
++ if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
++ return make_empty_result(); /* EOL or invalid byte sequence */
++
++ if (rc == 1 && cs->ctype)
++ {
++ /* Single byte letter found */
++ if (my_isalpha(cs, *from))
++ {
++ last_ch= get_scode(*from); // Code of the first letter
++ *to++= soundex_toupper(*from++); // Copy first letter
++ break;
++ }
++ from++;
++ }
++ else
++ {
++ from+= rc;
++ if (my_uni_isalpha(wc))
++ {
++ /* Multibyte letter found */
++ wc= soundex_toupper(wc);
++ last_ch= get_scode(wc); // Code of the first letter
++ if ((rc= cs->cset->wc_mb(cs, wc, (uchar*) to, (uchar*) to_end)) <= 0)
++ {
++ /* Extra safety - should not really happen */
++ DBUG_ASSERT(false);
++ return make_empty_result();
++ }
++ to+= rc;
++ break;
++ }
++ }
++ }
++
++ /*
++ last_ch is now set to the first 'double-letter' check.
++ loop on input letters until end of input
++ */
++ for (nchars= 1 ; ; )
++ {
++ if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
++ break; /* EOL or invalid byte sequence */
++
++ if (rc == 1 && cs->ctype)
++ {
++ if (!my_isalpha(cs, *from++))
++ continue;
++ }
++ else
++ {
++ from+= rc;
++ if (!my_uni_isalpha(wc))
++ continue;
++ }
++
++ ch= get_scode(wc);
++ if ((ch != '0') && (ch != last_ch)) // if not skipped or double
++ {
++ // letter, copy to output
++ if ((rc= cs->cset->wc_mb(cs, (my_wc_t) ch,
++ (uchar*) to, (uchar*) to_end)) <= 0)
++ {
++ // Extra safety - should not really happen
++ DBUG_ASSERT(false);
++ break;
++ }
++ to+= rc;
++ nchars++;
++ last_ch= ch; // save code of last input letter
++ } // for next double-letter check
++ }
++
++ /* Pad up to 4 characters with DIGIT ZERO, if the string is shorter */
++ if (nchars < 4)
++ {
++ uint nbytes= (4 - nchars) * cs->mbminlen;
++ cs->cset->fill(cs, to, nbytes, '0');
++ to+= nbytes;
++ }
++
++ tmp_value.length((uint) (to-tmp_value.ptr()));
++ return &tmp_value;
++}
++
++
++/**
++ Change a number to format '3,333,333,333.000'.
++
++ This should be 'internationalized' sometimes.
++*/
++
++const int FORMAT_MAX_DECIMALS= 30;
++
++Item_func_format::Item_func_format(Item *org, Item *dec)
++: Item_str_func(org, dec)
++{
++}
++
++void Item_func_format::fix_length_and_dec()
++{
++ uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
++ uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1;
++ collation.set(default_charset());
++ max_length= (char_length + max_sep_count + decimals) *
++ collation.collation->mbmaxlen;
++}
++
++
++/**
++ @todo
++ This needs to be fixed for multi-byte character set where numbers
++ are stored in more than one byte
++*/
++
++String *Item_func_format::val_str(String *str)
++{
++ uint32 length;
++ uint32 str_length;
++ /* Number of decimal digits */
++ int dec;
++ /* Number of characters used to represent the decimals, including '.' */
++ uint32 dec_length;
++ int diff;
++ DBUG_ASSERT(fixed == 1);
++
++ dec= (int) args[1]->val_int();
++ if (args[1]->null_value)
++ {
++ null_value=1;
++ return NULL;
++ }
++
++ dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS);
++ dec_length= dec ? dec+1 : 0;
++ null_value=0;
++
++ if (args[0]->result_type() == DECIMAL_RESULT ||
++ args[0]->result_type() == INT_RESULT)
++ {
++ my_decimal dec_val, rnd_dec, *res;
++ res= args[0]->val_decimal(&dec_val);
++ if ((null_value=args[0]->null_value))
++ return 0; /* purecov: inspected */
++ my_decimal_round(E_DEC_FATAL_ERROR, res, dec, false, &rnd_dec);
++ my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str);
++ str_length= str->length();
++ if (rnd_dec.sign())
++ str_length--;
++ }
++ else
++ {
++ double nr= args[0]->val_real();
++ if ((null_value=args[0]->null_value))
++ return 0; /* purecov: inspected */
++ nr= my_double_round(nr, (longlong) dec, FALSE, FALSE);
++ /* Here default_charset() is right as this is not an automatic conversion */
++ str->set_real(nr, dec, default_charset());
++ if (isnan(nr))
++ return str;
++ str_length=str->length();
++ if (nr < 0)
++ str_length--; // Don't count sign
++ }
++ /* We need this test to handle 'nan' values */
++ if (str_length >= dec_length+4)
++ {
++ char *tmp,*pos;
++ length= str->length()+(diff=((int)(str_length- dec_length-1))/3);
++ str= copy_if_not_alloced(&tmp_str,str,length);
++ str->length(length);
++ tmp= (char*) str->ptr()+length - dec_length-1;
++ for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--)
++ pos[0]= pos[-diff];
++ while (diff)
++ {
++ *pos= *(pos - diff);
++ pos--;
++ *pos= *(pos - diff);
++ pos--;
++ *pos= *(pos - diff);
++ pos--;
++ pos[0]=',';
++ pos--;
++ diff--;
++ }
++ }
++ return str;
++}
++
++
++void Item_func_format::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("format("));
++ args[0]->print(str, query_type);
++ str->append(',');
++ args[1]->print(str, query_type);
++ str->append(')');
++}
++
++void Item_func_elt::fix_length_and_dec()
++{
++ max_length=0;
++ decimals=0;
++
++ if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV, 1))
++ return;
++
++ for (uint i= 1 ; i < arg_count ; i++)
++ {
++ set_if_bigger(max_length,args[i]->max_length);
++ set_if_bigger(decimals,args[i]->decimals);
++ }
++ maybe_null=1; // NULL if wrong first arg
++}
++
++
++double Item_func_elt::val_real()
++{
++ DBUG_ASSERT(fixed == 1);
++ uint tmp;
++ null_value=1;
++ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
++ return 0.0;
++ double result= args[tmp]->val_real();
++ null_value= args[tmp]->null_value;
++ return result;
++}
++
++
++longlong Item_func_elt::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ uint tmp;
++ null_value=1;
++ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
++ return 0;
++
++ longlong result= args[tmp]->val_int();
++ null_value= args[tmp]->null_value;
++ return result;
++}
++
++
++String *Item_func_elt::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint tmp;
++ null_value=1;
++ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
++ return NULL;
++
++ String *result= args[tmp]->val_str(str);
++ if (result)
++ result->set_charset(collation.collation);
++ null_value= args[tmp]->null_value;
++ return result;
++}
++
++
++void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
++ List<Item> &fields)
++{
++ item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE);
++ Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
++}
++
++
++void Item_func_make_set::fix_length_and_dec()
++{
++ max_length=arg_count-1;
++
++ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
++ return;
++
++ for (uint i=0 ; i < arg_count ; i++)
++ max_length+=args[i]->max_length;
++
++ used_tables_cache|= item->used_tables();
++ not_null_tables_cache&= item->not_null_tables();
++ const_item_cache&= item->const_item();
++ with_sum_func= with_sum_func || item->with_sum_func;
++}
++
++
++void Item_func_make_set::update_used_tables()
++{
++ Item_func::update_used_tables();
++ item->update_used_tables();
++ used_tables_cache|=item->used_tables();
++ const_item_cache&=item->const_item();
++}
++
++
++String *Item_func_make_set::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ ulonglong bits;
++ bool first_found=0;
++ Item **ptr=args;
++ String *result=&my_empty_string;
++
++ bits=item->val_int();
++ if ((null_value=item->null_value))
++ return NULL;
++
++ if (arg_count < 64)
++ bits &= ((ulonglong) 1 << arg_count)-1;
++
++ for (; bits; bits >>= 1, ptr++)
++ {
++ if (bits & 1)
++ {
++ String *res= (*ptr)->val_str(str);
++ if (res) // Skip nulls
++ {
++ if (!first_found)
++ { // First argument
++ first_found=1;
++ if (res != str)
++ result=res; // Use original string
++ else
++ {
++ if (tmp_str.copy(*res)) // Don't use 'str'
++ return make_empty_result();
++ result= &tmp_str;
++ }
++ }
++ else
++ {
++ if (result != &tmp_str)
++ { // Copy data to tmp_str
++ if (tmp_str.alloc(result->length()+res->length()+1) ||
++ tmp_str.copy(*result))
++ return make_empty_result();
++ result= &tmp_str;
++ }
++ if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
++ return make_empty_result();
++ }
++ }
++ }
++ }
++ return result;
++}
++
++
++Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg)
++{
++ DBUG_ASSERT(!current_thd->is_stmt_prepare());
++
++ Item *new_item= item->transform(transformer, arg);
++ if (!new_item)
++ return 0;
++
++ /*
++ THD::change_item_tree() should be called only if the tree was
++ really transformed, i.e. when a new item has been created.
++ Otherwise we'll be allocating a lot of unnecessary memory for
++ change records at each execution.
++ */
++ if (item != new_item)
++ current_thd->change_item_tree(&item, new_item);
++ return Item_str_func::transform(transformer, arg);
++}
++
++
++void Item_func_make_set::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("make_set("));
++ item->print(str, query_type);
++ if (arg_count)
++ {
++ str->append(',');
++ print_args(str, 0, query_type);
++ }
++ str->append(')');
++}
++
++
++String *Item_func_char::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ str->length(0);
++ str->set_charset(collation.collation);
++ for (uint i=0 ; i < arg_count ; i++)
++ {
++ int32 num=(int32) args[i]->val_int();
++ if (!args[i]->null_value)
++ {
++ char char_num= (char) num;
++ if (num&0xFF000000L) {
++ str->append((char)(num>>24));
++ goto b2;
++ } else if (num&0xFF0000L) {
++ b2: str->append((char)(num>>16));
++ goto b1;
++ } else if (num&0xFF00L) {
++ b1: str->append((char)(num>>8));
++ }
++ str->append(&char_num, 1);
++ }
++ }
++ str->realloc(str->length()); // Add end 0 (for Purify)
++ return check_well_formed_result(str);
++}
++
++
++inline String* alloc_buffer(String *res,String *str,String *tmp_value,
++ ulong length)
++{
++ if (res->alloced_length() < length)
++ {
++ if (str->alloced_length() >= length)
++ {
++ (void) str->copy(*res);
++ str->length(length);
++ return str;
++ }
++ if (tmp_value->alloc(length))
++ return 0;
++ (void) tmp_value->copy(*res);
++ tmp_value->length(length);
++ return tmp_value;
++ }
++ res->length(length);
++ return res;
++}
++
++
++void Item_func_repeat::fix_length_and_dec()
++{
++ collation.set(args[0]->collation);
++ if (args[1]->const_item())
++ {
++ /* must be longlong to avoid truncation */
++ longlong count= args[1]->val_int();
++
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if (count > INT_MAX32)
++ count= INT_MAX32;
++
++ ulonglong max_result_length= (ulonglong) args[0]->max_length * count;
++ if (max_result_length >= MAX_BLOB_WIDTH)
++ {
++ max_result_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) max_result_length;
++ }
++ else
++ {
++ max_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++}
++
++/**
++ Item_func_repeat::str is carefully written to avoid reallocs
++ as much as possible at the cost of a local buffer
++*/
++
++String *Item_func_repeat::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint length,tot_length;
++ char *to;
++ /* must be longlong to avoid truncation */
++ longlong count= args[1]->val_int();
++ String *res= args[0]->val_str(str);
++
++ if (args[0]->null_value || args[1]->null_value)
++ goto err; // string and/or delim are null
++ null_value= 0;
++
++ if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
++ return make_empty_result();
++
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Bounds check on count: If this is triggered, we will error. */
++ if ((ulonglong) count > INT_MAX32)
++ count= INT_MAX32;
++ if (count == 1) // To avoid reallocs
++ return res;
++ length=res->length();
++ // Safe length check
++ if (length > current_thd->variables.max_allowed_packet / (uint) count)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(), current_thd->variables.max_allowed_packet);
++ goto err;
++ }
++ tot_length= length*(uint) count;
++ if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
++ goto err;
++
++ to=(char*) res->ptr()+length;
++ while (--count)
++ {
++ memcpy(to,res->ptr(),length);
++ to+=length;
++ }
++ return (res);
++
++err:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_rpad::fix_length_and_dec()
++{
++ // Handle character set for args[0] and args[2].
++ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
++ return;
++ if (args[1]->const_item())
++ {
++ ulonglong length= 0;
++
++ if (collation.collation->mbmaxlen > 0)
++ {
++ ulonglong temp= (ulonglong) args[1]->val_int();
++
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if (temp > INT_MAX32)
++ temp = INT_MAX32;
++
++ length= temp * collation.collation->mbmaxlen;
++ }
++
++ if (length >= MAX_BLOB_WIDTH)
++ {
++ length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) length;
++ }
++ else
++ {
++ max_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++}
++
++
++String *Item_func_rpad::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length;
++ char *to;
++ const char *ptr_pad;
++ /* must be longlong to avoid truncation */
++ longlong count= args[1]->val_int();
++ longlong byte_count;
++ String *res= args[0]->val_str(str);
++ String *rpad= args[2]->val_str(&rpad_str);
++
++ if (!res || args[1]->null_value || !rpad ||
++ ((count < 0) && !args[1]->unsigned_flag))
++ goto err;
++ null_value=0;
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if ((ulonglong) count > INT_MAX32)
++ count= INT_MAX32;
++ /*
++ There is one exception not handled (intentionaly) by the character set
++ aggregation code. If one string is strong side and is binary, and
++ another one is weak side and is a multi-byte character string,
++ then we need to operate on the second string in terms on bytes when
++ calling ::numchars() and ::charpos(), rather than in terms of characters.
++ Lets substitute its character set to binary.
++ */
++ if (collation.collation == &my_charset_bin)
++ {
++ res->set_charset(&my_charset_bin);
++ rpad->set_charset(&my_charset_bin);
++ }
++
++ if (count <= (res_char_length= res->numchars()))
++ { // String to pad is big enough
++ res->length(res->charpos((int) count)); // Shorten result if longer
++ return (res);
++ }
++ pad_char_length= rpad->numchars();
++
++ byte_count= count * collation.collation->mbmaxlen;
++ if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(), current_thd->variables.max_allowed_packet);
++ goto err;
++ }
++ if (args[2]->null_value || !pad_char_length)
++ goto err;
++ res_byte_length= res->length(); /* Must be done before alloc_buffer */
++ if (!(res= alloc_buffer(res,str,&tmp_value, (ulong) byte_count)))
++ goto err;
++
++ to= (char*) res->ptr()+res_byte_length;
++ ptr_pad=rpad->ptr();
++ pad_byte_length= rpad->length();
++ count-= res_char_length;
++ for ( ; (uint32) count > pad_char_length; count-= pad_char_length)
++ {
++ memcpy(to,ptr_pad,pad_byte_length);
++ to+= pad_byte_length;
++ }
++ if (count)
++ {
++ pad_byte_length= rpad->charpos((int) count);
++ memcpy(to,ptr_pad,(size_t) pad_byte_length);
++ to+= pad_byte_length;
++ }
++ res->length((uint) (to- (char*) res->ptr()));
++ return (res);
++
++ err:
++ null_value=1;
++ return 0;
++}
++
++
++void Item_func_lpad::fix_length_and_dec()
++{
++ // Handle character set for args[0] and args[2].
++ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
++ return;
++
++ if (args[1]->const_item())
++ {
++ ulonglong length= 0;
++
++ if (collation.collation->mbmaxlen > 0)
++ {
++ ulonglong temp= (ulonglong) args[1]->val_int();
++
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if (temp > INT_MAX32)
++ temp= INT_MAX32;
++
++ length= temp * collation.collation->mbmaxlen;
++ }
++
++ if (length >= MAX_BLOB_WIDTH)
++ {
++ length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++ max_length= (ulong) length;
++ }
++ else
++ {
++ max_length= MAX_BLOB_WIDTH;
++ maybe_null= 1;
++ }
++}
++
++
++String *Item_func_lpad::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint32 res_char_length,pad_char_length;
++ /* must be longlong to avoid truncation */
++ longlong count= args[1]->val_int();
++ longlong byte_count;
++ String *res= args[0]->val_str(&tmp_value);
++ String *pad= args[2]->val_str(&lpad_str);
++
++ if (!res || args[1]->null_value || !pad ||
++ ((count < 0) && !args[1]->unsigned_flag))
++ goto err;
++ null_value=0;
++ /* Assumes that the maximum length of a String is < INT_MAX32. */
++ /* Set here so that rest of code sees out-of-bound value as such. */
++ if ((ulonglong) count > INT_MAX32)
++ count= INT_MAX32;
++
++ /*
++ There is one exception not handled (intentionaly) by the character set
++ aggregation code. If one string is strong side and is binary, and
++ another one is weak side and is a multi-byte character string,
++ then we need to operate on the second string in terms on bytes when
++ calling ::numchars() and ::charpos(), rather than in terms of characters.
++ Lets substitute its character set to binary.
++ */
++ if (collation.collation == &my_charset_bin)
++ {
++ res->set_charset(&my_charset_bin);
++ pad->set_charset(&my_charset_bin);
++ }
++
++ res_char_length= res->numchars();
++
++ if (count <= res_char_length)
++ {
++ res->length(res->charpos((int) count));
++ return res;
++ }
++
++ pad_char_length= pad->numchars();
++ byte_count= count * collation.collation->mbmaxlen;
++
++ if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(), current_thd->variables.max_allowed_packet);
++ goto err;
++ }
++
++ if (args[2]->null_value || !pad_char_length ||
++ str->alloc((uint32) byte_count))
++ goto err;
++
++ str->length(0);
++ str->set_charset(collation.collation);
++ count-= res_char_length;
++ while (count >= pad_char_length)
++ {
++ str->append(*pad);
++ count-= pad_char_length;
++ }
++ if (count > 0)
++ str->append(pad->ptr(), pad->charpos((int) count), collation.collation);
++
++ str->append(*res);
++ null_value= 0;
++ return str;
++
++err:
++ null_value= 1;
++ return 0;
++}
++
++
++String *Item_func_conv::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ char *endptr,ans[65],*ptr;
++ longlong dec;
++ int from_base= (int) args[1]->val_int();
++ int to_base= (int) args[2]->val_int();
++ int err;
++
++ if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
++ abs(to_base) > 36 || abs(to_base) < 2 ||
++ abs(from_base) > 36 || abs(from_base) < 2 || !(res->length()))
++ {
++ null_value= 1;
++ return NULL;
++ }
++ null_value= 0;
++ unsigned_flag= !(from_base < 0);
++
++ if (args[0]->field_type() == MYSQL_TYPE_BIT)
++ {
++ /*
++ Special case: The string representation of BIT doesn't resemble the
++ decimal representation, so we shouldn't change it to string and then to
++ decimal.
++ */
++ dec= args[0]->val_int();
++ }
++ else
++ {
++ if (from_base < 0)
++ dec= my_strntoll(res->charset(), res->ptr(), res->length(),
++ -from_base, &endptr, &err);
++ else
++ dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
++ from_base, &endptr, &err);
++ }
++
++ ptr= longlong2str(dec, ans, to_base);
++ if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
++ return make_empty_result();
++ return str;
++}
++
++
++String *Item_func_conv_charset::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ if (use_cached_value)
++ return null_value ? 0 : &str_value;
++ String *arg= args[0]->val_str(str);
++ uint dummy_errors;
++ if (!arg)
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value= tmp_value.copy(arg->ptr(), arg->length(), arg->charset(),
++ conv_charset, &dummy_errors);
++ return null_value ? 0 : check_well_formed_result(&tmp_value);
++}
++
++void Item_func_conv_charset::fix_length_and_dec()
++{
++ collation.set(conv_charset, DERIVATION_IMPLICIT);
++ max_length = args[0]->max_length*conv_charset->mbmaxlen;
++}
++
++void Item_func_conv_charset::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("convert("));
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" using "));
++ str->append(conv_charset->csname);
++ str->append(')');
++}
++
++String *Item_func_set_collation::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ str=args[0]->val_str(str);
++ if ((null_value=args[0]->null_value))
++ return 0;
++ str->set_charset(collation.collation);
++ return str;
++}
++
++void Item_func_set_collation::fix_length_and_dec()
++{
++ CHARSET_INFO *set_collation;
++ const char *colname;
++ String tmp, *str= args[1]->val_str(&tmp);
++ colname= str->c_ptr();
++ if (colname == binary_keyword)
++ set_collation= get_charset_by_csname(args[0]->collation.collation->csname,
++ MY_CS_BINSORT,MYF(0));
++ else
++ {
++ if (!(set_collation= get_charset_by_name(colname,MYF(0))))
++ {
++ my_error(ER_UNKNOWN_COLLATION, MYF(0), colname);
++ return;
++ }
++ }
++
++ if (!set_collation ||
++ !my_charset_same(args[0]->collation.collation,set_collation))
++ {
++ my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
++ colname, args[0]->collation.collation->csname);
++ return;
++ }
++ collation.set(set_collation, DERIVATION_EXPLICIT,
++ args[0]->collation.repertoire);
++ max_length= args[0]->max_length;
++}
++
++
++bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
++{
++ /* Assume we don't have rtti */
++ if (this == item)
++ return 1;
++ if (item->type() != FUNC_ITEM)
++ return 0;
++ Item_func *item_func=(Item_func*) item;
++ if (arg_count != item_func->arg_count ||
++ functype() != item_func->functype())
++ return 0;
++ Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item;
++ if (collation.collation != item_func_sc->collation.collation)
++ return 0;
++ for (uint i=0; i < arg_count ; i++)
++ if (!args[i]->eq(item_func_sc->args[i], binary_cmp))
++ return 0;
++ return 1;
++}
++
++
++void Item_func_set_collation::print(String *str, enum_query_type query_type)
++{
++ str->append('(');
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" collate "));
++ DBUG_ASSERT(args[1]->basic_const_item() &&
++ args[1]->type() == Item::STRING_ITEM);
++ args[1]->str_value.print(str);
++ str->append(')');
++}
++
++String *Item_func_charset::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint dummy_errors;
++
++ CHARSET_INFO *cs= args[0]->collation.collation;
++ null_value= 0;
++ str->copy(cs->csname, (uint) strlen(cs->csname),
++ &my_charset_latin1, collation.collation, &dummy_errors);
++ return str;
++}
++
++String *Item_func_collation::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uint dummy_errors;
++ CHARSET_INFO *cs= args[0]->collation.collation;
++
++ null_value= 0;
++ str->copy(cs->name, (uint) strlen(cs->name),
++ &my_charset_latin1, collation.collation, &dummy_errors);
++ return str;
++}
++
++
++String *Item_func_hex::val_str(String *str)
++{
++ String *res;
++ DBUG_ASSERT(fixed == 1);
++ if (args[0]->result_type() != STRING_RESULT)
++ {
++ ulonglong dec;
++ char ans[65],*ptr;
++ /* Return hex of unsigned longlong value */
++ if (args[0]->result_type() == REAL_RESULT ||
++ args[0]->result_type() == DECIMAL_RESULT)
++ {
++ double val= args[0]->val_real();
++ if ((val <= (double) LONGLONG_MIN) ||
++ (val >= (double) (ulonglong) ULONGLONG_MAX))
++ dec= ~(longlong) 0;
++ else
++ dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
++ }
++ else
++ dec= (ulonglong) args[0]->val_int();
++
++ if ((null_value= args[0]->null_value))
++ return 0;
++ ptr= longlong2str(dec,ans,16);
++ if (str->copy(ans,(uint32) (ptr-ans),default_charset()))
++ return make_empty_result(); // End of memory
++ return str;
++ }
++
++ /* Convert given string to a hex string, character by character */
++ res= args[0]->val_str(str);
++ if (!res || tmp_value.alloc(res->length()*2+1))
++ {
++ null_value=1;
++ return 0;
++ }
++ null_value=0;
++ tmp_value.length(res->length()*2);
++
++ octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
++ return &tmp_value;
++}
++
++ /** Convert given hex string to a binary string. */
++
++String *Item_func_unhex::val_str(String *str)
++{
++ const char *from, *end;
++ char *to;
++ String *res;
++ uint length;
++ DBUG_ASSERT(fixed == 1);
++
++ res= args[0]->val_str(str);
++ if (!res || tmp_value.alloc(length= (1+res->length())/2))
++ {
++ null_value=1;
++ return 0;
++ }
++
++ from= res->ptr();
++ null_value= 0;
++ tmp_value.length(length);
++ to= (char*) tmp_value.ptr();
++ if (res->length() % 2)
++ {
++ int hex_char;
++ *to++= hex_char= hexchar_to_int(*from++);
++ if ((null_value= (hex_char == -1)))
++ return 0;
++ }
++ for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
++ {
++ int hex_char;
++ *to= (hex_char= hexchar_to_int(from[0])) << 4;
++ if ((null_value= (hex_char == -1)))
++ return 0;
++ *to|= hex_char= hexchar_to_int(from[1]);
++ if ((null_value= (hex_char == -1)))
++ return 0;
++ }
++ return &tmp_value;
++}
++
++
++void Item_func_binary::print(String *str, enum_query_type query_type)
++{
++ str->append(STRING_WITH_LEN("cast("));
++ args[0]->print(str, query_type);
++ str->append(STRING_WITH_LEN(" as binary)"));
++}
++
++
++#include <my_dir.h> // For my_stat
++
++String *Item_load_file::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *file_name;
++ File file;
++ MY_STAT stat_info;
++ char path[FN_REFLEN];
++ DBUG_ENTER("load_file");
++
++ if (!(file_name= args[0]->val_str(str))
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ || !(current_thd->security_ctx->master_access & FILE_ACL)
++#endif
++ )
++ goto err;
++
++ (void) fn_format(path, file_name->c_ptr_safe(), mysql_real_data_home, "",
++ MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
++
++ /* Read only allowed from within dir specified by secure_file_priv */
++ if (!is_secure_file_path(path))
++ goto err;
++
++ if (!my_stat(path, &stat_info, MYF(0)))
++ goto err;
++
++ if (!(stat_info.st_mode & S_IROTH))
++ {
++ /* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
++ goto err;
++ }
++ if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
++ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
++ func_name(), current_thd->variables.max_allowed_packet);
++ goto err;
++ }
++ if (tmp_value.alloc(stat_info.st_size))
++ goto err;
++ if ((file = my_open(file_name->ptr(), O_RDONLY, MYF(0))) < 0)
++ goto err;
++ if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP)))
++ {
++ my_close(file, MYF(0));
++ goto err;
++ }
++ tmp_value.length(stat_info.st_size);
++ my_close(file, MYF(0));
++ null_value = 0;
++ DBUG_RETURN(&tmp_value);
++
++err:
++ null_value = 1;
++ DBUG_RETURN(0);
++}
++
++
++String* Item_func_export_set::val_str(String* str)
++{
++ DBUG_ASSERT(fixed == 1);
++ ulonglong the_set = (ulonglong) args[0]->val_int();
++ String yes_buf, *yes;
++ yes = args[1]->val_str(&yes_buf);
++ String no_buf, *no;
++ no = args[2]->val_str(&no_buf);
++ String *sep = NULL, sep_buf ;
++
++ uint num_set_values = 64;
++ ulonglong mask = 0x1;
++ str->length(0);
++ str->set_charset(collation.collation);
++
++ /* Check if some argument is a NULL value */
++ if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
++ {
++ null_value=1;
++ return 0;
++ }
++ /*
++ Arg count can only be 3, 4 or 5 here. This is guaranteed from the
++ grammar for EXPORT_SET()
++ */
++ switch(arg_count) {
++ case 5:
++ num_set_values = (uint) args[4]->val_int();
++ if (num_set_values > 64)
++ num_set_values=64;
++ if (args[4]->null_value)
++ {
++ null_value=1;
++ return 0;
++ }
++ /* Fall through */
++ case 4:
++ if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
++ {
++ null_value=1;
++ return 0;
++ }
++ break;
++ case 3:
++ {
++ /* errors is not checked - assume "," can always be converted */
++ uint errors;
++ sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
++ sep = &sep_buf;
++ }
++ break;
++ default:
++ DBUG_ASSERT(0); // cannot happen
++ }
++ null_value=0;
++
++ for (uint i = 0; i < num_set_values; i++, mask = (mask << 1))
++ {
++ if (the_set & mask)
++ str->append(*yes);
++ else
++ str->append(*no);
++ if (i != num_set_values - 1)
++ str->append(*sep);
++ }
++ return str;
++}
++
++void Item_func_export_set::fix_length_and_dec()
++{
++ uint length=max(args[1]->max_length,args[2]->max_length);
++ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
++ max_length=length*64+sep_length*63;
++
++ if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ MY_COLL_ALLOW_CONV, 1))
++ return;
++}
++
++String* Item_func_inet_ntoa::val_str(String* str)
++{
++ DBUG_ASSERT(fixed == 1);
++ uchar buf[8], *p;
++ ulonglong n = (ulonglong) args[0]->val_int();
++ char num[4];
++
++ /*
++ We do not know if args[0] is NULL until we have called
++ some val function on it if args[0] is not a constant!
++
++ Also return null if n > 255.255.255.255
++ */
++ if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
++ return 0; // Null value
++
++ str->set_charset(collation.collation);
++ str->length(0);
++ int4store(buf,n);
++
++ /* Now we can assume little endian. */
++
++ num[3]='.';
++ for (p=buf+4 ; p-- > buf ; )
++ {
++ uint c = *p;
++ uint n1,n2; // Try to avoid divisions
++ n1= c / 100; // 100 digits
++ c-= n1*100;
++ n2= c / 10; // 10 digits
++ c-=n2*10; // last digit
++ num[0]=(char) n1+'0';
++ num[1]=(char) n2+'0';
++ num[2]=(char) c+'0';
++ uint length=(n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero
++
++ (void) str->append(num+4-length,length);
++ }
++ str->length(str->length()-1); // Remove last '.';
++ return str;
++}
++
++
++#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
++
++/**
++ QUOTE() function returns argument string in single quotes suitable for
++ using in a SQL statement.
++
++ Adds a \\ before all characters that needs to be escaped in a SQL string.
++ We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
++ running commands from a file in windows.
++
++ This function is very useful when you want to generate SQL statements.
++
++ @note
++ QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
++
++ @retval
++ str Quoted string
++ @retval
++ NULL Out of memory.
++*/
++
++String *Item_func_quote::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ /*
++ Bit mask that has 1 for set for the position of the following characters:
++ 0, \, ' and ^Z
++ */
++
++ static uchar escmask[32]=
++ {
++ 0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
++ };
++
++ char *from, *to, *end, *start;
++ String *arg= args[0]->val_str(str);
++ uint arg_length, new_length;
++ if (!arg) // Null argument
++ {
++ /* Return the string 'NULL' */
++ str->copy(STRING_WITH_LEN("NULL"), collation.collation);
++ null_value= 0;
++ return str;
++ }
++
++ arg_length= arg->length();
++
++ if (collation.collation->mbmaxlen == 1)
++ {
++ new_length= arg_length + 2; /* for beginning and ending ' signs */
++ for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
++ new_length+= get_esc_bit(escmask, (uchar) *from);
++ }
++ else
++ {
++ new_length= (arg_length * 2) + /* For string characters */
++ (2 * collation.collation->mbmaxlen); /* For quotes */
++ }
++
++ if (tmp_value.alloc(new_length))
++ goto null;
++
++ if (collation.collation->mbmaxlen > 1)
++ {
++ CHARSET_INFO *cs= collation.collation;
++ int mblen;
++ uchar *to_end;
++ to= (char*) tmp_value.ptr();
++ to_end= (uchar*) to + new_length;
++
++ /* Put leading quote */
++ if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
++ goto null;
++ to+= mblen;
++
++ for (start= (char*) arg->ptr(), end= start + arg_length; start < end; )
++ {
++ my_wc_t wc;
++ bool escape;
++ if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0)
++ goto null;
++ start+= mblen;
++ switch (wc) {
++ case 0: escape= 1; wc= '0'; break;
++ case '\032': escape= 1; wc= 'Z'; break;
++ case '\'': escape= 1; break;
++ case '\\': escape= 1; break;
++ default: escape= 0; break;
++ }
++ if (escape)
++ {
++ if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0)
++ goto null;
++ to+= mblen;
++ }
++ if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0)
++ goto null;
++ to+= mblen;
++ }
++
++ /* Put trailing quote */
++ if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
++ goto null;
++ to+= mblen;
++ new_length= to - tmp_value.ptr();
++ goto ret;
++ }
++
++ /*
++ We replace characters from the end to the beginning
++ */
++ to= (char*) tmp_value.ptr() + new_length - 1;
++ *to--= '\'';
++ for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
++ {
++ /*
++ We can't use the bitmask here as we want to replace \O and ^Z with 0
++ and Z
++ */
++ switch (*end) {
++ case 0:
++ *to--= '0';
++ *to= '\\';
++ break;
++ case '\032':
++ *to--= 'Z';
++ *to= '\\';
++ break;
++ case '\'':
++ case '\\':
++ *to--= *end;
++ *to= '\\';
++ break;
++ default:
++ *to= *end;
++ break;
++ }
++ }
++ *to= '\'';
++
++ret:
++ tmp_value.length(new_length);
++ tmp_value.set_charset(collation.collation);
++ null_value= 0;
++ return &tmp_value;
++
++null:
++ null_value= 1;
++ return 0;
++}
++
++longlong Item_func_uncompressed_length::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ if (res->is_empty()) return 0;
++
++ /*
++ If length is <= 4 bytes, data is corrupt. This is the best we can do
++ to detect garbage input without decompressing it.
++ */
++ if (res->length() <= 4)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_ZLIB_Z_DATA_ERROR,
++ ER(ER_ZLIB_Z_DATA_ERROR));
++ null_value= 1;
++ return 0;
++ }
++
++ /*
++ res->ptr() using is safe because we have tested that string is at least
++ 5 bytes long.
++ res->c_ptr() is not used because:
++ - we do not need \0 terminated string to get first 4 bytes
++ - c_ptr() tests simbol after string end (uninitialiozed memory) which
++ confuse valgrind
++ */
++ return uint4korr(res->ptr()) & 0x3FFFFFFF;
++}
++
++longlong Item_func_crc32::val_int()
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res=args[0]->val_str(&value);
++ if (!res)
++ {
++ null_value=1;
++ return 0; /* purecov: inspected */
++ }
++ null_value=0;
++ return (longlong) crc32(0L, (uchar*)res->ptr(), res->length());
++}
++
++#ifdef HAVE_COMPRESS
++#include "zlib.h"
++
++String *Item_func_compress::val_str(String *str)
++{
++ int err= Z_OK, code;
++ ulong new_size;
++ String *res;
++ Byte *body;
++ char *tmp, *last_char;
++ DBUG_ASSERT(fixed == 1);
++
++ if (!(res= args[0]->val_str(str)))
++ {
++ null_value= 1;
++ return 0;
++ }
++ null_value= 0;
++ if (res->is_empty()) return res;
++
++ /*
++ Citation from zlib.h (comment for compress function):
++
++ Compresses the source buffer into the destination buffer. sourceLen is
++ the byte length of the source buffer. Upon entry, destLen is the total
++ size of the destination buffer, which must be at least 0.1% larger than
++ sourceLen plus 12 bytes.
++ We assume here that the buffer can't grow more than .25 %.
++ */
++ new_size= res->length() + res->length() / 5 + 12;
++
++ // Check new_size overflow: new_size <= res->length()
++ if (((uint32) (new_size+5) <= res->length()) ||
++ buffer.realloc((uint32) new_size + 4 + 1))
++ {
++ null_value= 1;
++ return 0;
++ }
++
++ body= ((Byte*)buffer.ptr()) + 4;
++
++ // As far as we have checked res->is_empty() we can use ptr()
++ if ((err= compress(body, &new_size,
++ (const Bytef*)res->ptr(), res->length())) != Z_OK)
++ {
++ code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
++ push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
++ null_value= 1;
++ return 0;
++ }
++
++ tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
++ int4store(tmp, res->length() & 0x3FFFFFFF);
++
++ /* This is to ensure that things works for CHAR fields, which trim ' ': */
++ last_char= ((char*)body)+new_size-1;
++ if (*last_char == ' ')
++ {
++ *++last_char= '.';
++ new_size++;
++ }
++
++ buffer.length((uint32)new_size + 4);
++ return &buffer;
++}
++
++
++String *Item_func_uncompress::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ String *res= args[0]->val_str(str);
++ ulong new_size;
++ int err;
++ uint code;
++
++ if (!res)
++ goto err;
++ null_value= 0;
++ if (res->is_empty())
++ return res;
++
++ /* If length is less than 4 bytes, data is corrupt */
++ if (res->length() <= 4)
++ {
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_ZLIB_Z_DATA_ERROR,
++ ER(ER_ZLIB_Z_DATA_ERROR));
++ goto err;
++ }
++
++ /* Size of uncompressed data is stored as first 4 bytes of field */
++ new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
++ if (new_size > current_thd->variables.max_allowed_packet)
++ {
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_TOO_BIG_FOR_UNCOMPRESS,
++ ER(ER_TOO_BIG_FOR_UNCOMPRESS),
++ current_thd->variables.max_allowed_packet);
++ goto err;
++ }
++ if (buffer.realloc((uint32)new_size))
++ goto err;
++
++ if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
++ ((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
++ {
++ buffer.length((uint32) new_size);
++ return &buffer;
++ }
++
++ code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
++ ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
++ push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
++
++err:
++ null_value= 1;
++ return 0;
++}
++#endif
++
++/*
++ UUID, as in
++ DCE 1.1: Remote Procedure Call,
++ Open Group Technical Standard Document Number C706, October 1997,
++ (supersedes C309 DCE: Remote Procedure Call 8/1994,
++ which was basis for ISO/IEC 11578:1996 specification)
++*/
++
++static struct rand_struct uuid_rand;
++static uint nanoseq;
++static ulonglong uuid_time=0;
++static char clock_seq_and_node_str[]="-0000-000000000000";
++
++/**
++ number of 100-nanosecond intervals between
++ 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
++*/
++#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \
++ 1000 * 1000 * 10)
++
++#define UUID_VERSION 0x1000
++#define UUID_VARIANT 0x8000
++
++static void tohex(char *to, uint from, uint len)
++{
++ to+= len;
++ while (len--)
++ {
++ *--to= _dig_vec_lower[from & 15];
++ from >>= 4;
++ }
++}
++
++static void set_clock_seq_str()
++{
++ uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
++ tohex(clock_seq_and_node_str+1, clock_seq, 4);
++ nanoseq= 0;
++}
++
++String *Item_func_uuid::val_str(String *str)
++{
++ DBUG_ASSERT(fixed == 1);
++ char *s;
++ THD *thd= current_thd;
++
++ pthread_mutex_lock(&LOCK_uuid_generator);
++ if (! uuid_time) /* first UUID() call. initializing data */
++ {
++ ulong tmp=sql_rnd_with_mutex();
++ uchar mac[6];
++ int i;
++ if (my_gethwaddr(mac))
++ {
++ /* purecov: begin inspected */
++ /*
++ generating random "hardware addr"
++ and because specs explicitly specify that it should NOT correlate
++ with a clock_seq value (initialized random below), we use a separate
++ randominit() here
++ */
++ randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
++ for (i=0; i < (int)sizeof(mac); i++)
++ mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
++ /* purecov: end */
++ }
++ s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
++ for (i=sizeof(mac)-1 ; i>=0 ; i--)
++ {
++ *--s=_dig_vec_lower[mac[i] & 15];
++ *--s=_dig_vec_lower[mac[i] >> 4];
++ }
++ randominit(&uuid_rand, tmp + (ulong) server_start_time,
++ tmp + (ulong) thd->status_var.bytes_sent);
++ set_clock_seq_str();
++ }
++
++ ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
++
++ if (likely(tv > uuid_time))
++ {
++ /*
++ Current time is ahead of last timestamp, as it should be.
++ If we "borrowed time", give it back, just as long as we
++ stay ahead of the previous timestamp.
++ */
++ if (nanoseq)
++ {
++ DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0));
++ /*
++ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
++ */
++ ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ tv-= delta;
++ nanoseq-= delta;
++ }
++ }
++ else
++ {
++ if (unlikely(tv == uuid_time))
++ {
++ /*
++ For low-res system clocks. If several requests for UUIDs
++ end up on the same tick, we add a nano-second to make them
++ different.
++ ( current_timestamp + nanoseq * calls_in_this_period )
++ may end up > next_timestamp; this is OK. Nonetheless, we'll
++ try to unwind nanoseq when we get a chance to.
++ If nanoseq overflows, we'll start over with a new numberspace
++ (so the if() below is needed so we can avoid the ++tv and thus
++ match the follow-up if() if nanoseq overflows!).
++ */
++ if (likely(++nanoseq))
++ ++tv;
++ }
++
++ if (unlikely(tv <= uuid_time))
++ {
++ /*
++ If the admin changes the system clock (or due to Daylight
++ Saving Time), the system clock may be turned *back* so we
++ go through a period once more for which we already gave out
++ UUIDs. To avoid duplicate UUIDs despite potentially identical
++ times, we make a new random component.
++ We also come here if the nanoseq "borrowing" overflows.
++ In either case, we throw away any nanoseq borrowing since it's
++ irrelevant in the new numberspace.
++ */
++ set_clock_seq_str();
++ tv= my_getsystime() + UUID_TIME_OFFSET;
++ nanoseq= 0;
++ DBUG_PRINT("uuid",("making new numberspace"));
++ }
++ }
++
++ uuid_time=tv;
++ pthread_mutex_unlock(&LOCK_uuid_generator);
++
++ uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
++ uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
++ uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
++
++ str->realloc(UUID_LENGTH+1);
++ str->length(UUID_LENGTH);
++ str->set_charset(system_charset_info);
++ s=(char *) str->ptr();
++ s[8]=s[13]='-';
++ tohex(s, time_low, 8);
++ tohex(s+9, time_mid, 4);
++ tohex(s+14, time_hi_and_version, 4);
++ strmov(s+18, clock_seq_and_node_str);
++ return str;
++}
+diff -urN mysql-old/sql/item_strfunc.h.orig mysql/sql/item_strfunc.h.orig
+--- mysql-old/sql/item_strfunc.h.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/item_strfunc.h.orig 2011-04-12 12:11:38.000000000 +0000
+@@ -0,0 +1,868 @@
++/* Copyright (C) 2000-2003 MySQL AB
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++
++/* This file defines all string functions */
++
++#ifdef USE_PRAGMA_INTERFACE
++#pragma interface /* gcc class implementation */
++#endif
++
++class Item_str_func :public Item_func
++{
++protected:
++ /**
++ Sets the result value of the function an empty string, using the current
++ character set. No memory is allocated.
++ @retval A pointer to the str_value member.
++ */
++ String *make_empty_result() {
++ str_value.set("", 0, collation.collation);
++ return &str_value;
++ }
++public:
++ Item_str_func() :Item_func() { decimals=NOT_FIXED_DEC; }
++ Item_str_func(Item *a) :Item_func(a) {decimals=NOT_FIXED_DEC; }
++ Item_str_func(Item *a,Item *b) :Item_func(a,b) { decimals=NOT_FIXED_DEC; }
++ Item_str_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { decimals=NOT_FIXED_DEC; }
++ Item_str_func(Item *a,Item *b,Item *c,Item *d) :Item_func(a,b,c,d) {decimals=NOT_FIXED_DEC; }
++ Item_str_func(Item *a,Item *b,Item *c,Item *d, Item* e) :Item_func(a,b,c,d,e) {decimals=NOT_FIXED_DEC; }
++ Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; }
++ longlong val_int();
++ double val_real();
++ my_decimal *val_decimal(my_decimal *);
++ enum Item_result result_type () const { return STRING_RESULT; }
++ void left_right_max_length();
++ bool fix_fields(THD *thd, Item **ref);
++};
++
++class Item_func_md5 :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_md5(Item *a) :Item_str_func(a)
++ {
++ collation.set(&my_charset_bin);
++ }
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "md5"; }
++};
++
++
++class Item_func_sha :public Item_str_func
++{
++public:
++ Item_func_sha(Item *a) :Item_str_func(a)
++ {
++ collation.set(&my_charset_bin);
++ }
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "sha"; }
++};
++
++class Item_func_aes_encrypt :public Item_str_func
++{
++public:
++ Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "aes_encrypt"; }
++};
++
++class Item_func_aes_decrypt :public Item_str_func
++{
++public:
++ Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "aes_decrypt"; }
++};
++
++
++class Item_func_concat :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_concat(List<Item> &list) :Item_str_func(list) {}
++ Item_func_concat(Item *a,Item *b) :Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "concat"; }
++};
++
++class Item_func_concat_ws :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_concat_ws(List<Item> &list) :Item_str_func(list) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "concat_ws"; }
++ table_map not_null_tables() const { return 0; }
++};
++
++class Item_func_reverse :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_reverse(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "reverse"; }
++};
++
++
++class Item_func_replace :public Item_str_func
++{
++ String tmp_value,tmp_value2;
++public:
++ Item_func_replace(Item *org,Item *find,Item *replace)
++ :Item_str_func(org,find,replace) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "replace"; }
++};
++
++
++class Item_func_insert :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_insert(Item *org,Item *start,Item *length,Item *new_str)
++ :Item_str_func(org,start,length,new_str) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "insert"; }
++};
++
++
++class Item_str_conv :public Item_str_func
++{
++protected:
++ uint multiply;
++ my_charset_conv_case converter;
++ String tmp_value;
++public:
++ Item_str_conv(Item *item) :Item_str_func(item) {}
++ String *val_str(String *);
++};
++
++
++class Item_func_lcase :public Item_str_conv
++{
++public:
++ Item_func_lcase(Item *item) :Item_str_conv(item) {}
++ const char *func_name() const { return "lcase"; }
++ void fix_length_and_dec();
++};
++
++class Item_func_ucase :public Item_str_conv
++{
++public:
++ Item_func_ucase(Item *item) :Item_str_conv(item) {}
++ const char *func_name() const { return "ucase"; }
++ void fix_length_and_dec();
++};
++
++
++class Item_func_left :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_left(Item *a,Item *b) :Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "left"; }
++};
++
++
++class Item_func_right :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_right(Item *a,Item *b) :Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "right"; }
++};
++
++
++class Item_func_substr :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_substr(Item *a,Item *b) :Item_str_func(a,b) {}
++ Item_func_substr(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "substr"; }
++};
++
++
++class Item_func_substr_index :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "substring_index"; }
++};
++
++
++class Item_func_trim :public Item_str_func
++{
++protected:
++ String tmp_value;
++ String remove;
++public:
++ Item_func_trim(Item *a,Item *b) :Item_str_func(a,b) {}
++ Item_func_trim(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "trim"; }
++ virtual void print(String *str, enum_query_type query_type);
++ virtual const char *mode_name() const { return "both"; }
++};
++
++
++class Item_func_ltrim :public Item_func_trim
++{
++public:
++ Item_func_ltrim(Item *a,Item *b) :Item_func_trim(a,b) {}
++ Item_func_ltrim(Item *a) :Item_func_trim(a) {}
++ String *val_str(String *);
++ const char *func_name() const { return "ltrim"; }
++ const char *mode_name() const { return "leading"; }
++};
++
++
++class Item_func_rtrim :public Item_func_trim
++{
++public:
++ Item_func_rtrim(Item *a,Item *b) :Item_func_trim(a,b) {}
++ Item_func_rtrim(Item *a) :Item_func_trim(a) {}
++ String *val_str(String *);
++ const char *func_name() const { return "rtrim"; }
++ const char *mode_name() const { return "trailing"; }
++};
++
++
++/*
++ Item_func_password -- new (4.1.1) PASSWORD() function implementation.
++ Returns strcat('*', octet2hex(sha1(sha1(password)))). '*' stands for new
++ password format, sha1(sha1(password) is so-called hash_stage2 value.
++ Length of returned string is always 41 byte. To find out how entire
++ authentication procedure works, see comments in password.c.
++*/
++
++class Item_func_password :public Item_str_func
++{
++ char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
++public:
++ Item_func_password(Item *a) :Item_str_func(a) {}
++ String *val_str(String *str);
++ void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; }
++ const char *func_name() const { return "password"; }
++ static char *alloc(THD *thd, const char *password, size_t pass_len);
++};
++
++
++/*
++ Item_func_old_password -- PASSWORD() implementation used in MySQL 3.21 - 4.0
++ compatibility mode. This item is created in sql_yacc.yy when
++ 'old_passwords' session variable is set, and to handle OLD_PASSWORD()
++ function.
++*/
++
++class Item_func_old_password :public Item_str_func
++{
++ char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1];
++public:
++ Item_func_old_password(Item *a) :Item_str_func(a) {}
++ String *val_str(String *str);
++ void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; }
++ const char *func_name() const { return "old_password"; }
++ static char *alloc(THD *thd, const char *password, size_t pass_len);
++};
++
++
++class Item_func_des_encrypt :public Item_str_func
++{
++ String tmp_value,tmp_arg;
++public:
++ Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
++ Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ maybe_null=1;
++ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
++ max_length = args[0]->max_length + 9;
++ }
++ const char *func_name() const { return "des_encrypt"; }
++};
++
++class Item_func_des_decrypt :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
++ Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ maybe_null=1;
++ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
++ max_length = args[0]->max_length - 9;
++ }
++ const char *func_name() const { return "des_decrypt"; }
++};
++
++class Item_func_encrypt :public Item_str_func
++{
++ String tmp_value;
++
++ /* Encapsulate common constructor actions */
++ void constructor_helper()
++ {
++ collation.set(&my_charset_bin);
++ }
++public:
++ Item_func_encrypt(Item *a) :Item_str_func(a)
++ {
++ constructor_helper();
++ }
++ Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b)
++ {
++ constructor_helper();
++ }
++ String *val_str(String *);
++ void fix_length_and_dec() { maybe_null=1; max_length = 13; }
++ const char *func_name() const { return "encrypt"; }
++};
++
++#include "sql_crypt.h"
++
++
++class Item_func_encode :public Item_str_func
++{
++private:
++ /** Whether the PRNG has already been seeded. */
++ bool seeded;
++protected:
++ SQL_CRYPT sql_crypt;
++public:
++ Item_func_encode(Item *a, Item *seed):
++ Item_str_func(a, seed) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "encode"; }
++protected:
++ virtual void crypto_transform(String *);
++private:
++ /** Provide a seed for the PRNG sequence. */
++ bool seed();
++};
++
++
++class Item_func_decode :public Item_func_encode
++{
++public:
++ Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {}
++ const char *func_name() const { return "decode"; }
++protected:
++ void crypto_transform(String *);
++};
++
++
++class Item_func_sysconst :public Item_str_func
++{
++public:
++ Item_func_sysconst()
++ { collation.set(system_charset_info,DERIVATION_SYSCONST); }
++ Item *safe_charset_converter(CHARSET_INFO *tocs);
++ /*
++ Used to create correct Item name in new converted item in
++ safe_charset_converter, return string representation of this function
++ call
++ */
++ virtual const char *fully_qualified_func_name() const = 0;
++};
++
++
++class Item_func_database :public Item_func_sysconst
++{
++public:
++ Item_func_database() :Item_func_sysconst() {}
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
++ maybe_null=1;
++ }
++ const char *func_name() const { return "database"; }
++ const char *fully_qualified_func_name() const { return "database()"; }
++};
++
++
++class Item_func_user :public Item_func_sysconst
++{
++protected:
++ bool init (const char *user, const char *host);
++
++public:
++ Item_func_user()
++ {
++ str_value.set("", 0, system_charset_info);
++ }
++ String *val_str(String *)
++ {
++ DBUG_ASSERT(fixed == 1);
++ return (null_value ? 0 : &str_value);
++ }
++ bool fix_fields(THD *thd, Item **ref);
++ void fix_length_and_dec()
++ {
++ max_length= (USERNAME_LENGTH +
++ (HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN);
++ }
++ const char *func_name() const { return "user"; }
++ const char *fully_qualified_func_name() const { return "user()"; }
++ int save_in_field(Field *field, bool no_conversions)
++ {
++ return save_str_value_in_field(field, &str_value);
++ }
++};
++
++
++class Item_func_current_user :public Item_func_user
++{
++ Name_resolution_context *context;
++
++public:
++ Item_func_current_user(Name_resolution_context *context_arg)
++ : context(context_arg) {}
++ bool fix_fields(THD *thd, Item **ref);
++ const char *func_name() const { return "current_user"; }
++ const char *fully_qualified_func_name() const { return "current_user()"; }
++};
++
++
++class Item_func_soundex :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_soundex(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "soundex"; }
++};
++
++
++class Item_func_elt :public Item_str_func
++{
++public:
++ Item_func_elt(List<Item> &list) :Item_str_func(list) {}
++ double val_real();
++ longlong val_int();
++ String *val_str(String *str);
++ void fix_length_and_dec();
++ const char *func_name() const { return "elt"; }
++};
++
++
++class Item_func_make_set :public Item_str_func
++{
++ Item *item;
++ String tmp_str;
++
++public:
++ Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
++ String *val_str(String *str);
++ bool fix_fields(THD *thd, Item **ref)
++ {
++ DBUG_ASSERT(fixed == 0);
++ return ((!item->fixed && item->fix_fields(thd, &item)) ||
++ item->check_cols(1) ||
++ Item_func::fix_fields(thd, ref));
++ }
++ void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
++ void fix_length_and_dec();
++ void update_used_tables();
++ const char *func_name() const { return "make_set"; }
++
++ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
++ {
++ return item->walk(processor, walk_subquery, arg) ||
++ Item_str_func::walk(processor, walk_subquery, arg);
++ }
++ Item *transform(Item_transformer transformer, uchar *arg);
++ virtual void print(String *str, enum_query_type query_type);
++};
++
++
++class Item_func_format :public Item_str_func
++{
++ String tmp_str;
++public:
++ Item_func_format(Item *org, Item *dec);
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "format"; }
++ virtual void print(String *str, enum_query_type query_type);
++};
++
++
++class Item_func_char :public Item_str_func
++{
++public:
++ Item_func_char(List<Item> &list) :Item_str_func(list)
++ { collation.set(&my_charset_bin); }
++ Item_func_char(List<Item> &list, CHARSET_INFO *cs) :Item_str_func(list)
++ { collation.set(cs); }
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ max_length= arg_count * 4;
++ }
++ const char *func_name() const { return "char"; }
++};
++
++
++class Item_func_repeat :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_repeat(Item *arg1,Item *arg2) :Item_str_func(arg1,arg2) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "repeat"; }
++};
++
++
++class Item_func_rpad :public Item_str_func
++{
++ String tmp_value, rpad_str;
++public:
++ Item_func_rpad(Item *arg1,Item *arg2,Item *arg3)
++ :Item_str_func(arg1,arg2,arg3) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "rpad"; }
++};
++
++
++class Item_func_lpad :public Item_str_func
++{
++ String tmp_value, lpad_str;
++public:
++ Item_func_lpad(Item *arg1,Item *arg2,Item *arg3)
++ :Item_str_func(arg1,arg2,arg3) {}
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "lpad"; }
++};
++
++
++class Item_func_conv :public Item_str_func
++{
++public:
++ Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
++ const char *func_name() const { return "conv"; }
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ collation.set(default_charset());
++ max_length=64;
++ maybe_null= 1;
++ }
++};
++
++
++class Item_func_hex :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_hex(Item *a) :Item_str_func(a) {}
++ const char *func_name() const { return "hex"; }
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ collation.set(default_charset());
++ decimals=0;
++ max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
++ }
++};
++
++class Item_func_unhex :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_unhex(Item *a) :Item_str_func(a)
++ {
++ /* there can be bad hex strings */
++ maybe_null= 1;
++ }
++ const char *func_name() const { return "unhex"; }
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ collation.set(&my_charset_bin);
++ decimals=0;
++ max_length=(1+args[0]->max_length)/2;
++ }
++};
++
++
++class Item_func_binary :public Item_str_func
++{
++public:
++ Item_func_binary(Item *a) :Item_str_func(a) {}
++ String *val_str(String *a)
++ {
++ DBUG_ASSERT(fixed == 1);
++ String *tmp=args[0]->val_str(a);
++ null_value=args[0]->null_value;
++ if (tmp)
++ tmp->set_charset(&my_charset_bin);
++ return tmp;
++ }
++ void fix_length_and_dec()
++ {
++ collation.set(&my_charset_bin);
++ max_length=args[0]->max_length;
++ }
++ virtual void print(String *str, enum_query_type query_type);
++ const char *func_name() const { return "cast_as_binary"; }
++};
++
++
++class Item_load_file :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_load_file(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ const char *func_name() const { return "load_file"; }
++ void fix_length_and_dec()
++ {
++ collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
++ maybe_null=1;
++ max_length=MAX_BLOB_WIDTH;
++ }
++};
++
++
++class Item_func_export_set: public Item_str_func
++{
++ public:
++ Item_func_export_set(Item *a,Item *b,Item* c) :Item_str_func(a,b,c) {}
++ Item_func_export_set(Item *a,Item *b,Item* c,Item* d) :Item_str_func(a,b,c,d) {}
++ Item_func_export_set(Item *a,Item *b,Item* c,Item* d,Item* e) :Item_str_func(a,b,c,d,e) {}
++ String *val_str(String *str);
++ void fix_length_and_dec();
++ const char *func_name() const { return "export_set"; }
++};
++
++class Item_func_inet_ntoa : public Item_str_func
++{
++public:
++ Item_func_inet_ntoa(Item *a) :Item_str_func(a)
++ {
++ }
++ String* val_str(String* str);
++ const char *func_name() const { return "inet_ntoa"; }
++ void fix_length_and_dec()
++ {
++ decimals= 0;
++ max_length= 3 * 8 + 7;
++ maybe_null= 1;
++ }
++};
++
++class Item_func_quote :public Item_str_func
++{
++ String tmp_value;
++public:
++ Item_func_quote(Item *a) :Item_str_func(a) {}
++ const char *func_name() const { return "quote"; }
++ String *val_str(String *);
++ void fix_length_and_dec()
++ {
++ collation.set(args[0]->collation);
++ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
++ 2 * collation.collation->mbmaxlen;
++ max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ }
++};
++
++class Item_func_conv_charset :public Item_str_func
++{
++ bool use_cached_value;
++ String tmp_value;
++public:
++ bool safe;
++ CHARSET_INFO *conv_charset; // keep it public
++ Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
++ { conv_charset= cs; use_cached_value= 0; safe= 0; }
++ Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const)
++ :Item_str_func(a)
++ {
++ DBUG_ASSERT(args[0]->fixed);
++ conv_charset= cs;
++ if (cache_if_const && args[0]->const_item())
++ {
++ uint errors= 0;
++ String tmp, *str= args[0]->val_str(&tmp);
++ if (!str || str_value.copy(str->ptr(), str->length(),
++ str->charset(), conv_charset, &errors))
++ null_value= 1;
++ use_cached_value= 1;
++ str_value.mark_as_const();
++ safe= (errors == 0);
++ }
++ else
++ {
++ use_cached_value= 0;
++ /*
++ Conversion from and to "binary" is safe.
++ Conversion to Unicode is safe.
++ Other kind of conversions are potentially lossy.
++ */
++ safe= (args[0]->collation.collation == &my_charset_bin ||
++ cs == &my_charset_bin ||
++ (cs->state & MY_CS_UNICODE));
++ }
++ }
++ String *val_str(String *);
++ void fix_length_and_dec();
++ const char *func_name() const { return "convert"; }
++ virtual void print(String *str, enum_query_type query_type);
++};
++
++class Item_func_set_collation :public Item_str_func
++{
++public:
++ Item_func_set_collation(Item *a, Item *b) :Item_str_func(a,b) {};
++ String *val_str(String *);
++ void fix_length_and_dec();
++ bool eq(const Item *item, bool binary_cmp) const;
++ const char *func_name() const { return "collate"; }
++ enum Functype functype() const { return COLLATE_FUNC; }
++ virtual void print(String *str, enum_query_type query_type);
++ Item_field *filed_for_view_update()
++ {
++ /* this function is transparent for view updating */
++ return args[0]->filed_for_view_update();
++ }
++};
++
++class Item_func_charset :public Item_str_func
++{
++public:
++ Item_func_charset(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ const char *func_name() const { return "charset"; }
++ void fix_length_and_dec()
++ {
++ collation.set(system_charset_info);
++ max_length= 64 * collation.collation->mbmaxlen; // should be enough
++ maybe_null= 0;
++ };
++ table_map not_null_tables() const { return 0; }
++};
++
++class Item_func_collation :public Item_str_func
++{
++public:
++ Item_func_collation(Item *a) :Item_str_func(a) {}
++ String *val_str(String *);
++ const char *func_name() const { return "collation"; }
++ void fix_length_and_dec()
++ {
++ collation.set(system_charset_info);
++ max_length= 64 * collation.collation->mbmaxlen; // should be enough
++ maybe_null= 0;
++ };
++ table_map not_null_tables() const { return 0; }
++};
++
++class Item_func_crc32 :public Item_int_func
++{
++ String value;
++public:
++ Item_func_crc32(Item *a) :Item_int_func(a) { unsigned_flag= 1; }
++ const char *func_name() const { return "crc32"; }
++ void fix_length_and_dec() { max_length=10; }
++ longlong val_int();
++};
++
++class Item_func_uncompressed_length : public Item_int_func
++{
++ String value;
++public:
++ Item_func_uncompressed_length(Item *a):Item_int_func(a){}
++ const char *func_name() const{return "uncompressed_length";}
++ void fix_length_and_dec() { max_length=10; }
++ longlong val_int();
++};
++
++#ifdef HAVE_COMPRESS
++#define ZLIB_DEPENDED_FUNCTION ;
++#else
++#define ZLIB_DEPENDED_FUNCTION { null_value=1; return 0; }
++#endif
++
++class Item_func_compress: public Item_str_func
++{
++ String buffer;
++public:
++ Item_func_compress(Item *a):Item_str_func(a){}
++ void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
++ const char *func_name() const{return "compress";}
++ String *val_str(String *) ZLIB_DEPENDED_FUNCTION
++};
++
++class Item_func_uncompress: public Item_str_func
++{
++ String buffer;
++public:
++ Item_func_uncompress(Item *a): Item_str_func(a){}
++ void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
++ const char *func_name() const{return "uncompress";}
++ String *val_str(String *) ZLIB_DEPENDED_FUNCTION
++};
++
++#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
++class Item_func_uuid: public Item_str_func
++{
++public:
++ Item_func_uuid(): Item_str_func() {}
++ void fix_length_and_dec() {
++ collation.set(system_charset_info);
++ /*
++ NOTE! uuid() should be changed to use 'ascii'
++ charset when hex(), format(), md5(), etc, and implicit
++ number-to-string conversion will use 'ascii'
++ */
++ max_length= UUID_LENGTH * system_charset_info->mbmaxlen;
++ }
++ const char *func_name() const{ return "uuid"; }
++ String *val_str(String *);
++};
++
+diff -urN mysql-old/sql/item_strfunc.h.rej mysql/sql/item_strfunc.h.rej
+--- mysql-old/sql/item_strfunc.h.rej 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/item_strfunc.h.rej 2011-05-10 17:56:01.353349043 +0000
+@@ -0,0 +1,11 @@
++--- sql/item_strfunc.h 2010-08-03 17:24:28.000000000 +0000
+++++ sql/item_strfunc.h 2010-08-20 22:27:12.919596025 +0000
++@@ -705,7 +705,7 @@
++ void fix_length_and_dec()
++ {
++ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2;
++- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
+++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
++ collation.set(args[0]->collation);
++ }
++ };
+diff -urN mysql-old/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql-old/sql/item_sum.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/item_sum.cc 2011-05-10 17:56:01.353349043 +0000
+@@ -1143,7 +1143,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1206,16 +1206,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1406,13 +1406,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3349,7 +3349,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -urN mysql-old/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql-old/sql/item_timefunc.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/item_timefunc.cc 2011-05-10 17:56:01.356682376 +0000
+@@ -308,14 +308,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -324,7 +324,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -341,15 +341,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -360,14 +360,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -375,7 +375,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -427,7 +427,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -439,7 +439,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -451,7 +451,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -596,7 +596,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1823,7 +1823,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -urN mysql-old/sql/key.cc mysql/sql/key.cc
+--- mysql-old/sql/key.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/key.cc 2011-05-10 17:56:01.356682376 +0000
+@@ -125,13 +125,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -215,7 +215,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -224,7 +224,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -285,7 +285,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -351,7 +351,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -urN mysql-old/sql/log.cc mysql/sql/log.cc
+--- mysql-old/sql/log.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/log.cc 2011-05-10 17:56:01.360015709 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2429,7 +2429,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5236,7 +5236,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -urN mysql-old/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql-old/sql/log_event.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/log_event.cc 2011-05-10 17:56:01.456682377 +0000
+@@ -1075,7 +1075,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2671,7 +2671,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5588,7 +5588,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7315,7 +7315,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -urN mysql-old/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql-old/sql/log_event_old.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/log_event_old.cc 2011-05-10 17:56:01.460015710 +0000
+@@ -1420,7 +1420,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -urN mysql-old/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql-old/sql/mysqld.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/mysqld.cc 2011-05-10 17:56:01.463349043 +0000
+@@ -3383,7 +3383,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3395,15 +3395,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -5085,7 +5085,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -urN mysql-old/sql/mysqld.cc.orig mysql/sql/mysqld.cc.orig
+--- mysql-old/sql/mysqld.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/mysqld.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,9292 @@
++/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++#include "mysql_priv.h"
++#include <m_ctype.h>
++#include <my_dir.h>
++#include <my_bit.h>
++#include "slave.h"
++#include "rpl_mi.h"
++#include "sql_repl.h"
++#include "rpl_filter.h"
++#include "repl_failsafe.h"
++#include <my_stacktrace.h>
++#include "mysqld_suffix.h"
++#include "mysys_err.h"
++#include "events.h"
++#include "debug_sync.h"
++
++#include "../storage/myisam/ha_myisam.h"
++
++#include "rpl_injector.h"
++
++#ifdef HAVE_SYS_PRCTL_H
++#include <sys/prctl.h>
++#endif
++
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++#if defined(NOT_ENOUGH_TESTED) \
++ && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
++#define OPT_NDB_SHM_DEFAULT 1
++#else
++#define OPT_NDB_SHM_DEFAULT 0
++#endif
++#endif
++
++#ifndef DEFAULT_SKIP_THREAD_PRIORITY
++#define DEFAULT_SKIP_THREAD_PRIORITY 0
++#endif
++
++#include <thr_alarm.h>
++#include <ft_global.h>
++#include <errmsg.h>
++#include "sp_rcontext.h"
++#include "sp_cache.h"
++
++#define mysqld_charset &my_charset_latin1
++
++#ifdef HAVE_purify
++#define IF_PURIFY(A,B) (A)
++#else
++#define IF_PURIFY(A,B) (B)
++#endif
++
++#if SIZEOF_CHARP == 4
++#define MAX_MEM_TABLE_SIZE ~(ulong) 0
++#else
++#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
++#endif
++
++/* stack traces are only supported on linux intel */
++#if defined(__linux__) && defined(__i386__)
++#define HAVE_STACK_TRACE_ON_SEGV
++#endif /* __linux__ */
++
++/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
++
++#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
++#define HAVE_CLOSE_SERVER_SOCK 1
++#endif
++
++extern "C" { // Because of SCO 3.2V4.2
++#include <errno.h>
++#include <sys/stat.h>
++#ifndef __GNU_LIBRARY__
++#define __GNU_LIBRARY__ // Skip warnings in getopt.h
++#endif
++#include <my_getopt.h>
++#ifdef HAVE_SYSENT_H
++#include <sysent.h>
++#endif
++#ifdef HAVE_PWD_H
++#include <pwd.h> // For getpwent
++#endif
++#ifdef HAVE_GRP_H
++#include <grp.h>
++#endif
++#include <my_net.h>
++
++#if !defined(__WIN__)
++# ifndef __NETWARE__
++#include <sys/resource.h>
++# endif /* __NETWARE__ */
++#ifdef HAVE_SYS_UN_H
++# include <sys/un.h>
++#endif
++#include <netdb.h>
++#ifdef HAVE_SELECT_H
++# include <select.h>
++#endif
++#ifdef HAVE_SYS_SELECT_H
++#include <sys/select.h>
++#endif
++#include <sys/utsname.h>
++#endif /* __WIN__ */
++
++#include <my_libwrap.h>
++
++#ifdef HAVE_SYS_MMAN_H
++#include <sys/mman.h>
++#endif
++
++#ifdef __WIN__
++#include <crtdbg.h>
++#define SIGNAL_FMT "exception 0x%x"
++#else
++#define SIGNAL_FMT "signal %d"
++#endif
++
++#ifdef __NETWARE__
++#define zVOLSTATE_ACTIVE 6
++#define zVOLSTATE_DEACTIVE 2
++#define zVOLSTATE_MAINTENANCE 3
++
++#undef __event_h__
++#include <../include/event.h>
++/*
++ This #undef exists here because both libc of NetWare and MySQL have
++ files named event.h which causes compilation errors.
++*/
++
++#include <nks/netware.h>
++#include <nks/vm.h>
++#include <library.h>
++#include <monitor.h>
++#include <zOmni.h> //For NEB
++#include <neb.h> //For NEB
++#include <nebpub.h> //For NEB
++#include <zEvent.h> //For NSS event structures
++#include <zPublics.h>
++
++static void *neb_consumer_id= NULL; //For storing NEB consumer id
++static char datavolname[256]= {0};
++static VolumeID_t datavolid;
++static event_handle_t eh;
++static Report_t ref;
++static void *refneb= NULL;
++my_bool event_flag= FALSE;
++static int volumeid= -1;
++
++ /* NEB event callback */
++unsigned long neb_event_callback(struct EventBlock *eblock);
++static void registerwithneb();
++static void getvolumename();
++static void getvolumeID(BYTE *volumeName);
++#endif /* __NETWARE__ */
++
++
++#ifdef _AIX41
++int initgroups(const char *,unsigned int);
++#endif
++
++#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
++#include <ieeefp.h>
++#ifdef HAVE_FP_EXCEPT // Fix type conflict
++typedef fp_except fp_except_t;
++#endif
++#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
++#ifdef HAVE_SYS_FPU_H
++/* for IRIX to use set_fpc_csr() */
++#include <sys/fpu.h>
++#endif
++#ifdef HAVE_FPU_CONTROL_H
++#include <fpu_control.h>
++#endif
++#if defined(__i386__) && !defined(HAVE_FPU_CONTROL_H)
++# define fpu_control_t unsigned int
++# define _FPU_EXTENDED 0x300
++# define _FPU_DOUBLE 0x200
++# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
++# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
++# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
++# else
++# define _FPU_GETCW(cw) (cw= 0)
++# define _FPU_SETCW(cw)
++# endif
++#endif
++
++extern "C" my_bool reopen_fstreams(const char *filename,
++ FILE *outstream, FILE *errstream);
++
++inline void setup_fpu()
++{
++#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
++ /* We can't handle floating point exceptions with threads, so disable
++ this on freebsd
++ Don't fall for overflow, underflow,divide-by-zero or loss of precision
++ */
++#if defined(__i386__)
++ fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
++ FP_X_IMP));
++#else
++ fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
++ FP_X_IMP));
++#endif /* __i386__ */
++#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
++
++#ifdef HAVE_FESETROUND
++ /* Set FPU rounding mode to "round-to-nearest" */
++ fesetround(FE_TONEAREST);
++#endif /* HAVE_FESETROUND */
++
++ /*
++ x86 (32-bit) requires FPU precision to be explicitly set to 64 bit
++ (double precision) for portable results of floating point operations.
++ However, there is no need to do so if compiler is using SSE2 for floating
++ point, double values will be stored and processed in 64 bits anyway.
++ */
++#if defined(__i386__) && !defined(__SSE2_MATH__)
++#if defined(_WIN32)
++#if !defined(_WIN64)
++ _control87(_PC_53, MCW_PC);
++#endif /* !_WIN64 */
++#else /* !_WIN32 */
++ fpu_control_t cw;
++ _FPU_GETCW(cw);
++ cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
++ _FPU_SETCW(cw);
++#endif /* _WIN32 && */
++#endif /* __i386__ */
++
++#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
++ /* Enable denormalized DOUBLE values support for IRIX */
++ union fpc_csr n;
++ n.fc_word = get_fpc_csr();
++ n.fc_struct.flush = 0;
++ set_fpc_csr(n.fc_word);
++#endif
++}
++
++} /* cplusplus */
++
++#define MYSQL_KILL_SIGNAL SIGTERM
++
++#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
++#include <sys/types.h>
++#else
++#include <my_pthread.h> // For thr_setconcurency()
++#endif
++
++#ifdef SOLARIS
++extern "C" int gethostname(char *name, int namelen);
++#endif
++
++extern "C" sig_handler handle_segfault(int sig);
++
++#if defined(__linux__)
++#define ENABLE_TEMP_POOL 1
++#else
++#define ENABLE_TEMP_POOL 0
++#endif
++
++/* Constants */
++
++const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
++/*
++ WARNING: When adding new SQL modes don't forget to update the
++ tables definitions that stores it's value.
++ (ie: mysql.event, mysql.proc)
++*/
++static const char *sql_mode_names[]=
++{
++ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
++ "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
++ "NO_DIR_IN_CREATE",
++ "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
++ "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
++ "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
++ "STRICT_ALL_TABLES",
++ "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES",
++ "ERROR_FOR_DIVISION_BY_ZERO",
++ "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE",
++ "NO_ENGINE_SUBSTITUTION",
++ "PAD_CHAR_TO_FULL_LENGTH",
++ NullS
++};
++
++static const unsigned int sql_mode_names_len[]=
++{
++ /*REAL_AS_FLOAT*/ 13,
++ /*PIPES_AS_CONCAT*/ 15,
++ /*ANSI_QUOTES*/ 11,
++ /*IGNORE_SPACE*/ 12,
++ /*?*/ 1,
++ /*ONLY_FULL_GROUP_BY*/ 18,
++ /*NO_UNSIGNED_SUBTRACTION*/ 23,
++ /*NO_DIR_IN_CREATE*/ 16,
++ /*POSTGRESQL*/ 10,
++ /*ORACLE*/ 6,
++ /*MSSQL*/ 5,
++ /*DB2*/ 3,
++ /*MAXDB*/ 5,
++ /*NO_KEY_OPTIONS*/ 14,
++ /*NO_TABLE_OPTIONS*/ 16,
++ /*NO_FIELD_OPTIONS*/ 16,
++ /*MYSQL323*/ 8,
++ /*MYSQL40*/ 7,
++ /*ANSI*/ 4,
++ /*NO_AUTO_VALUE_ON_ZERO*/ 21,
++ /*NO_BACKSLASH_ESCAPES*/ 20,
++ /*STRICT_TRANS_TABLES*/ 19,
++ /*STRICT_ALL_TABLES*/ 17,
++ /*NO_ZERO_IN_DATE*/ 15,
++ /*NO_ZERO_DATE*/ 12,
++ /*ALLOW_INVALID_DATES*/ 19,
++ /*ERROR_FOR_DIVISION_BY_ZERO*/ 26,
++ /*TRADITIONAL*/ 11,
++ /*NO_AUTO_CREATE_USER*/ 19,
++ /*HIGH_NOT_PRECEDENCE*/ 19,
++ /*NO_ENGINE_SUBSTITUTION*/ 22,
++ /*PAD_CHAR_TO_FULL_LENGTH*/ 23
++};
++
++TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
++ sql_mode_names,
++ (unsigned int *)sql_mode_names_len };
++
++static const char *optimizer_switch_names[]=
++{
++ "index_merge","index_merge_union","index_merge_sort_union",
++ "index_merge_intersection", "default", NullS
++};
++/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
++static const unsigned int optimizer_switch_names_len[]=
++{
++ sizeof("index_merge") - 1,
++ sizeof("index_merge_union") - 1,
++ sizeof("index_merge_sort_union") - 1,
++ sizeof("index_merge_intersection") - 1,
++ sizeof("default") - 1
++};
++TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
++ optimizer_switch_names,
++ (unsigned int *)optimizer_switch_names_len };
++
++static const char *tc_heuristic_recover_names[]=
++{
++ "COMMIT", "ROLLBACK", NullS
++};
++static TYPELIB tc_heuristic_recover_typelib=
++{
++ array_elements(tc_heuristic_recover_names)-1,"",
++ tc_heuristic_recover_names, NULL
++};
++
++static const char *thread_handling_names[]=
++{ "one-thread-per-connection", "no-threads",
++#if HAVE_POOL_OF_THREADS == 1
++ "pool-of-threads",
++#endif
++ NullS};
++
++TYPELIB thread_handling_typelib=
++{
++ array_elements(thread_handling_names) - 1, "",
++ thread_handling_names, NULL
++};
++
++const char *first_keyword= "first", *binary_keyword= "BINARY";
++const char *my_localhost= "localhost", *delayed_user= "DELAYED";
++#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
++#define GET_HA_ROWS GET_ULL
++#else
++#define GET_HA_ROWS GET_ULONG
++#endif
++
++bool opt_large_files= sizeof(my_off_t) > 4;
++
++/*
++ Used with --help for detailed option
++*/
++static my_bool opt_help= 0, opt_verbose= 0;
++
++arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
++{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
++ {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
++ {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
++ {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
++ {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
++
++const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
++static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
++TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
++ log_output_names,
++ (unsigned int *) log_output_names_len};
++
++/* static variables */
++
++/* the default log output is log tables */
++static bool lower_case_table_names_used= 0;
++static bool max_long_data_size_used= false;
++static bool volatile select_thread_in_use, signal_thread_in_use;
++static bool volatile ready_to_exit;
++static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
++static my_bool opt_short_log_format= 0;
++static uint kill_cached_threads, wake_thread;
++static ulong killed_threads, thread_created;
++static ulong max_used_connections;
++static ulong my_bind_addr; /**< the address we bind to */
++static volatile ulong cached_thread_count= 0;
++static const char *sql_mode_str= "OFF";
++/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
++static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
++ "index_merge_sort_union=on,"
++ "index_merge_intersection=on";
++static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
++static char *opt_init_slave, *language_ptr, *opt_init_connect;
++static char *default_character_set_name;
++static char *character_set_filesystem_name;
++static char *lc_time_names_name;
++static char *my_bind_addr_str;
++static char *default_collation_name;
++static char *default_storage_engine_str;
++static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
++static I_List<THD> thread_cache;
++static double long_query_time;
++
++static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
++
++/* Global variables */
++
++bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
++my_bool opt_log, opt_slow_log;
++ulong log_output_options;
++my_bool opt_log_queries_not_using_indexes= 0;
++bool opt_error_log= IF_WIN(1,0);
++bool opt_disable_networking=0, opt_skip_show_db=0;
++bool opt_skip_name_resolve=0;
++my_bool opt_character_set_client_handshake= 1;
++bool server_id_supplied = 0;
++bool opt_endinfo, using_udf_functions;
++my_bool locked_in_memory;
++bool opt_using_transactions;
++bool volatile abort_loop;
++bool volatile shutdown_in_progress;
++/*
++ True if the bootstrap thread is running. Protected by LOCK_thread_count,
++ just like thread_count.
++ Used in bootstrap() function to determine if the bootstrap thread
++ has completed. Note, that we can't use 'thread_count' instead,
++ since in 5.1, in presence of the Event Scheduler, there may be
++ event threads running in parallel, so it's impossible to know
++ what value of 'thread_count' is a sign of completion of the
++ bootstrap thread.
++
++ At the same time, we can't start the event scheduler after
++ bootstrap either, since we want to be able to process event-related
++ SQL commands in the init file and in --bootstrap mode.
++*/
++bool in_bootstrap= FALSE;
++/**
++ @brief 'grant_option' is used to indicate if privileges needs
++ to be checked, in which case the lock, LOCK_grant, is used
++ to protect access to the grant table.
++ @note This flag is dropped in 5.1
++ @see grant_init()
++ */
++bool volatile grant_option;
++
++my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
++my_bool opt_reckless_slave = 0;
++my_bool opt_enable_named_pipe= 0;
++my_bool opt_local_infile, opt_slave_compressed_protocol;
++my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
++my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
++my_bool opt_log_slave_updates= 0;
++bool slave_warning_issued = false;
++
++/*
++ Legacy global handlerton. These will be removed (please do not add more).
++*/
++handlerton *heap_hton;
++handlerton *myisam_hton;
++handlerton *partition_hton;
++
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++const char *opt_ndbcluster_connectstring= 0;
++const char *opt_ndb_connectstring= 0;
++char opt_ndb_constrbuf[1024]= {0};
++unsigned opt_ndb_constrbuf_len= 0;
++my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
++ulong opt_ndb_cache_check_time;
++const char *opt_ndb_mgmd;
++ulong opt_ndb_nodeid;
++ulong ndb_extra_logging;
++#ifdef HAVE_NDB_BINLOG
++ulong ndb_report_thresh_binlog_epoch_slip;
++ulong ndb_report_thresh_binlog_mem_usage;
++#endif
++
++extern const char *ndb_distribution_names[];
++extern TYPELIB ndb_distribution_typelib;
++extern const char *opt_ndb_distribution;
++extern enum ndb_distribution opt_ndb_distribution_id;
++#endif
++my_bool opt_readonly, use_temp_pool, relay_log_purge;
++my_bool opt_sync_frm, opt_allow_suspicious_udfs;
++my_bool opt_secure_auth= 0;
++char* opt_secure_file_priv= 0;
++my_bool opt_log_slow_admin_statements= 0;
++my_bool opt_log_slow_slave_statements= 0;
++my_bool lower_case_file_system= 0;
++my_bool opt_large_pages= 0;
++my_bool opt_myisam_use_mmap= 0;
++uint opt_large_page_size= 0;
++#if defined(ENABLED_DEBUG_SYNC)
++uint opt_debug_sync_timeout= 0;
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
++/*
++ True if there is at least one per-hour limit for some user, so we should
++ check them before each query (and possibly reset counters when hour is
++ changed). False otherwise.
++*/
++volatile bool mqh_used = 0;
++my_bool opt_noacl;
++my_bool sp_automatic_privileges= 1;
++
++ulong opt_binlog_rows_event_max_size;
++const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
++TYPELIB binlog_format_typelib=
++ { array_elements(binlog_format_names) - 1, "",
++ binlog_format_names, NULL };
++ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
++const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
++#ifdef HAVE_INITGROUPS
++static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
++#endif
++uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
++uint mysqld_port_timeout;
++uint delay_key_write_options, protocol_version;
++uint lower_case_table_names;
++uint tc_heuristic_recover= 0;
++uint volatile thread_count, thread_running;
++ulonglong thd_startup_options;
++ulong back_log, connect_timeout, concurrency, server_id;
++ulong table_cache_size, table_def_size;
++ulong what_to_log;
++ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
++ulong open_files_limit, max_binlog_size, max_relay_log_size;
++ulong slave_net_timeout, slave_trans_retries;
++ulong slave_exec_mode_options;
++static const char *slave_exec_mode_str= "STRICT";
++ulong thread_cache_size=0, thread_pool_size= 0;
++ulong binlog_cache_size=0;
++ulonglong max_binlog_cache_size=0;
++ulong query_cache_size=0;
++ulong refresh_version; /* Increments on each reload */
++query_id_t global_query_id;
++ulong aborted_threads, aborted_connects;
++ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
++ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
++ulong delayed_insert_errors,flush_time;
++ulong specialflag=0;
++ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
++ulong max_connections, max_connect_errors;
++/*
++ Maximum length of parameter value which can be set through
++ mysql_send_long_data() call.
++*/
++ulong max_long_data_size;
++uint max_user_connections= 0;
++/**
++ Limit of the total number of prepared statements in the server.
++ Is necessary to protect the server against out-of-memory attacks.
++*/
++ulong max_prepared_stmt_count;
++/**
++ Current total number of prepared statements in the server. This number
++ is exact, and therefore may not be equal to the difference between
++ `com_stmt_prepare' and `com_stmt_close' (global status variables), as
++ the latter ones account for all registered attempts to prepare
++ a statement (including unsuccessful ones). Prepared statements are
++ currently connection-local: if the same SQL query text is prepared in
++ two different connections, this counts as two distinct prepared
++ statements.
++*/
++ulong prepared_stmt_count=0;
++ulong thread_id=1L,current_pid;
++ulong slow_launch_threads = 0, sync_binlog_period;
++ulong expire_logs_days = 0;
++ulong rpl_recovery_rank=0;
++const char *log_output_str= "FILE";
++
++time_t server_start_time, flush_status_time;
++
++char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
++char *default_tz_name;
++char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
++char mysql_real_data_home[FN_REFLEN],
++ language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
++ *opt_init_file, *opt_tc_log_file,
++ def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
++char mysql_unpacked_real_data_home[FN_REFLEN];
++int mysql_unpacked_real_data_home_len;
++uint reg_ext_length;
++const key_map key_map_empty(0);
++key_map key_map_full(0); // Will be initialized later
++
++const char *opt_date_time_formats[3];
++
++uint mysql_data_home_len;
++char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
++char server_version[SERVER_VERSION_LENGTH];
++char *mysqld_unix_port, *opt_mysql_tmpdir;
++const char **errmesg; /**< Error messages */
++const char *myisam_recover_options_str="OFF";
++const char *myisam_stats_method_str="nulls_unequal";
++
++/** name of reference on left espression in rewritten IN subquery */
++const char *in_left_expr_name= "<left expr>";
++/** name of additional condition */
++const char *in_additional_cond= "<IN COND>";
++const char *in_having_cond= "<IN HAVING>";
++
++my_decimal decimal_zero;
++/* classes for comparation parsing/processing */
++Eq_creator eq_creator;
++Ne_creator ne_creator;
++Gt_creator gt_creator;
++Lt_creator lt_creator;
++Ge_creator ge_creator;
++Le_creator le_creator;
++
++FILE *bootstrap_file;
++int bootstrap_error;
++FILE *stderror_file=0;
++
++I_List<THD> threads;
++I_List<NAMED_LIST> key_caches;
++Rpl_filter* rpl_filter;
++Rpl_filter* binlog_filter;
++
++struct system_variables global_system_variables;
++struct system_variables max_system_variables;
++struct system_status_var global_status_var;
++
++MY_TMPDIR mysql_tmpdir_list;
++MY_BITMAP temp_pool;
++
++CHARSET_INFO *system_charset_info, *files_charset_info ;
++CHARSET_INFO *national_charset_info, *table_alias_charset;
++CHARSET_INFO *character_set_filesystem;
++
++MY_LOCALE *my_default_lc_time_names;
++
++SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
++SHOW_COMP_OPTION have_geometry, have_rtree_keys;
++SHOW_COMP_OPTION have_crypt, have_compress;
++SHOW_COMP_OPTION have_community_features;
++
++/* Thread specific variables */
++
++pthread_key(MEM_ROOT**,THR_MALLOC);
++pthread_key(THD*, THR_THD);
++pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
++ LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
++ LOCK_error_log, LOCK_uuid_generator,
++ LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
++ LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
++ LOCK_global_system_variables,
++ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
++ LOCK_connection_count;
++/**
++ The below lock protects access to two global server variables:
++ max_prepared_stmt_count and prepared_stmt_count. These variables
++ set the limit and hold the current total number of prepared statements
++ in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
++ server may be fairly high, we need a dedicated lock.
++*/
++pthread_mutex_t LOCK_prepared_stmt_count;
++#ifdef HAVE_OPENSSL
++pthread_mutex_t LOCK_des_key_file;
++#endif
++rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
++rw_lock_t LOCK_system_variables_hash;
++pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
++pthread_t signal_thread;
++pthread_attr_t connection_attrib;
++pthread_mutex_t LOCK_server_started;
++pthread_cond_t COND_server_started;
++
++int mysqld_server_started= 0;
++
++File_parser_dummy_hook file_parser_dummy_hook;
++
++/* replication parameters, if master_host is not NULL, we are a slave */
++uint master_port= MYSQL_PORT, master_connect_retry = 60;
++uint report_port= MYSQL_PORT;
++ulong master_retry_count=0;
++char *master_user, *master_password, *master_host, *master_info_file;
++char *relay_log_info_file, *report_user, *report_password, *report_host;
++char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
++my_bool master_ssl;
++char *master_ssl_key, *master_ssl_cert;
++char *master_ssl_ca, *master_ssl_capath, *master_ssl_cipher;
++char *opt_logname, *opt_slow_logname;
++
++/* Static variables */
++
++static bool kill_in_progress, segfaulted;
++#ifdef HAVE_STACK_TRACE_ON_SEGV
++static my_bool opt_do_pstack;
++#endif /* HAVE_STACK_TRACE_ON_SEGV */
++static my_bool opt_bootstrap, opt_myisam_log;
++static int cleanup_done;
++static ulong opt_specialflag, opt_myisam_block_size;
++static char *opt_update_logname, *opt_binlog_index_name;
++static char *opt_tc_heuristic_recover;
++static char *mysql_home_ptr, *pidfile_name_ptr;
++static int defaults_argc;
++static char **defaults_argv;
++static char *opt_bin_logname;
++
++int orig_argc;
++char **orig_argv;
++
++static my_socket unix_sock,ip_sock;
++struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
++
++#ifndef EMBEDDED_LIBRARY
++struct passwd *user_info;
++static pthread_t select_thread;
++static uint thr_kill_signal;
++#endif
++
++/* OS specific variables */
++
++#ifdef __WIN__
++#undef getpid
++#include <process.h>
++
++static pthread_cond_t COND_handler_count;
++static uint handler_count;
++static bool start_mode=0, use_opt_args;
++static int opt_argc;
++static char **opt_argv;
++
++#if !defined(EMBEDDED_LIBRARY)
++static HANDLE hEventShutdown;
++static char shutdown_event_name[40];
++#include "nt_servc.h"
++static NTService Service; ///< Service object for WinNT
++#endif /* EMBEDDED_LIBRARY */
++#endif /* __WIN__ */
++
++#ifdef __NT__
++static char pipe_name[512];
++static SECURITY_ATTRIBUTES saPipeSecurity;
++static SECURITY_DESCRIPTOR sdPipeDescriptor;
++static HANDLE hPipe = INVALID_HANDLE_VALUE;
++#endif
++
++#ifndef EMBEDDED_LIBRARY
++bool mysqld_embedded=0;
++#else
++bool mysqld_embedded=1;
++#endif
++
++static my_bool plugins_are_initialized= FALSE;
++
++#ifndef DBUG_OFF
++static const char* default_dbug_option;
++#endif
++#ifdef HAVE_LIBWRAP
++const char *libwrapName= NULL;
++int allow_severity = LOG_INFO;
++int deny_severity = LOG_WARNING;
++#endif
++#ifdef HAVE_QUERY_CACHE
++static ulong query_cache_limit= 0;
++ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
++Query_cache query_cache;
++#endif
++#ifdef HAVE_SMEM
++char *shared_memory_base_name= default_shared_memory_base_name;
++my_bool opt_enable_shared_memory;
++HANDLE smem_event_connect_request= 0;
++#endif
++
++scheduler_functions thread_scheduler;
++
++#define SSL_VARS_NOT_STATIC
++#include "sslopt-vars.h"
++#ifdef HAVE_OPENSSL
++#include <openssl/crypto.h>
++#ifndef HAVE_YASSL
++typedef struct CRYPTO_dynlock_value
++{
++ rw_lock_t lock;
++} openssl_lock_t;
++
++static openssl_lock_t *openssl_stdlocks;
++static openssl_lock_t *openssl_dynlock_create(const char *, int);
++static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
++static void openssl_lock_function(int, int, const char *, int);
++static void openssl_lock(int, openssl_lock_t *, const char *, int);
++static unsigned long openssl_id_function();
++#endif
++char *des_key_file;
++struct st_VioSSLFd *ssl_acceptor_fd;
++#endif /* HAVE_OPENSSL */
++
++/**
++ Number of currently active user connections. The variable is protected by
++ LOCK_connection_count.
++*/
++uint connection_count= 0;
++
++/* Function declarations */
++
++pthread_handler_t signal_hand(void *arg);
++static int mysql_init_variables(void);
++static int get_options(int *argc,char **argv);
++extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
++static void set_server_version(void);
++static int init_thread_environment();
++static char *get_relative_path(const char *path);
++static int fix_paths(void);
++pthread_handler_t handle_connections_sockets(void *arg);
++pthread_handler_t kill_server_thread(void *arg);
++static void bootstrap(FILE *file);
++static bool read_init_file(char *file_name);
++#ifdef __NT__
++pthread_handler_t handle_connections_namedpipes(void *arg);
++#endif
++#ifdef HAVE_SMEM
++pthread_handler_t handle_connections_shared_memory(void *arg);
++#endif
++pthread_handler_t handle_slave(void *arg);
++static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
++static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
++ const char *option, int *error);
++static void clean_up(bool print_message);
++static int test_if_case_insensitive(const char *dir_name);
++
++#ifndef EMBEDDED_LIBRARY
++static void usage(void);
++static void start_signal_handler(void);
++static void close_server_sock();
++static void clean_up_mutexes(void);
++static void wait_for_signal_thread_to_end(void);
++static void create_pid_file();
++static void end_ssl();
++#endif
++
++
++#ifndef EMBEDDED_LIBRARY
++/****************************************************************************
++** Code to end mysqld
++****************************************************************************/
++
++static void close_connections(void)
++{
++#ifdef EXTRA_DEBUG
++ int count=0;
++#endif
++ DBUG_ENTER("close_connections");
++
++ /* Clear thread cache */
++ kill_cached_threads++;
++ flush_thread_cache();
++
++ /* kill connection thread */
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
++ (ulong) select_thread));
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++
++ while (select_thread_in_use)
++ {
++ struct timespec abstime;
++ int error;
++ LINT_INIT(error);
++ DBUG_PRINT("info",("Waiting for select thread"));
++
++#ifndef DONT_USE_THR_ALARM
++ if (pthread_kill(select_thread, thr_client_alarm))
++ break; // allready dead
++#endif
++ set_timespec(abstime, 2);
++ for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
++ {
++ error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
++ &abstime);
++ if (error != EINTR)
++ break;
++ }
++#ifdef EXTRA_DEBUG
++ if (error != 0 && !count++)
++ sql_print_error("Got error %d from pthread_cond_timedwait",error);
++#endif
++ close_server_sock();
++ }
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++#endif /* __WIN__ */
++
++
++ /* Abort listening to new connections */
++ DBUG_PRINT("quit",("Closing sockets"));
++ if (!opt_disable_networking )
++ {
++ if (ip_sock != INVALID_SOCKET)
++ {
++ (void) shutdown(ip_sock, SHUT_RDWR);
++ (void) closesocket(ip_sock);
++ ip_sock= INVALID_SOCKET;
++ }
++ }
++#ifdef __NT__
++ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
++ {
++ HANDLE temp;
++ DBUG_PRINT("quit", ("Closing named pipes") );
++
++ /* Create connection to the handle named pipe handler to break the loop */
++ if ((temp = CreateFile(pipe_name,
++ GENERIC_READ | GENERIC_WRITE,
++ 0,
++ NULL,
++ OPEN_EXISTING,
++ 0,
++ NULL )) != INVALID_HANDLE_VALUE)
++ {
++ WaitNamedPipe(pipe_name, 1000);
++ DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
++ SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
++ CancelIo(temp);
++ DisconnectNamedPipe(temp);
++ CloseHandle(temp);
++ }
++ }
++#endif
++#ifdef HAVE_SYS_UN_H
++ if (unix_sock != INVALID_SOCKET)
++ {
++ (void) shutdown(unix_sock, SHUT_RDWR);
++ (void) closesocket(unix_sock);
++ (void) unlink(mysqld_unix_port);
++ unix_sock= INVALID_SOCKET;
++ }
++#endif
++ end_thr_alarm(0); // Abort old alarms.
++
++ /*
++ First signal all threads that it's time to die
++ This will give the threads some time to gracefully abort their
++ statements and inform their clients that the server is about to die.
++ */
++
++ THD *tmp;
++ (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
++
++ I_List_iterator<THD> it(threads);
++ while ((tmp=it++))
++ {
++ DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
++ tmp->thread_id));
++ /* We skip slave threads & scheduler on this first loop through. */
++ if (tmp->slave_thread)
++ continue;
++
++ tmp->killed= THD::KILL_CONNECTION;
++ thread_scheduler.post_kill_notification(tmp);
++ if (tmp->mysys_var)
++ {
++ tmp->mysys_var->abort=1;
++ pthread_mutex_lock(&tmp->mysys_var->mutex);
++ if (tmp->mysys_var->current_cond)
++ {
++ pthread_mutex_lock(tmp->mysys_var->current_mutex);
++ pthread_cond_broadcast(tmp->mysys_var->current_cond);
++ pthread_mutex_unlock(tmp->mysys_var->current_mutex);
++ }
++ pthread_mutex_unlock(&tmp->mysys_var->mutex);
++ }
++ }
++ (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
++
++ Events::deinit();
++ end_slave();
++
++ if (thread_count)
++ sleep(2); // Give threads time to die
++
++ /*
++ Force remaining threads to die by closing the connection to the client
++ This will ensure that threads that are waiting for a command from the
++ client on a blocking read call are aborted.
++ */
++
++ for (;;)
++ {
++ DBUG_PRINT("quit",("Locking LOCK_thread_count"));
++ (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
++ if (!(tmp=threads.get()))
++ {
++ DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ break;
++ }
++#ifndef __bsdi__ // Bug in BSDI kernel
++ if (tmp->vio_ok())
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
++ tmp->thread_id,
++ (tmp->main_security_ctx.user ?
++ tmp->main_security_ctx.user : ""));
++ close_connection(tmp,0,0);
++ }
++#endif
++ DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ }
++ /* All threads has now been aborted */
++ DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ while (thread_count)
++ {
++ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
++ DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
++ }
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++
++ close_active_mi();
++ DBUG_PRINT("quit",("close_connections thread"));
++ DBUG_VOID_RETURN;
++}
++
++
++static void close_server_sock()
++{
++#ifdef HAVE_CLOSE_SERVER_SOCK
++ DBUG_ENTER("close_server_sock");
++ my_socket tmp_sock;
++ tmp_sock=ip_sock;
++ if (tmp_sock != INVALID_SOCKET)
++ {
++ ip_sock=INVALID_SOCKET;
++ DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
++ VOID(shutdown(tmp_sock, SHUT_RDWR));
++#if defined(__NETWARE__)
++ /*
++ The following code is disabled for normal systems as it causes MySQL
++ to hang on AIX 4.3 during shutdown
++ */
++ DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
++ VOID(closesocket(tmp_sock));
++#endif
++ }
++ tmp_sock=unix_sock;
++ if (tmp_sock != INVALID_SOCKET)
++ {
++ unix_sock=INVALID_SOCKET;
++ DBUG_PRINT("info",("calling shutdown on unix socket"));
++ VOID(shutdown(tmp_sock, SHUT_RDWR));
++#if defined(__NETWARE__)
++ /*
++ The following code is disabled for normal systems as it may cause MySQL
++ to hang on AIX 4.3 during shutdown
++ */
++ DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
++ VOID(closesocket(tmp_sock));
++#endif
++ VOID(unlink(mysqld_unix_port));
++ }
++ DBUG_VOID_RETURN;
++#endif
++}
++
++#endif /*EMBEDDED_LIBRARY*/
++
++
++void kill_mysql(void)
++{
++ DBUG_ENTER("kill_mysql");
++
++#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
++ abort_loop=1; // Break connection loops
++ close_server_sock(); // Force accept to wake up
++#endif
++
++#if defined(__WIN__)
++#if !defined(EMBEDDED_LIBRARY)
++ {
++ if (!SetEvent(hEventShutdown))
++ {
++ DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
++ }
++ /*
++ or:
++ HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
++ SetEvent(hEventShutdown);
++ CloseHandle(hEvent);
++ */
++ }
++#endif
++#elif defined(HAVE_PTHREAD_KILL)
++ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
++ {
++ DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
++ }
++#elif !defined(SIGNALS_DONT_BREAK_READ)
++ kill(current_pid, MYSQL_KILL_SIGNAL);
++#endif
++ DBUG_PRINT("quit",("After pthread_kill"));
++ shutdown_in_progress=1; // Safety if kill didn't work
++#ifdef SIGNALS_DONT_BREAK_READ
++ if (!kill_in_progress)
++ {
++ pthread_t tmp;
++ abort_loop=1;
++ if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
++ (void*) 0))
++ sql_print_error("Can't create thread to kill server");
++ }
++#endif
++ DBUG_VOID_RETURN;
++}
++
++/**
++ Force server down. Kill all connections and threads and exit.
++
++ @param sig_ptr Signal number that caused kill_server to be called.
++
++ @note
++ A signal number of 0 mean that the function was not called
++ from a signal handler and there is thus no signal to block
++ or stop, we just want to kill the server.
++*/
++
++#if defined(__NETWARE__)
++extern "C" void kill_server(int sig_ptr)
++#define RETURN_FROM_KILL_SERVER return
++#elif !defined(__WIN__)
++static void *kill_server(void *sig_ptr)
++#define RETURN_FROM_KILL_SERVER return 0
++#else
++static void __cdecl kill_server(int sig_ptr)
++#define RETURN_FROM_KILL_SERVER return
++#endif
++{
++ DBUG_ENTER("kill_server");
++#ifndef EMBEDDED_LIBRARY
++ int sig=(int) (long) sig_ptr; // This is passed a int
++ // if there is a signal during the kill in progress, ignore the other
++ if (kill_in_progress) // Safety
++ {
++ DBUG_LEAVE;
++ RETURN_FROM_KILL_SERVER;
++ }
++ kill_in_progress=TRUE;
++ abort_loop=1; // This should be set
++ if (sig != 0) // 0 is not a valid signal number
++ my_sigset(sig, SIG_IGN); /* purify inspected */
++ if (sig == MYSQL_KILL_SIGNAL || sig == 0)
++ sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
++ else
++ sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
++
++#if defined(HAVE_SMEM) && defined(__WIN__)
++ /*
++ Send event to smem_event_connect_request for aborting
++ */
++ if (!SetEvent(smem_event_connect_request))
++ {
++ DBUG_PRINT("error",
++ ("Got error: %ld from SetEvent of smem_event_connect_request",
++ GetLastError()));
++ }
++#endif
++
++ close_connections();
++ if (sig != MYSQL_KILL_SIGNAL &&
++ sig != 0)
++ unireg_abort(1); /* purecov: inspected */
++ else
++ unireg_end();
++
++ /* purecov: begin deadcode */
++#ifdef __NETWARE__
++ if (!event_flag)
++ pthread_join(select_thread, NULL); // wait for main thread
++#endif /* __NETWARE__ */
++
++ DBUG_LEAVE; // Must match DBUG_ENTER()
++ my_thread_end();
++ pthread_exit(0);
++ /* purecov: end */
++
++ RETURN_FROM_KILL_SERVER; // Avoid compiler warnings
++
++#else /* EMBEDDED_LIBRARY*/
++
++ DBUG_LEAVE;
++ RETURN_FROM_KILL_SERVER;
++
++#endif /* EMBEDDED_LIBRARY */
++}
++
++
++#if defined(USE_ONE_SIGNAL_HAND) || (defined(__NETWARE__) && defined(SIGNALS_DONT_BREAK_READ))
++pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
++{
++ my_thread_init(); // Initialize new thread
++ kill_server(0);
++ /* purecov: begin deadcode */
++ my_thread_end();
++ pthread_exit(0);
++ return 0;
++ /* purecov: end */
++}
++#endif
++
++
++extern "C" sig_handler print_signal_warning(int sig)
++{
++ if (global_system_variables.log_warnings)
++ sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
++#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
++ my_sigset(sig,print_signal_warning); /* int. thread system calls */
++#endif
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ if (sig == SIGALRM)
++ alarm(2); /* reschedule alarm */
++#endif
++}
++
++#ifndef EMBEDDED_LIBRARY
++
++/**
++ cleanup all memory and end program nicely.
++
++ If SIGNALS_DONT_BREAK_READ is defined, this function is called
++ by the main thread. To get MySQL to shut down nicely in this case
++ (Mac OS X) we have to call exit() instead if pthread_exit().
++
++ @note
++ This function never returns.
++*/
++void unireg_end(void)
++{
++ clean_up(1);
++ my_thread_end();
++#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__)
++ exit(0);
++#else
++ pthread_exit(0); // Exit is in main thread
++#endif
++}
++
++extern "C" void unireg_abort(int exit_code)
++{
++ DBUG_ENTER("unireg_abort");
++
++ if (opt_help)
++ usage();
++ if (exit_code)
++ sql_print_error("Aborting\n");
++ clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
++ DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
++ wait_for_signal_thread_to_end();
++ clean_up_mutexes();
++ my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
++ exit(exit_code); /* purecov: inspected */
++}
++
++#endif /*EMBEDDED_LIBRARY*/
++
++
++void clean_up(bool print_message)
++{
++ DBUG_PRINT("exit",("clean_up"));
++ if (cleanup_done++)
++ return; /* purecov: inspected */
++
++ stop_handle_manager();
++ release_ddl_log();
++
++ /*
++ make sure that handlers finish up
++ what they have that is dependent on the binlog
++ */
++ ha_binlog_end(current_thd);
++
++ logger.cleanup_base();
++
++ injector::free_instance();
++ mysql_bin_log.cleanup();
++
++#ifdef HAVE_REPLICATION
++ if (use_slave_mask)
++ bitmap_free(&slave_error_mask);
++#endif
++ my_tz_free();
++ my_database_names_free();
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ servers_free(1);
++ acl_free(1);
++ grant_free();
++#endif
++ query_cache_destroy();
++ table_cache_free();
++ table_def_free();
++ hostname_cache_free();
++ item_user_lock_free();
++ lex_free(); /* Free some memory */
++ item_create_cleanup();
++ set_var_free();
++ free_charsets();
++ if (!opt_noacl)
++ {
++#ifdef HAVE_DLOPEN
++ udf_free();
++#endif
++ }
++ plugin_shutdown();
++ ha_end();
++ if (tc_log)
++ tc_log->close();
++ xid_cache_free();
++ delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
++ multi_keycache_free();
++ free_status_vars();
++ end_thr_alarm(1); /* Free allocated memory */
++ my_free_open_file_info();
++ my_free((char*) global_system_variables.date_format,
++ MYF(MY_ALLOW_ZERO_PTR));
++ my_free((char*) global_system_variables.time_format,
++ MYF(MY_ALLOW_ZERO_PTR));
++ my_free((char*) global_system_variables.datetime_format,
++ MYF(MY_ALLOW_ZERO_PTR));
++ if (defaults_argv)
++ free_defaults(defaults_argv);
++ my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
++ my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
++ my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
++ my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
++ free_tmpdir(&mysql_tmpdir_list);
++#ifdef HAVE_REPLICATION
++ my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
++#endif
++ x_free(opt_bin_logname);
++ x_free(opt_relay_logname);
++ x_free(opt_secure_file_priv);
++ bitmap_free(&temp_pool);
++ free_max_user_conn();
++#ifdef HAVE_REPLICATION
++ end_slave_list();
++#endif
++ delete binlog_filter;
++ delete rpl_filter;
++#ifndef EMBEDDED_LIBRARY
++ end_ssl();
++#endif
++ vio_end();
++#ifdef USE_REGEX
++ my_regex_end();
++#endif
++#if defined(ENABLED_DEBUG_SYNC)
++ /* End the debug sync facility. See debug_sync.cc. */
++ debug_sync_end();
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++
++#if !defined(EMBEDDED_LIBRARY)
++ if (!opt_bootstrap)
++ (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
++#endif
++ if (print_message && errmesg && server_start_time)
++ sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
++ thread_scheduler.end();
++ finish_client_errs();
++ my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
++ MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
++ DBUG_PRINT("quit", ("Error messages freed"));
++ /* Tell main we are ready */
++ logger.cleanup_end();
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ DBUG_PRINT("quit", ("got thread count lock"));
++ ready_to_exit=1;
++ /* do the broadcast inside the lock to ensure that my_end() is not called */
++ (void) pthread_cond_broadcast(&COND_thread_count);
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++
++ /*
++ The following lines may never be executed as the main thread may have
++ killed us
++ */
++ DBUG_PRINT("quit", ("done with cleanup"));
++} /* clean_up */
++
++
++#ifndef EMBEDDED_LIBRARY
++
++/**
++ This is mainly needed when running with purify, but it's still nice to
++ know that all child threads have died when mysqld exits.
++*/
++static void wait_for_signal_thread_to_end()
++{
++#ifndef __NETWARE__
++ uint i;
++ /*
++ Wait up to 10 seconds for signal thread to die. We use this mainly to
++ avoid getting warnings that my_thread_end has not been called
++ */
++ for (i= 0 ; i < 100 && signal_thread_in_use; i++)
++ {
++ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
++ break;
++ my_sleep(100); // Give it time to die
++ }
++#endif
++}
++
++
++static void clean_up_mutexes()
++{
++ (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
++ (void) pthread_mutex_destroy(&LOCK_lock_db);
++ (void) pthread_mutex_destroy(&LOCK_Acl);
++ (void) rwlock_destroy(&LOCK_grant);
++ (void) pthread_mutex_destroy(&LOCK_open);
++ (void) pthread_mutex_destroy(&LOCK_thread_count);
++ (void) pthread_mutex_destroy(&LOCK_mapped_file);
++ (void) pthread_mutex_destroy(&LOCK_status);
++ (void) pthread_mutex_destroy(&LOCK_error_log);
++ (void) pthread_mutex_destroy(&LOCK_delayed_insert);
++ (void) pthread_mutex_destroy(&LOCK_delayed_status);
++ (void) pthread_mutex_destroy(&LOCK_delayed_create);
++ (void) pthread_mutex_destroy(&LOCK_manager);
++ (void) pthread_mutex_destroy(&LOCK_crypt);
++ (void) pthread_mutex_destroy(&LOCK_bytes_sent);
++ (void) pthread_mutex_destroy(&LOCK_bytes_received);
++ (void) pthread_mutex_destroy(&LOCK_user_conn);
++ (void) pthread_mutex_destroy(&LOCK_connection_count);
++ Events::destroy_mutexes();
++#ifdef HAVE_OPENSSL
++ (void) pthread_mutex_destroy(&LOCK_des_key_file);
++#ifndef HAVE_YASSL
++ for (int i= 0; i < CRYPTO_num_locks(); ++i)
++ (void) rwlock_destroy(&openssl_stdlocks[i].lock);
++ OPENSSL_free(openssl_stdlocks);
++#endif
++#endif
++#ifdef HAVE_REPLICATION
++ (void) pthread_mutex_destroy(&LOCK_rpl_status);
++ (void) pthread_cond_destroy(&COND_rpl_status);
++#endif
++ (void) pthread_mutex_destroy(&LOCK_active_mi);
++ (void) rwlock_destroy(&LOCK_sys_init_connect);
++ (void) rwlock_destroy(&LOCK_sys_init_slave);
++ (void) pthread_mutex_destroy(&LOCK_global_system_variables);
++ (void) rwlock_destroy(&LOCK_system_variables_hash);
++ (void) pthread_mutex_destroy(&LOCK_global_read_lock);
++ (void) pthread_mutex_destroy(&LOCK_uuid_generator);
++ (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
++ (void) pthread_cond_destroy(&COND_thread_count);
++ (void) pthread_cond_destroy(&COND_refresh);
++ (void) pthread_cond_destroy(&COND_global_read_lock);
++ (void) pthread_cond_destroy(&COND_thread_cache);
++ (void) pthread_cond_destroy(&COND_flush_thread_cache);
++ (void) pthread_cond_destroy(&COND_manager);
++}
++
++#endif /*EMBEDDED_LIBRARY*/
++
++
++/****************************************************************************
++** Init IP and UNIX socket
++****************************************************************************/
++
++#ifndef EMBEDDED_LIBRARY
++static void set_ports()
++{
++ char *env;
++ if (!mysqld_port && !opt_disable_networking)
++ { // Get port if not from commandline
++ mysqld_port= MYSQL_PORT;
++
++ /*
++ if builder specifically requested a default port, use that
++ (even if it coincides with our factory default).
++ only if they didn't do we check /etc/services (and, failing
++ on that, fall back to the factory default of 3306).
++ either default can be overridden by the environment variable
++ MYSQL_TCP_PORT, which in turn can be overridden with command
++ line options.
++ */
++
++#if MYSQL_PORT_DEFAULT == 0
++ struct servent *serv_ptr;
++ if ((serv_ptr= getservbyname("mysql", "tcp")))
++ mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
++#endif
++ if ((env = getenv("MYSQL_TCP_PORT")))
++ mysqld_port= (uint) atoi(env); /* purecov: inspected */
++ }
++ if (!mysqld_unix_port)
++ {
++#ifdef __WIN__
++ mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
++#else
++ mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
++#endif
++ if ((env = getenv("MYSQL_UNIX_PORT")))
++ mysqld_unix_port= env; /* purecov: inspected */
++ }
++}
++
++/* Change to run as another user if started with --user */
++
++static struct passwd *check_user(const char *user)
++{
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ struct passwd *tmp_user_info;
++ uid_t user_id= geteuid();
++
++ // Don't bother if we aren't superuser
++ if (user_id)
++ {
++ if (user)
++ {
++ /* Don't give a warning, if real user is same as given with --user */
++ /* purecov: begin tested */
++ tmp_user_info= getpwnam(user);
++ if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
++ global_system_variables.log_warnings)
++ sql_print_warning(
++ "One can only use the --user switch if running as root\n");
++ /* purecov: end */
++ }
++ return NULL;
++ }
++ if (!user)
++ {
++ if (!opt_bootstrap)
++ {
++ sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
++ unireg_abort(1);
++ }
++ return NULL;
++ }
++ /* purecov: begin tested */
++ if (!strcmp(user,"root"))
++ return NULL; // Avoid problem with dynamic libraries
++
++ if (!(tmp_user_info= getpwnam(user)))
++ {
++ // Allow a numeric uid to be used
++ const char *pos;
++ for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
++ if (*pos) // Not numeric id
++ goto err;
++ if (!(tmp_user_info= getpwuid(atoi(user))))
++ goto err;
++ }
++ return tmp_user_info;
++ /* purecov: end */
++
++err:
++ sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
++ unireg_abort(1);
++
++#ifdef PR_SET_DUMPABLE
++ if (test_flags & TEST_CORE_ON_SIGNAL)
++ {
++ /* inform kernel that process is dumpable */
++ (void) prctl(PR_SET_DUMPABLE, 1);
++ }
++#endif
++
++#endif
++ return NULL;
++}
++
++static void set_user(const char *user, struct passwd *user_info_arg)
++{
++ /* purecov: begin tested */
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ DBUG_ASSERT(user_info_arg != 0);
++#ifdef HAVE_INITGROUPS
++ /*
++ We can get a SIGSEGV when calling initgroups() on some systems when NSS
++ is configured to use LDAP and the server is statically linked. We set
++ calling_initgroups as a flag to the SIGSEGV handler that is then used to
++ output a specific message to help the user resolve this problem.
++ */
++ calling_initgroups= TRUE;
++ initgroups((char*) user, user_info_arg->pw_gid);
++ calling_initgroups= FALSE;
++#endif
++ if (setgid(user_info_arg->pw_gid) == -1)
++ {
++ sql_perror("setgid");
++ unireg_abort(1);
++ }
++ if (setuid(user_info_arg->pw_uid) == -1)
++ {
++ sql_perror("setuid");
++ unireg_abort(1);
++ }
++#endif
++ /* purecov: end */
++}
++
++
++static void set_effective_user(struct passwd *user_info_arg)
++{
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ DBUG_ASSERT(user_info_arg != 0);
++ if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
++ {
++ sql_perror("setregid");
++ unireg_abort(1);
++ }
++ if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
++ {
++ sql_perror("setreuid");
++ unireg_abort(1);
++ }
++#endif
++}
++
++
++/** Change root user if started with @c --chroot . */
++static void set_root(const char *path)
++{
++#if !defined(__WIN__) && !defined(__NETWARE__)
++ if (chroot(path) == -1)
++ {
++ sql_perror("chroot");
++ unireg_abort(1);
++ }
++ my_setwd("/", MYF(0));
++#endif
++}
++
++static void network_init(void)
++{
++ struct sockaddr_in IPaddr;
++#ifdef HAVE_SYS_UN_H
++ struct sockaddr_un UNIXaddr;
++#endif
++ int arg=1;
++ int ret;
++ uint waited;
++ uint this_wait;
++ uint retry;
++ DBUG_ENTER("network_init");
++ LINT_INIT(ret);
++
++ if (thread_scheduler.init())
++ unireg_abort(1); /* purecov: inspected */
++
++ set_ports();
++
++ if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
++ {
++ DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
++ ip_sock = socket(AF_INET, SOCK_STREAM, 0);
++ if (ip_sock == INVALID_SOCKET)
++ {
++ DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
++ sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
++ unireg_abort(1); /* purecov: tested */
++ }
++ bzero((char*) &IPaddr, sizeof(IPaddr));
++ IPaddr.sin_family = AF_INET;
++ IPaddr.sin_addr.s_addr = my_bind_addr;
++ IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
++
++#ifndef __WIN__
++ /*
++ We should not use SO_REUSEADDR on windows as this would enable a
++ user to open two mysqld servers with the same TCP/IP port.
++ */
++ (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
++#endif /* __WIN__ */
++ /*
++ Sometimes the port is not released fast enough when stopping and
++ restarting the server. This happens quite often with the test suite
++ on busy Linux systems. Retry to bind the address at these intervals:
++ Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
++ Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
++ Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
++ */
++ for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
++ {
++ if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
++ sizeof(IPaddr))) >= 0) ||
++ (socket_errno != SOCKET_EADDRINUSE) ||
++ (waited >= mysqld_port_timeout))
++ break;
++ sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
++ this_wait= retry * retry / 3 + 1;
++ sleep(this_wait);
++ }
++ if (ret < 0)
++ {
++ DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
++ sql_perror("Can't start server: Bind on TCP/IP port");
++ sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
++ unireg_abort(1);
++ }
++ if (listen(ip_sock,(int) back_log) < 0)
++ {
++ sql_perror("Can't start server: listen() on TCP/IP port");
++ sql_print_error("listen() on TCP/IP failed with error %d",
++ socket_errno);
++ unireg_abort(1);
++ }
++ }
++
++#ifdef __NT__
++ /* create named pipe */
++ if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
++ opt_enable_named_pipe)
++ {
++
++ strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
++ mysqld_unix_port, NullS);
++ bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
++ bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
++ if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
++ SECURITY_DESCRIPTOR_REVISION))
++ {
++ sql_perror("Can't start server : Initialize security descriptor");
++ unireg_abort(1);
++ }
++ if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
++ {
++ sql_perror("Can't start server : Set security descriptor");
++ unireg_abort(1);
++ }
++ saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
++ saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
++ saPipeSecurity.bInheritHandle = FALSE;
++ if ((hPipe= CreateNamedPipe(pipe_name,
++ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
++ PIPE_TYPE_BYTE |
++ PIPE_READMODE_BYTE |
++ PIPE_WAIT,
++ PIPE_UNLIMITED_INSTANCES,
++ (int) global_system_variables.net_buffer_length,
++ (int) global_system_variables.net_buffer_length,
++ NMPWAIT_USE_DEFAULT_WAIT,
++ &saPipeSecurity)) == INVALID_HANDLE_VALUE)
++ {
++ LPVOID lpMsgBuf;
++ int error=GetLastError();
++ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
++ FORMAT_MESSAGE_FROM_SYSTEM,
++ NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
++ (LPTSTR) &lpMsgBuf, 0, NULL );
++ sql_perror((char *)lpMsgBuf);
++ LocalFree(lpMsgBuf);
++ unireg_abort(1);
++ }
++ }
++#endif
++
++#if defined(HAVE_SYS_UN_H)
++ /*
++ ** Create the UNIX socket
++ */
++ if (mysqld_unix_port[0] && !opt_bootstrap)
++ {
++ DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
++
++ if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
++ {
++ sql_print_error("The socket file path is too long (> %u): %s",
++ (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
++ unireg_abort(1);
++ }
++ if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
++ {
++ sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
++ unireg_abort(1); /* purecov: inspected */
++ }
++ bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
++ UNIXaddr.sun_family = AF_UNIX;
++ strmov(UNIXaddr.sun_path, mysqld_unix_port);
++ (void) unlink(mysqld_unix_port);
++ (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
++ sizeof(arg));
++ umask(0);
++ if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
++ sizeof(UNIXaddr)) < 0)
++ {
++ sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
++ sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
++ unireg_abort(1); /* purecov: tested */
++ }
++ umask(((~my_umask) & 0666));
++#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
++ (void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
++#endif
++ if (listen(unix_sock,(int) back_log) < 0)
++ sql_print_warning("listen() on Unix socket failed with error %d",
++ socket_errno);
++ }
++#endif
++ DBUG_PRINT("info",("server started"));
++ DBUG_VOID_RETURN;
++}
++
++#endif /*!EMBEDDED_LIBRARY*/
++
++
++#ifndef EMBEDDED_LIBRARY
++/**
++ Close a connection.
++
++ @param thd Thread handle
++ @param errcode Error code to print to console
++ @param lock 1 if we have have to lock LOCK_thread_count
++
++ @note
++ For the connection that is doing shutdown, this is called twice
++*/
++void close_connection(THD *thd, uint errcode, bool lock)
++{
++ st_vio *vio;
++ DBUG_ENTER("close_connection");
++ DBUG_PRINT("enter",("fd: %s error: '%s'",
++ thd->net.vio ? vio_description(thd->net.vio) :
++ "(not connected)",
++ errcode ? ER(errcode) : ""));
++ if (lock)
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ thd->killed= THD::KILL_CONNECTION;
++ if ((vio= thd->net.vio) != 0)
++ {
++ if (errcode)
++ net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
++ vio_close(vio); /* vio is freed in delete thd */
++ }
++ if (lock)
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ DBUG_VOID_RETURN;
++}
++#endif /* EMBEDDED_LIBRARY */
++
++
++/** Called when a thread is aborted. */
++/* ARGSUSED */
++extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
++{
++ THD *thd=current_thd;
++ DBUG_ENTER("end_thread_signal");
++ if (thd && ! thd->bootstrap)
++ {
++ statistic_increment(killed_threads, &LOCK_status);
++ thread_scheduler.end_thread(thd,0); /* purecov: inspected */
++ }
++ DBUG_VOID_RETURN; /* purecov: deadcode */
++}
++
++
++/*
++ Unlink thd from global list of available connections and free thd
++
++ SYNOPSIS
++ unlink_thd()
++ thd Thread handler
++
++ NOTES
++ LOCK_thread_count is locked and left locked
++*/
++
++void unlink_thd(THD *thd)
++{
++ DBUG_ENTER("unlink_thd");
++ DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
++ thd->cleanup();
++
++ pthread_mutex_lock(&LOCK_connection_count);
++ --connection_count;
++ pthread_mutex_unlock(&LOCK_connection_count);
++
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ thread_count--;
++ delete thd;
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Store thread in cache for reuse by new connections
++
++ SYNOPSIS
++ cache_thread()
++
++ NOTES
++ LOCK_thread_count has to be locked
++
++ RETURN
++ 0 Thread was not put in cache
++ 1 Thread is to be reused by new connection.
++ (ie, caller should return, not abort with pthread_exit())
++*/
++
++
++static bool cache_thread()
++{
++ safe_mutex_assert_owner(&LOCK_thread_count);
++ if (cached_thread_count < thread_cache_size &&
++ ! abort_loop && !kill_cached_threads)
++ {
++ /* Don't kill the thread, just put it in cache for reuse */
++ DBUG_PRINT("info", ("Adding thread to cache"));
++ cached_thread_count++;
++ while (!abort_loop && ! wake_thread && ! kill_cached_threads)
++ (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
++ cached_thread_count--;
++ if (kill_cached_threads)
++ pthread_cond_signal(&COND_flush_thread_cache);
++ if (wake_thread)
++ {
++ THD *thd;
++ wake_thread--;
++ thd= thread_cache.get();
++ thd->thread_stack= (char*) &thd; // For store_globals
++ (void) thd->store_globals();
++ /*
++ THD::mysys_var::abort is associated with physical thread rather
++ than with THD object. So we need to reset this flag before using
++ this thread for handling of new THD object/connection.
++ */
++ thd->mysys_var->abort= 0;
++ thd->thr_create_utime= my_micro_time();
++ threads.append(thd);
++ return(1);
++ }
++ }
++ return(0);
++}
++
++
++/*
++ End thread for the current connection
++
++ SYNOPSIS
++ one_thread_per_connection_end()
++ thd Thread handler
++ put_in_cache Store thread in cache, if there is room in it
++ Normally this is true in all cases except when we got
++ out of resources initializing the current thread
++
++ NOTES
++ If thread is cached, we will wait until thread is scheduled to be
++ reused and then we will return.
++ If thread is not cached, we end the thread.
++
++ RETURN
++ 0 Signal to handle_one_connection to reuse connection
++*/
++
++bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
++{
++ DBUG_ENTER("one_thread_per_connection_end");
++ unlink_thd(thd);
++ if (put_in_cache)
++ put_in_cache= cache_thread();
++ pthread_mutex_unlock(&LOCK_thread_count);
++ if (put_in_cache)
++ DBUG_RETURN(0); // Thread is reused
++
++ /* It's safe to broadcast outside a lock (COND... is not deleted here) */
++ DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
++ DBUG_LEAVE; // Must match DBUG_ENTER()
++ my_thread_end();
++ (void) pthread_cond_broadcast(&COND_thread_count);
++
++ pthread_exit(0);
++ return 0; // Avoid compiler warnings
++}
++
++
++void flush_thread_cache()
++{
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ kill_cached_threads++;
++ while (cached_thread_count)
++ {
++ pthread_cond_broadcast(&COND_thread_cache);
++ pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
++ }
++ kill_cached_threads--;
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++}
++
++
++#ifdef THREAD_SPECIFIC_SIGPIPE
++/**
++ Aborts a thread nicely. Comes here on SIGPIPE.
++
++ @todo
++ One should have to fix that thr_alarm know about this thread too.
++*/
++extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
++{
++ THD *thd=current_thd;
++ DBUG_ENTER("abort_thread");
++ if (thd)
++ thd->killed= THD::KILL_CONNECTION;
++ DBUG_VOID_RETURN;
++}
++#endif
++
++
++/******************************************************************************
++ Setup a signal thread with handles all signals.
++ Because Linux doesn't support schemas use a mutex to check that
++ the signal thread is ready before continuing
++******************************************************************************/
++
++#if defined(__WIN__)
++
++
++/*
++ On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
++ with graceful shutdown.
++ Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
++ provides possibility to pass the exception to just-in-time debugger, collect
++ dumps and potentially also the exception and thread context used to output
++ callstack.
++*/
++
++static BOOL WINAPI console_event_handler( DWORD type )
++{
++ DBUG_ENTER("console_event_handler");
++#ifndef EMBEDDED_LIBRARY
++ if(type == CTRL_C_EVENT)
++ {
++ /*
++ Do not shutdown before startup is finished and shutdown
++ thread is initialized. Otherwise there is a race condition
++ between main thread doing initialization and CTRL-C thread doing
++ cleanup, which can result into crash.
++ */
++#ifndef EMBEDDED_LIBRARY
++ if(hEventShutdown)
++ kill_mysql();
++ else
++#endif
++ sql_print_warning("CTRL-C ignored during startup");
++ DBUG_RETURN(TRUE);
++ }
++#endif
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ In Visual Studio 2005 and later, default SIGABRT handler will overwrite
++ any unhandled exception filter set by the application and will try to
++ call JIT debugger. This is not what we want, this we calling __debugbreak
++ to stop in debugger, if process is being debugged or to generate
++ EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
++*/
++
++#if (_MSC_VER >= 1400)
++static void my_sigabrt_handler(int sig)
++{
++ __debugbreak();
++}
++#endif /*_MSC_VER >=1400 */
++
++void win_install_sigabrt_handler(void)
++{
++#if (_MSC_VER >=1400)
++ /*abort() should not override our exception filter*/
++ _set_abort_behavior(0,_CALL_REPORTFAULT);
++ signal(SIGABRT,my_sigabrt_handler);
++#endif /* _MSC_VER >=1400 */
++}
++
++#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
++#define DEBUGGER_ATTACH_TIMEOUT 120
++/*
++ Wait for debugger to attach and break into debugger. If debugger is not attached,
++ resume after timeout.
++*/
++static void wait_for_debugger(int timeout_sec)
++{
++ if(!IsDebuggerPresent())
++ {
++ int i;
++ printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
++ fflush(stdout);
++ for(i= 0; i < timeout_sec; i++)
++ {
++ Sleep(1000);
++ if(IsDebuggerPresent())
++ {
++ /* Break into debugger */
++ __debugbreak();
++ return;
++ }
++ }
++ printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
++ timeout_sec);
++ fflush(stdout);
++ }
++}
++#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
++
++LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
++{
++ static BOOL first_time= TRUE;
++ if(!first_time)
++ {
++ /*
++ This routine can be called twice, typically
++ when detaching in JIT debugger.
++ Return EXCEPTION_EXECUTE_HANDLER to terminate process.
++ */
++ return EXCEPTION_EXECUTE_HANDLER;
++ }
++ first_time= FALSE;
++#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
++ /*
++ Unfortunately there is no clean way to debug unhandled exception filters,
++ as debugger does not stop there(also documented in MSDN)
++ To overcome, one could put a MessageBox, but this will not work in service.
++ Better solution is to print error message and sleep some minutes
++ until debugger is attached
++ */
++ wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
++#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
++ __try
++ {
++ my_set_exception_pointers(ex_pointers);
++ handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
++ }
++ __except(EXCEPTION_EXECUTE_HANDLER)
++ {
++ DWORD written;
++ const char msg[] = "Got exception in exception handler!\n";
++ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1,
++ &written,NULL);
++ }
++ /*
++ Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
++ (drwtsn32 or vsjitdebugger) possibility to attach,
++ if JIT debugger is configured.
++ Windows Error reporting might generate a dump here.
++ */
++ return EXCEPTION_CONTINUE_SEARCH;
++}
++
++
++static void init_signals(void)
++{
++ win_install_sigabrt_handler();
++ if(opt_console)
++ SetConsoleCtrlHandler(console_event_handler,TRUE);
++
++ /* Avoid MessageBox()es*/
++ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
++ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
++ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
++ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
++ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
++ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
++
++ /*
++ Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
++ because it would prevent JIT debugger and Windows error reporting
++ from working. We need WER or JIT-debugging, since our own unhandled
++ exception filter is not guaranteed to work in all situation
++ (like heap corruption or stack overflow)
++ */
++ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
++ | SEM_NOOPENFILEERRORBOX);
++ SetUnhandledExceptionFilter(my_unhandler_exception_filter);
++}
++
++
++static void start_signal_handler(void)
++{
++#ifndef EMBEDDED_LIBRARY
++ // Save vm id of this process
++ if (!opt_bootstrap)
++ create_pid_file();
++#endif /* EMBEDDED_LIBRARY */
++}
++
++
++static void check_data_home(const char *path)
++{}
++
++
++#elif defined(__NETWARE__)
++
++/// down server event callback.
++void mysql_down_server_cb(void *, void *)
++{
++ event_flag= TRUE;
++ kill_server(0);
++}
++
++
++/// destroy callback resources.
++void mysql_cb_destroy(void *)
++{
++ UnRegisterEventNotification(eh); // cleanup down event notification
++ NX_UNWRAP_INTERFACE(ref);
++ /* Deregister NSS volume deactivation event */
++ NX_UNWRAP_INTERFACE(refneb);
++ if (neb_consumer_id)
++ UnRegisterConsumer(neb_consumer_id, NULL);
++}
++
++
++/// initialize callbacks.
++void mysql_cb_init()
++{
++ // register for down server event
++ void *handle = getnlmhandle();
++ rtag_t rt= AllocateResourceTag(handle, "MySQL Down Server Callback",
++ EventSignature);
++ NX_WRAP_INTERFACE((void *)mysql_down_server_cb, 2, (void **)&ref);
++ eh= RegisterForEventNotification(rt, EVENT_PRE_DOWN_SERVER,
++ EVENT_PRIORITY_APPLICATION,
++ NULL, ref, NULL);
++
++ /*
++ Register for volume deactivation event
++ Wrap the callback function, as it is called by non-LibC thread
++ */
++ (void *) NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
++ registerwithneb();
++
++ NXVmRegisterExitHandler(mysql_cb_destroy, NULL); // clean-up
++}
++
++
++/** To get the name of the NetWare volume having MySQL data folder. */
++static void getvolumename()
++{
++ char *p;
++ /*
++ We assume that data path is already set.
++ If not it won't come here. Terminate after volume name
++ */
++ if ((p= strchr(mysql_real_data_home, ':')))
++ strmake(datavolname, mysql_real_data_home,
++ (uint) (p - mysql_real_data_home));
++}
++
++
++/**
++ Registering with NEB for NSS Volume Deactivation event.
++*/
++
++static void registerwithneb()
++{
++
++ ConsumerRegistrationInfo reg_info;
++
++ /* Clear NEB registration structure */
++ bzero((char*) ®_info, sizeof(struct ConsumerRegistrationInfo));
++
++ /* Fill the NEB consumer information structure */
++ reg_info.CRIVersion= 1; // NEB version
++ /* NEB Consumer name */
++ reg_info.CRIConsumerName= (BYTE *) "MySQL Database Server";
++ /* Event of interest */
++ reg_info.CRIEventName= (BYTE *) "NSS.ChangeVolState.Enter";
++ reg_info.CRIUserParameter= NULL; // Consumer Info
++ reg_info.CRIEventFlags= 0; // Event flags
++ /* Consumer NLM handle */
++ reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle();
++ reg_info.CRIConsumerESR= NULL; // No consumer ESR required
++ reg_info.CRISecurityToken= 0; // No security token for the event
++ reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT;
++ reg_info.CRIFilterName= 0; // No event filtering
++ reg_info.CRIFilterDataLength= 0; // No filtering data
++ reg_info.CRIFilterData= 0; // No filtering data
++ /* Callback function for the event */
++ (void *)reg_info.CRIConsumerCallback= (void *) refneb;
++ reg_info.CRIOrder= 0; // Event callback order
++ reg_info.CRIConsumerType= CHECK_CONSUMER; // Consumer type
++
++ /* Register for the event with NEB */
++ if (RegisterConsumer(®_info))
++ {
++ consoleprintf("Failed to register for NSS Volume Deactivation event \n");
++ return;
++ }
++ /* This ID is required for deregistration */
++ neb_consumer_id= reg_info.CRIConsumerID;
++
++ /* Get MySQL data volume name, stored in global variable datavolname */
++ getvolumename();
++
++ /*
++ Get the NSS volume ID of the MySQL Data volume.
++ Volume ID is stored in a global variable
++ */
++ getvolumeID((BYTE*) datavolname);
++}
++
++
++/**
++ Callback for NSS Volume Deactivation event.
++*/
++
++ulong neb_event_callback(struct EventBlock *eblock)
++{
++ EventChangeVolStateEnter_s *voldata;
++ extern bool nw_panic;
++
++ voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData;
++
++ /* Deactivation of a volume */
++ if ((voldata->oldState == zVOLSTATE_ACTIVE &&
++ voldata->newState == zVOLSTATE_DEACTIVE ||
++ voldata->newState == zVOLSTATE_MAINTENANCE))
++ {
++ /*
++ Ensure that we bring down MySQL server only for MySQL data
++ volume deactivation
++ */
++ if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t)))
++ {
++ consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n");
++ event_flag= TRUE;
++ nw_panic = TRUE;
++ event_flag= TRUE;
++ kill_server(0);
++ }
++ }
++ return 0;
++}
++
++
++#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
++
++/**
++ Function to get NSS volume ID of the MySQL data.
++*/
++static void getvolumeID(BYTE *volumeName)
++{
++ char path[zMAX_FULL_NAME];
++ Key_t rootKey= 0, fileKey= 0;
++ QUAD getInfoMask;
++ zInfo_s info;
++ STATUS status;
++
++ /* Get the root key */
++ if ((status= zRootKey(0, &rootKey)) != zOK)
++ {
++ consoleprintf("\nGetNSSVolumeProperties - Failed to get root key, status: %d\n.", (int) status);
++ goto exit;
++ }
++
++ /*
++ Get the file key. This is the key to the volume object in the
++ NSS admin volumes directory.
++ */
++
++ strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
++ NullS);
++ if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8,
++ (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
++ {
++ consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status);
++ goto exit;
++ }
++
++ getInfoMask= zGET_IDS | zGET_VOLUME_INFO ;
++ if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info),
++ zINFO_VERSION_A, &info)) != zOK)
++ {
++ consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status);
++ goto exit;
++ }
++
++ /* Copy the data to global variable */
++ datavolid.timeLow= info.vol.volumeID.timeLow;
++ datavolid.timeMid= info.vol.volumeID.timeMid;
++ datavolid.timeHighAndVersion= info.vol.volumeID.timeHighAndVersion;
++ datavolid.clockSeqHighAndReserved= info.vol.volumeID.clockSeqHighAndReserved;
++ datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow;
++ /* This is guranteed to be 6-byte length (but sizeof() would be better) */
++ memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6);
++
++exit:
++ if (rootKey)
++ zClose(rootKey);
++ if (fileKey)
++ zClose(fileKey);
++}
++
++
++static void init_signals(void)
++{
++ int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT};
++
++ for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
++ signal(signals[i], kill_server);
++ mysql_cb_init(); // initialize callbacks
++
++}
++
++
++static void start_signal_handler(void)
++{
++ // Save vm id of this process
++ if (!opt_bootstrap)
++ create_pid_file();
++ // no signal handler
++}
++
++
++/**
++ Warn if the data is on a Traditional volume.
++
++ @note
++ Already done by mysqld_safe
++*/
++
++static void check_data_home(const char *path)
++{
++}
++
++#endif /*__WIN__ || __NETWARE */
++
++#ifdef HAVE_LINUXTHREADS
++#define UNSAFE_DEFAULT_LINUX_THREADS 200
++#endif
++
++
++#if BACKTRACE_DEMANGLE
++#include <cxxabi.h>
++extern "C" char *my_demangle(const char *mangled_name, int *status)
++{
++ return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
++}
++#endif
++
++
++extern "C" sig_handler handle_segfault(int sig)
++{
++ time_t curr_time;
++ struct tm tm;
++
++ /*
++ Strictly speaking, one needs a mutex here
++ but since we have got SIGSEGV already, things are a mess
++ so not having the mutex is not as bad as possibly using a buggy
++ mutex - so we keep things simple
++ */
++ if (segfaulted)
++ {
++ fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
++ exit(1);
++ }
++
++ segfaulted = 1;
++
++ curr_time= my_time(0);
++ localtime_r(&curr_time, &tm);
++
++ fprintf(stderr,"\
++%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
++This could be because you hit a bug. It is also possible that this binary\n\
++or one of the libraries it was linked against is corrupt, improperly built,\n\
++or misconfigured. This error can also be caused by malfunctioning hardware.\n",
++ tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
++ tm.tm_hour, tm.tm_min, tm.tm_sec,
++ sig);
++ fprintf(stderr, "\
++We will try our best to scrape up some info that will hopefully help diagnose\n\
++the problem, but since we have already crashed, something is definitely wrong\n\
++and this may fail.\n\n");
++ fprintf(stderr, "key_buffer_size=%lu\n",
++ (ulong) dflt_key_cache->key_cache_mem_size);
++ fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
++ fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
++ fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
++ fprintf(stderr, "threads_connected=%u\n", thread_count);
++ fprintf(stderr, "It is possible that mysqld could use up to \n\
++key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
++bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
++ (global_system_variables.read_buff_size +
++ global_system_variables.sortbuff_size) *
++ thread_scheduler.max_threads +
++ max_connections * sizeof(THD)) / 1024);
++ fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
++
++#if defined(HAVE_LINUXTHREADS)
++ if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
++ {
++ fprintf(stderr, "\
++You seem to be running 32-bit Linux and have %d concurrent connections.\n\
++If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
++yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
++the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
++ thread_count);
++ }
++#endif /* HAVE_LINUXTHREADS */
++
++#ifdef HAVE_STACKTRACE
++ THD *thd=current_thd;
++
++ if (!(test_flags & TEST_NO_STACKTRACE))
++ {
++ fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
++ fprintf(stderr, "Attempting backtrace. You can use the following "
++ "information to find out\nwhere mysqld died. If "
++ "you see no messages after this, something went\n"
++ "terribly wrong...\n");
++ my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
++ my_thread_stack_size);
++ }
++ if (thd)
++ {
++ const char *kreason= "UNKNOWN";
++ switch (thd->killed) {
++ case THD::NOT_KILLED:
++ kreason= "NOT_KILLED";
++ break;
++ case THD::KILL_BAD_DATA:
++ kreason= "KILL_BAD_DATA";
++ break;
++ case THD::KILL_CONNECTION:
++ kreason= "KILL_CONNECTION";
++ break;
++ case THD::KILL_QUERY:
++ kreason= "KILL_QUERY";
++ break;
++ case THD::KILLED_NO_VALUE:
++ kreason= "KILLED_NO_VALUE";
++ break;
++ }
++ fprintf(stderr, "\nTrying to get some variables.\n"
++ "Some pointers may be invalid and cause the dump to abort.\n");
++ fprintf(stderr, "Query (%p): ", thd->query());
++ my_safe_print_str(thd->query(), min(1024, thd->query_length()));
++ fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
++ fprintf(stderr, "Status: %s\n", kreason);
++ fputc('\n', stderr);
++ }
++ fprintf(stderr, "\
++The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
++information that should help you find out what is causing the crash.\n");
++ fflush(stderr);
++#endif /* HAVE_STACKTRACE */
++
++#ifdef HAVE_INITGROUPS
++ if (calling_initgroups)
++ fprintf(stderr, "\n\
++This crash occured while the server was calling initgroups(). This is\n\
++often due to the use of a mysqld that is statically linked against glibc\n\
++and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
++upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
++later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
++mysqld that is not statically linked.\n");
++#endif
++
++#ifdef HAVE_NPTL
++ if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
++ fprintf(stderr,"\n\
++You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
++This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
++You should either build a dynamically-linked binary, or force LinuxThreads\n\
++to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
++the documentation for your distribution on how to do that.\n");
++#endif
++
++ if (locked_in_memory)
++ {
++ fprintf(stderr, "\n\
++The \"--memlock\" argument, which was enabled, uses system calls that are\n\
++unreliable and unstable on some operating systems and operating-system\n\
++versions (notably, some versions of Linux). This crash could be due to use\n\
++of those buggy OS calls. You should consider whether you really need the\n\
++\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
++bugs.\n");
++ }
++
++#ifdef HAVE_WRITE_CORE
++ if (test_flags & TEST_CORE_ON_SIGNAL)
++ {
++ fprintf(stderr, "Writing a core file\n");
++ fflush(stderr);
++ my_write_core(sig);
++ }
++#endif
++
++#ifndef __WIN__
++ /* On Windows, do not terminate, but pass control to exception filter */
++ exit(1);
++#endif
++}
++
++#if !defined(__WIN__) && !defined(__NETWARE__)
++#ifndef SA_RESETHAND
++#define SA_RESETHAND 0
++#endif
++#ifndef SA_NODEFER
++#define SA_NODEFER 0
++#endif
++
++#ifndef EMBEDDED_LIBRARY
++
++static void init_signals(void)
++{
++ sigset_t set;
++ struct sigaction sa;
++ DBUG_ENTER("init_signals");
++
++ my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
++
++ if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
++ {
++ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
++ sigemptyset(&sa.sa_mask);
++ sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
++
++#ifdef HAVE_STACKTRACE
++ my_init_stacktrace();
++#endif
++#if defined(__amiga__)
++ sa.sa_handler=(void(*)())handle_segfault;
++#else
++ sa.sa_handler=handle_segfault;
++#endif
++ sigaction(SIGSEGV, &sa, NULL);
++ sigaction(SIGABRT, &sa, NULL);
++#ifdef SIGBUS
++ sigaction(SIGBUS, &sa, NULL);
++#endif
++ sigaction(SIGILL, &sa, NULL);
++ sigaction(SIGFPE, &sa, NULL);
++ }
++
++#ifdef HAVE_GETRLIMIT
++ if (test_flags & TEST_CORE_ON_SIGNAL)
++ {
++ /* Change limits so that we will get a core file */
++ STRUCT_RLIMIT rl;
++ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
++ if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
++ sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
++ }
++#endif
++ (void) sigemptyset(&set);
++ my_sigset(SIGPIPE,SIG_IGN);
++ sigaddset(&set,SIGPIPE);
++#ifndef IGNORE_SIGHUP_SIGQUIT
++ sigaddset(&set,SIGQUIT);
++ sigaddset(&set,SIGHUP);
++#endif
++ sigaddset(&set,SIGTERM);
++
++ /* Fix signals if blocked by parents (can happen on Mac OS X) */
++ sigemptyset(&sa.sa_mask);
++ sa.sa_flags = 0;
++ sa.sa_handler = print_signal_warning;
++ sigaction(SIGTERM, &sa, (struct sigaction*) 0);
++ sa.sa_flags = 0;
++ sa.sa_handler = print_signal_warning;
++ sigaction(SIGHUP, &sa, (struct sigaction*) 0);
++#ifdef SIGTSTP
++ sigaddset(&set,SIGTSTP);
++#endif
++ if (thd_lib_detected != THD_LIB_LT)
++ sigaddset(&set,THR_SERVER_ALARM);
++ if (test_flags & TEST_SIGINT)
++ {
++ my_sigset(thr_kill_signal, end_thread_signal);
++ // May be SIGINT
++ sigdelset(&set, thr_kill_signal);
++ }
++ else
++ sigaddset(&set,SIGINT);
++ sigprocmask(SIG_SETMASK,&set,NULL);
++ pthread_sigmask(SIG_SETMASK,&set,NULL);
++ DBUG_VOID_RETURN;
++}
++
++
++static void start_signal_handler(void)
++{
++ int error;
++ pthread_attr_t thr_attr;
++ DBUG_ENTER("start_signal_handler");
++
++ (void) pthread_attr_init(&thr_attr);
++#if !defined(HAVE_DEC_3_2_THREADS)
++ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
++ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
++ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
++#if defined(__ia64__) || defined(__ia64)
++ /*
++ Peculiar things with ia64 platforms - it seems we only have half the
++ stack size in reality, so we have to double it here
++ */
++ pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
++#else
++ pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
++#endif
++#endif
++
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
++ {
++ sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
++ error,errno);
++ exit(1);
++ }
++ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
++ pthread_mutex_unlock(&LOCK_thread_count);
++
++ (void) pthread_attr_destroy(&thr_attr);
++ DBUG_VOID_RETURN;
++}
++
++
++/** This threads handles all signals and alarms. */
++/* ARGSUSED */
++pthread_handler_t signal_hand(void *arg __attribute__((unused)))
++{
++ sigset_t set;
++ int sig;
++ my_thread_init(); // Init new thread
++ DBUG_ENTER("signal_hand");
++ signal_thread_in_use= 1;
++
++ /*
++ Setup alarm handler
++ This should actually be '+ max_number_of_slaves' instead of +10,
++ but the +10 should be quite safe.
++ */
++ init_thr_alarm(thread_scheduler.max_threads +
++ global_system_variables.max_insert_delayed_threads + 10);
++ if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
++ {
++ (void) sigemptyset(&set); // Setup up SIGINT for debug
++ (void) sigaddset(&set,SIGINT); // For debugging
++ (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
++ }
++ (void) sigemptyset(&set); // Setup up SIGINT for debug
++#ifdef USE_ONE_SIGNAL_HAND
++ (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms
++#endif
++#ifndef IGNORE_SIGHUP_SIGQUIT
++ (void) sigaddset(&set,SIGQUIT);
++ (void) sigaddset(&set,SIGHUP);
++#endif
++ (void) sigaddset(&set,SIGTERM);
++ (void) sigaddset(&set,SIGTSTP);
++
++ /* Save pid to this process (or thread on Linux) */
++ if (!opt_bootstrap)
++ create_pid_file();
++
++ /*
++ signal to start_signal_handler that we are ready
++ This works by waiting for start_signal_handler to free mutex,
++ after which we signal it that we are ready.
++ At this pointer there is no other threads running, so there
++ should not be any other pthread_cond_signal() calls.
++ */
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ (void) pthread_cond_broadcast(&COND_thread_count);
++
++ (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
++ for (;;)
++ {
++ int error; // Used when debugging
++ if (shutdown_in_progress && !abort_loop)
++ {
++ sig= SIGTERM;
++ error=0;
++ }
++ else
++ while ((error=my_sigwait(&set,&sig)) == EINTR) ;
++ if (cleanup_done)
++ {
++ DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
++ my_thread_end();
++ signal_thread_in_use= 0;
++ DBUG_LEAVE; // Must match DBUG_ENTER()
++ pthread_exit(0); // Safety
++ return 0; // Avoid compiler warnings
++ }
++ switch (sig) {
++ case SIGTERM:
++ case SIGQUIT:
++ case SIGKILL:
++#ifdef EXTRA_DEBUG
++ sql_print_information("Got signal %d to shutdown mysqld",sig);
++#endif
++ /* switch to the old log message processing */
++ logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
++ opt_log ? LOG_FILE:LOG_NONE);
++ DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop));
++ if (!abort_loop)
++ {
++ abort_loop=1; // mark abort for threads
++#ifdef USE_ONE_SIGNAL_HAND
++ pthread_t tmp;
++ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
++ if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
++ (void*) &sig))
++ sql_print_error("Can't create thread to kill server");
++#else
++ kill_server((void*) sig); // MIT THREAD has a alarm thread
++#endif
++ }
++ break;
++ case SIGHUP:
++ if (!abort_loop)
++ {
++ int not_used;
++ mysql_print_status(); // Print some debug info
++ reload_acl_and_cache((THD*) 0,
++ (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
++ REFRESH_GRANT |
++ REFRESH_THREADS | REFRESH_HOSTS),
++ (TABLE_LIST*) 0, ¬_used); // Flush logs
++ }
++ /* reenable logs after the options were reloaded */
++ if (log_output_options & LOG_NONE)
++ {
++ logger.set_handlers(LOG_FILE,
++ opt_slow_log ? LOG_TABLE : LOG_NONE,
++ opt_log ? LOG_TABLE : LOG_NONE);
++ }
++ else
++ {
++ logger.set_handlers(LOG_FILE,
++ opt_slow_log ? log_output_options : LOG_NONE,
++ opt_log ? log_output_options : LOG_NONE);
++ }
++ break;
++#ifdef USE_ONE_SIGNAL_HAND
++ case THR_SERVER_ALARM:
++ process_alarm(sig); // Trigger alarms.
++ break;
++#endif
++ default:
++#ifdef EXTRA_DEBUG
++ sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */
++#endif
++ break; /* purecov: tested */
++ }
++ }
++ return(0); /* purecov: deadcode */
++}
++
++static void check_data_home(const char *path)
++{}
++
++#endif /*!EMBEDDED_LIBRARY*/
++#endif /* __WIN__*/
++
++
++/**
++ All global error messages are sent here where the first one is stored
++ for the client.
++*/
++/* ARGSUSED */
++extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
++
++int my_message_sql(uint error, const char *str, myf MyFlags)
++{
++ THD *thd;
++ DBUG_ENTER("my_message_sql");
++ DBUG_PRINT("error", ("error: %u message: '%s'", error, str));
++
++ DBUG_ASSERT(str != NULL);
++ /*
++ An error should have a valid error number (!= 0), so it can be caught
++ in stored procedures by SQL exception handlers.
++ Calling my_error() with error == 0 is a bug.
++ Remaining known places to fix:
++ - storage/myisam/mi_create.c, my_printf_error()
++ TODO:
++ DBUG_ASSERT(error != 0);
++ */
++
++ if (error == 0)
++ {
++ /* At least, prevent new abuse ... */
++ DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0);
++ error= ER_UNKNOWN_ERROR;
++ }
++
++ if ((thd= current_thd))
++ {
++ /*
++ TODO: There are two exceptions mechanism (THD and sp_rcontext),
++ this could be improved by having a common stack of handlers.
++ */
++ if (thd->handle_error(error, str,
++ MYSQL_ERROR::WARN_LEVEL_ERROR))
++ DBUG_RETURN(0);
++
++ thd->is_slave_error= 1; // needed to catch query errors during replication
++
++ /*
++ thd->lex->current_select == 0 if lex structure is not inited
++ (not query command (COM_QUERY))
++ */
++ if (thd->lex->current_select &&
++ thd->lex->current_select->no_error && !thd->is_fatal_error)
++ {
++ DBUG_PRINT("error",
++ ("Error converted to warning: current_select: no_error %d "
++ "fatal_error: %d",
++ (thd->lex->current_select ?
++ thd->lex->current_select->no_error : 0),
++ (int) thd->is_fatal_error));
++ }
++ else
++ {
++ if (! thd->main_da.is_error()) // Return only first message
++ {
++ thd->main_da.set_error_status(thd, error, str);
++ }
++ query_cache_abort(&thd->net);
++ }
++ /*
++ If a continue handler is found, the error message will be cleared
++ by the stored procedures code.
++ */
++ if (thd->spcont &&
++ ! (MyFlags & ME_NO_SP_HANDLER) &&
++ thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
++ {
++ /*
++ Do not push any warnings, a handled error must be completely
++ silenced.
++ */
++ DBUG_RETURN(0);
++ }
++
++ /* When simulating OOM, skip writing to error log to avoid mtr errors */
++ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
++
++ if (!thd->no_warnings_for_error &&
++ !(MyFlags & ME_NO_WARNING_FOR_ERROR))
++ {
++ /*
++ Suppress infinite recursion if there a memory allocation error
++ inside push_warning.
++ */
++ thd->no_warnings_for_error= TRUE;
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
++ thd->no_warnings_for_error= FALSE;
++ }
++ }
++
++ /* When simulating OOM, skip writing to error log to avoid mtr errors */
++ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
++
++ if (!thd || MyFlags & ME_NOREFRESH)
++ sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
++ DBUG_RETURN(0);
++}
++
++
++#ifndef EMBEDDED_LIBRARY
++extern "C" void *my_str_malloc_mysqld(size_t size);
++extern "C" void my_str_free_mysqld(void *ptr);
++
++void *my_str_malloc_mysqld(size_t size)
++{
++ return my_malloc(size, MYF(MY_FAE));
++}
++
++
++void my_str_free_mysqld(void *ptr)
++{
++ my_free((uchar*)ptr, MYF(MY_FAE));
++}
++#endif /* EMBEDDED_LIBRARY */
++
++
++#ifdef __WIN__
++
++pthread_handler_t handle_shutdown(void *arg)
++{
++ MSG msg;
++ my_thread_init();
++
++ /* this call should create the message queue for this thread */
++ PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
++#if !defined(EMBEDDED_LIBRARY)
++ if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
++#endif /* EMBEDDED_LIBRARY */
++ kill_server(MYSQL_KILL_SIGNAL);
++ return 0;
++}
++#endif
++
++const char *load_default_groups[]= {
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++"mysql_cluster",
++#endif
++"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
++
++#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
++static const int load_default_groups_sz=
++sizeof(load_default_groups)/sizeof(load_default_groups[0]);
++#endif
++
++
++#ifndef EMBEDDED_LIBRARY
++static
++int
++check_enough_stack_size()
++{
++ uchar stack_top;
++
++ return check_stack_overrun(current_thd, STACK_MIN_SIZE,
++ &stack_top);
++}
++#endif
++
++
++/**
++ Initialize one of the global date/time format variables.
++
++ @param format_type What kind of format should be supported
++ @param var_ptr Pointer to variable that should be updated
++
++ @note
++ The default value is taken from either opt_date_time_formats[] or
++ the ISO format (ANSI SQL)
++
++ @retval
++ 0 ok
++ @retval
++ 1 error
++*/
++
++static bool init_global_datetime_format(timestamp_type format_type,
++ DATE_TIME_FORMAT **var_ptr)
++{
++ /* Get command line option */
++ const char *str= opt_date_time_formats[format_type];
++
++ if (!str) // No specified format
++ {
++ str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
++ format_type);
++ /*
++ Set the "command line" option to point to the generated string so
++ that we can set global formats back to default
++ */
++ opt_date_time_formats[format_type]= str;
++ }
++ if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
++ {
++ fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
++ return 1;
++ }
++ return 0;
++}
++
++SHOW_VAR com_status_vars[]= {
++ {"admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
++ {"assign_to_keycache", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
++ {"alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
++ {"alter_db_upgrade", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
++ {"alter_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
++ {"alter_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]), SHOW_LONG_STATUS},
++ {"alter_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]), SHOW_LONG_STATUS},
++ {"alter_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]), SHOW_LONG_STATUS},
++ {"alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
++ {"alter_tablespace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
++ {"analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
++ {"backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
++ {"begin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
++ {"binlog", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
++ {"call_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
++ {"change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
++ {"change_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
++ {"check", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
++ {"checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
++ {"commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
++ {"create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
++ {"create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
++ {"create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
++ {"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
++ {"create_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
++ {"create_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
++ {"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
++ {"create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
++ {"create_udf", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
++ {"create_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
++ {"create_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]), SHOW_LONG_STATUS},
++ {"dealloc_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
++ {"delete", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
++ {"delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
++ {"do", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
++ {"drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
++ {"drop_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
++ {"drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
++ {"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
++ {"drop_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
++ {"drop_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
++ {"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
++ {"drop_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
++ {"drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
++ {"drop_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
++ {"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
++ {"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
++ {"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
++ {"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
++ {"ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
++ {"ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
++ {"ha_read", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
++ {"help", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
++ {"insert", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
++ {"insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
++ {"install_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]), SHOW_LONG_STATUS},
++ {"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
++ {"load", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
++ {"load_master_data", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
++ {"load_master_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), SHOW_LONG_STATUS},
++ {"lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
++ {"optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
++ {"preload_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
++ {"prepare_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
++ {"purge", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
++ {"purge_before_date", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
++ {"release_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
++ {"rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
++ {"rename_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
++ {"repair", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
++ {"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
++ {"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
++ {"reset", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
++ {"restore_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
++ {"revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
++ {"revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
++ {"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
++ {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
++ {"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
++ {"select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
++ {"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
++ {"show_authors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
++ {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
++ {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
++ {"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
++ {"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
++ {"show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
++ {"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
++ {"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
++ {"show_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
++ {"show_create_func", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]), SHOW_LONG_STATUS},
++ {"show_create_proc", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]), SHOW_LONG_STATUS},
++ {"show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
++ {"show_create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]), SHOW_LONG_STATUS},
++ {"show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
++ {"show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
++ {"show_engine_mutex", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
++ {"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
++ {"show_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
++ {"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
++ {"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
++#ifndef DBUG_OFF
++ {"show_function_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
++#endif
++ {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
++ {"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
++ {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
++ {"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
++ {"show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
++ {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
++ {"show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
++ {"show_privileges", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
++#ifndef DBUG_OFF
++ {"show_procedure_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]), SHOW_LONG_STATUS},
++#endif
++ {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]), SHOW_LONG_STATUS},
++ {"show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
++ {"show_profile", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILE]), SHOW_LONG_STATUS},
++ {"show_profiles", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]), SHOW_LONG_STATUS},
++ {"show_slave_hosts", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
++ {"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
++ {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
++ {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
++ {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
++ {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
++ {"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
++ {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
++ {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
++ {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
++ {"slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
++ {"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
++ {"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
++ {"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
++ {"stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
++ {"stmt_reprepare", (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
++ {"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
++ {"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
++ {"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
++ {"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
++ {"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
++ {"update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
++ {"update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
++ {"xa_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
++ {"xa_end", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
++ {"xa_prepare", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
++ {"xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
++ {"xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
++ {"xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
++ {NullS, NullS, SHOW_LONG}
++};
++
++static int init_common_variables(const char *conf_file_name, int argc,
++ char **argv, const char **groups)
++{
++ char buff[FN_REFLEN], *s;
++ umask(((~my_umask) & 0666));
++ my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
++ tzset(); // Set tzname
++
++ max_system_variables.pseudo_thread_id= (ulong)~0;
++ server_start_time= flush_status_time= my_time(0);
++
++ rpl_filter= new Rpl_filter;
++ binlog_filter= new Rpl_filter;
++ if (!rpl_filter || !binlog_filter)
++ {
++ sql_perror("Could not allocate replication and binlog filters");
++ return 1;
++ }
++
++ if (init_thread_environment() ||
++ mysql_init_variables())
++ return 1;
++
++#ifdef HAVE_TZNAME
++ {
++ struct tm tm_tmp;
++ localtime_r(&server_start_time,&tm_tmp);
++ strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
++ sizeof(system_time_zone)-1);
++
++ }
++#endif
++ /*
++ We set SYSTEM time zone as reasonable default and
++ also for failure of my_tz_init() and bootstrap mode.
++ If user explicitly set time zone with --default-time-zone
++ option we will change this value in my_tz_init().
++ */
++ global_system_variables.time_zone= my_tz_SYSTEM;
++
++ /*
++ Init mutexes for the global MYSQL_BIN_LOG objects.
++ As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
++ global MYSQL_BIN_LOGs in their constructors, because then they would be
++ inited before MY_INIT(). So we do it here.
++ */
++ mysql_bin_log.init_pthread_objects();
++
++ /* TODO: remove this when my_time_t is 64 bit compatible */
++ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
++ {
++ sql_print_error("This MySQL server doesn't support dates later then 2038");
++ return 1;
++ }
++
++ if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
++ {
++ strmake(glob_hostname, STRING_WITH_LEN("localhost"));
++ sql_print_warning("gethostname failed, using '%s' as hostname",
++ glob_hostname);
++ strmake(pidfile_name, STRING_WITH_LEN("mysql"));
++ }
++ else
++ strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
++ strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
++
++ /*
++ Add server status variables to the dynamic list of
++ status variables that is shown by SHOW STATUS.
++ Later, in plugin_init, and mysql_install_plugin
++ new entries could be added to that list.
++ */
++ if (add_status_vars(status_vars))
++ return 1; // an error was already reported
++
++#ifndef DBUG_OFF
++ /*
++ We have few debug-only commands in com_status_vars, only visible in debug
++ builds. for simplicity we enable the assert only in debug builds
++
++ There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
++ (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
++ that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
++
++ Com_admin_commands => com_other
++ Com_stmt_close => com_stmt_close
++ Com_stmt_execute => com_stmt_execute
++ Com_stmt_fetch => com_stmt_fetch
++ Com_stmt_prepare => com_stmt_prepare
++ Com_stmt_reprepare => com_stmt_reprepare
++ Com_stmt_reset => com_stmt_reset
++ Com_stmt_send_long_data => com_stmt_send_long_data
++
++ With this correction the number of Com_ variables (number of elements in
++ the array, excluding the last element - terminator) must match the number
++ of SQLCOM_ constants.
++ */
++ compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
++ SQLCOM_END + 8);
++#endif
++
++ orig_argc=argc;
++ orig_argv=argv;
++ load_defaults(conf_file_name, groups, &argc, &argv);
++ defaults_argv=argv;
++ defaults_argc=argc;
++ if (get_options(&defaults_argc, defaults_argv))
++ return 1;
++ set_server_version();
++
++ DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
++ server_version, SYSTEM_TYPE,MACHINE_TYPE));
++
++#ifdef HAVE_LARGE_PAGES
++ /* Initialize large page size */
++ if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
++ {
++ my_use_large_pages= 1;
++ my_large_page_size= opt_large_page_size;
++ }
++#endif /* HAVE_LARGE_PAGES */
++
++ /* connections and databases needs lots of files */
++ {
++ uint files, wanted_files, max_open_files;
++
++ /* MyISAM requires two file handles per table. */
++ wanted_files= 10+max_connections+table_cache_size*2;
++ /*
++ We are trying to allocate no less than max_connections*5 file
++ handles (i.e. we are trying to set the limit so that they will
++ be available). In addition, we allocate no less than how much
++ was already allocated. However below we report a warning and
++ recompute values only if we got less file handles than were
++ explicitly requested. No warning and re-computation occur if we
++ can't get max_connections*5 but still got no less than was
++ requested (value of wanted_files).
++ */
++ max_open_files= max(max(wanted_files, max_connections*5),
++ open_files_limit);
++ files= my_set_max_open_files(max_open_files);
++
++ if (files < wanted_files)
++ {
++ if (!open_files_limit)
++ {
++ /*
++ If we have requested too much file handles than we bring
++ max_connections in supported bounds.
++ */
++ max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections);
++ /*
++ Decrease table_cache_size according to max_connections, but
++ not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ never increase table_cache_size automatically (that could
++ happen if max_connections is decreased above).
++ */
++ table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ TABLE_OPEN_CACHE_MIN),
++ table_cache_size);
++ DBUG_PRINT("warning",
++ ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
++ files, max_connections, table_cache_size));
++ if (global_system_variables.log_warnings)
++ sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
++ files, max_connections, table_cache_size);
++ }
++ else if (global_system_variables.log_warnings)
++ sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
++ }
++ open_files_limit= files;
++ }
++ unireg_init(opt_specialflag); /* Set up extern variabels */
++ if (init_errmessage()) /* Read error messages from file */
++ return 1;
++ init_client_errs();
++ lex_init();
++ if (item_create_init())
++ return 1;
++ item_init();
++ if (set_var_init())
++ return 1;
++#ifdef HAVE_REPLICATION
++ if (init_replication_sys_vars())
++ return 1;
++#endif
++ mysys_uses_curses=0;
++#ifdef USE_REGEX
++#ifndef EMBEDDED_LIBRARY
++ my_regex_init(&my_charset_latin1, check_enough_stack_size);
++#else
++ my_regex_init(&my_charset_latin1, NULL);
++#endif
++#endif
++ /*
++ Process a comma-separated character set list and choose
++ the first available character set. This is mostly for
++ test purposes, to be able to start "mysqld" even if
++ the requested character set is not available (see bug#18743).
++ */
++ for (;;)
++ {
++ char *next_character_set_name= strchr(default_character_set_name, ',');
++ if (next_character_set_name)
++ *next_character_set_name++= '\0';
++ if (!(default_charset_info=
++ get_charset_by_csname(default_character_set_name,
++ MY_CS_PRIMARY, MYF(MY_WME))))
++ {
++ if (next_character_set_name)
++ {
++ default_character_set_name= next_character_set_name;
++ default_collation_name= 0; // Ignore collation
++ }
++ else
++ return 1; // Eof of the list
++ }
++ else
++ break;
++ }
++
++ if (default_collation_name)
++ {
++ CHARSET_INFO *default_collation;
++ default_collation= get_charset_by_name(default_collation_name, MYF(0));
++ if (!default_collation)
++ {
++ sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
++ return 1;
++ }
++ if (!my_charset_same(default_charset_info, default_collation))
++ {
++ sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
++ default_collation_name,
++ default_charset_info->csname);
++ return 1;
++ }
++ default_charset_info= default_collation;
++ }
++ /* Set collactions that depends on the default collation */
++ global_system_variables.collation_server= default_charset_info;
++ global_system_variables.collation_database= default_charset_info;
++ global_system_variables.collation_connection= default_charset_info;
++ global_system_variables.character_set_results= default_charset_info;
++ global_system_variables.character_set_client= default_charset_info;
++
++ if (!(character_set_filesystem=
++ get_charset_by_csname(character_set_filesystem_name,
++ MY_CS_PRIMARY, MYF(MY_WME))))
++ return 1;
++ global_system_variables.character_set_filesystem= character_set_filesystem;
++
++ if (!(my_default_lc_time_names=
++ my_locale_by_name(lc_time_names_name)))
++ {
++ sql_print_error("Unknown locale: '%s'", lc_time_names_name);
++ return 1;
++ }
++ global_system_variables.lc_time_names= my_default_lc_time_names;
++
++ sys_init_connect.value_length= 0;
++ if ((sys_init_connect.value= opt_init_connect))
++ sys_init_connect.value_length= strlen(opt_init_connect);
++ else
++ sys_init_connect.value=my_strdup("",MYF(0));
++ sys_init_connect.is_os_charset= TRUE;
++
++ sys_init_slave.value_length= 0;
++ if ((sys_init_slave.value= opt_init_slave))
++ sys_init_slave.value_length= strlen(opt_init_slave);
++ else
++ sys_init_slave.value=my_strdup("",MYF(0));
++ sys_init_slave.is_os_charset= TRUE;
++
++ /* check log options and issue warnings if needed */
++ if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
++ !(log_output_options & LOG_NONE))
++ sql_print_warning("Although a path was specified for the "
++ "--log option, log tables are used. "
++ "To enable logging to files use the --log-output option.");
++
++ if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
++ && !(log_output_options & LOG_NONE))
++ sql_print_warning("Although a path was specified for the "
++ "--log_slow_queries option, log tables are used. "
++ "To enable logging to files use the --log-output=file option.");
++
++ s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
++ sys_var_general_log_path.value= my_strdup(s, MYF(0));
++ sys_var_general_log_path.value_length= strlen(s);
++
++ s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
++ sys_var_slow_log_path.value= my_strdup(s, MYF(0));
++ sys_var_slow_log_path.value_length= strlen(s);
++
++#if defined(ENABLED_DEBUG_SYNC)
++ /* Initialize the debug sync facility. See debug_sync.cc. */
++ if (debug_sync_init())
++ return 1; /* purecov: tested */
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++
++#if (ENABLE_TEMP_POOL)
++ if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
++ return 1;
++#else
++ use_temp_pool= 0;
++#endif
++
++ if (my_database_names_init())
++ return 1;
++
++ /*
++ Ensure that lower_case_table_names is set on system where we have case
++ insensitive names. If this is not done the users MyISAM tables will
++ get corrupted if accesses with names of different case.
++ */
++ DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
++ lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
++ if (!lower_case_table_names && lower_case_file_system == 1)
++ {
++ if (lower_case_table_names_used)
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning("\
++You have forced lower_case_table_names to 0 through a command-line \
++option, even though your file system '%s' is case insensitive. This means \
++that you can corrupt a MyISAM table by accessing it with different cases. \
++You should consider changing lower_case_table_names to 1 or 2",
++ mysql_real_data_home);
++ }
++ else
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
++ lower_case_table_names= 2;
++ }
++ }
++ else if (lower_case_table_names == 2 &&
++ !(lower_case_file_system=
++ (test_if_case_insensitive(mysql_real_data_home) == 1)))
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning("lower_case_table_names was set to 2, even though your "
++ "the file system '%s' is case sensitive. Now setting "
++ "lower_case_table_names to 0 to avoid future problems.",
++ mysql_real_data_home);
++ lower_case_table_names= 0;
++ }
++ else
++ {
++ lower_case_file_system=
++ (test_if_case_insensitive(mysql_real_data_home) == 1);
++ }
++
++ /* Reset table_alias_charset, now that lower_case_table_names is set. */
++ table_alias_charset= (lower_case_table_names ?
++ files_charset_info :
++ &my_charset_bin);
++
++ return 0;
++}
++
++
++static int init_thread_environment()
++{
++ (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
++ (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
++ (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
++ (void) pthread_mutex_init(&LOCK_open, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
++ (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
++ (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
++ (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
++ (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
++#ifdef HAVE_OPENSSL
++ (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
++#ifndef HAVE_YASSL
++ openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
++ sizeof(openssl_lock_t));
++ for (int i= 0; i < CRYPTO_num_locks(); ++i)
++ (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
++ CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
++ CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
++ CRYPTO_set_dynlock_lock_callback(openssl_lock);
++ CRYPTO_set_locking_callback(openssl_lock_function);
++ CRYPTO_set_id_callback(openssl_id_function);
++#endif
++#endif
++ (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
++ (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
++ (void) my_rwlock_init(&LOCK_grant, NULL);
++ (void) pthread_cond_init(&COND_thread_count,NULL);
++ (void) pthread_cond_init(&COND_refresh,NULL);
++ (void) pthread_cond_init(&COND_global_read_lock,NULL);
++ (void) pthread_cond_init(&COND_thread_cache,NULL);
++ (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
++ (void) pthread_cond_init(&COND_manager,NULL);
++#ifdef HAVE_REPLICATION
++ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
++ (void) pthread_cond_init(&COND_rpl_status, NULL);
++#endif
++ (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
++ (void) pthread_cond_init(&COND_server_started,NULL);
++ sp_cache_init();
++#ifdef HAVE_EVENT_SCHEDULER
++ Events::init_mutexes();
++#endif
++ /* Parameter for threads created for connections */
++ (void) pthread_attr_init(&connection_attrib);
++ (void) pthread_attr_setdetachstate(&connection_attrib,
++ PTHREAD_CREATE_DETACHED);
++ pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
++ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
++
++ if (pthread_key_create(&THR_THD,NULL) ||
++ pthread_key_create(&THR_MALLOC,NULL))
++ {
++ sql_print_error("Can't create thread-keys");
++ return 1;
++ }
++ return 0;
++}
++
++
++#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
++static unsigned long openssl_id_function()
++{
++ return (unsigned long) pthread_self();
++}
++
++
++static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
++{
++ openssl_lock_t *lock= new openssl_lock_t;
++ my_rwlock_init(&lock->lock, NULL);
++ return lock;
++}
++
++
++static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
++ int line)
++{
++ rwlock_destroy(&lock->lock);
++ delete lock;
++}
++
++
++static void openssl_lock_function(int mode, int n, const char *file, int line)
++{
++ if (n < 0 || n > CRYPTO_num_locks())
++ {
++ /* Lock number out of bounds. */
++ sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
++ abort();
++ }
++ openssl_lock(mode, &openssl_stdlocks[n], file, line);
++}
++
++
++static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
++ int line)
++{
++ int err;
++ char const *what;
++
++ switch (mode) {
++ case CRYPTO_LOCK|CRYPTO_READ:
++ what = "read lock";
++ err = rw_rdlock(&lock->lock);
++ break;
++ case CRYPTO_LOCK|CRYPTO_WRITE:
++ what = "write lock";
++ err = rw_wrlock(&lock->lock);
++ break;
++ case CRYPTO_UNLOCK|CRYPTO_READ:
++ case CRYPTO_UNLOCK|CRYPTO_WRITE:
++ what = "unlock";
++ err = rw_unlock(&lock->lock);
++ break;
++ default:
++ /* Unknown locking mode. */
++ sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
++ abort();
++ }
++ if (err)
++ {
++ sql_print_error("Fatal: can't %s OpenSSL lock", what);
++ abort();
++ }
++}
++#endif /* HAVE_OPENSSL */
++
++
++#ifndef EMBEDDED_LIBRARY
++
++static void init_ssl()
++{
++#ifdef HAVE_OPENSSL
++ if (opt_use_ssl)
++ {
++ enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
++
++ /* having ssl_acceptor_fd != 0 signals the use of SSL */
++ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
++ opt_ssl_ca, opt_ssl_capath,
++ opt_ssl_cipher, &error);
++ DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
++ if (!ssl_acceptor_fd)
++ {
++ sql_print_warning("Failed to setup SSL");
++ sql_print_warning("SSL error: %s", sslGetErrString(error));
++ opt_use_ssl = 0;
++ have_ssl= SHOW_OPTION_DISABLED;
++ }
++ }
++ else
++ {
++ have_ssl= SHOW_OPTION_DISABLED;
++ }
++ if (des_key_file)
++ load_des_key_file(des_key_file);
++#endif /* HAVE_OPENSSL */
++}
++
++
++static void end_ssl()
++{
++#ifdef HAVE_OPENSSL
++ if (ssl_acceptor_fd)
++ {
++ free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
++ ssl_acceptor_fd= 0;
++ }
++#endif /* HAVE_OPENSSL */
++}
++
++#endif /* EMBEDDED_LIBRARY */
++
++
++static int init_server_components()
++{
++ DBUG_ENTER("init_server_components");
++ /*
++ We need to call each of these following functions to ensure that
++ all things are initialized so that unireg_abort() doesn't fail
++ */
++ if (table_cache_init() | table_def_init() | hostname_cache_init())
++ unireg_abort(1);
++
++ query_cache_result_size_limit(query_cache_limit);
++ query_cache_set_min_res_unit(query_cache_min_res_unit);
++ query_cache_init();
++ query_cache_resize(query_cache_size);
++ randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
++ setup_fpu();
++ init_thr_lock();
++#ifdef HAVE_REPLICATION
++ init_slave_list();
++#endif
++
++ /* Setup logs */
++
++ /*
++ Enable old-fashioned error log, except when the user has requested
++ help information. Since the implementation of plugin server
++ variables the help output is now written much later.
++ */
++ if (opt_error_log && !opt_help)
++ {
++ if (!log_error_file_ptr[0])
++ fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
++ MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
++ else
++ fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
++ MY_UNPACK_FILENAME | MY_SAFE_PATH);
++ if (!log_error_file[0])
++ opt_error_log= 1; // Too long file name
++ else
++ {
++ my_bool res;
++#ifndef EMBEDDED_LIBRARY
++ res= reopen_fstreams(log_error_file, stdout, stderr);
++#else
++ res= reopen_fstreams(log_error_file, NULL, stderr);
++#endif
++
++ if (!res)
++ setbuf(stderr, NULL);
++ }
++ }
++
++ if (xid_cache_init())
++ {
++ sql_print_error("Out of memory");
++ unireg_abort(1);
++ }
++
++ /* need to configure logging before initializing storage engines */
++ if (opt_update_log)
++ {
++ /*
++ Update log is removed since 5.0. But we still accept the option.
++ The idea is if the user already uses the binlog and the update log,
++ we completely ignore any option/variable related to the update log, like
++ if the update log did not exist. But if the user uses only the update
++ log, then we translate everything into binlog for him (with warnings).
++ Implementation of the above :
++ - If mysqld is started with --log-update and --log-bin,
++ ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
++ is used, and turn off --sql-bin-update-same.
++ This will completely ignore SQL_LOG_UPDATE
++ - If mysqld is started with --log-update only,
++ change it to --log-bin (with the filename passed to log-update,
++ plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
++ used, and turn on --sql-bin-update-same.
++ This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
++
++ Note that we tell the user that --sql-bin-update-same is deprecated and
++ does nothing, and we don't take into account if he used this option or
++ not; but internally we give this variable a value to have the behaviour
++ we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
++ As sql-bin-update-same, log-update and log-bin cannot be changed by the
++ user after starting the server (they are not variables), the user will
++ not later interfere with the settings we do here.
++ */
++ if (opt_bin_log)
++ {
++ opt_sql_bin_update= 0;
++ sql_print_error("The update log is no longer supported by MySQL in \
++version 5.0 and above. It is replaced by the binary log.");
++ }
++ else
++ {
++ opt_sql_bin_update= 1;
++ opt_bin_log= 1;
++ if (opt_update_logname)
++ {
++ /* as opt_bin_log==0, no need to free opt_bin_logname */
++ if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
++ {
++ sql_print_error("Out of memory");
++ return EXIT_OUT_OF_MEMORY;
++ }
++ sql_print_error("The update log is no longer supported by MySQL in \
++version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
++with --log-bin='%s' instead.",opt_bin_logname);
++ }
++ else
++ sql_print_error("The update log is no longer supported by MySQL in \
++version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
++with --log-bin instead.");
++ }
++ }
++ if (opt_log_slave_updates && !opt_bin_log)
++ {
++ sql_print_error("You need to use --log-bin to make "
++ "--log-slave-updates work.");
++ unireg_abort(1);
++ }
++ if (!opt_bin_log)
++ {
++ if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
++ {
++ sql_print_error("You need to use --log-bin to make "
++ "--binlog-format work.");
++ unireg_abort(1);
++ }
++ else
++ {
++ global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
++ }
++ }
++ else
++ if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
++ global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
++ else
++ {
++ DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
++ }
++
++ /* Check that we have not let the format to unspecified at this point */
++ DBUG_ASSERT((uint)global_system_variables.binlog_format <=
++ array_elements(binlog_format_names)-1);
++
++#ifdef HAVE_REPLICATION
++ if (opt_log_slave_updates && replicate_same_server_id)
++ {
++ sql_print_error("\
++using --replicate-same-server-id in conjunction with \
++--log-slave-updates is impossible, it would lead to infinite loops in this \
++server.");
++ unireg_abort(1);
++ }
++#endif
++
++ if (opt_bin_log)
++ {
++ /* Reports an error and aborts, if the --log-bin's path
++ is a directory.*/
++ if (opt_bin_logname &&
++ opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
++ {
++ sql_print_error("Path '%s' is a directory name, please specify \
++a file name for --log-bin option", opt_bin_logname);
++ unireg_abort(1);
++ }
++
++ /* Reports an error and aborts, if the --log-bin-index's path
++ is a directory.*/
++ if (opt_binlog_index_name &&
++ opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
++ == FN_LIBCHAR)
++ {
++ sql_print_error("Path '%s' is a directory name, please specify \
++a file name for --log-bin-index option", opt_binlog_index_name);
++ unireg_abort(1);
++ }
++
++ char buf[FN_REFLEN];
++ const char *ln;
++ ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
++ if (!opt_bin_logname && !opt_binlog_index_name)
++ {
++ /*
++ User didn't give us info to name the binlog index file.
++ Picking `hostname`-bin.index like did in 4.x, causes replication to
++ fail if the hostname is changed later. So, we would like to instead
++ require a name. But as we don't want to break many existing setups, we
++ only give warning, not error.
++ */
++ sql_print_warning("No argument was provided to --log-bin, and "
++ "--log-bin-index was not used; so replication "
++ "may break when this MySQL server acts as a "
++ "master and has his hostname changed!! Please "
++ "use '--log-bin=%s' to avoid this problem.", ln);
++ }
++ if (ln == buf)
++ {
++ my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
++ opt_bin_logname=my_strdup(buf, MYF(0));
++ }
++ if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
++ {
++ unireg_abort(1);
++ }
++ }
++
++ /* call ha_init_key_cache() on all key caches to init them */
++ process_key_caches(&ha_init_key_cache);
++
++ /* Allow storage engine to give real error messages */
++ if (ha_init_errors())
++ DBUG_RETURN(1);
++
++ {
++ if (plugin_init(&defaults_argc, defaults_argv,
++ (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
++ (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
++ {
++ sql_print_error("Failed to initialize plugins.");
++ unireg_abort(1);
++ }
++ plugins_are_initialized= TRUE; /* Don't separate from init function */
++ }
++
++ if (opt_help)
++ unireg_abort(0);
++
++ /* we do want to exit if there are any other unknown options */
++ if (defaults_argc > 1)
++ {
++ int ho_error;
++ char **tmp_argv= defaults_argv;
++ struct my_option no_opts[]=
++ {
++ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
++ };
++ /*
++ We need to eat any 'loose' arguments first before we conclude
++ that there are unprocessed options.
++ But we need to preserve defaults_argv pointer intact for
++ free_defaults() to work. Thus we use a copy here.
++ */
++ my_getopt_skip_unknown= 0;
++
++ if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
++ mysqld_get_one_option)))
++ unireg_abort(ho_error);
++ my_getopt_skip_unknown= TRUE;
++
++ if (defaults_argc)
++ {
++ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
++ "Use --verbose --help to get a list of available options\n",
++ my_progname, *tmp_argv);
++ unireg_abort(1);
++ }
++ }
++
++ /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
++ if (!errmesg[0][0])
++ unireg_abort(1);
++
++ /* We have to initialize the storage engines before CSV logging */
++ if (ha_init())
++ {
++ sql_print_error("Can't init databases");
++ unireg_abort(1);
++ }
++
++#ifdef WITH_CSV_STORAGE_ENGINE
++ if (opt_bootstrap)
++ log_output_options= LOG_FILE;
++ else
++ logger.init_log_tables();
++
++ if (log_output_options & LOG_NONE)
++ {
++ /*
++ Issue a warining if there were specified additional options to the
++ log-output along with NONE. Probably this wasn't what user wanted.
++ */
++ if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
++ sql_print_warning("There were other values specified to "
++ "log-output besides NONE. Disabling slow "
++ "and general logs anyway.");
++ logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
++ }
++ else
++ {
++ /* fall back to the log files if tables are not present */
++ LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
++ if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
++ {
++ /* purecov: begin inspected */
++ sql_print_error("CSV engine is not present, falling back to the "
++ "log files");
++ log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
++ /* purecov: end */
++ }
++
++ logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
++ opt_log ? log_output_options:LOG_NONE);
++ }
++#else
++ logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
++ opt_log ? LOG_FILE:LOG_NONE);
++#endif
++
++ /*
++ Check that the default storage engine is actually available.
++ */
++ if (default_storage_engine_str)
++ {
++ LEX_STRING name= { default_storage_engine_str,
++ strlen(default_storage_engine_str) };
++ plugin_ref plugin;
++ handlerton *hton;
++
++ if ((plugin= ha_resolve_by_name(0, &name)))
++ hton= plugin_data(plugin, handlerton*);
++ else
++ {
++ sql_print_error("Unknown/unsupported table type: %s",
++ default_storage_engine_str);
++ unireg_abort(1);
++ }
++ if (!ha_storage_engine_is_enabled(hton))
++ {
++ if (!opt_bootstrap)
++ {
++ sql_print_error("Default storage engine (%s) is not available",
++ default_storage_engine_str);
++ unireg_abort(1);
++ }
++ DBUG_ASSERT(global_system_variables.table_plugin);
++ }
++ else
++ {
++ /*
++ Need to unlock as global_system_variables.table_plugin
++ was acquired during plugin_init()
++ */
++ plugin_unlock(0, global_system_variables.table_plugin);
++ global_system_variables.table_plugin= plugin;
++ }
++ }
++
++ tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
++ (TC_LOG *) &mysql_bin_log :
++ (TC_LOG *) &tc_log_mmap) :
++ (TC_LOG *) &tc_log_dummy);
++
++ if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
++ {
++ sql_print_error("Can't init tc log");
++ unireg_abort(1);
++ }
++
++ if (ha_recover(0))
++ {
++ unireg_abort(1);
++ }
++
++ if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
++ WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
++ unireg_abort(1);
++
++#ifdef HAVE_REPLICATION
++ if (opt_bin_log && expire_logs_days)
++ {
++ time_t purge_time= server_start_time - expire_logs_days*24*60*60;
++ if (purge_time >= 0)
++ mysql_bin_log.purge_logs_before_date(purge_time);
++ }
++#endif
++#ifdef __NETWARE__
++ /* Increasing stacksize of threads on NetWare */
++ pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
++#endif
++
++ if (opt_myisam_log)
++ (void) mi_log(1);
++
++#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
++ if (locked_in_memory && !getuid())
++ {
++ if (setreuid((uid_t)-1, 0) == -1)
++ { // this should never happen
++ sql_perror("setreuid");
++ unireg_abort(1);
++ }
++ if (mlockall(MCL_CURRENT))
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
++ locked_in_memory= 0;
++ }
++ if (user_info)
++ set_user(mysqld_user, user_info);
++ }
++ else
++#endif
++ locked_in_memory=0;
++
++ ft_init_stopwords();
++
++ init_max_user_conn();
++ init_update_queries();
++ DBUG_RETURN(0);
++}
++
++
++#ifndef EMBEDDED_LIBRARY
++
++static void create_shutdown_thread()
++{
++#ifdef __WIN__
++ hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
++ pthread_t hThread;
++ if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
++ sql_print_warning("Can't create thread to handle shutdown requests");
++
++ // On "Stop Service" we have to do regular shutdown
++ Service.SetShutdownEvent(hEventShutdown);
++#endif /* __WIN__ */
++}
++
++#endif /* EMBEDDED_LIBRARY */
++
++
++#if (defined(__NT__) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
++static void handle_connections_methods()
++{
++ pthread_t hThread;
++ DBUG_ENTER("handle_connections_methods");
++#ifdef __NT__
++ if (hPipe == INVALID_HANDLE_VALUE &&
++ (!have_tcpip || opt_disable_networking) &&
++ !opt_enable_shared_memory)
++ {
++ sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
++ unireg_abort(1); // Will not return
++ }
++#endif
++
++ pthread_mutex_lock(&LOCK_thread_count);
++ (void) pthread_cond_init(&COND_handler_count,NULL);
++ handler_count=0;
++#ifdef __NT__
++ if (hPipe != INVALID_HANDLE_VALUE)
++ {
++ handler_count++;
++ if (pthread_create(&hThread,&connection_attrib,
++ handle_connections_namedpipes, 0))
++ {
++ sql_print_warning("Can't create thread to handle named pipes");
++ handler_count--;
++ }
++ }
++#endif /* __NT__ */
++ if (have_tcpip && !opt_disable_networking)
++ {
++ handler_count++;
++ if (pthread_create(&hThread,&connection_attrib,
++ handle_connections_sockets, 0))
++ {
++ sql_print_warning("Can't create thread to handle TCP/IP");
++ handler_count--;
++ }
++ }
++#ifdef HAVE_SMEM
++ if (opt_enable_shared_memory)
++ {
++ handler_count++;
++ if (pthread_create(&hThread,&connection_attrib,
++ handle_connections_shared_memory, 0))
++ {
++ sql_print_warning("Can't create thread to handle shared memory");
++ handler_count--;
++ }
++ }
++#endif
++
++ while (handler_count > 0)
++ pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
++ pthread_mutex_unlock(&LOCK_thread_count);
++ DBUG_VOID_RETURN;
++}
++
++void decrement_handler_count()
++{
++ pthread_mutex_lock(&LOCK_thread_count);
++ handler_count--;
++ pthread_cond_signal(&COND_handler_count);
++ pthread_mutex_unlock(&LOCK_thread_count);
++ my_thread_end();
++}
++#else
++#define decrement_handler_count()
++#endif /* defined(__NT__) || defined(HAVE_SMEM) */
++
++
++#ifndef EMBEDDED_LIBRARY
++#ifndef DBUG_OFF
++/*
++ Debugging helper function to keep the locale database
++ (see sql_locale.cc) and max_month_name_length and
++ max_day_name_length variable values in consistent state.
++*/
++static void test_lc_time_sz()
++{
++ DBUG_ENTER("test_lc_time_sz");
++ for (MY_LOCALE **loc= my_locales; *loc; loc++)
++ {
++ uint max_month_len= 0;
++ uint max_day_len = 0;
++ for (const char **month= (*loc)->month_names->type_names; *month; month++)
++ {
++ set_if_bigger(max_month_len,
++ my_numchars_mb(&my_charset_utf8_general_ci,
++ *month, *month + strlen(*month)));
++ }
++ for (const char **day= (*loc)->day_names->type_names; *day; day++)
++ {
++ set_if_bigger(max_day_len,
++ my_numchars_mb(&my_charset_utf8_general_ci,
++ *day, *day + strlen(*day)));
++ }
++ if ((*loc)->max_month_name_length != max_month_len ||
++ (*loc)->max_day_name_length != max_day_len)
++ {
++ DBUG_PRINT("Wrong max day name(or month name) length for locale:",
++ ("%s", (*loc)->name));
++ DBUG_ASSERT(0);
++ }
++ }
++ DBUG_VOID_RETURN;
++}
++#endif//DBUG_OFF
++
++
++#ifdef __WIN__
++int win_main(int argc, char **argv)
++#else
++int main(int argc, char **argv)
++#endif
++{
++ MY_INIT(argv[0]); // init my_sys library & pthreads
++ /* nothing should come before this line ^^^ */
++
++ /* Set signal used to kill MySQL */
++#if defined(SIGUSR2)
++ thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
++#else
++ thr_kill_signal= SIGINT;
++#endif
++
++ /*
++ Perform basic logger initialization logger. Should be called after
++ MY_INIT, as it initializes mutexes. Log tables are inited later.
++ */
++ logger.init_base();
++
++#ifdef _CUSTOMSTARTUPCONFIG_
++ if (_cust_check_startup())
++ {
++ / * _cust_check_startup will report startup failure error * /
++ exit(1);
++ }
++#endif
++
++#ifdef __WIN__
++ /*
++ Before performing any socket operation (like retrieving hostname
++ in init_common_variables we have to call WSAStartup
++ */
++ {
++ WSADATA WsaData;
++ if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
++ {
++ /* errors are not read yet, so we use english text here */
++ my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
++ unireg_abort(1);
++ }
++ }
++#endif /* __WIN__ */
++
++ if (init_common_variables(MYSQL_CONFIG_NAME,
++ argc, argv, load_default_groups))
++ unireg_abort(1); // Will do exit
++
++ init_signals();
++ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
++#if defined(__ia64__) || defined(__ia64)
++ /*
++ Peculiar things with ia64 platforms - it seems we only have half the
++ stack size in reality, so we have to double it here
++ */
++ pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
++#else
++ pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
++#endif
++#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
++ {
++ /* Retrieve used stack size; Needed for checking stack overflows */
++ size_t stack_size= 0;
++ pthread_attr_getstacksize(&connection_attrib, &stack_size);
++#if defined(__ia64__) || defined(__ia64)
++ stack_size/= 2;
++#endif
++ /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
++ if (stack_size && stack_size < my_thread_stack_size)
++ {
++ if (global_system_variables.log_warnings)
++ sql_print_warning("Asked for %lu thread stack, but got %ld",
++ my_thread_stack_size, (long) stack_size);
++#if defined(__ia64__) || defined(__ia64)
++ my_thread_stack_size= stack_size*2;
++#else
++ my_thread_stack_size= stack_size;
++#endif
++ }
++ }
++#endif
++#ifdef __NETWARE__
++ /* Increasing stacksize of threads on NetWare */
++ pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
++#endif
++
++ (void) thr_setconcurrency(concurrency); // 10 by default
++
++ select_thread=pthread_self();
++ select_thread_in_use=1;
++
++#ifdef HAVE_LIBWRAP
++ libwrapName= my_progname+dirname_length(my_progname);
++ openlog(libwrapName, LOG_PID, LOG_AUTH);
++#endif
++
++#ifndef DBUG_OFF
++ test_lc_time_sz();
++#endif
++
++ /*
++ We have enough space for fiddling with the argv, continue
++ */
++ check_data_home(mysql_real_data_home);
++ if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
++ unireg_abort(1); /* purecov: inspected */
++ mysql_data_home= mysql_data_home_buff;
++ mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
++ mysql_data_home[1]=0;
++ mysql_data_home_len= 2;
++
++ if ((user_info= check_user(mysqld_user)))
++ {
++#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
++ if (locked_in_memory) // getuid() == 0 here
++ set_effective_user(user_info);
++ else
++#endif
++ set_user(mysqld_user, user_info);
++ }
++
++ if (opt_bin_log && !server_id)
++ {
++ server_id= !master_host ? 1 : 2;
++#ifdef EXTRA_DEBUG
++ switch (server_id) {
++ case 1:
++ sql_print_warning("\
++You have enabled the binary log, but you haven't set server-id to \
++a non-zero value: we force server id to 1; updates will be logged to the \
++binary log, but connections from slaves will not be accepted.");
++ break;
++ case 2:
++ sql_print_warning("\
++You should set server-id to a non-0 value if master_host is set; \
++we force server id to 2, but this MySQL server will not act as a slave.");
++ break;
++ }
++#endif
++ }
++
++ if (init_server_components())
++ unireg_abort(1);
++
++ init_ssl();
++ network_init();
++
++#ifdef __WIN__
++ if (!opt_console)
++ {
++ if (reopen_fstreams(log_error_file, stdout, stderr))
++ unireg_abort(1);
++ setbuf(stderr, NULL);
++ FreeConsole(); // Remove window
++ }
++#endif
++
++ /*
++ Initialize my_str_malloc() and my_str_free()
++ */
++ my_str_malloc= &my_str_malloc_mysqld;
++ my_str_free= &my_str_free_mysqld;
++
++ /*
++ init signals & alarm
++ After this we can't quit by a simple unireg_abort
++ */
++ error_handler_hook= my_message_sql;
++ start_signal_handler(); // Creates pidfile
++
++ if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
++ my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
++ {
++ abort_loop=1;
++ select_thread_in_use=0;
++#ifndef __NETWARE__
++ (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
++#endif /* __NETWARE__ */
++
++ if (!opt_bootstrap)
++ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
++
++ if (unix_sock != INVALID_SOCKET)
++ unlink(mysqld_unix_port);
++ exit(1);
++ }
++ if (!opt_noacl)
++ (void) grant_init();
++
++ if (!opt_bootstrap)
++ servers_init(0);
++
++ if (!opt_noacl)
++ {
++#ifdef HAVE_DLOPEN
++ udf_init();
++#endif
++ }
++
++ init_status_vars();
++ if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
++ opt_skip_slave_start= 1;
++ /*
++ init_slave() must be called after the thread keys are created.
++ Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
++ places) assume that active_mi != 0, so let's fail if it's 0 (out of
++ memory); a message has already been printed.
++ */
++ if (init_slave() && !active_mi)
++ {
++ unireg_abort(1);
++ }
++
++ execute_ddl_log_recovery();
++
++ if (Events::init(opt_noacl || opt_bootstrap))
++ unireg_abort(1);
++
++ if (opt_bootstrap)
++ {
++ select_thread_in_use= 0; // Allow 'kill' to work
++ bootstrap(stdin);
++ unireg_abort(bootstrap_error ? 1 : 0);
++ }
++ if (opt_init_file)
++ {
++ if (read_init_file(opt_init_file))
++ unireg_abort(1);
++ }
++
++ create_shutdown_thread();
++ start_handle_manager();
++
++ sql_print_information(ER(ER_STARTUP),my_progname,server_version,
++ ((unix_sock == INVALID_SOCKET) ? (char*) ""
++ : mysqld_unix_port),
++ mysqld_port,
++ MYSQL_COMPILATION_COMMENT);
++#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
++ Service.SetRunning();
++#endif
++
++
++ /* Signal threads waiting for server to be started */
++ pthread_mutex_lock(&LOCK_server_started);
++ mysqld_server_started= 1;
++ pthread_cond_signal(&COND_server_started);
++ pthread_mutex_unlock(&LOCK_server_started);
++
++#if defined(__NT__) || defined(HAVE_SMEM)
++ handle_connections_methods();
++#else
++#ifdef __WIN__
++ if (!have_tcpip || opt_disable_networking)
++ {
++ sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces");
++ unireg_abort(1);
++ }
++#endif
++ handle_connections_sockets(0);
++#endif /* __NT__ */
++
++ /* (void) pthread_attr_destroy(&connection_attrib); */
++
++ DBUG_PRINT("quit",("Exiting main thread"));
++
++#ifndef __WIN__
++#ifdef EXTRA_DEBUG2
++ sql_print_error("Before Lock_thread_count");
++#endif
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ DBUG_PRINT("quit", ("Got thread_count mutex"));
++ select_thread_in_use=0; // For close_connections
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ (void) pthread_cond_broadcast(&COND_thread_count);
++#ifdef EXTRA_DEBUG2
++ sql_print_error("After lock_thread_count");
++#endif
++#endif /* __WIN__ */
++
++ /* Wait until cleanup is done */
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ while (!ready_to_exit)
++ pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++
++#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
++ if (Service.IsNT() && start_mode)
++ Service.Stop();
++ else
++ {
++ Service.SetShutdownEvent(0);
++ if (hEventShutdown)
++ CloseHandle(hEventShutdown);
++ }
++#endif
++ clean_up(1);
++ wait_for_signal_thread_to_end();
++ clean_up_mutexes();
++ my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
++
++ exit(0);
++ return(0); /* purecov: deadcode */
++}
++
++#endif /* EMBEDDED_LIBRARY */
++
++
++/****************************************************************************
++ Main and thread entry function for Win32
++ (all this is needed only to run mysqld as a service on WinNT)
++****************************************************************************/
++
++#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
++int mysql_service(void *p)
++{
++ if (use_opt_args)
++ win_main(opt_argc, opt_argv);
++ else
++ win_main(Service.my_argc, Service.my_argv);
++ return 0;
++}
++
++
++/* Quote string if it contains space, else copy */
++
++static char *add_quoted_string(char *to, const char *from, char *to_end)
++{
++ uint length= (uint) (to_end-to);
++
++ if (!strchr(from, ' '))
++ return strmake(to, from, length-1);
++ return strxnmov(to, length-1, "\"", from, "\"", NullS);
++}
++
++
++/**
++ Handle basic handling of services, like installation and removal.
++
++ @param argv Pointer to argument list
++ @param servicename Internal name of service
++ @param displayname Display name of service (in taskbar ?)
++ @param file_path Path to this program
++ @param startup_option Startup option to mysqld
++
++ @retval
++ 0 option handled
++ @retval
++ 1 Could not handle option
++*/
++
++static bool
++default_service_handling(char **argv,
++ const char *servicename,
++ const char *displayname,
++ const char *file_path,
++ const char *extra_opt,
++ const char *account_name)
++{
++ char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
++ const char *opt_delim;
++ end= path_and_service + sizeof(path_and_service)-3;
++
++ /* We have to quote filename if it contains spaces */
++ pos= add_quoted_string(path_and_service, file_path, end);
++ if (*extra_opt)
++ {
++ /*
++ Add option after file_path. There will be zero or one extra option. It's
++ assumed to be --defaults-file=file but isn't checked. The variable (not
++ the option name) should be quoted if it contains a string.
++ */
++ *pos++= ' ';
++ if (opt_delim= strchr(extra_opt, '='))
++ {
++ size_t length= ++opt_delim - extra_opt;
++ pos= strnmov(pos, extra_opt, length);
++ }
++ else
++ opt_delim= extra_opt;
++
++ pos= add_quoted_string(pos, opt_delim, end);
++ }
++ /* We must have servicename last */
++ *pos++= ' ';
++ (void) add_quoted_string(pos, servicename, end);
++
++ if (Service.got_service_option(argv, "install"))
++ {
++ Service.Install(1, servicename, displayname, path_and_service,
++ account_name);
++ return 0;
++ }
++ if (Service.got_service_option(argv, "install-manual"))
++ {
++ Service.Install(0, servicename, displayname, path_and_service,
++ account_name);
++ return 0;
++ }
++ if (Service.got_service_option(argv, "remove"))
++ {
++ Service.Remove(servicename);
++ return 0;
++ }
++ return 1;
++}
++
++
++int main(int argc, char **argv)
++{
++ /*
++ When several instances are running on the same machine, we
++ need to have an unique named hEventShudown through the
++ application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
++ */
++ int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
++ "MySQLShutdown"), 10);
++
++ /* Must be initialized early for comparison of service name */
++ system_charset_info= &my_charset_utf8_general_ci;
++
++ if (Service.GetOS()) /* true NT family */
++ {
++ char file_path[FN_REFLEN];
++ my_path(file_path, argv[0], ""); /* Find name in path */
++ fn_format(file_path,argv[0],file_path,"",
++ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
++
++ if (argc == 2)
++ {
++ if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
++ file_path, "", NULL))
++ return 0;
++ if (Service.IsService(argv[1])) /* Start an optional service */
++ {
++ /*
++ Only add the service name to the groups read from the config file
++ if it's not "MySQL". (The default service name should be 'mysqld'
++ but we started a bad tradition by calling it MySQL from the start
++ and we are now stuck with it.
++ */
++ if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
++ load_default_groups[load_default_groups_sz-2]= argv[1];
++ start_mode= 1;
++ Service.Init(argv[1], mysql_service);
++ return 0;
++ }
++ }
++ else if (argc == 3) /* install or remove any optional service */
++ {
++ if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
++ NULL))
++ return 0;
++ if (Service.IsService(argv[2]))
++ {
++ /*
++ mysqld was started as
++ mysqld --defaults-file=my_path\my.ini service-name
++ */
++ use_opt_args=1;
++ opt_argc= 2; // Skip service-name
++ opt_argv=argv;
++ start_mode= 1;
++ if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
++ load_default_groups[load_default_groups_sz-2]= argv[2];
++ Service.Init(argv[2], mysql_service);
++ return 0;
++ }
++ }
++ else if (argc == 4 || argc == 5)
++ {
++ /*
++ This may seem strange, because we handle --local-service while
++ preserving 4.1's behavior of allowing any one other argument that is
++ passed to the service on startup. (The assumption is that this is
++ --defaults-file=file, but that was not enforced in 4.1, so we don't
++ enforce it here.)
++ */
++ const char *extra_opt= NullS;
++ const char *account_name = NullS;
++ int index;
++ for (index = 3; index < argc; index++)
++ {
++ if (!strcmp(argv[index], "--local-service"))
++ account_name= "NT AUTHORITY\\LocalService";
++ else
++ extra_opt= argv[index];
++ }
++
++ if (argc == 4 || account_name)
++ if (!default_service_handling(argv, argv[2], argv[2], file_path,
++ extra_opt, account_name))
++ return 0;
++ }
++ else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
++ {
++ /* start the default service */
++ start_mode= 1;
++ Service.Init(MYSQL_SERVICENAME, mysql_service);
++ return 0;
++ }
++ }
++ /* Start as standalone server */
++ Service.my_argc=argc;
++ Service.my_argv=argv;
++ mysql_service(NULL);
++ return 0;
++}
++#endif
++
++
++/**
++ Execute all commands from a file. Used by the mysql_install_db script to
++ create MySQL privilege tables without having to start a full MySQL server.
++*/
++
++static void bootstrap(FILE *file)
++{
++ DBUG_ENTER("bootstrap");
++
++ THD *thd= new THD;
++ thd->bootstrap=1;
++ my_net_init(&thd->net,(st_vio*) 0);
++ thd->max_client_packet_length= thd->net.max_packet;
++ thd->security_ctx->master_access= ~(ulong)0;
++ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
++ thread_count++;
++ in_bootstrap= TRUE;
++
++ bootstrap_file=file;
++#ifndef EMBEDDED_LIBRARY // TODO: Enable this
++ if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
++ (void*) thd))
++ {
++ sql_print_warning("Can't create thread to handle bootstrap");
++ bootstrap_error=-1;
++ DBUG_VOID_RETURN;
++ }
++ /* Wait for thread to die */
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ while (in_bootstrap)
++ {
++ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
++ DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
++ }
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++#else
++ thd->mysql= 0;
++ handle_bootstrap((void *)thd);
++#endif
++
++ DBUG_VOID_RETURN;
++}
++
++
++static bool read_init_file(char *file_name)
++{
++ FILE *file;
++ DBUG_ENTER("read_init_file");
++ DBUG_PRINT("enter",("name: %s",file_name));
++ if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
++ DBUG_RETURN(TRUE);
++ bootstrap(file);
++ (void) my_fclose(file,MYF(MY_WME));
++ DBUG_RETURN(FALSE);
++}
++
++
++#ifndef EMBEDDED_LIBRARY
++
++/*
++ Simple scheduler that use the main thread to handle the request
++
++ NOTES
++ This is only used for debugging, when starting mysqld with
++ --thread-handling=no-threads or --one-thread
++
++ When we enter this function, LOCK_thread_count is hold!
++*/
++
++void handle_connection_in_main_thread(THD *thd)
++{
++ safe_mutex_assert_owner(&LOCK_thread_count);
++ thread_cache_size=0; // Safety
++ threads.append(thd);
++ pthread_mutex_unlock(&LOCK_thread_count);
++ thd->start_utime= my_micro_time();
++ handle_one_connection(thd);
++}
++
++
++/*
++ Scheduler that uses one thread per connection
++*/
++
++void create_thread_to_handle_connection(THD *thd)
++{
++ if (cached_thread_count > wake_thread)
++ {
++ /* Get thread from cache */
++ thread_cache.append(thd);
++ wake_thread++;
++ pthread_cond_signal(&COND_thread_cache);
++ }
++ else
++ {
++ char error_message_buff[MYSQL_ERRMSG_SIZE];
++ /* Create new thread to handle connection */
++ int error;
++ thread_created++;
++ threads.append(thd);
++ DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
++ thd->prior_thr_create_utime= thd->start_utime= my_micro_time();
++ if ((error=pthread_create(&thd->real_id,&connection_attrib,
++ handle_one_connection,
++ (void*) thd)))
++ {
++ /* purecov: begin inspected */
++ DBUG_PRINT("error",
++ ("Can't create thread to handle request (error %d)",
++ error));
++ thread_count--;
++ thd->killed= THD::KILL_CONNECTION; // Safety
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++
++ pthread_mutex_lock(&LOCK_connection_count);
++ --connection_count;
++ pthread_mutex_unlock(&LOCK_connection_count);
++
++ statistic_increment(aborted_connects,&LOCK_status);
++ /* Can't use my_error() since store_globals has not been called. */
++ my_snprintf(error_message_buff, sizeof(error_message_buff),
++ ER(ER_CANT_CREATE_THREAD), error);
++ net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ close_connection(thd,0,0);
++ delete thd;
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ return;
++ /* purecov: end */
++ }
++ }
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ DBUG_PRINT("info",("Thread created"));
++}
++
++
++/**
++ Create new thread to handle incoming connection.
++
++ This function will create new thread to handle the incoming
++ connection. If there are idle cached threads one will be used.
++ 'thd' will be pushed into 'threads'.
++
++ In single-threaded mode (\#define ONE_THREAD) connection will be
++ handled inside this function.
++
++ @param[in,out] thd Thread handle of future thread.
++*/
++
++static void create_new_thread(THD *thd)
++{
++ NET *net=&thd->net;
++ DBUG_ENTER("create_new_thread");
++
++ if (protocol_version > 9)
++ net->return_errno=1;
++
++ /*
++ Don't allow too many connections. We roughly check here that we allow
++ only (max_connections + 1) connections.
++ */
++
++ pthread_mutex_lock(&LOCK_connection_count);
++
++ if (connection_count >= max_connections + 1 || abort_loop)
++ {
++ pthread_mutex_unlock(&LOCK_connection_count);
++
++ DBUG_PRINT("error",("Too many connections"));
++ close_connection(thd, ER_CON_COUNT_ERROR, 1);
++ delete thd;
++ DBUG_VOID_RETURN;
++ }
++
++ ++connection_count;
++
++ if (connection_count > max_used_connections)
++ max_used_connections= connection_count;
++
++ pthread_mutex_unlock(&LOCK_connection_count);
++
++ /* Start a new thread to handle connection. */
++
++ pthread_mutex_lock(&LOCK_thread_count);
++
++ /*
++ The initialization of thread_id is done in create_embedded_thd() for
++ the embedded library.
++ TODO: refactor this to avoid code duplication there
++ */
++ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
++
++ thread_count++;
++
++ thread_scheduler.add_connection(thd);
++
++ DBUG_VOID_RETURN;
++}
++#endif /* EMBEDDED_LIBRARY */
++
++
++#ifdef SIGNALS_DONT_BREAK_READ
++inline void kill_broken_server()
++{
++ /* hack to get around signals ignored in syscalls for problem OS's */
++ if (
++#if !defined(__NETWARE__)
++ unix_sock == INVALID_SOCKET ||
++#endif
++ (!opt_disable_networking && ip_sock == INVALID_SOCKET))
++ {
++ select_thread_in_use = 0;
++ /* The following call will never return */
++ kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL));
++ }
++}
++#define MAYBE_BROKEN_SYSCALL kill_broken_server();
++#else
++#define MAYBE_BROKEN_SYSCALL
++#endif
++
++ /* Handle new connections and spawn new process to handle them */
++
++#ifndef EMBEDDED_LIBRARY
++pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
++{
++ my_socket sock,new_sock;
++ uint error_count=0;
++ uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ fd_set readFDs,clientFDs;
++ THD *thd;
++ struct sockaddr_in cAddr;
++ int ip_flags=0,socket_flags=0,flags;
++ st_vio *vio_tmp;
++ DBUG_ENTER("handle_connections_sockets");
++
++ LINT_INIT(new_sock);
++
++ (void) my_pthread_getprio(pthread_self()); // For debugging
++
++ FD_ZERO(&clientFDs);
++ if (ip_sock != INVALID_SOCKET)
++ {
++ FD_SET(ip_sock,&clientFDs);
++#ifdef HAVE_FCNTL
++ ip_flags = fcntl(ip_sock, F_GETFL, 0);
++#endif
++ }
++#ifdef HAVE_SYS_UN_H
++ FD_SET(unix_sock,&clientFDs);
++#ifdef HAVE_FCNTL
++ socket_flags=fcntl(unix_sock, F_GETFL, 0);
++#endif
++#endif
++
++ DBUG_PRINT("general",("Waiting for connections."));
++ MAYBE_BROKEN_SYSCALL;
++ while (!abort_loop)
++ {
++ readFDs=clientFDs;
++#ifdef HPUX10
++ if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
++ continue;
++#else
++ if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
++ {
++ if (socket_errno != SOCKET_EINTR)
++ {
++ if (!select_errors++ && !abort_loop) /* purecov: inspected */
++ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
++ }
++ MAYBE_BROKEN_SYSCALL
++ continue;
++ }
++#endif /* HPUX10 */
++ if (abort_loop)
++ {
++ MAYBE_BROKEN_SYSCALL;
++ break;
++ }
++
++ /* Is this a new connection request ? */
++#ifdef HAVE_SYS_UN_H
++ if (FD_ISSET(unix_sock,&readFDs))
++ {
++ sock = unix_sock;
++ flags= socket_flags;
++ }
++ else
++#endif
++ {
++ sock = ip_sock;
++ flags= ip_flags;
++ }
++
++#if !defined(NO_FCNTL_NONBLOCK)
++ if (!(test_flags & TEST_BLOCKING))
++ {
++#if defined(O_NONBLOCK)
++ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
++#elif defined(O_NDELAY)
++ fcntl(sock, F_SETFL, flags | O_NDELAY);
++#endif
++ }
++#endif /* NO_FCNTL_NONBLOCK */
++ for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
++ {
++ size_socket length=sizeof(struct sockaddr_in);
++ new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
++ &length);
++#ifdef __NETWARE__
++ // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
++ if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
++ {
++ kill_server(SIGTERM);
++ }
++#endif
++ if (new_sock != INVALID_SOCKET ||
++ (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
++ break;
++ MAYBE_BROKEN_SYSCALL;
++#if !defined(NO_FCNTL_NONBLOCK)
++ if (!(test_flags & TEST_BLOCKING))
++ {
++ if (retry == MAX_ACCEPT_RETRY - 1)
++ fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK
++ }
++#endif
++ }
++#if !defined(NO_FCNTL_NONBLOCK)
++ if (!(test_flags & TEST_BLOCKING))
++ fcntl(sock, F_SETFL, flags);
++#endif
++ if (new_sock == INVALID_SOCKET)
++ {
++ if ((error_count++ & 255) == 0) // This can happen often
++ sql_perror("Error in accept");
++ MAYBE_BROKEN_SYSCALL;
++ if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
++ sleep(1); // Give other threads some time
++ continue;
++ }
++
++#ifdef HAVE_LIBWRAP
++ {
++ if (sock == ip_sock)
++ {
++ struct request_info req;
++ signal(SIGCHLD, SIG_DFL);
++ request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
++ my_fromhost(&req);
++ if (!my_hosts_access(&req))
++ {
++ /*
++ This may be stupid but refuse() includes an exit(0)
++ which we surely don't want...
++ clean_exit() - same stupid thing ...
++ */
++ syslog(deny_severity, "refused connect from %s",
++ my_eval_client(&req));
++
++ /*
++ C++ sucks (the gibberish in front just translates the supplied
++ sink function pointer in the req structure from a void (*sink)();
++ to a void(*sink)(int) if you omit the cast, the C++ compiler
++ will cry...
++ */
++ if (req.sink)
++ ((void (*)(int))req.sink)(req.fd);
++
++ (void) shutdown(new_sock, SHUT_RDWR);
++ (void) closesocket(new_sock);
++ continue;
++ }
++ }
++ }
++#endif /* HAVE_LIBWRAP */
++
++ {
++ size_socket dummyLen;
++ struct sockaddr dummy;
++ dummyLen = sizeof(struct sockaddr);
++ if (getsockname(new_sock,&dummy, &dummyLen) < 0)
++ {
++ sql_perror("Error on new connection socket");
++ (void) shutdown(new_sock, SHUT_RDWR);
++ (void) closesocket(new_sock);
++ continue;
++ }
++ }
++
++ /*
++ ** Don't allow too many connections
++ */
++
++ if (!(thd= new THD))
++ {
++ (void) shutdown(new_sock, SHUT_RDWR);
++ VOID(closesocket(new_sock));
++ continue;
++ }
++ if (!(vio_tmp=vio_new(new_sock,
++ sock == unix_sock ? VIO_TYPE_SOCKET :
++ VIO_TYPE_TCPIP,
++ sock == unix_sock ? VIO_LOCALHOST: 0)) ||
++ my_net_init(&thd->net,vio_tmp))
++ {
++ /*
++ Only delete the temporary vio if we didn't already attach it to the
++ NET object. The destructor in THD will delete any initialized net
++ structure.
++ */
++ if (vio_tmp && thd->net.vio != vio_tmp)
++ vio_delete(vio_tmp);
++ else
++ {
++ (void) shutdown(new_sock, SHUT_RDWR);
++ (void) closesocket(new_sock);
++ }
++ delete thd;
++ continue;
++ }
++ if (sock == unix_sock)
++ thd->security_ctx->host=(char*) my_localhost;
++
++ create_new_thread(thd);
++ }
++ DBUG_LEAVE;
++ decrement_handler_count();
++ return 0;
++}
++
++
++#ifdef __NT__
++pthread_handler_t handle_connections_namedpipes(void *arg)
++{
++ HANDLE hConnectedPipe;
++ OVERLAPPED connectOverlapped= {0};
++ THD *thd;
++ my_thread_init();
++ DBUG_ENTER("handle_connections_namedpipes");
++ connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
++ if (!connectOverlapped.hEvent)
++ {
++ sql_print_error("Can't create event, last error=%u", GetLastError());
++ unireg_abort(1);
++ }
++ DBUG_PRINT("general",("Waiting for named pipe connections."));
++ while (!abort_loop)
++ {
++ /* wait for named pipe connection */
++ BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
++ if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
++ {
++ /*
++ ERROR_IO_PENDING says async IO has started but not yet finished.
++ GetOverlappedResult will wait for completion.
++ */
++ DWORD bytes;
++ fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
++ }
++ if (abort_loop)
++ break;
++ if (!fConnected)
++ fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
++ if (!fConnected)
++ {
++ CloseHandle(hPipe);
++ if ((hPipe= CreateNamedPipe(pipe_name,
++ PIPE_ACCESS_DUPLEX |
++ FILE_FLAG_OVERLAPPED,
++ PIPE_TYPE_BYTE |
++ PIPE_READMODE_BYTE |
++ PIPE_WAIT,
++ PIPE_UNLIMITED_INSTANCES,
++ (int) global_system_variables.
++ net_buffer_length,
++ (int) global_system_variables.
++ net_buffer_length,
++ NMPWAIT_USE_DEFAULT_WAIT,
++ &saPipeSecurity)) ==
++ INVALID_HANDLE_VALUE)
++ {
++ sql_perror("Can't create new named pipe!");
++ break; // Abort
++ }
++ }
++ hConnectedPipe = hPipe;
++ /* create new pipe for new connection */
++ if ((hPipe = CreateNamedPipe(pipe_name,
++ PIPE_ACCESS_DUPLEX |
++ FILE_FLAG_OVERLAPPED,
++ PIPE_TYPE_BYTE |
++ PIPE_READMODE_BYTE |
++ PIPE_WAIT,
++ PIPE_UNLIMITED_INSTANCES,
++ (int) global_system_variables.net_buffer_length,
++ (int) global_system_variables.net_buffer_length,
++ NMPWAIT_USE_DEFAULT_WAIT,
++ &saPipeSecurity)) ==
++ INVALID_HANDLE_VALUE)
++ {
++ sql_perror("Can't create new named pipe!");
++ hPipe=hConnectedPipe;
++ continue; // We have to try again
++ }
++
++ if (!(thd = new THD))
++ {
++ DisconnectNamedPipe(hConnectedPipe);
++ CloseHandle(hConnectedPipe);
++ continue;
++ }
++ if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
++ my_net_init(&thd->net, thd->net.vio))
++ {
++ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
++ delete thd;
++ continue;
++ }
++ /* Host is unknown */
++ thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
++ create_new_thread(thd);
++ }
++ CloseHandle(connectOverlapped.hEvent);
++ DBUG_LEAVE;
++ decrement_handler_count();
++ return 0;
++}
++#endif /* __NT__ */
++
++
++#ifdef HAVE_SMEM
++
++/**
++ Thread of shared memory's service.
++
++ @param arg Arguments of thread
++*/
++pthread_handler_t handle_connections_shared_memory(void *arg)
++{
++ /* file-mapping object, use for create shared memory */
++ HANDLE handle_connect_file_map= 0;
++ char *handle_connect_map= 0; // pointer on shared memory
++ HANDLE event_connect_answer= 0;
++ ulong smem_buffer_length= shared_memory_buffer_length + 4;
++ ulong connect_number= 1;
++ char *tmp= NULL;
++ char *suffix_pos;
++ char connect_number_char[22], *p;
++ const char *errmsg= 0;
++ SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
++ my_thread_init();
++ DBUG_ENTER("handle_connections_shared_memorys");
++ DBUG_PRINT("general",("Waiting for allocated shared memory."));
++
++ /*
++ get enough space base-name + '_' + longest suffix we might ever send
++ */
++ if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
++ goto error;
++
++ if (my_security_attr_create(&sa_event, &errmsg,
++ GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
++ goto error;
++
++ if (my_security_attr_create(&sa_mapping, &errmsg,
++ GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
++ goto error;
++
++ /*
++ The name of event and file-mapping events create agree next rule:
++ shared_memory_base_name+unique_part
++ Where:
++ shared_memory_base_name is unique value for each server
++ unique_part is unique value for each object (events and file-mapping)
++ */
++ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
++ strmov(suffix_pos, "CONNECT_REQUEST");
++ if ((smem_event_connect_request= CreateEvent(sa_event,
++ FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create request event";
++ goto error;
++ }
++ strmov(suffix_pos, "CONNECT_ANSWER");
++ if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg="Could not create answer event";
++ goto error;
++ }
++ strmov(suffix_pos, "CONNECT_DATA");
++ if ((handle_connect_file_map=
++ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
++ PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
++ {
++ errmsg= "Could not create file mapping";
++ goto error;
++ }
++ if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
++ FILE_MAP_WRITE,0,0,
++ sizeof(DWORD))) == 0)
++ {
++ errmsg= "Could not create shared memory service";
++ goto error;
++ }
++
++ while (!abort_loop)
++ {
++ /* Wait a request from client */
++ WaitForSingleObject(smem_event_connect_request,INFINITE);
++
++ /*
++ it can be after shutdown command
++ */
++ if (abort_loop)
++ goto error;
++
++ HANDLE handle_client_file_map= 0;
++ char *handle_client_map= 0;
++ HANDLE event_client_wrote= 0;
++ HANDLE event_client_read= 0; // for transfer data server <-> client
++ HANDLE event_server_wrote= 0;
++ HANDLE event_server_read= 0;
++ HANDLE event_conn_closed= 0;
++ THD *thd= 0;
++
++ p= int10_to_str(connect_number, connect_number_char, 10);
++ /*
++ The name of event and file-mapping events create agree next rule:
++ shared_memory_base_name+unique_part+number_of_connection
++ Where:
++ shared_memory_base_name is uniquel value for each server
++ unique_part is unique value for each object (events and file-mapping)
++ number_of_connection is connection-number between server and client
++ */
++ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
++ "_",NullS);
++ strmov(suffix_pos, "DATA");
++ if ((handle_client_file_map=
++ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
++ PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
++ {
++ errmsg= "Could not create file mapping";
++ goto errorconn;
++ }
++ if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
++ FILE_MAP_WRITE,0,0,
++ smem_buffer_length)) == 0)
++ {
++ errmsg= "Could not create memory map";
++ goto errorconn;
++ }
++ strmov(suffix_pos, "CLIENT_WROTE");
++ if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create client write event";
++ goto errorconn;
++ }
++ strmov(suffix_pos, "CLIENT_READ");
++ if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create client read event";
++ goto errorconn;
++ }
++ strmov(suffix_pos, "SERVER_READ");
++ if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create server read event";
++ goto errorconn;
++ }
++ strmov(suffix_pos, "SERVER_WROTE");
++ if ((event_server_wrote= CreateEvent(sa_event,
++ FALSE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create server write event";
++ goto errorconn;
++ }
++ strmov(suffix_pos, "CONNECTION_CLOSED");
++ if ((event_conn_closed= CreateEvent(sa_event,
++ TRUE, FALSE, tmp)) == 0)
++ {
++ errmsg= "Could not create closed connection event";
++ goto errorconn;
++ }
++ if (abort_loop)
++ goto errorconn;
++ if (!(thd= new THD))
++ goto errorconn;
++ /* Send number of connection to client */
++ int4store(handle_connect_map, connect_number);
++ if (!SetEvent(event_connect_answer))
++ {
++ errmsg= "Could not send answer event";
++ goto errorconn;
++ }
++ /* Set event that client should receive data */
++ if (!SetEvent(event_client_read))
++ {
++ errmsg= "Could not set client to read mode";
++ goto errorconn;
++ }
++ if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
++ handle_client_map,
++ event_client_wrote,
++ event_client_read,
++ event_server_wrote,
++ event_server_read,
++ event_conn_closed)) ||
++ my_net_init(&thd->net, thd->net.vio))
++ {
++ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
++ errmsg= 0;
++ goto errorconn;
++ }
++ thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
++ create_new_thread(thd);
++ connect_number++;
++ continue;
++
++errorconn:
++ /* Could not form connection; Free used handlers/memort and retry */
++ if (errmsg)
++ {
++ char buff[180];
++ strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
++ NullS);
++ sql_perror(buff);
++ }
++ if (handle_client_file_map)
++ CloseHandle(handle_client_file_map);
++ if (handle_client_map)
++ UnmapViewOfFile(handle_client_map);
++ if (event_server_wrote)
++ CloseHandle(event_server_wrote);
++ if (event_server_read)
++ CloseHandle(event_server_read);
++ if (event_client_wrote)
++ CloseHandle(event_client_wrote);
++ if (event_client_read)
++ CloseHandle(event_client_read);
++ if (event_conn_closed)
++ CloseHandle(event_conn_closed);
++ delete thd;
++ }
++
++ /* End shared memory handling */
++error:
++ if (tmp)
++ my_free(tmp, MYF(0));
++
++ if (errmsg)
++ {
++ char buff[180];
++ strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
++ sql_perror(buff);
++ }
++ my_security_attr_free(sa_event);
++ my_security_attr_free(sa_mapping);
++ if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
++ if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
++ if (event_connect_answer) CloseHandle(event_connect_answer);
++ if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
++ DBUG_LEAVE;
++ decrement_handler_count();
++ return 0;
++}
++#endif /* HAVE_SMEM */
++#endif /* EMBEDDED_LIBRARY */
++
++
++/****************************************************************************
++ Handle start options
++******************************************************************************/
++
++enum options_mysqld
++{
++ OPT_ISAM_LOG=256, OPT_SKIP_NEW,
++ OPT_SKIP_GRANT, OPT_SKIP_LOCK,
++ OPT_ENABLE_LOCK, OPT_USE_LOCKING,
++ OPT_SOCKET, OPT_UPDATE_LOG,
++ OPT_BIN_LOG, OPT_SKIP_RESOLVE,
++ OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
++ OPT_BIND_ADDRESS, OPT_PID_FILE,
++ OPT_SKIP_PRIOR, OPT_BIG_TABLES,
++ OPT_STANDALONE, OPT_ONE_THREAD,
++ OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
++ OPT_SKIP_HOST_CACHE, OPT_SHORT_LOG_FORMAT,
++ OPT_FLUSH, OPT_SAFE,
++ OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
++ OPT_STORAGE_ENGINE, OPT_INIT_FILE,
++ OPT_DELAY_KEY_WRITE_ALL, OPT_SLOW_QUERY_LOG,
++ OPT_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
++ OPT_MASTER_HOST, OPT_MASTER_USER,
++ OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
++ OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
++ OPT_MASTER_RETRY_COUNT, OPT_LOG_TC, OPT_LOG_TC_SIZE,
++ OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
++ OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CAPATH,
++ OPT_MASTER_SSL_CIPHER, OPT_MASTER_SSL_CA,
++ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
++ OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
++ OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
++ OPT_BINLOG_FORMAT,
++#ifndef DBUG_OFF
++ OPT_BINLOG_SHOW_XID,
++#endif
++ OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
++ OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
++ OPT_MEMLOCK, OPT_MYISAM_RECOVER,
++ OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
++ OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB,
++ OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
++ OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
++ OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
++ OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
++ OPT_ABORT_SLAVE_EVENT_COUNT,
++ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
++ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
++ OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
++ OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
++ OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
++ OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
++ OPT_NDB_MGMD, OPT_NDB_NODEID,
++ OPT_NDB_DISTRIBUTION,
++ OPT_NDB_INDEX_STAT_ENABLE,
++ OPT_NDB_EXTRA_LOGGING,
++ OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
++ OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
++ OPT_NDB_USE_COPYING_ALTER_TABLE,
++ OPT_SKIP_SAFEMALLOC,
++ OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
++ OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
++ OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
++ OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
++ OPT_HAVE_NAMED_PIPE,
++ OPT_DO_PSTACK, OPT_EVENT_SCHEDULER, OPT_REPORT_HOST,
++ OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
++ OPT_SHOW_SLAVE_AUTH_INFO,
++ OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
++ OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
++ OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
++ OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
++ OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
++ OPT_SSL_CAPATH, OPT_SSL_CIPHER,
++ OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
++ OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
++ OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
++ OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
++ OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
++ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
++ OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
++ OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
++ OPT_LONG_QUERY_TIME,
++ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
++ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
++ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
++ OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
++ OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
++ OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
++ OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
++ OPT_MAX_LENGTH_FOR_SORT_DATA,
++ OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
++ OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
++ OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
++ OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
++ OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
++ OPT_MYISAM_MMAP_SIZE,
++ OPT_MYISAM_STATS_METHOD,
++ OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
++ OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
++ OPT_OPEN_FILES_LIMIT,
++ OPT_PRELOAD_BUFFER_SIZE,
++ OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
++ OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
++ OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
++ OPT_RELAY_LOG_PURGE,
++ OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
++ OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
++ OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
++ OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
++ OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
++ OPT_WAIT_TIMEOUT,
++ OPT_ERROR_LOG_FILE,
++ OPT_DEFAULT_WEEK_FORMAT,
++ OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
++ OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
++ OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
++ OPT_SYNC_FRM, OPT_SYNC_BINLOG,
++ OPT_SYNC_REPLICATION,
++ OPT_SYNC_REPLICATION_SLAVE_ID,
++ OPT_SYNC_REPLICATION_TIMEOUT,
++ OPT_ENABLE_SHARED_MEMORY,
++ OPT_SHARED_MEMORY_BASE_NAME,
++ OPT_OLD_PASSWORDS,
++ OPT_OLD_ALTER_TABLE,
++ OPT_EXPIRE_LOGS_DAYS,
++ OPT_GROUP_CONCAT_MAX_LEN,
++ OPT_DEFAULT_COLLATION,
++ OPT_DEFAULT_COLLATION_OLD,
++ OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
++ OPT_CHARACTER_SET_FILESYSTEM,
++ OPT_LC_TIME_NAMES,
++ OPT_INIT_CONNECT,
++ OPT_INIT_SLAVE,
++ OPT_SECURE_AUTH,
++ OPT_DATE_FORMAT,
++ OPT_TIME_FORMAT,
++ OPT_DATETIME_FORMAT,
++ OPT_LOG_QUERIES_NOT_USING_INDEXES,
++ OPT_DEFAULT_TIME_ZONE,
++ OPT_SYSDATE_IS_NOW,
++ OPT_OPTIMIZER_SEARCH_DEPTH,
++ OPT_OPTIMIZER_PRUNE_LEVEL,
++ OPT_OPTIMIZER_SWITCH,
++ OPT_UPDATABLE_VIEWS_WITH_LIMIT,
++ OPT_SP_AUTOMATIC_PRIVILEGES,
++ OPT_MAX_SP_RECURSION_DEPTH,
++ OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
++ OPT_ENABLE_LARGE_PAGES,
++ OPT_TIMED_MUTEXES,
++ OPT_OLD_STYLE_USER_LIMITS,
++ OPT_LOG_SLOW_ADMIN_STATEMENTS,
++ OPT_TABLE_LOCK_WAIT_TIMEOUT,
++ OPT_PLUGIN_LOAD,
++ OPT_PLUGIN_DIR,
++ OPT_SYMBOLIC_LINKS,
++ OPT_WARNINGS,
++ OPT_RECORD_BUFFER_OLD,
++ OPT_LOG_OUTPUT,
++ OPT_PORT_OPEN_TIMEOUT,
++ OPT_PROFILING,
++ OPT_KEEP_FILES_ON_CREATE,
++ OPT_GENERAL_LOG,
++ OPT_SLOW_LOG,
++ OPT_THREAD_HANDLING,
++ OPT_INNODB_ROLLBACK_ON_TIMEOUT,
++ OPT_SECURE_FILE_PRIV,
++ OPT_MIN_EXAMINED_ROW_LIMIT,
++ OPT_LOG_SLOW_SLAVE_STATEMENTS,
++#if defined(ENABLED_DEBUG_SYNC)
++ OPT_DEBUG_SYNC_TIMEOUT,
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++ OPT_OLD_MODE,
++ OPT_SLAVE_EXEC_MODE,
++ OPT_GENERAL_LOG_FILE,
++ OPT_SLOW_QUERY_LOG_FILE,
++ OPT_IGNORE_BUILTIN_INNODB,
++ OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
++ OPT_DEFAULT_CHARACTER_SET_OLD,
++ OPT_MAX_LONG_DATA_SIZE
++};
++
++
++#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
++
++struct my_option my_long_options[] =
++{
++ {"help", '?', "Display this help and exit.",
++ &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
++ 0, 0},
++#ifdef HAVE_REPLICATION
++ {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
++ "Option used by mysql-test for debugging and testing of replication.",
++ &abort_slave_event_count, &abort_slave_event_count,
++ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#endif /* HAVE_REPLICATION */
++ {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
++ "Allows use of UDFs consisting of only one symbol xxx() "
++ "without corresponding xxx_init() or xxx_deinit(). That also means "
++ "that one can load any function from any library, for example exit() "
++ "from libc.so",
++ &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
++ "will also set transaction isolation level 'serializable'.", 0, 0, 0,
++ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"auto-increment-increment", OPT_AUTO_INCREMENT,
++ "Auto-increment columns are incremented by this.",
++ &global_system_variables.auto_increment_increment,
++ &max_system_variables.auto_increment_increment, 0, GET_ULONG,
++ OPT_ARG, 1, 1, 65535, 0, 1, 0 },
++ {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
++ "Offset added to Auto-increment columns. Used when auto-increment-increment != 1.",
++ &global_system_variables.auto_increment_offset,
++ &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
++ 1, 1, 65535, 0, 1, 0 },
++ {"automatic-sp-privileges", OPT_SP_AUTOMATIC_PRIVILEGES,
++ "Creating and dropping stored procedures alters ACLs. Disable with --skip-automatic-sp-privileges.",
++ &sp_automatic_privileges, &sp_automatic_privileges,
++ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
++ {"basedir", 'b',
++ "Path to installation directory. All paths are usually resolved relative to this.",
++ &mysql_home_ptr, &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"big-tables", OPT_BIG_TABLES,
++ "Allow big result sets by saving all temporary sets on file (solves most 'table full' errors).",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
++ &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"binlog_format", OPT_BINLOG_FORMAT,
++ "Does not have any effect without '--log-bin'. "
++ "Tell the master the form of binary logging to use: either 'row' for "
++ "row-based binary logging, 'statement' for statement-based binary "
++ "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
++ "for statements where only row-based is correct: Statements that involve "
++ "user-defined functions (i.e., UDFs) or the UUID() function."
++#ifdef HAVE_NDB_BINLOG
++ "If ndbcluster is enabled and binlog_format is `mixed', the format switches"
++ " to 'row' and back implicitly per each query accessing a NDB table."
++#endif
++ , &opt_binlog_format, &opt_binlog_format,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"binlog-do-db", OPT_BINLOG_DO_DB,
++ "Tells the master it should log updates for the specified database, "
++ "and exclude all others not explicitly mentioned.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
++ "Tells the master that updates to the given database should not be logged to the binary log.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
++ "The maximum size of a row-based binary log event in bytes. Rows will be "
++ "grouped into events smaller than this size if possible. "
++ "The value has to be a multiple of 256.",
++ &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
++ 0, GET_ULONG, REQUIRED_ARG,
++ /* def_value */ 1024, /* min_value */ 256, /* max_value */ ULONG_MAX,
++ /* sub_size */ 0, /* block_size */ 256,
++ /* app_type */ 0
++ },
++#ifndef DISABLE_GRANT_OPTIONS
++ {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
++ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
++ "Don't ignore client side character set value sent during handshake.",
++ &opt_character_set_client_handshake,
++ &opt_character_set_client_handshake,
++ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
++ {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
++ "Set the filesystem character set.",
++ &character_set_filesystem_name,
++ &character_set_filesystem_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"character-set-server", 'C', "Set the default character set.",
++ &default_character_set_name, &default_character_set_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"character-sets-dir", OPT_CHARSETS_DIR,
++ "Directory where character sets are.", &charsets_dir,
++ &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"chroot", 'r', "Chroot mysqld daemon during startup.",
++ &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
++ &default_collation_name, &default_collation_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
++ &global_system_variables.completion_type,
++ &max_system_variables.completion_type, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
++ {"concurrent-insert", OPT_CONCURRENT_INSERT,
++ "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0.",
++ &myisam_concurrent_insert, &myisam_concurrent_insert,
++ 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
++ {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
++ &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
++ 0, 0, 0},
++ {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"datadir", 'h', "Path to the database root.", &mysql_data_home,
++ &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef DBUG_OFF
++ {"debug", '#', "Debug log.", &default_dbug_option,
++ &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
++ "Set the default character set (deprecated option, use --character-set-server instead).",
++ &default_character_set_name, &default_character_set_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation "
++ "(deprecated option, use --collation-server instead).",
++ &default_collation_name, &default_collation_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"default-storage-engine", OPT_STORAGE_ENGINE,
++ "Set the default storage engine (table type) for tables.",
++ &default_storage_engine_str, &default_storage_engine_str,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"default-table-type", OPT_STORAGE_ENGINE,
++ "(deprecated) Use --default-storage-engine.",
++ &default_storage_engine_str, &default_storage_engine_str,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
++ &default_tz_name, &default_tz_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
++ 0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
++ "Don't flush key buffers between writes for any MyISAM table. "
++ "(Deprecated option, use --delay-key-write=all instead.)",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_OPENSSL
++ {"des-key-file", OPT_DES_KEY_FILE,
++ "Load keys for des_encrypt() and des_encrypt from given file.",
++ &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++#endif /* HAVE_OPENSSL */
++#ifdef HAVE_REPLICATION
++ {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
++ "Option used by mysql-test for debugging and testing of replication.",
++ &disconnect_slave_event_count, &disconnect_slave_event_count,
++ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#endif /* HAVE_REPLICATION */
++ {"enable-locking", OPT_ENABLE_LOCK,
++ "Deprecated option, use --external-locking instead.",
++ &opt_external_locking, &opt_external_locking,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef __NT__
++ {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT).",
++ &opt_enable_named_pipe, &opt_enable_named_pipe, 0, GET_BOOL,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++#ifdef HAVE_STACK_TRACE_ON_SEGV
++ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
++ "This option is deprecated and has no effect; a symbolic stack trace will "
++ "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif /* HAVE_STACK_TRACE_ON_SEGV */
++ {"engine-condition-pushdown",
++ OPT_ENGINE_CONDITION_PUSHDOWN,
++ "Push supported query conditions to the storage engine.",
++ &global_system_variables.engine_condition_pushdown,
++ &global_system_variables.engine_condition_pushdown,
++ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
++ /* See how it's handled in get_one_option() */
++ {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.",
++ NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0,
++ GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"external-locking", OPT_USE_LOCKING, "Use system (external) locking "
++ "(disabled by default). With this option enabled you can run myisamchk "
++ "to test (not repair) tables while the MySQL server is running. "
++ "Disable with --skip-external-locking.",
++ &opt_external_locking, &opt_external_locking,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
++ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ /* We must always support the next option to make scripts like mysqltest
++ easier to do */
++ {"gdb", OPT_DEBUGGING,
++ "Set up signals usable for debugging.",
++ &opt_debugging, &opt_debugging,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"general_log", OPT_GENERAL_LOG,
++ "Enable/disable general log.", &opt_log,
++ &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_LARGE_PAGES
++ {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. "
++ "Disable with --skip-large-pages.", &opt_large_pages, &opt_large_pages,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
++ "Disable initialization of builtin InnoDB plugin.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"init-connect", OPT_INIT_CONNECT,
++ "Command(s) that are executed for each new connection.",
++ &opt_init_connect, &opt_init_connect, 0, GET_STR_ALLOC,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef DISABLE_GRANT_OPTIONS
++ {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
++ &opt_init_file, &opt_init_file, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++#endif
++ {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
++each time the SQL thread starts.",
++ &opt_init_slave, &opt_init_slave, 0, GET_STR_ALLOC,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"language", 'L',
++ "Client error messages in given language. May be given as a full path.",
++ &language_ptr, &language_ptr, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"lc-time-names", OPT_LC_TIME_NAMES,
++ "Set the language used for the month names and the days of the week.",
++ &lc_time_names_name, &lc_time_names_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
++ {"local-infile", OPT_LOCAL_INFILE,
++ "Enable/disable LOAD DATA LOCAL INFILE (takes values 1 or 0).",
++ &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG,
++ 1, 0, 0, 0, 0, 0},
++ {"log", 'l', "Log connections and queries to file (deprecated option, use "
++ "--general_log/--general_log_file instead).", &opt_logname,
++ &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"general_log_file", OPT_GENERAL_LOG_FILE,
++ "Log connections and queries to given file.", &opt_logname,
++ &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-bin", OPT_BIN_LOG,
++ "Log update queries in binary format. Optional (but strongly recommended "
++ "to avoid replication problems if server's hostname changes) argument "
++ "should be the chosen location for the binary log files.",
++ &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC,
++ OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-bin-index", OPT_BIN_LOG_INDEX,
++ "File that holds the names for last binary log files.",
++ &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
++ /*
++ In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
++ log-bin-trust-function-creators but kept also the old name for
++ compatibility; the behaviour was also changed to apply only to functions
++ (and triggers). In a future release this old name could be removed.
++ */
++ {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
++ "(deprecated) Use log-bin-trust-function-creators.",
++ &trust_function_creators, &trust_function_creators, 0,
++ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ /*
++ This option starts with "log-bin" to emphasize that it is specific of
++ binary logging.
++ */
++ {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
++ "If equal to 0 (the default), then when --log-bin is used, creation of "
++ "a stored function (or trigger) is allowed only to users having the SUPER "
++ "privilege, and only if this stored function (trigger) may not break "
++ "binary logging."
++ "Note that if ALL connections to this server ALWAYS use row-based binary "
++ "logging, the security issues do not exist and the binary logging cannot "
++ "break, so you can safely set this to 1."
++ ,&trust_function_creators, &trust_function_creators, 0,
++ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
++ &log_error_file_ptr, &log_error_file_ptr, 0, GET_STR,
++ OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
++ &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
++ OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-long-format", '0',
++ "Log some extra information to update log. Please note that this option "
++ "is deprecated; see --log-short-format option.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef WITH_CSV_STORAGE_ENGINE
++ {"log-output", OPT_LOG_OUTPUT,
++ "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
++ "FILE or NONE.",
++ &log_output_str, &log_output_str, 0,
++ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
++ "Log queries that are executed without benefit of any index to the slow log if it is open.",
++ &opt_log_queries_not_using_indexes, &opt_log_queries_not_using_indexes,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-short-format", OPT_SHORT_LOG_FORMAT,
++ "Don't log extra information to update and slow-query logs.",
++ &opt_short_log_format, &opt_short_log_format,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
++ "Tells the slave to log the updates from the slave thread to the binary log. "
++ "You will need to turn it on if you plan to daisy-chain the slaves.",
++ &opt_log_slave_updates, &opt_log_slave_updates, 0, GET_BOOL,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
++ "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements "
++ "to the slow log if it is open.", &opt_log_slow_admin_statements,
++ &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
++ "Log slow statements executed by slave thread to the slow log if it is open.",
++ &opt_log_slow_slave_statements,
++ &opt_log_slow_slave_statements,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"log_slow_queries", OPT_SLOW_QUERY_LOG,
++ "Log slow queries to a table or log file. Defaults logging to table "
++ "mysql.slow_log or hostname-slow.log if --log-output=file is used. "
++ "Must be enabled to activate other slow log options. "
++ "(deprecated option, use --slow_query_log/--slow_query_log_file instead)",
++ &opt_slow_logname, &opt_slow_logname, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE,
++ "Log slow queries to given log file. Defaults logging to hostname-slow.log. "
++ "Must be enabled to activate other slow log options.",
++ &opt_slow_logname, &opt_slow_logname, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-tc", OPT_LOG_TC,
++ "Path to transaction coordinator log (used for transactions that affect "
++ "more than one storage engine, when binary log is disabled).",
++ &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_MMAP
++ {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
++ &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
++ REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
++ TC_LOG_PAGE_SIZE, 0},
++#endif
++ {"log-update", OPT_UPDATE_LOG,
++ "The update log is deprecated since version 5.0, is replaced by the binary "
++ "log and this option just turns on --log-bin instead.",
++ &opt_update_logname, &opt_update_logname, 0, GET_STR,
++ OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"log-warnings", 'W', "Log some not critical warnings to the log file.",
++ &global_system_variables.log_warnings,
++ &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
++ 0, 0, 0},
++ {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
++ "INSERT/DELETE/UPDATE has lower priority than selects.",
++ &global_system_variables.low_priority_updates,
++ &max_system_variables.low_priority_updates,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
++ "The number of seconds the slave thread will sleep before retrying to "
++ "connect to the master, in case the master goes down or the connection "
++ "is lost.",
++ &master_connect_retry, &master_connect_retry, 0, GET_UINT,
++ REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
++ {"master-host", OPT_MASTER_HOST,
++ "Master hostname or IP address for replication. If not set, the slave "
++ "thread will not be started. Note that the setting of master-host will "
++ "be ignored if there exists a valid master.info file.",
++ &master_host, &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
++ 0, 0, 0, 0},
++ {"master-info-file", OPT_MASTER_INFO_FILE,
++ "The location and name of the file that remembers the master and where "
++ "the I/O replication thread is in the master's binlogs.",
++ &master_info_file, &master_info_file, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"master-password", OPT_MASTER_PASSWORD,
++ "The password the slave thread will authenticate with when connecting to "
++ "the master. If not set, an empty password is assumed. The value in "
++ "master.info will take precedence if it can be read.",
++ &master_password, &master_password, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"master-port", OPT_MASTER_PORT,
++ "The port the master is listening on. If not set, the compiled setting of "
++ "MYSQL_PORT is assumed. If you have not tinkered with configure options, "
++ "this should be 3306. The value in master.info will take precedence if it "
++ "can be read.", &master_port, &master_port, 0, GET_UINT, REQUIRED_ARG,
++ MYSQL_PORT, 0, 0, 0, 0, 0},
++ {"master-retry-count", OPT_MASTER_RETRY_COUNT,
++ "The number of tries the slave will make to connect to the master before giving up.",
++ &master_retry_count, &master_retry_count, 0, GET_ULONG,
++ REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
++ {"master-ssl", OPT_MASTER_SSL,
++ "Enable the slave to connect to the master using SSL.",
++ &master_ssl, &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
++ 0, 0},
++ {"master-ssl-ca", OPT_MASTER_SSL_CA,
++ "Master SSL CA file. Only applies if you have enabled master-ssl.",
++ &master_ssl_ca, &master_ssl_ca, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"master-ssl-capath", OPT_MASTER_SSL_CAPATH,
++ "Master SSL CA path. Only applies if you have enabled master-ssl.",
++ &master_ssl_capath, &master_ssl_capath, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"master-ssl-cert", OPT_MASTER_SSL_CERT,
++ "Master SSL certificate file name. Only applies if you have enabled "
++ "master-ssl.",
++ &master_ssl_cert, &master_ssl_cert, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER,
++ "Master SSL cipher. Only applies if you have enabled master-ssl.",
++ &master_ssl_cipher, &master_ssl_capath, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"master-ssl-key", OPT_MASTER_SSL_KEY,
++ "Master SSL keyfile name. Only applies if you have enabled master-ssl.",
++ &master_ssl_key, &master_ssl_key, 0, GET_STR, OPT_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"master-user", OPT_MASTER_USER,
++ "The username the slave thread will use for authentication when "
++ "connecting to the master. The user must have FILE privilege. "
++ "If the master user is not set, user test is assumed. The value "
++ "in master.info will take precedence if it can be read.",
++ &master_user, &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
++ 0, 0, 0, 0},
++#ifdef HAVE_REPLICATION
++ {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
++ "Option used by mysql-test for debugging and testing of replication.",
++ &max_binlog_dump_events, &max_binlog_dump_events, 0,
++ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#endif /* HAVE_REPLICATION */
++ {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", &locked_in_memory,
++ &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"myisam-recover", OPT_MYISAM_RECOVER,
++ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
++ &myisam_recover_options_str, &myisam_recover_options_str, 0,
++ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++ {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
++ "Connect string for ndbcluster.",
++ &opt_ndb_connectstring, &opt_ndb_connectstring,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"ndb-mgmd-host", OPT_NDB_MGMD,
++ "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
++ &opt_ndb_mgmd, &opt_ndb_mgmd,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"ndb-nodeid", OPT_NDB_NODEID,
++ "Nodeid for this mysqlserver in the cluster.",
++ &opt_ndb_nodeid,
++ &opt_ndb_nodeid,
++ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
++ "Specify number of autoincrement values that are prefetched.",
++ &global_system_variables.ndb_autoincrement_prefetch_sz,
++ &max_system_variables.ndb_autoincrement_prefetch_sz,
++ 0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
++ {"ndb-force-send", OPT_NDB_FORCE_SEND,
++ "Force send of buffers to ndb immediately without waiting for "
++ "other threads.",
++ &global_system_variables.ndb_force_send,
++ &global_system_variables.ndb_force_send,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb_force_send", OPT_NDB_FORCE_SEND,
++ "same as --ndb-force-send.",
++ &global_system_variables.ndb_force_send,
++ &global_system_variables.ndb_force_send,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb-extra-logging", OPT_NDB_EXTRA_LOGGING,
++ "Turn on more logging in the error log.",
++ &ndb_extra_logging,
++ &ndb_extra_logging,
++ 0, GET_INT, OPT_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_NDB_BINLOG
++ {"ndb-report-thresh-binlog-epoch-slip", OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
++ "Threshold on number of epochs to be behind before reporting binlog status. "
++ "E.g., 3 means that if the difference between what epoch has been received "
++ "from the storage nodes and what has been applied to the binlog is 3 or more, "
++ "a status message will be sent to the cluster log.",
++ &ndb_report_thresh_binlog_epoch_slip,
++ &ndb_report_thresh_binlog_epoch_slip,
++ 0, GET_ULONG, REQUIRED_ARG, 3, 0, 256, 0, 0, 0},
++ {"ndb-report-thresh-binlog-mem-usage", OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
++ "Threshold on percentage of free memory before reporting binlog status. E.g., "
++ "10 means that if amount of available memory for receiving binlog data from "
++ "the storage nodes goes below 10%, "
++ "a status message will be sent to the cluster log.",
++ &ndb_report_thresh_binlog_mem_usage,
++ &ndb_report_thresh_binlog_mem_usage,
++ 0, GET_ULONG, REQUIRED_ARG, 10, 0, 100, 0, 0, 0},
++#endif
++ {"ndb-use-exact-count", OPT_NDB_USE_EXACT_COUNT,
++ "Use exact records count during query planning and for fast "
++ "select count(*), disable for faster queries.",
++ &global_system_variables.ndb_use_exact_count,
++ &global_system_variables.ndb_use_exact_count,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
++ "Same as --ndb-use-exact-count.",
++ &global_system_variables.ndb_use_exact_count,
++ &global_system_variables.ndb_use_exact_count,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
++ "Use transactions for large inserts, if enabled then large "
++ "inserts will be split into several smaller transactions",
++ &global_system_variables.ndb_use_transactions,
++ &global_system_variables.ndb_use_transactions,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
++ "Same as --ndb-use-transactions.",
++ &global_system_variables.ndb_use_transactions,
++ &global_system_variables.ndb_use_transactions,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ {"ndb-shm", OPT_NDB_SHM,
++ "Use shared memory connections when available.",
++ &opt_ndb_shm, &opt_ndb_shm,
++ 0, GET_BOOL, OPT_ARG, OPT_NDB_SHM_DEFAULT, 0, 0, 0, 0, 0},
++ {"ndb-optimized-node-selection", OPT_NDB_OPTIMIZED_NODE_SELECTION,
++ "Select nodes for transactions in a more optimal way.",
++ &opt_ndb_optimized_node_selection,
++ &opt_ndb_optimized_node_selection,
++ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
++ { "ndb-cache-check-time", OPT_NDB_CACHE_CHECK_TIME,
++ "A dedicated thread is created to, at the given milliseconds interval, "
++ "invalidate the query cache if another MySQL server in the cluster has "
++ "changed the data in the database.",
++ &opt_ndb_cache_check_time, &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
++ 0, 0, LONG_TIMEOUT, 0, 1, 0},
++ {"ndb-index-stat-enable", OPT_NDB_INDEX_STAT_ENABLE,
++ "Use ndb index statistics in query optimization.",
++ &global_system_variables.ndb_index_stat_enable,
++ &max_system_variables.ndb_index_stat_enable,
++ 0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 0, 0},
++#endif
++ {"ndb-use-copying-alter-table",
++ OPT_NDB_USE_COPYING_ALTER_TABLE,
++ "Force ndbcluster to always copy tables at alter table "
++ "(should only be used if on-line alter table fails).",
++ &global_system_variables.ndb_use_copying_alter_table,
++ &global_system_variables.ndb_use_copying_alter_table,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"new", 'n', "Use very new, possibly 'unsafe', functions.",
++ &global_system_variables.new_mode,
++ &max_system_variables.new_mode,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef NOT_YET
++ {"no-mix-table-types", OPT_NO_MIX_TYPE,
++ "Don't allow commands that use two different table types.",
++ &opt_no_mix_types, &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++#endif
++ {"old-alter-table", OPT_OLD_ALTER_TABLE,
++ "Use old, non-optimized alter table.",
++ &global_system_variables.old_alter_table,
++ &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"old-passwords", OPT_OLD_PASSWORDS, "Use old password "
++ "encryption method (needed for 4.0 and older clients).",
++ &global_system_variables.old_passwords,
++ &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"one-thread", OPT_ONE_THREAD,
++ "(Deprecated): Only use one thread (for debugging under Linux). Use "
++ "thread-handling=no-threads instead.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
++ "Enable old-style user limits (before 5.0.3, user resources were counted "
++ "per each user+host vs. per account).",
++ &opt_old_style_user_limits, &opt_old_style_user_limits,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
++ &pidfile_name_ptr, &pidfile_name_ptr, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"port", 'P', "Port number to use for connection or 0 for default to, in "
++ "order of preference, my.cnf, $MYSQL_TCP_PORT, "
++#if MYSQL_PORT_DEFAULT == 0
++ "/etc/services, "
++#endif
++ "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
++ &mysqld_port,
++ &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
++ "Maximum time in seconds to wait for the port to become free. "
++ "(Default: No wait).", &mysqld_port_timeout,
++ &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory.",
++ &global_system_variables.profiling_history_size,
++ &max_system_variables.profiling_history_size,
++ 0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
++#endif
++ {"relay-log", OPT_RELAY_LOG,
++ "The location and name to use for relay logs.",
++ &opt_relay_logname, &opt_relay_logname, 0,
++ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"relay-log-index", OPT_RELAY_LOG_INDEX,
++ "The location and name to use for the file that keeps a list of the last \
++relay logs.",
++ &opt_relaylog_index_name, &opt_relaylog_index_name, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
++ "The location and name of the file that remembers where the SQL replication \
++thread is in the relay logs.",
++ &relay_log_info_file, &relay_log_info_file, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-do-db", OPT_REPLICATE_DO_DB,
++ "Tells the slave thread to restrict replication to the specified database. "
++ "To specify more than one database, use the directive multiple times, "
++ "once for each database. Note that this will only work if you do not use "
++ "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
++ "while having selected a different or no database. If you need cross "
++ "database updates to work, make sure you have 3.23.28 or later, and use "
++ "replicate-wild-do-table=db_name.%.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
++ "Tells the slave thread to restrict replication to the specified table. "
++ "To specify more than one table, use the directive multiple times, once "
++ "for each table. This will work for cross-database updates, in contrast "
++ "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
++ "Tells the slave thread to not replicate to the specified database. To "
++ "specify more than one database to ignore, use the directive multiple "
++ "times, once for each database. This option will not work if you use "
++ "cross database updates. If you need cross database updates to work, "
++ "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
++ "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
++ "Tells the slave thread to not replicate to the specified table. To specify "
++ "more than one table to ignore, use the directive multiple times, once for "
++ "each table. This will work for cross-database updates, in contrast to "
++ "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
++ "Updates to a database with a different name than the original. Example: "
++ "replicate-rewrite-db=master_db_name->slave_db_name.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_REPLICATION
++ {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
++ "In replication, if set to 1, do not skip events having our server id. "
++ "Default value is 0 (to break infinite loops in circular replication). "
++ "Can't be set to 1 if --log-slave-updates is used.",
++ &replicate_same_server_id, &replicate_same_server_id,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
++ "Tells the slave thread to restrict replication to the tables that match "
++ "the specified wildcard pattern. To specify more than one table, use the "
++ "directive multiple times, once for each table. This will work for cross-"
++ "database updates. Example: replicate-wild-do-table=foo%.bar% will "
++ "replicate only updates to tables in all databases that start with foo "
++ "and whose table names start with bar.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
++ "Tells the slave thread to not replicate to the tables that match the "
++ "given wildcard pattern. To specify more than one table to ignore, use "
++ "the directive multiple times, once for each table. This will work for "
++ "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
++ "will not do updates to tables in databases that start with foo and whose "
++ "table names start with bar.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ // In replication, we may need to tell the other servers how to connect
++ {"report-host", OPT_REPORT_HOST,
++ "Hostname or IP of the slave to be reported to the master during slave "
++ "registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset "
++ "if you do not want the slave to register itself with the master. Note that "
++ "it is not sufficient for the master to simply read the IP of the slave "
++ "from the socket once the slave connects. Due to NAT and other routing "
++ "issues, that IP may not be valid for connecting to the slave from the "
++ "master or other hosts.",
++ &report_host, &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
++ 0, 0, 0, 0},
++ {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
++ &report_password, &report_password, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"report-port", OPT_REPORT_PORT,
++ "Port for connecting to slave reported to the master during slave "
++ "registration. Set it only if the slave is listening on a non-default "
++ "port or if you have a special tunnel from the master or other clients "
++ "to the slave. If not sure, leave this option unset.",
++ &report_port, &report_port, 0, GET_UINT, REQUIRED_ARG,
++ MYSQL_PORT, 0, 0, 0, 0, 0},
++ {"report-user", OPT_REPORT_USER, "Undocumented.", &report_user,
++ &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.",
++ &rpl_recovery_rank, &rpl_recovery_rank, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef TO_BE_DELETED
++ {"safe-show-database", OPT_SAFE_SHOW_DB,
++ "Deprecated option; use GRANT SHOW DATABASES instead.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"safe-user-create", OPT_SAFE_USER_CREATE,
++ "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
++ &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
++ "Simulate memory shortage when compiled with the --with-debug=full option.",
++ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
++ &opt_secure_auth, &opt_secure_auth, 0, GET_BOOL, NO_ARG,
++ my_bool(0), 0, 0, 0, 0, 0},
++ {"secure-file-priv", OPT_SECURE_FILE_PRIV,
++ "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory.",
++ &opt_secure_file_priv, &opt_secure_file_priv, 0,
++ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"server-id", OPT_SERVER_ID,
++ "Uniquely identifies the server instance in the community of replication partners.",
++ &server_id, &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX32,
++ 0, 0, 0},
++ {"set-variable", 'O',
++ "Change the value of a variable. Please note that this option is deprecated; "
++ "you can set variables directly with --variable-name=value.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_SMEM
++ {"shared-memory", OPT_ENABLE_SHARED_MEMORY,
++ "Enable the shared memory.",&opt_enable_shared_memory, &opt_enable_shared_memory,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++#ifdef HAVE_SMEM
++ {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
++ "Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
++ "Show user and password in SHOW SLAVE HOSTS on this master.",
++ &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
++ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef DISABLE_GRANT_OPTIONS
++ {"skip-grant-tables", OPT_SKIP_GRANT,
++ "Start without grant tables. This gives all users FULL ACCESS to all tables.",
++ &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
++ 0},
++#endif
++ {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
++ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"skip-locking", OPT_SKIP_LOCK,
++ "Deprecated option, use --skip-external-locking instead.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"skip-name-resolve", OPT_SKIP_RESOLVE,
++ "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"skip-networking", OPT_SKIP_NETWORKING,
++ "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
++ 0, 0, 0},
++ {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++#ifndef DBUG_OFF
++#ifdef SAFEMALLOC
++ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
++ "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++#endif
++#endif
++ {"skip-show-database", OPT_SKIP_SHOW_DB,
++ "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
++ 0, 0, 0, 0},
++ {"skip-slave-start", OPT_SKIP_SLAVE_START,
++ "If set, slave is not autostarted.", &opt_skip_slave_start,
++ &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
++ "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
++ 0, 0, 0, 0},
++ {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. "
++ "Deprecated option. Use --skip-symbolic-links instead.",
++ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"skip-thread-priority", OPT_SKIP_PRIOR,
++ "Don't give threads different priorities. Deprecated option.", 0, 0, 0, GET_NO_ARG, NO_ARG,
++ DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
++#ifdef HAVE_REPLICATION
++ {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
++ "The location where the slave should put its temporary files when "
++ "replicating a LOAD DATA INFILE command.",
++ &slave_load_tmpdir, &slave_load_tmpdir, 0, GET_STR_ALLOC,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
++ "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
++ "Modes for how replication events should be executed. Legal values are "
++ "STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will "
++ "not stop for operations that are idempotent. In STRICT mode, replication "
++ "will stop on any unexpected difference between the master and the slave.",
++ &slave_exec_mode_str, &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"slow-query-log", OPT_SLOW_LOG,
++ "Enable/disable slow query log.", &opt_slow_log,
++ &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"socket", OPT_SOCKET, "Socket file to use for connection.",
++ &mysqld_unix_port, &mysqld_unix_port, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#ifdef HAVE_REPLICATION
++ {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
++ "Option used by mysql-test for debugging and testing of replication.",
++ &opt_sporadic_binlog_dump_fail,
++ &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
++ 0},
++#endif /* HAVE_REPLICATION */
++ {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
++ "The update log is deprecated since version 5.0, is replaced by the "
++ "binary log and this option does nothing anymore.",
++ 0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"sql-mode", OPT_SQL_MODE,
++ "Syntax: sql-mode=option[,option[,option...]] where option can be one "
++ "of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, "
++ "ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
++ &sql_mode_str, &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
++ 0, 0, 0, 0, 0},
++#ifdef HAVE_OPENSSL
++#include "sslopt-longopts.h"
++#endif
++#ifdef __WIN__
++ {"standalone", OPT_STANDALONE,
++ "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++#endif
++ {"symbolic-links", 's', "Enable symbolic link support.",
++ &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
++ /*
++ The system call realpath() produces warnings under valgrind and
++ purify. These are not suppressed: instead we disable symlinks
++ option if compiled with valgrind support.
++ */
++ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
++ {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
++ "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
++ "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
++ "invocations, even within the same statement.",
++ &global_system_variables.sysdate_is_now,
++ 0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
++ {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
++ "Decision to use in heuristic recover process. Possible values are COMMIT "
++ "or ROLLBACK.", &opt_tc_heuristic_recover, &opt_tc_heuristic_recover,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++#if defined(ENABLED_DEBUG_SYNC)
++ {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
++ "Enable the debug sync facility "
++ "and optionally specify a default wait timeout in seconds. "
++ "A zero value keeps the facility disabled.",
++ &opt_debug_sync_timeout, 0,
++ 0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++ {"temp-pool", OPT_TEMP_POOL,
++#if (ENABLE_TEMP_POOL)
++ "Using this option will cause most temporary files created to use a small "
++ "set of names, rather than a unique name for each new file.",
++#else
++ "This option is ignored on this OS.",
++#endif
++ &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
++ 0, 0, 0, 0, 0},
++ {"timed_mutexes", OPT_TIMED_MUTEXES,
++ "Specify whether to time mutexes (only InnoDB mutexes are currently supported).",
++ &timed_mutexes, &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
++ 0, 0, 0, 0, 0},
++ {"tmpdir", 't',
++ "Path for temporary files. Several paths may be specified, separated by a "
++#if defined(__WIN__) || defined(__NETWARE__)
++ "semicolon (;)"
++#else
++ "colon (:)"
++#endif
++ ", in this case they are used in a round-robin fashion.",
++ &opt_mysql_tmpdir, &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"transaction-isolation", OPT_TX_ISOLATION,
++ "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
++ 0, 0, 0, 0, 0},
++ {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. "
++ "Deprecated option; use --symbolic-links instead.",
++ &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
++ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
++ {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"verbose", 'v', "Used with --help option for detailed help.",
++ &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
++ NO_ARG, 0, 0, 0, 0, 0, 0},
++ {"warnings", OPT_WARNINGS, "Deprecated; use --log-warnings instead.",
++ &global_system_variables.log_warnings,
++ &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
++ 1, 0, ULONG_MAX, 0, 0, 0},
++ {"back_log", OPT_BACK_LOG,
++ "The number of outstanding connection requests MySQL can have. This "
++ "comes into play when the main MySQL thread gets very many connection "
++ "requests in a very short time.", &back_log, &back_log, 0, GET_ULONG,
++ REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
++ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
++ "The size of the cache to hold the SQL statements for the binary log "
++ "during a transaction. If you often use big, multi-statement "
++ "transactions you can increase this to get more performance.",
++ &binlog_cache_size, &binlog_cache_size, 0, GET_ULONG,
++ REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
++ {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
++ "Size of tree cache used in bulk insert optimization. Note that this "
++ "is a limit per thread.", &global_system_variables.bulk_insert_buff_size,
++ &max_system_variables.bulk_insert_buff_size,
++ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
++ {"connect_timeout", OPT_CONNECT_TIMEOUT,
++ "The number of seconds the mysqld server is waiting for a connect packet "
++ "before responding with 'Bad handshake'.", &connect_timeout, &connect_timeout,
++ 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
++ { "date_format", OPT_DATE_FORMAT,
++ "The DATE format (for future).",
++ &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
++ &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ { "datetime_format", OPT_DATETIME_FORMAT,
++ "The DATETIME/TIMESTAMP format (for future).",
++ &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
++ &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
++ "The default week format used by WEEK() functions.",
++ &global_system_variables.default_week_format,
++ &max_system_variables.default_week_format,
++ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
++ {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
++ "After inserting delayed_insert_limit rows, the INSERT DELAYED handler "
++ "will check if there are any SELECT statements pending. If so, it allows "
++ "these to execute before continuing.",
++ &delayed_insert_limit, &delayed_insert_limit, 0, GET_ULONG,
++ REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
++ {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
++ "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
++ &delayed_insert_timeout, &delayed_insert_timeout, 0,
++ GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
++ { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
++ "What size queue (in rows) should be allocated for handling INSERT DELAYED. "
++ "If the queue becomes full, any client that does INSERT DELAYED will wait "
++ "until there is room in the queue again.",
++ &delayed_queue_size, &delayed_queue_size, 0, GET_ULONG,
++ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
++ {"div_precision_increment", OPT_DIV_PRECINCREMENT,
++ "Precision of the result of '/' operator will be increased on that value.",
++ &global_system_variables.div_precincrement,
++ &max_system_variables.div_precincrement, 0, GET_ULONG,
++ REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
++ {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
++ "If non-zero, binary logs will be purged after expire_logs_days "
++ "days; possible purges happen at startup and at binary log rotation.",
++ &expire_logs_days, &expire_logs_days, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
++ { "flush_time", OPT_FLUSH_TIME,
++ "A dedicated thread is created to flush all tables at the given interval.",
++ &flush_time, &flush_time, 0, GET_ULONG, REQUIRED_ARG,
++ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
++ { "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
++ "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE).",
++ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
++ "The maximum length of the word to be included in a FULLTEXT index. "
++ "Note: FULLTEXT indexes must be rebuilt after changing this variable.",
++ &ft_max_word_len, &ft_max_word_len, 0, GET_ULONG,
++ REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0},
++ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
++ "The minimum length of the word to be included in a FULLTEXT index. "
++ "Note: FULLTEXT indexes must be rebuilt after changing this variable.",
++ &ft_min_word_len, &ft_min_word_len, 0, GET_ULONG,
++ REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0},
++ { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT,
++ "Number of best matches to use for query expansion.",
++ &ft_query_expansion_limit, &ft_query_expansion_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 20, 0, 1000, 0, 1, 0},
++ { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
++ "Use stopwords from this file instead of built-in list.",
++ &ft_stopword_file, &ft_stopword_file, 0, GET_STR,
++ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
++ "The maximum length of the result of function group_concat.",
++ &global_system_variables.group_concat_max_len,
++ &max_system_variables.group_concat_max_len, 0, GET_ULONG,
++ REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
++ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
++ "The number of seconds the server waits for activity on an interactive "
++ "connection before closing it.",
++ &global_system_variables.net_interactive_timeout,
++ &max_system_variables.net_interactive_timeout, 0,
++ GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
++ {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
++ "The size of the buffer that is used for full joins.",
++ &global_system_variables.join_buff_size,
++ &max_system_variables.join_buff_size, 0, GET_ULONG,
++ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
++ MALLOC_OVERHEAD, IO_SIZE, 0},
++ {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
++ "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
++ &global_system_variables.keep_files_on_create,
++ &max_system_variables.keep_files_on_create,
++ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
++ {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
++ "The size of the buffer used for index blocks for MyISAM tables. Increase "
++ "this to get better index handling (for all reads and multiple writes) to "
++ "as much as you can afford; 1GB on a 4GB machine that mainly runs MySQL is "
++ "quite common.",
++ &dflt_key_cache_var.param_buff_size, NULL, NULL, (GET_ULL | GET_ASK_ADDR),
++ REQUIRED_ARG, KEY_CACHE_SIZE, 0, SIZE_T_MAX, MALLOC_OVERHEAD,
++ IO_SIZE, 0},
++ {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
++ "This characterizes the number of hits a hot block has to be untouched "
++ "until it is considered aged enough to be downgraded to a warm block. "
++ "This specifies the percentage ratio of that number of hits to the total "
++ "number of blocks in key cache.",
++ &dflt_key_cache_var.param_age_threshold, NULL, NULL,
++ (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, ULONG_MAX, 0, 100, 0},
++ {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
++ "The default size of key cache blocks.",
++ &dflt_key_cache_var.param_block_size, NULL, NULL, (GET_ULONG | GET_ASK_ADDR),
++ REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
++ {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
++ "The minimum percentage of warm blocks in key cache.",
++ &dflt_key_cache_var.param_division_limit, NULL, NULL,
++ (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
++ {"long_query_time", OPT_LONG_QUERY_TIME,
++ "Log all queries that have taken more than long_query_time seconds to "
++ "execute. The argument will be treated as a decimal value with "
++ "microsecond precision.",
++ &long_query_time, &long_query_time, 0, GET_DOUBLE,
++ REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
++ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
++ "If set to 1, table names are stored in lowercase on disk and table names "
++ "will be case-insensitive. Should be set to 2 if you are using a case-"
++ "insensitive file system.",
++ &lower_case_table_names, &lower_case_table_names, 0, GET_UINT, OPT_ARG,
++#ifdef FN_NO_CASE_SENCE
++ 1
++#else
++ 0
++#endif
++ , 0, 2, 0, 1, 0},
++ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
++ "The maximum packet length to send to or receive from server.",
++ &global_system_variables.max_allowed_packet,
++ &max_system_variables.max_allowed_packet, 0, GET_ULONG,
++ REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
++ {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
++ "Can be used to restrict the total size used to cache a multi-transaction query.",
++ &max_binlog_cache_size, &max_binlog_cache_size, 0,
++ GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
++ {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
++ "Binary log will be rotated automatically when the size exceeds this "
++ "value. Will also apply to relay logs if max_relay_log_size is 0. "
++ "The minimum value for this variable is 4096.",
++ &max_binlog_size, &max_binlog_size, 0, GET_ULONG,
++ REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
++ {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
++ "If there is more than this number of interrupted connections from a host "
++ "this host will be blocked from further connections.",
++ &max_connect_errors, &max_connect_errors, 0, GET_ULONG,
++ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
++ // Default max_connections of 151 is larger than Apache's default max
++ // children, to avoid "too many connections" error in a common setup
++ {"max_connections", OPT_MAX_CONNECTIONS,
++ "The number of simultaneous clients allowed.", &max_connections,
++ &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1, 0},
++ {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
++ "Don't start more than this number of threads to handle INSERT DELAYED "
++ "statements. If set to zero, which means INSERT DELAYED is not used.",
++ &global_system_variables.max_insert_delayed_threads,
++ &max_system_variables.max_insert_delayed_threads,
++ 0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
++ {"max_error_count", OPT_MAX_ERROR_COUNT,
++ "Max number of errors/warnings to store for a statement.",
++ &global_system_variables.max_error_count,
++ &max_system_variables.max_error_count,
++ 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
++ {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
++ "Don't allow creation of heap tables bigger than this.",
++ &global_system_variables.max_heap_table_size,
++ &max_system_variables.max_heap_table_size, 0, GET_ULL,
++ REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
++ MALLOC_OVERHEAD, 1024, 0},
++ {"max_join_size", OPT_MAX_JOIN_SIZE,
++ "Joins that are probably going to read more than max_join_size records return an error.",
++ &global_system_variables.max_join_size,
++ &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
++ HA_POS_ERROR, 1, HA_POS_ERROR, 0, 1, 0},
++ {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
++ "Max number of bytes in sorted records.",
++ &global_system_variables.max_length_for_sort_data,
++ &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
++ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
++ {"max_long_data_size", OPT_MAX_LONG_DATA_SIZE,
++ "The maximum size of prepared statement parameter which can be provided "
++ "through mysql_send_long_data() API call. "
++ "Deprecated option; use max_allowed_packet instead.",
++ &max_long_data_size,
++ &max_long_data_size, 0, GET_ULONG,
++ REQUIRED_ARG, 1024*1024L, 1024, UINT_MAX32, MALLOC_OVERHEAD, 1, 0},
++ {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
++ "Maximum number of prepared statements in the server.",
++ &max_prepared_stmt_count, &max_prepared_stmt_count,
++ 0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
++ {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
++ "If non-zero: relay log will be rotated automatically when the size "
++ "exceeds this value; if zero (the default): when the size exceeds "
++ "max_binlog_size. 0 excepted, the minimum value for this variable is 4096.",
++ &max_relay_log_size, &max_relay_log_size, 0, GET_ULONG,
++ REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
++ { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
++ "Limit assumed max number of seeks when looking up rows based on a key.",
++ &global_system_variables.max_seeks_for_key,
++ &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
++ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
++ {"max_sort_length", OPT_MAX_SORT_LENGTH,
++ "The number of bytes to use when sorting BLOB or TEXT values (only the "
++ "first max_sort_length bytes of each value are used; the rest are ignored).",
++ &global_system_variables.max_sort_length,
++ &max_system_variables.max_sort_length, 0, GET_ULONG,
++ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
++ {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
++ "Maximum stored procedure recursion depth. (discussed with docs).",
++ &global_system_variables.max_sp_recursion_depth,
++ &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
++ OPT_ARG, 0, 0, 255, 0, 1, 0 },
++ {"max_tmp_tables", OPT_MAX_TMP_TABLES,
++ "Maximum number of temporary tables a client can keep open at a time.",
++ &global_system_variables.max_tmp_tables,
++ &max_system_variables.max_tmp_tables, 0, GET_ULONG,
++ REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
++ {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
++ "The maximum number of active connections for a single user (0 = no limit).",
++ &max_user_connections, &max_user_connections, 0, GET_UINT,
++ REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
++ {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
++ "After this many write locks, allow some read locks to run in between.",
++ &max_write_lock_count, &max_write_lock_count, 0, GET_ULONG,
++ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
++ {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
++ "Don't log queries which examine less than min_examined_row_limit rows to file.",
++ &global_system_variables.min_examined_row_limit,
++ &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
++ {"multi_range_count", OPT_MULTI_RANGE_COUNT,
++ "Number of key ranges to request at once.",
++ &global_system_variables.multi_range_count,
++ &max_system_variables.multi_range_count, 0,
++ GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
++ {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
++ "Block size to be used for MyISAM index pages.",
++ &opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
++ MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
++ 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
++ {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
++ "Default pointer size to be used for MyISAM tables.",
++ &myisam_data_pointer_size,
++ &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
++ 6, 2, 7, 0, 1, 0},
++ {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
++ "This is a deprecated option that does nothing anymore. "
++ "It will be removed in MySQL " VER_CELOSIA,
++ &global_system_variables.myisam_max_extra_sort_file_size,
++ &max_system_variables.myisam_max_extra_sort_file_size,
++ 0, GET_ULL, REQUIRED_ARG, (ulonglong) INT_MAX32,
++ 0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
++ {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
++ "Don't use the fast sort index method to created index if the temporary "
++ "file would get bigger than this.",
++ &global_system_variables.myisam_max_sort_file_size,
++ &max_system_variables.myisam_max_sort_file_size, 0,
++ GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
++ 0, 1024*1024, 0},
++ {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE,
++ "Can be used to restrict the total memory used for memory mmaping of myisam files",
++ &myisam_mmap_size, &myisam_mmap_size, 0,
++ GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0},
++ {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
++ "Specifies whether several threads should be used when repairing MyISAM "
++ "tables. For values > 1, one thread is used per index. The value of 1 "
++ "disables parallel repair.",
++ &global_system_variables.myisam_repair_threads,
++ &max_system_variables.myisam_repair_threads, 0,
++ GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
++ {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
++ "The buffer that is allocated when sorting the index when doing a REPAIR "
++ "or when creating indexes with CREATE INDEX or ALTER TABLE.",
++ &global_system_variables.myisam_sort_buff_size,
++ &max_system_variables.myisam_sort_buff_size, 0,
++ GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0},
++ {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
++ "Use memory mapping for reading and writing MyISAM tables.",
++ &opt_myisam_use_mmap, &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
++ "Specifies how MyISAM index statistics collection code should threat NULLs. "
++ "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
++ "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
++ &myisam_stats_method_str, &myisam_stats_method_str, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
++ "Buffer length for TCP/IP and socket communication.",
++ &global_system_variables.net_buffer_length,
++ &max_system_variables.net_buffer_length, 0, GET_ULONG,
++ REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
++ {"net_read_timeout", OPT_NET_READ_TIMEOUT,
++ "Number of seconds to wait for more data from a connection before aborting the read.",
++ &global_system_variables.net_read_timeout,
++ &max_system_variables.net_read_timeout, 0, GET_ULONG,
++ REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
++ {"net_retry_count", OPT_NET_RETRY_COUNT,
++ "If a read on a communication port is interrupted, retry this many times before giving up.",
++ &global_system_variables.net_retry_count,
++ &max_system_variables.net_retry_count,0,
++ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
++ {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
++ "Number of seconds to wait for a block to be written to a connection before "
++ "aborting the write.",
++ &global_system_variables.net_write_timeout,
++ &max_system_variables.net_write_timeout, 0, GET_ULONG,
++ REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
++ { "old", OPT_OLD_MODE, "Use compatible behavior.",
++ &global_system_variables.old_mode,
++ &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG,
++ 0, 0, 0, 0, 0, 0},
++ {"open_files_limit", OPT_OPEN_FILES_LIMIT,
++ "If this is not 0, then mysqld will use this value to reserve file "
++ "descriptors to use with setrlimit(). If this value is 0 then mysqld "
++ "will reserve max_connections*5 or max_connections + table_cache*2 "
++ "(whichever is larger) number of files.",
++ &open_files_limit, &open_files_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
++ {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
++ "Controls the heuristic(s) applied during query optimization to prune "
++ "less-promising partial plans from the optimizer search space. Meaning: "
++ "0 - do not apply any heuristic, thus perform exhaustive search; 1 - "
++ "prune plans based on number of retrieved rows.",
++ &global_system_variables.optimizer_prune_level,
++ &max_system_variables.optimizer_prune_level,
++ 0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
++ {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
++ "Maximum depth of search performed by the query optimizer. Values larger "
++ "than the number of relations in a query result in better query plans, "
++ "but take longer to compile a query. Smaller values than the number of "
++ "tables in a relation result in faster optimization, but may produce "
++ "very bad query plans. If set to 0, the system will automatically pick "
++ "a reasonable value; if set to MAX_TABLES+2, the optimizer will switch "
++ "to the original find_best (used for testing/comparison).",
++ &global_system_variables.optimizer_search_depth,
++ &max_system_variables.optimizer_search_depth,
++ 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
++ {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
++ "optimizer_switch=option=val[,option=val...], where option={index_merge, "
++ "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
++ "val={on, off, default}.",
++ &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
++ /*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0},
++ {"plugin_dir", OPT_PLUGIN_DIR,
++ "Directory for plugins.",
++ &opt_plugin_dir_ptr, &opt_plugin_dir_ptr, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"plugin-load", OPT_PLUGIN_LOAD,
++ "Optional semicolon-separated list of plugins to load, where each plugin is "
++ "identified as name=library, where name is the plugin name and library "
++ "is the plugin library in plugin_dir.",
++ &opt_plugin_load, &opt_plugin_load, 0,
++ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
++ "The size of the buffer that is allocated when preloading indexes.",
++ &global_system_variables.preload_buff_size,
++ &max_system_variables.preload_buff_size, 0, GET_ULONG,
++ REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
++ {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
++ "Allocation block size for query parsing and execution.",
++ &global_system_variables.query_alloc_block_size,
++ &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
++ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
++#ifdef HAVE_QUERY_CACHE
++ {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
++ "Don't cache results that are bigger than this.",
++ &query_cache_limit, &query_cache_limit, 0, GET_ULONG,
++ REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
++ {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
++ "Minimal size of unit in which space for results is allocated (last unit "
++ "will be trimmed after writing all result data).",
++ &query_cache_min_res_unit, &query_cache_min_res_unit,
++ 0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
++ 0, ULONG_MAX, 0, 1, 0},
++#endif /*HAVE_QUERY_CACHE*/
++ {"query_cache_size", OPT_QUERY_CACHE_SIZE,
++ "The memory allocated to store results from old queries.",
++ &query_cache_size, &query_cache_size, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
++#ifdef HAVE_QUERY_CACHE
++ {"query_cache_type", OPT_QUERY_CACHE_TYPE,
++ "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results "
++ "except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT "
++ "SQL_CACHE ... queries.", &global_system_variables.query_cache_type,
++ &max_system_variables.query_cache_type,
++ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
++ {"query_cache_wlock_invalidate", OPT_QUERY_CACHE_WLOCK_INVALIDATE,
++ "Invalidate queries in query cache on LOCK for write.",
++ &global_system_variables.query_cache_wlock_invalidate,
++ &max_system_variables.query_cache_wlock_invalidate,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
++#endif /*HAVE_QUERY_CACHE*/
++ {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
++ "Persistent buffer for query parsing and execution.",
++ &global_system_variables.query_prealloc_size,
++ &max_system_variables.query_prealloc_size, 0, GET_ULONG,
++ REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
++ ULONG_MAX, 0, 1024, 0},
++ {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
++ "Allocation block size for storing ranges during optimization.",
++ &global_system_variables.range_alloc_block_size,
++ &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
++ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
++ 0, 1024, 0},
++ {"read_buffer_size", OPT_RECORD_BUFFER,
++ "Each thread that does a sequential scan allocates a buffer of this size "
++ "for each table it scans. If you do many sequential scans, you may want "
++ "to increase this value.", &global_system_variables.read_buff_size,
++ &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
++ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
++ 0},
++ {"read_only", OPT_READONLY,
++ "Make all non-temporary tables read-only, with the exception of replication "
++ "(slave) threads and users with the SUPER privilege.",
++ &opt_readonly,
++ &opt_readonly,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
++ {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
++ "When reading rows in sorted order after a sort, the rows are read through "
++ "this buffer to avoid disk seeks. If not set, then it's set to the value of "
++ "record_buffer.",
++ &global_system_variables.read_rnd_buff_size,
++ &max_system_variables.read_rnd_buff_size, 0,
++ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
++ INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
++ {"record_buffer", OPT_RECORD_BUFFER_OLD,
++ "Alias for read_buffer_size. This variable is deprecated and will be removed in a future release.",
++ &global_system_variables.read_buff_size,
++ &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
++ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
++#ifdef HAVE_REPLICATION
++ {"relay_log_purge", OPT_RELAY_LOG_PURGE,
++ "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
++ &relay_log_purge,
++ &relay_log_purge, 0, GET_BOOL, NO_ARG,
++ 1, 0, 1, 0, 1, 0},
++ {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
++ "Maximum space to use for all relay logs.",
++ &relay_log_space_limit,
++ &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
++ (longlong) ULONG_MAX, 0, 1, 0},
++ {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
++ "Use compression on master/slave protocol.",
++ &opt_slave_compressed_protocol,
++ &opt_slave_compressed_protocol,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
++ {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
++ "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
++ &slave_net_timeout, &slave_net_timeout, 0,
++ GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
++ {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
++ "Number of times the slave SQL thread will retry a transaction in case "
++ "it failed with a deadlock or elapsed lock wait timeout, "
++ "before giving up and stopping.",
++ &slave_trans_retries, &slave_trans_retries, 0,
++ GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
++#endif /* HAVE_REPLICATION */
++ {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
++ "If creating the thread takes longer than this value (in seconds), "
++ "the Slow_launch_threads counter will be incremented.",
++ &slow_launch_time, &slow_launch_time, 0, GET_ULONG,
++ REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
++ {"sort_buffer_size", OPT_SORT_BUFFER,
++ "Each thread that needs to do a sort allocates a buffer of this size.",
++ &global_system_variables.sortbuff_size,
++ &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
++ MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
++ 1, 0},
++ {"sync-binlog", OPT_SYNC_BINLOG,
++ "Synchronously flush binary log to disk after every #th event. "
++ "Use 0 (default) to disable synchronous flushing.",
++ &sync_binlog_period, &sync_binlog_period, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
++ {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
++ &opt_sync_frm, &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
++ 0, 0, 0, 0},
++ {"table_cache", OPT_TABLE_OPEN_CACHE,
++ "Deprecated; use --table_open_cache instead.",
++ &table_cache_size, &table_cache_size, 0, GET_ULONG,
++ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
++ {"table_definition_cache", OPT_TABLE_DEF_CACHE,
++ "The number of cached table definitions.",
++ &table_def_size, &table_def_size,
++ 0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
++ 512*1024L, 0, 1, 0},
++ {"table_open_cache", OPT_TABLE_OPEN_CACHE,
++ "The number of cached open tables.",
++ &table_cache_size, &table_cache_size, 0, GET_ULONG,
++ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
++ {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
++ "Timeout in seconds to wait for a table level lock before returning an "
++ "error. Used only if the connection has active cursors.",
++ &table_lock_wait_timeout, &table_lock_wait_timeout,
++ 0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
++ {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
++ "How many threads we should keep in a cache for reuse.",
++ &thread_cache_size, &thread_cache_size, 0, GET_ULONG,
++ REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
++ {"thread_concurrency", OPT_THREAD_CONCURRENCY,
++ "Permits the application to give the threads system a hint for the "
++ "desired number of threads that should be run at the same time.",
++ &concurrency, &concurrency, 0, GET_ULONG, REQUIRED_ARG,
++ DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
++#if HAVE_POOL_OF_THREADS == 1
++ {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
++ "How many threads we should create to handle query requests in case of "
++ "'thread_handling=pool-of-threads'.",
++ &thread_pool_size, &thread_pool_size, 0, GET_ULONG,
++ REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
++#endif
++ {"thread_stack", OPT_THREAD_STACK,
++ "The stack size for each thread.", &my_thread_stack_size,
++ &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
++ 1024L*128L, ULONG_MAX, 0, 1024, 0},
++ { "time_format", OPT_TIME_FORMAT,
++ "The TIME format (for future).",
++ &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
++ &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"tmp_table_size", OPT_TMP_TABLE_SIZE,
++ "If an internal in-memory temporary table exceeds this size, MySQL will"
++ " automatically convert it to an on-disk MyISAM table.",
++ &global_system_variables.tmp_table_size,
++ &max_system_variables.tmp_table_size, 0, GET_ULL,
++ REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
++ {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
++ "Allocation block size for transactions to be stored in binary log.",
++ &global_system_variables.trans_alloc_block_size,
++ &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
++ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
++ {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
++ "Persistent buffer for transactions to be stored in binary log.",
++ &global_system_variables.trans_prealloc_size,
++ &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
++ REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
++ {"thread_handling", OPT_THREAD_HANDLING,
++ "Define threads usage for handling queries: "
++ "one-thread-per-connection or no-threads.", 0, 0,
++ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
++ {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
++ "1 = YES = Don't issue an error message (warning only) if a VIEW without "
++ "presence of a key of the underlying table is used in queries with a "
++ "LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which "
++ "does not contain a key of the underlying table and the query uses a "
++ "LIMIT clause (usually get from GUI tools).",
++ &global_system_variables.updatable_views_with_limit,
++ &max_system_variables.updatable_views_with_limit,
++ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 1, 0, 1, 0},
++ {"wait_timeout", OPT_WAIT_TIMEOUT,
++ "The number of seconds the server waits for activity on a connection before closing it.",
++ &global_system_variables.net_wait_timeout,
++ &max_system_variables.net_wait_timeout, 0, GET_ULONG,
++ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
++ 0, 1, 0},
++ {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
++ "Causes updates to non-transactional engines using statement format to be "
++ "written directly to binary log. Before using this option, make sure that "
++ "there are no dependencies between transactional and non-transactional "
++ "tables such as in the statement INSERT INTO t_myisam SELECT * FROM "
++ "t_innodb; otherwise, slaves may diverge from the master.",
++ &global_system_variables.binlog_direct_non_trans_update,
++ &max_system_variables.binlog_direct_non_trans_update,
++ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
++ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
++};
++
++
++static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONGLONG;
++ var->value= (char *)&thd->query_id;
++ return 0;
++}
++
++
++static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_MY_BOOL;
++ var->value= (char *)&thd->net.compress;
++ return 0;
++}
++
++static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (long) (thd->query_start() - server_start_time);
++ return 0;
++}
++
++#ifdef COMMUNITY_SERVER
++static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (long) (thd->query_start() - flush_status_time);
++ return 0;
++}
++#endif
++
++#ifdef HAVE_REPLICATION
++static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_CHAR;
++ var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
++ return 0;
++}
++
++static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_MY_BOOL;
++ pthread_mutex_lock(&LOCK_active_mi);
++ var->value= buff;
++ *((my_bool *)buff)= (my_bool) (active_mi &&
++ active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
++ active_mi->rli.slave_running);
++ pthread_mutex_unlock(&LOCK_active_mi);
++ return 0;
++}
++
++static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
++{
++ /*
++ TODO: with multimaster, have one such counter per line in
++ SHOW SLAVE STATUS, and have the sum over all lines here.
++ */
++ pthread_mutex_lock(&LOCK_active_mi);
++ if (active_mi)
++ {
++ var->type= SHOW_LONG;
++ var->value= buff;
++ pthread_mutex_lock(&active_mi->rli.data_lock);
++ *((long *)buff)= (long)active_mi->rli.retried_trans;
++ pthread_mutex_unlock(&active_mi->rli.data_lock);
++ }
++ else
++ var->type= SHOW_UNDEF;
++ pthread_mutex_unlock(&LOCK_active_mi);
++ return 0;
++}
++#endif /* HAVE_REPLICATION */
++
++static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (long)cached_open_tables();
++ return 0;
++}
++
++static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ pthread_mutex_lock(&LOCK_prepared_stmt_count);
++ *((long *)buff)= (long)prepared_stmt_count;
++ pthread_mutex_unlock(&LOCK_prepared_stmt_count);
++ return 0;
++}
++
++static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (long)cached_table_definitions();
++ return 0;
++}
++
++#ifdef HAVE_OPENSSL
++/* Functions relying on CTX */
++static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
++ SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
++ return 0;
++}
++
++static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_CHAR;
++ if (!ssl_acceptor_fd)
++ var->value= const_cast<char*>("NONE");
++ else
++ switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
++ {
++ case SSL_SESS_CACHE_OFF:
++ var->value= const_cast<char*>("OFF"); break;
++ case SSL_SESS_CACHE_CLIENT:
++ var->value= const_cast<char*>("CLIENT"); break;
++ case SSL_SESS_CACHE_SERVER:
++ var->value= const_cast<char*>("SERVER"); break;
++ case SSL_SESS_CACHE_BOTH:
++ var->value= const_cast<char*>("BOTH"); break;
++ case SSL_SESS_CACHE_NO_AUTO_CLEAR:
++ var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
++ case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
++ var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
++ default:
++ var->value= const_cast<char*>("Unknown"); break;
++ }
++ return 0;
++}
++
++/*
++ Functions relying on SSL
++ Note: In the show_ssl_* functions, we need to check if we have a
++ valid vio-object since this isn't always true, specifically
++ when session_status or global_status is requested from
++ inside an Event.
++ */
++static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_CHAR;
++ if( thd->vio_ok() && thd->net.vio->ssl_arg )
++ var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
++ else
++ var->value= (char *)"";
++ return 0;
++}
++
++static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ if( thd->vio_ok() && thd->net.vio->ssl_arg )
++ *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg);
++ else
++ *((long *)buff)= 0;
++ return 0;
++}
++
++static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ if( thd->vio_ok() && thd->net.vio->ssl_arg )
++ *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg);
++ else
++ *((long *)buff)= 0;
++ return 0;
++}
++
++static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ if( thd->net.vio && thd->net.vio->ssl_arg )
++ *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg);
++ else
++ *((long *)buff)= 0;
++ return 0;
++}
++
++static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_LONG;
++ var->value= buff;
++ if( thd->vio_ok() && thd->net.vio->ssl_arg )
++ *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg);
++ else
++ *((long *)buff)= 0;
++ return 0;
++}
++
++static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_CHAR;
++ if( thd->vio_ok() && thd->net.vio->ssl_arg )
++ var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
++ else
++ var->value= (char *)"";
++ return 0;
++}
++
++static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
++{
++ var->type= SHOW_CHAR;
++ var->value= buff;
++ if (thd->vio_ok() && thd->net.vio->ssl_arg)
++ {
++ int i;
++ const char *p;
++ char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
++ for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) &&
++ buff < end; i++)
++ {
++ buff= strnmov(buff, p, end-buff-1);
++ *buff++= ':';
++ }
++ if (i)
++ buff--;
++ }
++ *buff=0;
++ return 0;
++}
++
++#endif /* HAVE_OPENSSL */
++
++
++/*
++ Variables shown by SHOW STATUS in alphabetical order
++*/
++
++SHOW_VAR status_vars[]= {
++ {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
++ {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
++ {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
++ {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
++ {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
++ {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
++ {"Com", (char*) com_status_vars, SHOW_ARRAY},
++ {"Compression", (char*) &show_net_compression, SHOW_FUNC},
++ {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
++ {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
++ {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
++ {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
++ {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
++ {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
++ {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
++ {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
++ {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
++ {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
++ {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
++ {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
++ {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
++ {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
++ {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
++ {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
++ {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
++ {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
++ {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
++ {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
++ {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
++ {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
++ {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
++ {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
++ {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
++ {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
++ {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
++ {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
++ {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
++ {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
++ {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
++ {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
++ {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
++ {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH},
++ {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH},
++ {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC},
++ {"Open_tables", (char*) &show_open_tables, SHOW_FUNC},
++ {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
++ {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
++ {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
++ {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
++#ifdef HAVE_QUERY_CACHE
++ {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
++ {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
++ {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
++ {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
++ {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
++ {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
++ {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
++ {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
++#endif /*HAVE_QUERY_CACHE*/
++ {"Queries", (char*) &show_queries, SHOW_FUNC},
++ {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
++#ifdef HAVE_REPLICATION
++ {"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC},
++#endif
++ {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
++ {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
++ {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
++ {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
++ {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
++ {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
++#ifdef HAVE_REPLICATION
++ {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
++ {"Slave_running", (char*) &show_slave_running, SHOW_FUNC},
++#endif
++ {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
++ {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
++ {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
++ {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
++ {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
++ {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
++#ifdef HAVE_OPENSSL
++ {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC},
++ {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC},
++ {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC},
++ {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_FUNC},
++ {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_FUNC},
++ {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC},
++ {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC},
++ {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC},
++ {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC},
++ {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_FUNC},
++ {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC},
++ {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC},
++ {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC},
++ {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC},
++ {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC},
++ {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC},
++ {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC},
++ {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC},
++ {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_FUNC},
++ {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC},
++ {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
++ {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
++ {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
++#endif /* HAVE_OPENSSL */
++ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
++ {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
++#ifdef HAVE_MMAP
++ {"Tc_log_max_pages_used", (char*) &tc_log_max_pages_used, SHOW_LONG},
++ {"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG},
++ {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG},
++#endif
++ {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
++ {"Threads_connected", (char*) &thread_count, SHOW_INT},
++ {"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
++ {"Threads_running", (char*) &thread_running, SHOW_INT},
++ {"Uptime", (char*) &show_starttime, SHOW_FUNC},
++#ifdef COMMUNITY_SERVER
++ {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_FUNC},
++#endif
++ {NullS, NullS, SHOW_LONG}
++};
++
++#ifndef EMBEDDED_LIBRARY
++static void print_version(void)
++{
++ set_server_version();
++ /*
++ Note: the instance manager keys off the string 'Ver' so it can find the
++ version from the output of 'mysqld --version', so don't change it!
++ */
++ printf("%s Ver %s for %s on %s (%s)\n",my_progname,
++ server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
++}
++
++static void usage(void)
++{
++ if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
++ MY_CS_PRIMARY,
++ MYF(MY_WME))))
++ exit(1);
++ if (!default_collation_name)
++ default_collation_name= (char*) default_charset_info->name;
++ print_version();
++ puts("\
++Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
++Copyright (C) 2008 Sun Microsystems, Inc.\n\
++This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
++and you are welcome to modify and redistribute it under the GPL license\n\n\
++Starts the MySQL database server.\n");
++
++ printf("Usage: %s [OPTIONS]\n", my_progname);
++ if (!opt_verbose)
++ puts("\nFor more help options (several pages), use mysqld --verbose --help.");
++ else
++ {
++#ifdef __WIN__
++ puts("NT and Win32 specific options:\n\
++ --install Install the default service (NT).\n\
++ --install-manual Install the default service started manually (NT).\n\
++ --install service_name Install an optional service (NT).\n\
++ --install-manual service_name Install an optional service started manually (NT).\n\
++ --remove Remove the default service from the service list (NT).\n\
++ --remove service_name Remove the service_name from the service list (NT).\n\
++ --enable-named-pipe Only to be used for the default server (NT).\n\
++ --standalone Dummy option to start as a standalone server (NT).\
++");
++ puts("");
++#endif
++ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
++ puts("");
++ set_ports();
++
++ /* Print out all the options including plugin supplied options */
++ my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
++
++ if (! plugins_are_initialized)
++ {
++ puts("\n\
++Plugins have parameters that are not reflected in this list\n\
++because execution stopped before plugins were initialized.");
++ }
++
++ puts("\n\
++To see what values a running MySQL server is using, type\n\
++'mysqladmin variables' instead of 'mysqld --verbose --help'.");
++ }
++}
++#endif /*!EMBEDDED_LIBRARY*/
++
++
++/**
++ Initialize all MySQL global variables to default values.
++
++ We don't need to set numeric variables refered to in my_long_options
++ as these are initialized by my_getopt.
++
++ @note
++ The reason to set a lot of global variables to zero is to allow one to
++ restart the embedded server with a clean environment
++ It's also needed on some exotic platforms where global variables are
++ not set to 0 when a program starts.
++
++ We don't need to set numeric variables refered to in my_long_options
++ as these are initialized by my_getopt.
++*/
++
++static int mysql_init_variables(void)
++{
++ int error;
++ /* Things reset to zero */
++ opt_skip_slave_start= opt_reckless_slave = 0;
++ mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
++ myisam_test_invalid_symlink= test_if_data_home_dir;
++ opt_log= opt_slow_log= 0;
++ opt_update_log= 0;
++ log_output_options= find_bit_type(log_output_str, &log_output_typelib);
++ opt_bin_log= 0;
++ opt_disable_networking= opt_skip_show_db=0;
++ opt_skip_name_resolve= 0;
++ opt_ignore_builtin_innodb= 0;
++ opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
++ opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
++ opt_secure_auth= 0;
++ opt_secure_file_priv= 0;
++ opt_bootstrap= opt_myisam_log= 0;
++ mqh_used= 0;
++ segfaulted= kill_in_progress= 0;
++ cleanup_done= 0;
++ defaults_argc= 0;
++ defaults_argv= 0;
++ server_id_supplied= 0;
++ test_flags= select_errors= dropping_tables= ha_open_options=0;
++ thread_count= thread_running= kill_cached_threads= wake_thread=0;
++ slave_open_temp_tables= 0;
++ cached_thread_count= 0;
++ opt_endinfo= using_udf_functions= 0;
++ opt_using_transactions= 0;
++ abort_loop= select_thread_in_use= signal_thread_in_use= 0;
++ ready_to_exit= shutdown_in_progress= grant_option= 0;
++ aborted_threads= aborted_connects= 0;
++ delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
++ delayed_insert_errors= thread_created= 0;
++ specialflag= 0;
++ binlog_cache_use= binlog_cache_disk_use= 0;
++ max_used_connections= slow_launch_threads = 0;
++ mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
++ prepared_stmt_count= 0;
++ errmesg= 0;
++ mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
++ bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
++ bzero((char *) &global_status_var, sizeof(global_status_var));
++ opt_large_pages= 0;
++#if defined(ENABLED_DEBUG_SYNC)
++ opt_debug_sync_timeout= 0;
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++ key_map_full.set_all();
++
++ /* Character sets */
++ system_charset_info= &my_charset_utf8_general_ci;
++ files_charset_info= &my_charset_utf8_general_ci;
++ national_charset_info= &my_charset_utf8_general_ci;
++ table_alias_charset= &my_charset_bin;
++ character_set_filesystem= &my_charset_bin;
++
++ opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
++
++ /* Things with default values that are not zero */
++ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
++ slave_exec_mode_options= find_bit_type_or_exit(slave_exec_mode_str,
++ &slave_exec_mode_typelib,
++ NULL, &error);
++ /* Default mode string must not yield a error. */
++ DBUG_ASSERT(!error);
++ if (error)
++ return 1;
++ opt_specialflag= SPECIAL_ENGLISH;
++ unix_sock= ip_sock= INVALID_SOCKET;
++ mysql_home_ptr= mysql_home;
++ pidfile_name_ptr= pidfile_name;
++ log_error_file_ptr= log_error_file;
++ language_ptr= language;
++ mysql_data_home= mysql_real_data_home;
++ thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
++ OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
++ protocol_version= PROTOCOL_VERSION;
++ what_to_log= ~ (1L << (uint) COM_TIME);
++ refresh_version= 1L; /* Increments on each reload */
++ global_query_id= thread_id= 1L;
++ strmov(server_version, MYSQL_SERVER_VERSION);
++ myisam_recover_options_str= sql_mode_str= "OFF";
++ myisam_stats_method_str= "nulls_unequal";
++ my_bind_addr = htonl(INADDR_ANY);
++ threads.empty();
++ thread_cache.empty();
++ key_caches.empty();
++ if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
++ default_key_cache_base.length)))
++ {
++ sql_print_error("Cannot allocate the keycache");
++ return 1;
++ }
++ /* set key_cache_hash.default_value = dflt_key_cache */
++ multi_keycache_init();
++
++ /* Set directory paths */
++ strmake(language, LANGUAGE, sizeof(language)-1);
++ strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
++ sizeof(mysql_real_data_home)-1);
++ mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
++ mysql_data_home_buff[1]=0;
++ mysql_data_home_len= 2;
++
++ /* Replication parameters */
++ master_user= (char*) "test";
++ master_password= master_host= 0;
++ master_info_file= (char*) "master.info",
++ relay_log_info_file= (char*) "relay-log.info";
++ master_ssl_key= master_ssl_cert= master_ssl_ca=
++ master_ssl_capath= master_ssl_cipher= 0;
++ report_user= report_password = report_host= 0; /* TO BE DELETED */
++ opt_relay_logname= opt_relaylog_index_name= 0;
++
++ /* Variables in libraries */
++ charsets_dir= 0;
++ default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
++ default_collation_name= compiled_default_collation_name;
++ sys_charset_system.value= (char*) system_charset_info->csname;
++ character_set_filesystem_name= (char*) "binary";
++ lc_time_names_name= (char*) "en_US";
++ /* Set default values for some option variables */
++ default_storage_engine_str= (char*) "MyISAM";
++ global_system_variables.table_plugin= NULL;
++ global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
++ global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
++ max_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
++ global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
++ max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
++ global_system_variables.old_passwords= 0;
++ global_system_variables.old_alter_table= 0;
++ global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
++ /*
++ Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
++ when collecting index statistics for MyISAM tables.
++ */
++ global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
++
++ global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
++ /* Variables that depends on compile options */
++#ifndef DBUG_OFF
++ default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
++ "d:t:i:o,/tmp/mysqld.trace");
++#endif
++ opt_error_log= IF_WIN(1,0);
++#ifdef COMMUNITY_SERVER
++ have_community_features = SHOW_OPTION_YES;
++#else
++ have_community_features = SHOW_OPTION_NO;
++#endif
++ global_system_variables.ndb_index_stat_enable=FALSE;
++ max_system_variables.ndb_index_stat_enable=TRUE;
++ global_system_variables.ndb_index_stat_cache_entries=32;
++ max_system_variables.ndb_index_stat_cache_entries=~0L;
++ global_system_variables.ndb_index_stat_update_freq=20;
++ max_system_variables.ndb_index_stat_update_freq=~0L;
++#ifdef HAVE_OPENSSL
++ have_ssl=SHOW_OPTION_YES;
++#else
++ have_ssl=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_BROKEN_REALPATH
++ have_symlink=SHOW_OPTION_NO;
++#else
++ have_symlink=SHOW_OPTION_YES;
++#endif
++#ifdef HAVE_DLOPEN
++ have_dlopen=SHOW_OPTION_YES;
++#else
++ have_dlopen=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_QUERY_CACHE
++ have_query_cache=SHOW_OPTION_YES;
++#else
++ have_query_cache=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_SPATIAL
++ have_geometry=SHOW_OPTION_YES;
++#else
++ have_geometry=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_RTREE_KEYS
++ have_rtree_keys=SHOW_OPTION_YES;
++#else
++ have_rtree_keys=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_CRYPT
++ have_crypt=SHOW_OPTION_YES;
++#else
++ have_crypt=SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_COMPRESS
++ have_compress= SHOW_OPTION_YES;
++#else
++ have_compress= SHOW_OPTION_NO;
++#endif
++#ifdef HAVE_LIBWRAP
++ libwrapName= NullS;
++#endif
++#ifdef HAVE_OPENSSL
++ des_key_file = 0;
++ ssl_acceptor_fd= 0;
++#endif
++#ifdef HAVE_SMEM
++ shared_memory_base_name= default_shared_memory_base_name;
++#endif
++#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
++ opt_specialflag |= SPECIAL_NO_PRIOR;
++#endif
++
++#if defined(__WIN__) || defined(__NETWARE__)
++ /* Allow Win32 and NetWare users to move MySQL anywhere */
++ {
++ char prg_dev[LIBLEN];
++#if defined __WIN__
++ char executing_path_name[LIBLEN];
++ if (!test_if_hard_path(my_progname))
++ {
++ // we don't want to use GetModuleFileName inside of my_path since
++ // my_path is a generic path dereferencing function and here we care
++ // only about the executing binary.
++ GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
++ my_path(prg_dev, executing_path_name, NULL);
++ }
++ else
++#endif
++ my_path(prg_dev,my_progname,"mysql/bin");
++ strcat(prg_dev,"/../"); // Remove 'bin' to get base dir
++ cleanup_dirname(mysql_home,prg_dev);
++ }
++#else
++ const char *tmpenv;
++ if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
++ tmpenv = DEFAULT_MYSQL_HOME;
++ (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
++#endif
++ return 0;
++}
++
++
++my_bool
++mysqld_get_one_option(int optid,
++ const struct my_option *opt __attribute__((unused)),
++ char *argument)
++{
++ int error;
++
++ switch(optid) {
++ case '#':
++#ifndef DBUG_OFF
++ DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
++#endif
++ opt_endinfo=1; /* unireg: memory allocation */
++ break;
++ case '0':
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
++ break;
++ case 'a':
++ global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
++ global_system_variables.tx_isolation= ISO_SERIALIZABLE;
++ break;
++ case 'b':
++ strmake(mysql_home,argument,sizeof(mysql_home)-1);
++ break;
++ case OPT_DEFAULT_CHARACTER_SET_OLD: // --default-character-set
++ WARN_DEPRECATED(NULL, VER_CELOSIA,
++ "--default-character-set",
++ "--character-set-server");
++ /* Fall through */
++ case 'C':
++ if (default_collation_name == compiled_default_collation_name)
++ default_collation_name= 0;
++ break;
++ case 'l':
++ WARN_DEPRECATED(NULL, "7.0", "--log", "'--general_log'/'--general_log_file'");
++ opt_log=1;
++ break;
++ case 'h':
++ strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
++ /* Correct pointer set by my_getopt (for embedded library) */
++ mysql_data_home= mysql_real_data_home;
++ mysql_data_home_len= strlen(mysql_data_home);
++ break;
++ case 'u':
++ if (!mysqld_user || !strcmp(mysqld_user, argument))
++ mysqld_user= argument;
++ else
++ sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
++ break;
++ case 'L':
++ strmake(language, argument, sizeof(language)-1);
++ break;
++ case 'O':
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--set-variable", "--variable-name=value");
++ break;
++#ifdef HAVE_REPLICATION
++ case OPT_SLAVE_SKIP_ERRORS:
++ init_slave_skip_errors(argument);
++ break;
++ case OPT_SLAVE_EXEC_MODE:
++ slave_exec_mode_options= find_bit_type_or_exit(argument,
++ &slave_exec_mode_typelib,
++ "", &error);
++ if (error)
++ return 1;
++ break;
++#endif
++ case OPT_SAFEMALLOC_MEM_LIMIT:
++#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
++ sf_malloc_mem_limit = atoi(argument);
++#endif
++ break;
++#include <sslopt-case.h>
++#ifndef EMBEDDED_LIBRARY
++ case 'V':
++ print_version();
++ exit(0);
++#endif /*EMBEDDED_LIBRARY*/
++ case OPT_WARNINGS:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--warnings", "--log-warnings");
++ /* Note: fall-through to 'W' */
++ case 'W':
++ if (!argument)
++ global_system_variables.log_warnings++;
++ else if (argument == disabled_my_option)
++ global_system_variables.log_warnings= 0L;
++ else
++ global_system_variables.log_warnings= atoi(argument);
++ break;
++ case 'T':
++ test_flags= argument ? (uint) atoi(argument) : 0;
++ opt_endinfo=1;
++ break;
++ case (int) OPT_DEFAULT_COLLATION_OLD:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-collation", "--collation-server");
++ break;
++ case (int) OPT_SAFE_SHOW_DB:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--safe-show-database", "GRANT SHOW DATABASES");
++ break;
++ case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators");
++ break;
++ case (int) OPT_ENABLE_LOCK:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--enable-locking", "--external-locking");
++ break;
++ case (int) OPT_BIG_TABLES:
++ thd_startup_options|=OPTION_BIG_TABLES;
++ break;
++ case (int) OPT_IGNORE_BUILTIN_INNODB:
++ opt_ignore_builtin_innodb= 1;
++ break;
++ case (int) OPT_ISAM_LOG:
++ opt_myisam_log=1;
++ break;
++ case (int) OPT_UPDATE_LOG:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-update", "--log-bin");
++ opt_update_log=1;
++ break;
++ case (int) OPT_BIN_LOG:
++ opt_bin_log= test(argument != disabled_my_option);
++ break;
++ case (int) OPT_ERROR_LOG_FILE:
++ opt_error_log= 1;
++ break;
++#ifdef HAVE_REPLICATION
++ case (int) OPT_INIT_RPL_ROLE:
++ {
++ int role;
++ role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
++ rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
++ break;
++ }
++ case (int)OPT_REPLICATE_IGNORE_DB:
++ {
++ rpl_filter->add_ignore_db(argument);
++ break;
++ }
++ case (int)OPT_REPLICATE_DO_DB:
++ {
++ rpl_filter->add_do_db(argument);
++ break;
++ }
++ case (int)OPT_REPLICATE_REWRITE_DB:
++ {
++ char* key = argument,*p, *val;
++
++ if (!(p= strstr(argument, "->")))
++ {
++ sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
++ return 1;
++ }
++ val= p--;
++ while (my_isspace(mysqld_charset, *p) && p > argument)
++ *p-- = 0;
++ if (p == argument)
++ {
++ sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
++ return 1;
++ }
++ *val= 0;
++ val+= 2;
++ while (*val && my_isspace(mysqld_charset, *val))
++ val++;
++ if (!*val)
++ {
++ sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
++ return 1;
++ }
++
++ rpl_filter->add_db_rewrite(key, val);
++ break;
++ }
++
++ case (int)OPT_BINLOG_IGNORE_DB:
++ {
++ binlog_filter->add_ignore_db(argument);
++ break;
++ }
++ case OPT_BINLOG_FORMAT:
++ {
++ int id;
++ id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
++ global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
++ break;
++ }
++ case (int)OPT_BINLOG_DO_DB:
++ {
++ binlog_filter->add_do_db(argument);
++ break;
++ }
++ case (int)OPT_REPLICATE_DO_TABLE:
++ {
++ if (rpl_filter->add_do_table(argument))
++ {
++ sql_print_error("Could not add do table rule '%s'!\n", argument);
++ return 1;
++ }
++ break;
++ }
++ case (int)OPT_REPLICATE_WILD_DO_TABLE:
++ {
++ if (rpl_filter->add_wild_do_table(argument))
++ {
++ sql_print_error("Could not add do table rule '%s'!\n", argument);
++ return 1;
++ }
++ break;
++ }
++ case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
++ {
++ if (rpl_filter->add_wild_ignore_table(argument))
++ {
++ sql_print_error("Could not add ignore table rule '%s'!\n", argument);
++ return 1;
++ }
++ break;
++ }
++ case (int)OPT_REPLICATE_IGNORE_TABLE:
++ {
++ if (rpl_filter->add_ignore_table(argument))
++ {
++ sql_print_error("Could not add ignore table rule '%s'!\n", argument);
++ return 1;
++ }
++ break;
++ }
++#endif /* HAVE_REPLICATION */
++ case (int) OPT_SLOW_QUERY_LOG:
++ WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'");
++ opt_slow_log= 1;
++ break;
++#ifdef WITH_CSV_STORAGE_ENGINE
++ case OPT_LOG_OUTPUT:
++ {
++ if (!argument || !argument[0])
++ {
++ log_output_options= LOG_FILE;
++ log_output_str= log_output_typelib.type_names[1];
++ }
++ else
++ {
++ log_output_str= argument;
++ log_output_options=
++ find_bit_type_or_exit(argument, &log_output_typelib, opt->name, &error);
++ if (error)
++ return 1;
++ }
++ break;
++ }
++#endif
++ case OPT_EVENT_SCHEDULER:
++#ifndef HAVE_EVENT_SCHEDULER
++ sql_perror("Event scheduler is not supported in embedded build.");
++#else
++ if (Events::set_opt_event_scheduler(argument))
++ return 1;
++#endif
++ break;
++ case (int) OPT_SKIP_NEW:
++ opt_specialflag|= SPECIAL_NO_NEW_FUNC;
++ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
++ myisam_concurrent_insert=0;
++ myisam_recover_options= HA_RECOVER_NONE;
++ sp_automatic_privileges=0;
++ my_use_symdir=0;
++ ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
++#ifdef HAVE_QUERY_CACHE
++ query_cache_size=0;
++#endif
++ break;
++ case (int) OPT_SAFE:
++ opt_specialflag|= SPECIAL_SAFE_MODE;
++ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
++ myisam_recover_options= HA_RECOVER_DEFAULT;
++ ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
++ break;
++ case (int) OPT_SKIP_PRIOR:
++ opt_specialflag|= SPECIAL_NO_PRIOR;
++ sql_print_warning("The --skip-thread-priority startup option is deprecated "
++ "and will be removed in MySQL 7.0. MySQL 6.0 and up do not "
++ "give threads different priorities.");
++ break;
++ case (int) OPT_SKIP_LOCK:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-locking", "--skip-external-locking");
++ opt_external_locking=0;
++ break;
++ case (int) OPT_SQL_BIN_UPDATE_SAME:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--sql-bin-update-same", "the binary log");
++ break;
++ case (int) OPT_RECORD_BUFFER_OLD:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "record_buffer", "read_buffer_size");
++ break;
++ case (int) OPT_SYMBOLIC_LINKS:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--use-symbolic-links", "--symbolic-links");
++ break;
++ case (int) OPT_SKIP_HOST_CACHE:
++ opt_specialflag|= SPECIAL_NO_HOST_CACHE;
++ break;
++ case (int) OPT_SKIP_RESOLVE:
++ opt_skip_name_resolve= 1;
++ opt_specialflag|=SPECIAL_NO_RESOLVE;
++ break;
++ case (int) OPT_SKIP_NETWORKING:
++#if defined(__NETWARE__)
++ sql_perror("Can't start server: skip-networking option is currently not supported on NetWare");
++ return 1;
++#endif
++ opt_disable_networking=1;
++ mysqld_port=0;
++ break;
++ case (int) OPT_SKIP_SHOW_DB:
++ opt_skip_show_db=1;
++ opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
++ break;
++ case (int) OPT_WANT_CORE:
++ test_flags |= TEST_CORE_ON_SIGNAL;
++ break;
++ case (int) OPT_SKIP_STACK_TRACE:
++ test_flags|=TEST_NO_STACKTRACE;
++ break;
++ case (int) OPT_SKIP_SYMLINKS:
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links");
++ my_use_symdir=0;
++ break;
++ case (int) OPT_BIND_ADDRESS:
++ if ((my_bind_addr= (ulong) inet_addr(argument)) == INADDR_NONE)
++ {
++ struct hostent *ent;
++ if (argument[0])
++ ent=gethostbyname(argument);
++ else
++ {
++ char myhostname[255];
++ if (gethostname(myhostname,sizeof(myhostname)) < 0)
++ {
++ sql_perror("Can't start server: cannot get my own hostname!");
++ return 1;
++ }
++ ent=gethostbyname(myhostname);
++ }
++ if (!ent)
++ {
++ sql_perror("Can't start server: cannot resolve hostname!");
++ return 1;
++ }
++ my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
++ }
++ break;
++ case (int) OPT_PID_FILE:
++ strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
++ break;
++#ifdef __WIN__
++ case (int) OPT_STANDALONE: /* Dummy option for NT */
++ break;
++#endif
++ /*
++ The following change issues a deprecation warning if the slave
++ configuration is specified either in the my.cnf file or on
++ the command-line. See BUG#21490.
++ */
++ case OPT_MASTER_HOST:
++ case OPT_MASTER_USER:
++ case OPT_MASTER_PASSWORD:
++ case OPT_MASTER_PORT:
++ case OPT_MASTER_CONNECT_RETRY:
++ case OPT_MASTER_SSL:
++ case OPT_MASTER_SSL_KEY:
++ case OPT_MASTER_SSL_CERT:
++ case OPT_MASTER_SSL_CAPATH:
++ case OPT_MASTER_SSL_CIPHER:
++ case OPT_MASTER_SSL_CA:
++ if (!slave_warning_issued) //only show the warning once
++ {
++ slave_warning_issued = true;
++ WARN_DEPRECATED(NULL, "6.0", "for replication startup options",
++ "'CHANGE MASTER'");
++ }
++ break;
++ case OPT_CONSOLE:
++ if (opt_console)
++ opt_error_log= 0; // Force logs to stdout
++ break;
++ case (int) OPT_FLUSH:
++ myisam_flush=1;
++ flush_time=0; // No auto flush
++ break;
++ case OPT_LOW_PRIORITY_UPDATES:
++ thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
++ global_system_variables.low_priority_updates=1;
++ break;
++ case OPT_BOOTSTRAP:
++ opt_noacl=opt_bootstrap=1;
++ break;
++ case OPT_SERVER_ID:
++ server_id_supplied = 1;
++ break;
++ case OPT_DELAY_KEY_WRITE_ALL:
++ WARN_DEPRECATED(NULL, VER_CELOSIA,
++ "--delay-key-write-for-all-tables",
++ "--delay-key-write=ALL");
++ if (argument != disabled_my_option)
++ argument= (char*) "ALL";
++ /* Fall through */
++ case OPT_DELAY_KEY_WRITE:
++ if (argument == disabled_my_option)
++ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
++ else if (! argument)
++ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
++ else
++ {
++ int type;
++ type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
++ delay_key_write_options= (uint) type-1;
++ }
++ break;
++ case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE:
++ sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and "
++ "does nothing in this version. It will be removed in "
++ "a future release.");
++ break;
++ case OPT_CHARSETS_DIR:
++ strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
++ charsets_dir = mysql_charsets_dir;
++ break;
++ case OPT_TX_ISOLATION:
++ {
++ int type;
++ type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
++ global_system_variables.tx_isolation= (type-1);
++ break;
++ }
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++ case OPT_NDB_MGMD:
++ case OPT_NDB_NODEID:
++ {
++ int len= my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
++ sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
++ "%s%s%s",opt_ndb_constrbuf_len > 0 ? ",":"",
++ optid == OPT_NDB_NODEID ? "nodeid=" : "",
++ argument);
++ opt_ndb_constrbuf_len+= len;
++ }
++ /* fall through to add the connectstring to the end
++ * and set opt_ndbcluster_connectstring
++ */
++ case OPT_NDB_CONNECTSTRING:
++ if (opt_ndb_connectstring && opt_ndb_connectstring[0])
++ my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
++ sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
++ "%s%s", opt_ndb_constrbuf_len > 0 ? ",":"",
++ opt_ndb_connectstring);
++ else
++ opt_ndb_constrbuf[opt_ndb_constrbuf_len]= 0;
++ opt_ndbcluster_connectstring= opt_ndb_constrbuf;
++ break;
++ case OPT_NDB_DISTRIBUTION:
++ int id;
++ id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
++ opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
++ break;
++ case OPT_NDB_EXTRA_LOGGING:
++ if (!argument)
++ ndb_extra_logging++;
++ else if (argument == disabled_my_option)
++ ndb_extra_logging= 0L;
++ else
++ ndb_extra_logging= atoi(argument);
++ break;
++#endif
++ case OPT_MYISAM_RECOVER:
++ {
++ if (!argument)
++ {
++ myisam_recover_options= HA_RECOVER_DEFAULT;
++ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
++ }
++ else if (!argument[0])
++ {
++ myisam_recover_options= HA_RECOVER_NONE;
++ myisam_recover_options_str= "OFF";
++ }
++ else
++ {
++ myisam_recover_options_str=argument;
++ myisam_recover_options=
++ find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
++ &error);
++ if (error)
++ return 1;
++ }
++ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
++ break;
++ }
++ case OPT_CONCURRENT_INSERT:
++ /* The following code is mainly here to emulate old behavior */
++ if (!argument) /* --concurrent-insert */
++ myisam_concurrent_insert= 1;
++ else if (argument == disabled_my_option)
++ myisam_concurrent_insert= 0; /* --skip-concurrent-insert */
++ break;
++ case OPT_TC_HEURISTIC_RECOVER:
++ tc_heuristic_recover= find_type_or_exit(argument,
++ &tc_heuristic_recover_typelib,
++ opt->name);
++ break;
++ case OPT_MYISAM_STATS_METHOD:
++ {
++ ulong method_conv;
++ int method;
++ LINT_INIT(method_conv);
++
++ myisam_stats_method_str= argument;
++ method= find_type_or_exit(argument, &myisam_stats_method_typelib,
++ opt->name);
++ switch (method-1) {
++ case 2:
++ method_conv= MI_STATS_METHOD_IGNORE_NULLS;
++ break;
++ case 1:
++ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
++ break;
++ case 0:
++ default:
++ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
++ break;
++ }
++ global_system_variables.myisam_stats_method= method_conv;
++ break;
++ }
++ case OPT_SQL_MODE:
++ {
++ sql_mode_str= argument;
++ global_system_variables.sql_mode=
++ find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name, &error);
++ if (error)
++ return 1;
++ global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
++ sql_mode);
++ break;
++ }
++ case OPT_OPTIMIZER_SWITCH:
++ {
++ bool not_used;
++ char *error= 0;
++ uint error_len= 0;
++ optimizer_switch_str= argument;
++ global_system_variables.optimizer_switch=
++ (ulong)find_set_from_flags(&optimizer_switch_typelib,
++ optimizer_switch_typelib.count,
++ global_system_variables.optimizer_switch,
++ global_system_variables.optimizer_switch,
++ argument, strlen(argument), NULL,
++ &error, &error_len, ¬_used);
++ if (error)
++ {
++ char buf[512];
++ char *cbuf= buf;
++ cbuf += my_snprintf(buf, 512, "Error in parsing optimizer_switch setting near %*s\n", error_len, error);
++ sql_perror(buf);
++ return 1;
++ }
++ break;
++ }
++ case OPT_ONE_THREAD:
++ global_system_variables.thread_handling=
++ SCHEDULER_ONE_THREAD_PER_CONNECTION;
++ break;
++ case OPT_THREAD_HANDLING:
++ {
++ global_system_variables.thread_handling=
++ find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
++ break;
++ }
++ case OPT_FT_BOOLEAN_SYNTAX:
++ if (ft_boolean_check_syntax_string((uchar*) argument))
++ {
++ sql_print_error("Invalid ft-boolean-syntax string: %s\n", argument);
++ return 1;
++ }
++ strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
++ break;
++ case OPT_SKIP_SAFEMALLOC:
++#ifdef SAFEMALLOC
++ sf_malloc_quick=1;
++#endif
++ break;
++ case OPT_LOWER_CASE_TABLE_NAMES:
++ lower_case_table_names= argument ? atoi(argument) : 1;
++ lower_case_table_names_used= 1;
++ break;
++#ifdef HAVE_STACK_TRACE_ON_SEGV
++ case OPT_DO_PSTACK:
++ sql_print_warning("'--enable-pstack' is deprecated and will be removed "
++ "in a future release. A symbolic stack trace will be "
++ "printed after a crash whenever possible.");
++ break;
++#endif
++#if defined(ENABLED_DEBUG_SYNC)
++ case OPT_DEBUG_SYNC_TIMEOUT:
++ /*
++ Debug Sync Facility. See debug_sync.cc.
++ Default timeout for WAIT_FOR action.
++ Default value is zero (facility disabled).
++ If option is given without an argument, supply a non-zero value.
++ */
++ if (!argument)
++ {
++ /* purecov: begin tested */
++ opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
++ /* purecov: end */
++ }
++ break;
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++ case OPT_MAX_LONG_DATA_SIZE:
++ max_long_data_size_used= true;
++ WARN_DEPRECATED(NULL, VER_CELOSIA, "--max_long_data_size", "--max_allowed_packet");
++ break;
++ }
++ return 0;
++}
++
++
++/** Handle arguments for multiple key caches. */
++C_MODE_START
++static void* mysql_getopt_value(const char *, uint,
++ const struct my_option *, int *);
++C_MODE_END
++
++static void*
++mysql_getopt_value(const char *keyname, uint key_length,
++ const struct my_option *option, int *error)
++{
++ if (error)
++ *error= 0;
++ switch (option->id) {
++ case OPT_KEY_BUFFER_SIZE:
++ case OPT_KEY_CACHE_BLOCK_SIZE:
++ case OPT_KEY_CACHE_DIVISION_LIMIT:
++ case OPT_KEY_CACHE_AGE_THRESHOLD:
++ {
++ KEY_CACHE *key_cache;
++ if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
++ {
++ if (error)
++ *error= EXIT_OUT_OF_MEMORY;
++ return 0;
++ }
++ switch (option->id) {
++ case OPT_KEY_BUFFER_SIZE:
++ return &key_cache->param_buff_size;
++ case OPT_KEY_CACHE_BLOCK_SIZE:
++ return &key_cache->param_block_size;
++ case OPT_KEY_CACHE_DIVISION_LIMIT:
++ return &key_cache->param_division_limit;
++ case OPT_KEY_CACHE_AGE_THRESHOLD:
++ return &key_cache->param_age_threshold;
++ }
++ }
++ }
++ return option->value;
++}
++
++
++extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
++
++void option_error_reporter(enum loglevel level, const char *format, ...)
++{
++ va_list args;
++ va_start(args, format);
++
++ /* Don't print warnings for --loose options during bootstrap */
++ if (level == ERROR_LEVEL || !opt_bootstrap ||
++ global_system_variables.log_warnings)
++ {
++ vprint_msg_to_log(level, format, args);
++ }
++ va_end(args);
++}
++
++
++/**
++ @todo
++ - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
++*/
++static int get_options(int *argc,char **argv)
++{
++ int ho_error;
++
++ my_getopt_register_get_addr(mysql_getopt_value);
++ strmake(def_ft_boolean_syntax, ft_boolean_syntax,
++ sizeof(ft_boolean_syntax)-1);
++ my_getopt_error_reporter= option_error_reporter;
++
++ /* Skip unknown options so that they may be processed later by plugins */
++ my_getopt_skip_unknown= TRUE;
++
++ if ((ho_error= handle_options(argc, &argv, my_long_options,
++ mysqld_get_one_option)))
++ return ho_error;
++ (*argc)++; /* add back one for the progname handle_options removes */
++ /* no need to do this for argv as we are discarding it. */
++
++ if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
++ opt_log_slow_slave_statements) &&
++ !opt_slow_log)
++ sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log_slow_queries is not set");
++ if (global_system_variables.net_buffer_length >
++ global_system_variables.max_allowed_packet)
++ {
++ sql_print_warning("net_buffer_length (%lu) is set to be larger "
++ "than max_allowed_packet (%lu). Please rectify.",
++ global_system_variables.net_buffer_length,
++ global_system_variables.max_allowed_packet);
++ }
++
++#if defined(HAVE_BROKEN_REALPATH)
++ my_use_symdir=0;
++ my_disable_symlinks=1;
++ have_symlink=SHOW_OPTION_NO;
++#else
++ if (!my_use_symdir)
++ {
++ my_disable_symlinks=1;
++ have_symlink=SHOW_OPTION_DISABLED;
++ }
++#endif
++ if (opt_debugging)
++ {
++ /* Allow break with SIGINT, no core or stack trace */
++ test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
++ test_flags&= ~TEST_CORE_ON_SIGNAL;
++ }
++ /* Set global MyISAM variables from delay_key_write_options */
++ fix_delay_key_write((THD*) 0, OPT_GLOBAL);
++ /* Set global slave_exec_mode from its option */
++ fix_slave_exec_mode();
++
++#ifndef EMBEDDED_LIBRARY
++ if (mysqld_chroot)
++ set_root(mysqld_chroot);
++#else
++ global_system_variables.thread_handling = SCHEDULER_NO_THREADS;
++ max_allowed_packet= global_system_variables.max_allowed_packet;
++ net_buffer_length= global_system_variables.net_buffer_length;
++#endif
++ if (fix_paths())
++ return 1;
++
++ /*
++ Set some global variables from the global_system_variables
++ In most cases the global variables will not be used
++ */
++ my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
++ my_default_record_cache_size=global_system_variables.read_buff_size;
++ myisam_max_temp_length=
++ (my_off_t) global_system_variables.myisam_max_sort_file_size;
++
++ /* Set global variables based on startup options */
++ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
++
++ /* long_query_time is in microseconds */
++ global_system_variables.long_query_time= max_system_variables.long_query_time=
++ (longlong) (long_query_time * 1000000.0);
++
++ if (opt_short_log_format)
++ opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
++
++ if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
++ &global_system_variables.date_format) ||
++ init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
++ &global_system_variables.time_format) ||
++ init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
++ &global_system_variables.datetime_format))
++ return 1;
++
++#ifdef EMBEDDED_LIBRARY
++ one_thread_scheduler(&thread_scheduler);
++#else
++ if (global_system_variables.thread_handling <=
++ SCHEDULER_ONE_THREAD_PER_CONNECTION)
++ one_thread_per_connection_scheduler(&thread_scheduler);
++ else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
++ one_thread_scheduler(&thread_scheduler);
++ else
++ pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */
++#endif
++
++ /*
++ If max_long_data_size is not specified explicitly use
++ value of max_allowed_packet.
++ */
++ if (!max_long_data_size_used)
++ max_long_data_size= global_system_variables.max_allowed_packet;
++
++ return 0;
++}
++
++
++/*
++ Create version name for running mysqld version
++ We automaticly add suffixes -debug, -embedded and -log to the version
++ name to make the version more descriptive.
++ (MYSQL_SERVER_SUFFIX is set by the compilation environment)
++*/
++
++static void set_server_version(void)
++{
++ char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
++ MYSQL_SERVER_SUFFIX_STR, NullS);
++#ifdef EMBEDDED_LIBRARY
++ end= strmov(end, "-embedded");
++#endif
++#ifndef DBUG_OFF
++ if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
++ end= strmov(end, "-debug");
++#endif
++ if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
++ strmov(end, "-log"); // This may slow down system
++}
++
++
++static char *get_relative_path(const char *path)
++{
++ if (test_if_hard_path(path) &&
++ is_prefix(path,DEFAULT_MYSQL_HOME) &&
++ strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
++ {
++ path+=(uint) strlen(DEFAULT_MYSQL_HOME);
++ while (*path == FN_LIBCHAR)
++ path++;
++ }
++ return (char*) path;
++}
++
++
++/**
++ Fix filename and replace extension where 'dir' is relative to
++ mysql_real_data_home.
++ @return
++ 1 if len(path) > FN_REFLEN
++*/
++
++bool
++fn_format_relative_to_data_home(char * to, const char *name,
++ const char *dir, const char *extension)
++{
++ char tmp_path[FN_REFLEN];
++ if (!test_if_hard_path(dir))
++ {
++ strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
++ dir, NullS);
++ dir=tmp_path;
++ }
++ return !fn_format(to, name, dir, extension,
++ MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
++}
++
++
++/**
++ Test a file path to determine if the path is compatible with the secure file
++ path restriction.
++
++ @param path null terminated character string
++
++ @return
++ @retval TRUE The path is secure
++ @retval FALSE The path isn't secure
++*/
++
++bool is_secure_file_path(char *path)
++{
++ char buff1[FN_REFLEN], buff2[FN_REFLEN];
++ /*
++ All paths are secure if opt_secure_file_path is 0
++ */
++ if (!opt_secure_file_priv)
++ return TRUE;
++
++ if (strlen(path) >= FN_REFLEN)
++ return FALSE;
++
++ if (my_realpath(buff1, path, 0))
++ {
++ /*
++ The supplied file path might have been a file and not a directory.
++ */
++ int length= (int)dirname_length(path);
++ if (length >= FN_REFLEN)
++ return FALSE;
++ memcpy(buff2, path, length);
++ buff2[length]= '\0';
++ if (length == 0 || my_realpath(buff1, buff2, 0))
++ return FALSE;
++ }
++ convert_dirname(buff2, buff1, NullS);
++ if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
++ return FALSE;
++ return TRUE;
++}
++
++static int fix_paths(void)
++{
++ char buff[FN_REFLEN],*pos;
++ convert_dirname(mysql_home,mysql_home,NullS);
++ /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
++ my_realpath(mysql_home,mysql_home,MYF(0));
++ /* Ensure that mysql_home ends in FN_LIBCHAR */
++ pos=strend(mysql_home);
++ if (pos[-1] != FN_LIBCHAR)
++ {
++ pos[0]= FN_LIBCHAR;
++ pos[1]= 0;
++ }
++ convert_dirname(language,language,NullS);
++ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
++ (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
++ (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
++ (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
++ (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
++ get_relative_path(PLUGINDIR), mysql_home);
++ opt_plugin_dir_ptr= opt_plugin_dir;
++
++ my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
++ mysql_unpacked_real_data_home_len=
++ (int) strlen(mysql_unpacked_real_data_home);
++ if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
++ --mysql_unpacked_real_data_home_len;
++
++ char *sharedir=get_relative_path(SHAREDIR);
++ if (test_if_hard_path(sharedir))
++ strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
++ else
++ strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
++ convert_dirname(buff,buff,NullS);
++ (void) my_load_path(language,language,buff);
++
++ /* If --character-sets-dir isn't given, use shared library dir */
++ if (charsets_dir != mysql_charsets_dir)
++ {
++ strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
++ CHARSET_DIR, NullS);
++ }
++ (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
++ convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
++ charsets_dir=mysql_charsets_dir;
++
++ if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
++ return 1;
++#ifdef HAVE_REPLICATION
++ if (!slave_load_tmpdir)
++ {
++ if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
++ return 1;
++ }
++#endif /* HAVE_REPLICATION */
++ /*
++ Convert the secure-file-priv option to system format, allowing
++ a quick strcmp to check if read or write is in an allowed dir
++ */
++ if (opt_secure_file_priv)
++ {
++ if (*opt_secure_file_priv == 0)
++ {
++ opt_secure_file_priv= 0;
++ }
++ else
++ {
++ if (strlen(opt_secure_file_priv) >= FN_REFLEN)
++ opt_secure_file_priv[FN_REFLEN-1]= '\0';
++ if (my_realpath(buff, opt_secure_file_priv, 0))
++ {
++ sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
++ return 1;
++ }
++ char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
++ convert_dirname(secure_file_real_path, buff, NullS);
++ my_free(opt_secure_file_priv, MYF(0));
++ opt_secure_file_priv= secure_file_real_path;
++ }
++ }
++
++ return 0;
++}
++
++
++static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
++ const char *option, int *error)
++{
++ ulong result;
++ const char **ptr;
++
++ *error= 0;
++ if ((result= find_bit_type(x, bit_lib)) == ~(ulong) 0)
++ {
++ char *buff= (char *) my_alloca(2048);
++ char *cbuf;
++ ptr= bit_lib->type_names;
++ cbuf= buff + ((!*x) ?
++ my_snprintf(buff, 2048, "No option given to %s\n", option) :
++ my_snprintf(buff, 2048, "Wrong option to %s. Option(s) given: %s\n",
++ option, x));
++ cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), "Alternatives are: '%s'", *ptr);
++ while (*++ptr)
++ cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), ",'%s'", *ptr);
++ my_snprintf(cbuf, 2048 - (cbuf-buff), "\n");
++ sql_perror(buff);
++ *error= 1;
++ my_afree(buff);
++ return 0;
++ }
++
++ return result;
++}
++
++
++/**
++ @return
++ a bitfield from a string of substrings separated by ','
++ or
++ ~(ulong) 0 on error.
++*/
++
++static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
++{
++ bool found_end;
++ int found_count;
++ const char *end,*i,*j;
++ const char **array, *pos;
++ ulong found,found_int,bit;
++ DBUG_ENTER("find_bit_type");
++ DBUG_PRINT("enter",("x: '%s'",x));
++
++ found=0;
++ found_end= 0;
++ pos=(char *) x;
++ while (*pos == ' ') pos++;
++ found_end= *pos == 0;
++ while (!found_end)
++ {
++ if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
++ {
++ while (end > pos && end[-1] == ' ')
++ end--; /* Skip end-space */
++ found_end=1;
++ }
++ found_int=0; found_count=0;
++ for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
++ {
++ j=pos;
++ while (j != end)
++ {
++ if (my_toupper(mysqld_charset,*i++) !=
++ my_toupper(mysqld_charset,*j++))
++ goto skip;
++ }
++ found_int=bit;
++ if (! *i)
++ {
++ found_count=1;
++ break;
++ }
++ else if (j != pos) // Half field found
++ {
++ found_count++; // Could be one of two values
++ }
++skip: ;
++ }
++ if (found_count != 1)
++ DBUG_RETURN(~(ulong) 0); // No unique value
++ found|=found_int;
++ pos=end+1;
++ }
++
++ DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
++ DBUG_RETURN(found);
++} /* find_bit_type */
++
++
++/**
++ Check if file system used for databases is case insensitive.
++
++ @param dir_name Directory to test
++
++ @retval
++ -1 Don't know (Test failed)
++ @retval
++ 0 File system is case sensitive
++ @retval
++ 1 File system is case insensitive
++*/
++
++static int test_if_case_insensitive(const char *dir_name)
++{
++ int result= 0;
++ File file;
++ char buff[FN_REFLEN], buff2[FN_REFLEN];
++ MY_STAT stat_info;
++ DBUG_ENTER("test_if_case_insensitive");
++
++ fn_format(buff, glob_hostname, dir_name, ".lower-test",
++ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
++ fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
++ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
++ (void) my_delete(buff2, MYF(0));
++ if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
++ {
++ sql_print_warning("Can't create test file %s", buff);
++ DBUG_RETURN(-1);
++ }
++ my_close(file, MYF(0));
++ if (my_stat(buff2, &stat_info, MYF(0)))
++ result= 1; // Can access file
++ (void) my_delete(buff, MYF(MY_WME));
++ DBUG_PRINT("exit", ("result: %d", result));
++ DBUG_RETURN(result);
++}
++
++
++#ifndef EMBEDDED_LIBRARY
++
++/**
++ Create file to store pid number.
++*/
++static void create_pid_file()
++{
++ File file;
++ if ((file = my_create(pidfile_name,0664,
++ O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
++ {
++ char buff[21], *end;
++ end= int10_to_str((long) getpid(), buff, 10);
++ *end++= '\n';
++ if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
++ {
++ (void) my_close(file, MYF(0));
++ return;
++ }
++ (void) my_close(file, MYF(0));
++ }
++ sql_perror("Can't start server: can't create PID file");
++ exit(1);
++}
++#endif /* EMBEDDED_LIBRARY */
++
++/** Clear most status variables. */
++void refresh_status(THD *thd)
++{
++ pthread_mutex_lock(&LOCK_status);
++
++ /* Add thread's status variabes to global status */
++ add_to_status(&global_status_var, &thd->status_var);
++
++ /* Reset thread's status variables */
++ bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
++
++ /* Reset some global variables */
++ reset_status_vars();
++
++ /* Reset the counters of all key caches (default and named). */
++ process_key_caches(reset_key_cache_counters);
++#ifdef COMMUNITY_SERVER
++ flush_status_time= time((time_t*) 0);
++#endif
++ pthread_mutex_unlock(&LOCK_status);
++
++ /*
++ Set max_used_connections to the number of currently open
++ connections. Lock LOCK_thread_count out of LOCK_status to avoid
++ deadlocks. Status reset becomes not atomic, but status data is
++ not exact anyway.
++ */
++ pthread_mutex_lock(&LOCK_thread_count);
++ max_used_connections= thread_count-delayed_insert_threads;
++ pthread_mutex_unlock(&LOCK_thread_count);
++}
++
++
++/*****************************************************************************
++ Instantiate variables for missing storage engines
++ This section should go away soon
++*****************************************************************************/
++
++#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
++ulong ndb_cache_check_time;
++ulong ndb_extra_logging;
++#endif
++
++/*****************************************************************************
++ Instantiate templates
++*****************************************************************************/
++
++#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
++/* Used templates */
++template class I_List<THD>;
++template class I_List_iterator<THD>;
++template class I_List<i_string>;
++template class I_List<i_string_pair>;
++template class I_List<NAMED_LIST>;
++template class I_List<Statement>;
++template class I_List_iterator<Statement>;
++#endif
+diff -urN mysql-old/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql-old/sql/net_serv.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/net_serv.cc 2011-05-10 17:56:01.466682376 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -urN mysql-old/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql-old/sql/opt_range.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/opt_range.cc 2011-05-10 17:56:01.470015709 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -urN mysql-old/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql-old/sql/opt_range.h 2011-05-10 17:45:45.640015709 +0000
++++ mysql/sql/opt_range.h 2011-05-10 17:56:01.476682376 +0000
+@@ -83,7 +83,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -121,7 +121,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -urN mysql-old/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql-old/sql/protocol.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/protocol.cc 2011-05-10 17:56:01.476682376 +0000
+@@ -167,7 +167,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -262,7 +262,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -urN mysql-old/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql-old/sql/rpl_record.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/rpl_record.cc 2011-05-10 17:56:01.476682376 +0000
+@@ -285,7 +285,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -urN mysql-old/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql-old/sql/rpl_rli.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/rpl_rli.cc 2011-05-10 17:56:01.476682376 +0000
+@@ -686,7 +686,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -696,7 +696,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -urN mysql-old/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql-old/sql/rpl_utility.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/rpl_utility.cc 2011-05-10 17:56:01.480015710 +0000
+@@ -180,7 +180,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -urN mysql-old/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql-old/sql/rpl_utility.h 2011-05-10 17:45:45.640015709 +0000
++++ mysql/sql/rpl_utility.h 2011-05-10 17:56:01.480015710 +0000
+@@ -295,7 +295,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -urN mysql-old/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql-old/sql/set_var.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/set_var.cc 2011-05-10 17:56:01.480015710 +0000
+@@ -1845,7 +1845,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4030,7 +4030,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -urN mysql-old/sql/set_var.cc.orig mysql/sql/set_var.cc.orig
+--- mysql-old/sql/set_var.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/set_var.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,4357 @@
++/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++/**
++ @file
++
++ @brief
++ Handling of MySQL SQL variables
++
++ @details
++ To add a new variable, one has to do the following:
++
++ - Use one of the 'sys_var... classes from set_var.h or write a specific
++ one for the variable type.
++ - Define it in the 'variable definition list' in this file.
++ - If the variable is thread specific, add it to 'system_variables' struct.
++ If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
++ - If the variable should be changed from the command line, add a definition
++ of it in the my_option structure list in mysqld.cc
++ - Don't forget to initialize new fields in global_system_variables and
++ max_system_variables!
++
++ @todo
++ Add full support for the variable character_set (for 4.1)
++
++ @todo
++ When updating myisam_delay_key_write, we should do a 'flush tables'
++ of all MyISAM tables to ensure that they are reopen with the
++ new attribute.
++
++ @note
++ Be careful with var->save_result: sys_var::check() only updates
++ ulonglong_value; so other members of the union are garbage then; to use
++ them you must first assign a value to them (in specific ::check() for
++ example).
++*/
++
++#ifdef USE_PRAGMA_IMPLEMENTATION
++#pragma implementation // gcc: Class implementation
++#endif
++
++#include "mysql_priv.h"
++#include <mysql.h>
++#include "slave.h"
++#include "rpl_mi.h"
++#include <my_getopt.h>
++#include <thr_alarm.h>
++#include <myisam.h>
++#include <my_dir.h>
++
++#include "events.h"
++
++/* WITH_NDBCLUSTER_STORAGE_ENGINE */
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++extern ulong ndb_cache_check_time;
++extern char opt_ndb_constrbuf[];
++extern ulong ndb_extra_logging;
++#endif
++
++#ifdef HAVE_NDB_BINLOG
++extern ulong ndb_report_thresh_binlog_epoch_slip;
++extern ulong ndb_report_thresh_binlog_mem_usage;
++#endif
++
++extern CHARSET_INFO *character_set_filesystem;
++
++
++static HASH system_variable_hash;
++
++const char *bool_type_names[]= { "OFF", "ON", NullS };
++TYPELIB bool_typelib=
++{
++ array_elements(bool_type_names)-1, "", bool_type_names, NULL
++};
++
++const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
++TYPELIB delay_key_write_typelib=
++{
++ array_elements(delay_key_write_type_names)-1, "",
++ delay_key_write_type_names, NULL
++};
++
++static const char *slave_exec_mode_names[]= { "STRICT", "IDEMPOTENT", NullS };
++static unsigned int slave_exec_mode_names_len[]= { sizeof("STRICT") - 1,
++ sizeof("IDEMPOTENT") - 1, 0 };
++TYPELIB slave_exec_mode_typelib=
++{
++ array_elements(slave_exec_mode_names)-1, "",
++ slave_exec_mode_names, slave_exec_mode_names_len
++};
++
++static int sys_check_ftb_syntax(THD *thd, set_var *var);
++static bool sys_update_ftb_syntax(THD *thd, set_var * var);
++static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
++static bool sys_update_init_connect(THD*, set_var*);
++static void sys_default_init_connect(THD*, enum_var_type type);
++static bool sys_update_init_slave(THD*, set_var*);
++static void sys_default_init_slave(THD*, enum_var_type type);
++static bool set_option_bit(THD *thd, set_var *var);
++static bool set_option_log_bin_bit(THD *thd, set_var *var);
++static bool set_option_autocommit(THD *thd, set_var *var);
++static int check_log_update(THD *thd, set_var *var);
++static bool set_log_update(THD *thd, set_var *var);
++static int check_pseudo_thread_id(THD *thd, set_var *var);
++void fix_binlog_format_after_update(THD *thd, enum_var_type type);
++static void fix_low_priority_updates(THD *thd, enum_var_type type);
++static int check_tx_isolation(THD *thd, set_var *var);
++static void fix_tx_isolation(THD *thd, enum_var_type type);
++static int check_completion_type(THD *thd, set_var *var);
++static void fix_completion_type(THD *thd, enum_var_type type);
++static void fix_net_read_timeout(THD *thd, enum_var_type type);
++static void fix_net_write_timeout(THD *thd, enum_var_type type);
++static void fix_net_retry_count(THD *thd, enum_var_type type);
++static void fix_max_join_size(THD *thd, enum_var_type type);
++static void fix_query_cache_size(THD *thd, enum_var_type type);
++static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
++static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
++static void fix_max_binlog_size(THD *thd, enum_var_type type);
++static void fix_max_relay_log_size(THD *thd, enum_var_type type);
++static void fix_max_connections(THD *thd, enum_var_type type);
++static int check_max_delayed_threads(THD *thd, set_var *var);
++static void fix_thd_mem_root(THD *thd, enum_var_type type);
++static void fix_trans_mem_root(THD *thd, enum_var_type type);
++static void fix_server_id(THD *thd, enum_var_type type);
++bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
++ const char *name, longlong val);
++static KEY_CACHE *create_key_cache(const char *name, uint length);
++void fix_sql_mode_var(THD *thd, enum_var_type type);
++static uchar *get_error_count(THD *thd);
++static uchar *get_warning_count(THD *thd);
++static uchar *get_tmpdir(THD *thd);
++static int sys_check_log_path(THD *thd, set_var *var);
++static bool sys_update_general_log_path(THD *thd, set_var * var);
++static void sys_default_general_log_path(THD *thd, enum_var_type type);
++static bool sys_update_slow_log_path(THD *thd, set_var * var);
++static void sys_default_slow_log_path(THD *thd, enum_var_type type);
++static uchar *get_myisam_mmap_size(THD *thd);
++static int check_max_allowed_packet(THD *thd, set_var *var);
++static int check_net_buffer_length(THD *thd, set_var *var);
++
++/*
++ Variable definition list
++
++ These are variables that can be set from the command line, in
++ alphabetic order.
++
++ The variables are linked into the list. A variable is added to
++ it in the constructor (see sys_var class for details).
++*/
++
++static sys_var_chain vars = { NULL, NULL };
++
++static sys_var_thd_ulong
++sys_auto_increment_increment(&vars, "auto_increment_increment",
++ &SV::auto_increment_increment, NULL, NULL,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_thd_ulong
++sys_auto_increment_offset(&vars, "auto_increment_offset",
++ &SV::auto_increment_offset, NULL, NULL,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++
++static sys_var_bool_ptr sys_automatic_sp_privileges(&vars, "automatic_sp_privileges",
++ &sp_automatic_privileges);
++
++static sys_var_const sys_back_log(&vars, "back_log",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*) &back_log);
++static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
++static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
++ &binlog_cache_size);
++static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
++ &SV::binlog_format);
++static sys_var_thd_bool sys_binlog_direct_non_trans_update(&vars, "binlog_direct_non_transactional_updates",
++ &SV::binlog_direct_non_trans_update);
++static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
++ &SV::bulk_insert_buff_size);
++static sys_var_const_os sys_character_sets_dir(&vars,
++ "character_sets_dir",
++ OPT_GLOBAL, SHOW_CHAR,
++ (uchar*)
++ mysql_charsets_dir);
++static sys_var_character_set_sv
++sys_character_set_server(&vars, "character_set_server",
++ &SV::collation_server, &default_charset_info, 0,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++sys_var_const_str sys_charset_system(&vars, "character_set_system",
++ (char *)my_charset_utf8_general_ci.name);
++static sys_var_character_set_database
++sys_character_set_database(&vars, "character_set_database",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_character_set_client
++sys_character_set_client(&vars, "character_set_client",
++ &SV::character_set_client,
++ &default_charset_info,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_character_set_sv
++sys_character_set_connection(&vars, "character_set_connection",
++ &SV::collation_connection,
++ &default_charset_info, 0,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_character_set_sv sys_character_set_results(&vars, "character_set_results",
++ &SV::character_set_results,
++ &default_charset_info, true);
++static sys_var_character_set_sv sys_character_set_filesystem(&vars, "character_set_filesystem",
++ &SV::character_set_filesystem,
++ &character_set_filesystem);
++static sys_var_thd_ulong sys_completion_type(&vars, "completion_type",
++ &SV::completion_type,
++ check_completion_type,
++ fix_completion_type);
++static sys_var_collation_sv
++sys_collation_connection(&vars, "collation_connection",
++ &SV::collation_connection, &default_charset_info,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_collation_sv
++sys_collation_database(&vars, "collation_database", &SV::collation_database,
++ &default_charset_info,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_collation_sv
++sys_collation_server(&vars, "collation_server", &SV::collation_server,
++ &default_charset_info,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert",
++ &myisam_concurrent_insert);
++static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
++ &connect_timeout);
++static sys_var_const_os_str sys_datadir(&vars, "datadir", mysql_real_data_home);
++#ifndef DBUG_OFF
++static sys_var_thd_dbug sys_dbug(&vars, "debug");
++#endif
++static sys_var_enum sys_delay_key_write(&vars, "delay_key_write",
++ &delay_key_write_options,
++ &delay_key_write_typelib,
++ fix_delay_key_write);
++static sys_var_long_ptr sys_delayed_insert_limit(&vars, "delayed_insert_limit",
++ &delayed_insert_limit);
++static sys_var_long_ptr sys_delayed_insert_timeout(&vars, "delayed_insert_timeout",
++ &delayed_insert_timeout);
++static sys_var_long_ptr sys_delayed_queue_size(&vars, "delayed_queue_size",
++ &delayed_queue_size);
++
++#ifdef HAVE_EVENT_SCHEDULER
++static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
++#endif
++
++static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
++ &expire_logs_days);
++static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
++static sys_var_long_ptr sys_flush_time(&vars, "flush_time", &flush_time);
++static sys_var_str sys_ft_boolean_syntax(&vars, "ft_boolean_syntax",
++ sys_check_ftb_syntax,
++ sys_update_ftb_syntax,
++ sys_default_ftb_syntax,
++ ft_boolean_syntax);
++static sys_var_const sys_ft_max_word_len(&vars, "ft_max_word_len",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*) &ft_max_word_len);
++static sys_var_const sys_ft_min_word_len(&vars, "ft_min_word_len",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*) &ft_min_word_len);
++static sys_var_const sys_ft_query_expansion_limit(&vars,
++ "ft_query_expansion_limit",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*)
++ &ft_query_expansion_limit);
++static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file",
++ OPT_GLOBAL, SHOW_CHAR_PTR,
++ (uchar*) &ft_stopword_file);
++
++static sys_var_const sys_ignore_builtin_innodb(&vars, "ignore_builtin_innodb",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_ignore_builtin_innodb);
++
++sys_var_str sys_init_connect(&vars, "init_connect", 0,
++ sys_update_init_connect,
++ sys_default_init_connect,0);
++static sys_var_const sys_init_file(&vars, "init_file",
++ OPT_GLOBAL, SHOW_CHAR_PTR,
++ (uchar*) &opt_init_file);
++sys_var_str sys_init_slave(&vars, "init_slave", 0,
++ sys_update_init_slave,
++ sys_default_init_slave,0);
++static sys_var_thd_ulong sys_interactive_timeout(&vars, "interactive_timeout",
++ &SV::net_interactive_timeout);
++static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
++ &SV::join_buff_size);
++static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
++static sys_var_key_cache_long sys_key_cache_block_size(&vars, "key_cache_block_size",
++ offsetof(KEY_CACHE,
++ param_block_size));
++static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_division_limit",
++ offsetof(KEY_CACHE,
++ param_division_limit));
++static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
++ offsetof(KEY_CACHE,
++ param_age_threshold));
++static sys_var_const sys_language(&vars, "language",
++ OPT_GLOBAL, SHOW_CHAR,
++ (uchar*) language);
++static sys_var_const sys_large_files_support(&vars, "large_files_support",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_large_files);
++static sys_var_const sys_large_page_size(&vars, "large_page_size",
++ OPT_GLOBAL, SHOW_INT,
++ (uchar*) &opt_large_page_size);
++static sys_var_const sys_large_pages(&vars, "large_pages",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*) &opt_large_pages);
++static sys_var_bool_ptr sys_local_infile(&vars, "local_infile",
++ &opt_local_infile);
++#ifdef HAVE_MLOCKALL
++static sys_var_const sys_locked_in_memory(&vars, "locked_in_memory",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*) &locked_in_memory);
++#endif
++static sys_var_const sys_log_bin(&vars, "log_bin",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_bin_log);
++static sys_var_trust_routine_creators
++sys_trust_routine_creators(&vars, "log_bin_trust_routine_creators",
++ &trust_function_creators);
++static sys_var_bool_ptr
++sys_trust_function_creators(&vars, "log_bin_trust_function_creators",
++ &trust_function_creators);
++static sys_var_const sys_log_error(&vars, "log_error",
++ OPT_GLOBAL, SHOW_CHAR,
++ (uchar*) log_error_file);
++static sys_var_bool_ptr
++ sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes",
++ &opt_log_queries_not_using_indexes);
++static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
++static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time",
++ &SV::long_query_time);
++static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates",
++ &SV::low_priority_updates,
++ fix_low_priority_updates);
++#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
++static sys_var_thd_bool sys_sql_low_priority_updates(&vars, "sql_low_priority_updates",
++ &SV::low_priority_updates,
++ fix_low_priority_updates);
++#endif
++static sys_var_const sys_lower_case_file_system(&vars,
++ "lower_case_file_system",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*)
++ &lower_case_file_system);
++static sys_var_const sys_lower_case_table_names(&vars,
++ "lower_case_table_names",
++ OPT_GLOBAL, SHOW_INT,
++ (uchar*)
++ &lower_case_table_names);
++static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet",
++ &SV::max_allowed_packet,
++ check_max_allowed_packet);
++static sys_var_ulonglong_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size",
++ &max_binlog_cache_size);
++static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size",
++ &max_binlog_size,
++ fix_max_binlog_size);
++static sys_var_long_ptr sys_max_connections(&vars, "max_connections",
++ &max_connections,
++ fix_max_connections);
++static sys_var_long_ptr sys_max_connect_errors(&vars, "max_connect_errors",
++ &max_connect_errors);
++static sys_var_thd_ulong sys_max_insert_delayed_threads(&vars, "max_insert_delayed_threads",
++ &SV::max_insert_delayed_threads,
++ check_max_delayed_threads,
++ fix_max_connections);
++static sys_var_thd_ulong sys_max_delayed_threads(&vars, "max_delayed_threads",
++ &SV::max_insert_delayed_threads,
++ check_max_delayed_threads,
++ fix_max_connections);
++static sys_var_thd_ulong sys_max_error_count(&vars, "max_error_count",
++ &SV::max_error_count);
++static sys_var_thd_ulonglong sys_max_heap_table_size(&vars, "max_heap_table_size",
++ &SV::max_heap_table_size);
++static sys_var_thd_ulong sys_pseudo_thread_id(&vars, "pseudo_thread_id",
++ &SV::pseudo_thread_id,
++ check_pseudo_thread_id, 0,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_thd_ha_rows sys_max_join_size(&vars, "max_join_size",
++ &SV::max_join_size,
++ fix_max_join_size);
++static sys_var_thd_ulong sys_max_seeks_for_key(&vars, "max_seeks_for_key",
++ &SV::max_seeks_for_key);
++static sys_var_thd_ulong sys_max_length_for_sort_data(&vars, "max_length_for_sort_data",
++ &SV::max_length_for_sort_data);
++static sys_var_const sys_max_long_data_size(&vars,
++ "max_long_data_size",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*)
++ &max_long_data_size);
++
++#ifndef TO_BE_DELETED /* Alias for max_join_size */
++static sys_var_thd_ha_rows sys_sql_max_join_size(&vars, "sql_max_join_size",
++ &SV::max_join_size,
++ fix_max_join_size);
++#endif
++static sys_var_long_ptr_global
++sys_max_prepared_stmt_count(&vars, "max_prepared_stmt_count",
++ &max_prepared_stmt_count,
++ &LOCK_prepared_stmt_count);
++static sys_var_long_ptr sys_max_relay_log_size(&vars, "max_relay_log_size",
++ &max_relay_log_size,
++ fix_max_relay_log_size);
++static sys_var_thd_ulong sys_max_sort_length(&vars, "max_sort_length",
++ &SV::max_sort_length);
++static sys_var_thd_ulong sys_max_sp_recursion_depth(&vars, "max_sp_recursion_depth",
++ &SV::max_sp_recursion_depth);
++static sys_var_max_user_conn sys_max_user_connections(&vars, "max_user_connections");
++static sys_var_thd_ulong sys_max_tmp_tables(&vars, "max_tmp_tables",
++ &SV::max_tmp_tables);
++static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
++ &max_write_lock_count);
++static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit",
++ &SV::min_examined_row_limit);
++static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count",
++ &SV::multi_range_count);
++static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
++ &myisam_data_pointer_size);
++static sys_var_thd_ulonglong sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
++static sys_var_const sys_myisam_recover_options(&vars, "myisam_recover_options",
++ OPT_GLOBAL, SHOW_CHAR_PTR,
++ (uchar*)
++ &myisam_recover_options_str);
++static sys_var_thd_ulong sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads);
++static sys_var_thd_ulong sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
++static sys_var_bool_ptr sys_myisam_use_mmap(&vars, "myisam_use_mmap",
++ &opt_myisam_use_mmap);
++
++static sys_var_thd_enum sys_myisam_stats_method(&vars, "myisam_stats_method",
++ &SV::myisam_stats_method,
++ &myisam_stats_method_typelib,
++ NULL);
++
++#ifdef __NT__
++/* purecov: begin inspected */
++static sys_var_const sys_named_pipe(&vars, "named_pipe",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*) &opt_enable_named_pipe);
++/* purecov: end */
++#endif
++static sys_var_thd_ulong_session_readonly sys_net_buffer_length(&vars, "net_buffer_length",
++ &SV::net_buffer_length,
++ check_net_buffer_length);
++static sys_var_thd_ulong sys_net_read_timeout(&vars, "net_read_timeout",
++ &SV::net_read_timeout,
++ 0, fix_net_read_timeout);
++static sys_var_thd_ulong sys_net_write_timeout(&vars, "net_write_timeout",
++ &SV::net_write_timeout,
++ 0, fix_net_write_timeout);
++static sys_var_thd_ulong sys_net_retry_count(&vars, "net_retry_count",
++ &SV::net_retry_count,
++ 0, fix_net_retry_count);
++static sys_var_thd_bool sys_new_mode(&vars, "new", &SV::new_mode);
++static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
++ &global_system_variables.old_mode);
++/* these two cannot be static */
++sys_var_thd_bool sys_old_alter_table(&vars, "old_alter_table",
++ &SV::old_alter_table);
++sys_var_thd_bool sys_old_passwords(&vars, "old_passwords", &SV::old_passwords);
++static sys_var_const sys_open_files_limit(&vars, "open_files_limit",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*)
++ &open_files_limit);
++static sys_var_thd_ulong sys_optimizer_prune_level(&vars, "optimizer_prune_level",
++ &SV::optimizer_prune_level);
++static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_search_depth",
++ &SV::optimizer_search_depth);
++static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
++ &SV::optimizer_switch);
++static sys_var_const sys_pid_file(&vars, "pid_file",
++ OPT_GLOBAL, SHOW_CHAR,
++ (uchar*) pidfile_name);
++static sys_var_const_os sys_plugin_dir(&vars, "plugin_dir",
++ OPT_GLOBAL, SHOW_CHAR,
++ (uchar*) opt_plugin_dir);
++static sys_var_const sys_port(&vars, "port",
++ OPT_GLOBAL, SHOW_INT,
++ (uchar*) &mysqld_port);
++static sys_var_thd_ulong sys_preload_buff_size(&vars, "preload_buffer_size",
++ &SV::preload_buff_size);
++static sys_var_const sys_protocol_version(&vars, "protocol_version",
++ OPT_GLOBAL, SHOW_INT,
++ (uchar*)
++ &protocol_version);
++static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size",
++ &SV::read_buff_size);
++static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly);
++static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
++ &SV::read_rnd_buff_size);
++static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
++ &SV::div_precincrement);
++static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
++ &rpl_recovery_rank);
++static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
++ &query_cache_size,
++ fix_query_cache_size);
++
++static sys_var_thd_ulong sys_range_alloc_block_size(&vars, "range_alloc_block_size",
++ &SV::range_alloc_block_size);
++static sys_var_thd_ulong sys_query_alloc_block_size(&vars, "query_alloc_block_size",
++ &SV::query_alloc_block_size,
++ 0, fix_thd_mem_root);
++static sys_var_thd_ulong sys_query_prealloc_size(&vars, "query_prealloc_size",
++ &SV::query_prealloc_size,
++ 0, fix_thd_mem_root);
++#ifdef HAVE_SMEM
++/* purecov: begin tested */
++static sys_var_const sys_shared_memory(&vars, "shared_memory",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*)
++ &opt_enable_shared_memory);
++static sys_var_const sys_shared_memory_base_name(&vars,
++ "shared_memory_base_name",
++ OPT_GLOBAL, SHOW_CHAR_PTR,
++ (uchar*)
++ &shared_memory_base_name);
++/* purecov: end */
++#endif
++static sys_var_const sys_skip_external_locking(&vars,
++ "skip_external_locking",
++ OPT_GLOBAL, SHOW_MY_BOOL,
++ (uchar*)
++ &my_disable_locking);
++static sys_var_const sys_skip_networking(&vars, "skip_networking",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_disable_networking);
++static sys_var_const sys_skip_show_database(&vars, "skip_show_database",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_skip_show_db);
++
++static sys_var_const sys_skip_name_resolve(&vars, "skip_name_resolve",
++ OPT_GLOBAL, SHOW_BOOL,
++ (uchar*) &opt_skip_name_resolve);
++
++static sys_var_const sys_socket(&vars, "socket",
++ OPT_GLOBAL, SHOW_CHAR_PTR,
++ (uchar*) &mysqld_unix_port);
++
++#ifdef HAVE_THR_SETCONCURRENCY
++/* purecov: begin tested */
++static sys_var_const sys_thread_concurrency(&vars, "thread_concurrency",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*) &concurrency);
++/* purecov: end */
++#endif
++static sys_var_const sys_thread_stack(&vars, "thread_stack",
++ OPT_GLOBAL, SHOW_LONG,
++ (uchar*) &my_thread_stack_size);
++static sys_var_readonly_os sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
++static sys_var_thd_ulong sys_trans_alloc_block_size(&vars, "transaction_alloc_block_size",
++ &SV::trans_alloc_block_size,
++ 0, fix_trans_mem_root);
++static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
++ &SV::trans_prealloc_size,
++ 0, fix_trans_mem_root);
++sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
++ &SV::thread_handling,
++ &thread_handling_typelib,
++ NULL);
++
++#ifdef HAVE_QUERY_CACHE
++static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit",
++ &query_cache.query_cache_limit);
++static sys_var_long_ptr sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
++ &query_cache_min_res_unit,
++ fix_query_cache_min_res_unit);
++static sys_var_thd_enum sys_query_cache_type(&vars, "query_cache_type",
++ &SV::query_cache_type,
++ &query_cache_type_typelib);
++static sys_var_thd_bool
++sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
++ &SV::query_cache_wlock_invalidate);
++#endif /* HAVE_QUERY_CACHE */
++static sys_var_bool_ptr sys_secure_auth(&vars, "secure_auth", &opt_secure_auth);
++static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
++ &opt_secure_file_priv);
++static sys_var_long_ptr sys_server_id(&vars, "server_id", &server_id, fix_server_id);
++static sys_var_bool_ptr sys_slave_compressed_protocol(&vars, "slave_compressed_protocol",
++ &opt_slave_compressed_protocol);
++static sys_var_set_slave_mode slave_exec_mode(&vars,
++ "slave_exec_mode",
++ &slave_exec_mode_options,
++ &slave_exec_mode_typelib,
++ 0);
++static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
++ &slow_launch_time);
++static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size",
++ &SV::sortbuff_size);
++/*
++ sql_mode should *not* have binlog_mode=SESSION_VARIABLE_IN_BINLOG:
++ even though it is written to the binlog, the slave ignores the
++ MODE_NO_DIR_IN_CREATE variable, so slave's value differs from
++ master's (see log_event.cc: Query_log_event::do_apply_event()).
++*/
++static sys_var_thd_sql_mode sys_sql_mode(&vars, "sql_mode",
++ &SV::sql_mode);
++#ifdef HAVE_OPENSSL
++extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
++ *opt_ssl_key;
++static sys_var_const_os_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca);
++static sys_var_const_os_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath);
++static sys_var_const_os_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert);
++static sys_var_const_os_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher);
++static sys_var_const_os_str_ptr sys_ssl_key(&vars, "ssl_key", &opt_ssl_key);
++#else
++static sys_var_const_os_str sys_ssl_ca(&vars, "ssl_ca", NULL);
++static sys_var_const_os_str sys_ssl_capath(&vars, "ssl_capath", NULL);
++static sys_var_const_os_str sys_ssl_cert(&vars, "ssl_cert", NULL);
++static sys_var_const_os_str sys_ssl_cipher(&vars, "ssl_cipher", NULL);
++static sys_var_const_os_str sys_ssl_key(&vars, "ssl_key", NULL);
++#endif
++static sys_var_thd_enum
++sys_updatable_views_with_limit(&vars, "updatable_views_with_limit",
++ &SV::updatable_views_with_limit,
++ &updatable_views_with_limit_typelib);
++
++static sys_var_thd_table_type sys_table_type(&vars, "table_type",
++ &SV::table_plugin);
++static sys_var_thd_storage_engine sys_storage_engine(&vars, "storage_engine",
++ &SV::table_plugin);
++static sys_var_bool_ptr sys_sync_frm(&vars, "sync_frm", &opt_sync_frm);
++static sys_var_const_str sys_system_time_zone(&vars, "system_time_zone",
++ system_time_zone);
++static sys_var_long_ptr sys_table_def_size(&vars, "table_definition_cache",
++ &table_def_size);
++static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
++ &table_cache_size);
++static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
++ &table_lock_wait_timeout);
++
++#if defined(ENABLED_DEBUG_SYNC)
++/* Debug Sync Facility. Implemented in debug_sync.cc. */
++static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
++#endif /* defined(ENABLED_DEBUG_SYNC) */
++
++static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
++ &thread_cache_size);
++#if HAVE_POOL_OF_THREADS == 1
++sys_var_long_ptr sys_thread_pool_size(&vars, "thread_pool_size",
++ &thread_pool_size);
++#endif
++static sys_var_thd_enum sys_tx_isolation(&vars, "tx_isolation",
++ &SV::tx_isolation,
++ &tx_isolation_typelib,
++ fix_tx_isolation,
++ check_tx_isolation);
++static sys_var_thd_ulonglong sys_tmp_table_size(&vars, "tmp_table_size",
++ &SV::tmp_table_size);
++static sys_var_bool_ptr sys_timed_mutexes(&vars, "timed_mutexes",
++ &timed_mutexes);
++static sys_var_const_str sys_version(&vars, "version", server_version);
++static sys_var_const_str sys_version_comment(&vars, "version_comment",
++ MYSQL_COMPILATION_COMMENT);
++static sys_var_const_str sys_version_compile_machine(&vars, "version_compile_machine",
++ MACHINE_TYPE);
++static sys_var_const_str sys_version_compile_os(&vars, "version_compile_os",
++ SYSTEM_TYPE);
++static sys_var_thd_ulong sys_net_wait_timeout(&vars, "wait_timeout",
++ &SV::net_wait_timeout);
++
++/* Condition pushdown to storage engine */
++static sys_var_thd_bool
++sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
++ &SV::engine_condition_pushdown);
++
++#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
++/* ndb thread specific variable settings */
++static sys_var_thd_ulong
++sys_ndb_autoincrement_prefetch_sz(&vars, "ndb_autoincrement_prefetch_sz",
++ &SV::ndb_autoincrement_prefetch_sz);
++static sys_var_thd_bool
++sys_ndb_force_send(&vars, "ndb_force_send", &SV::ndb_force_send);
++#ifdef HAVE_NDB_BINLOG
++static sys_var_long_ptr
++sys_ndb_report_thresh_binlog_epoch_slip(&vars, "ndb_report_thresh_binlog_epoch_slip",
++ &ndb_report_thresh_binlog_epoch_slip);
++static sys_var_long_ptr
++sys_ndb_report_thresh_binlog_mem_usage(&vars, "ndb_report_thresh_binlog_mem_usage",
++ &ndb_report_thresh_binlog_mem_usage);
++#endif
++static sys_var_thd_bool
++sys_ndb_use_exact_count(&vars, "ndb_use_exact_count", &SV::ndb_use_exact_count);
++static sys_var_thd_bool
++sys_ndb_use_transactions(&vars, "ndb_use_transactions", &SV::ndb_use_transactions);
++static sys_var_long_ptr
++sys_ndb_cache_check_time(&vars, "ndb_cache_check_time", &ndb_cache_check_time);
++static sys_var_const_str
++sys_ndb_connectstring(&vars, "ndb_connectstring", opt_ndb_constrbuf);
++static sys_var_thd_bool
++sys_ndb_index_stat_enable(&vars, "ndb_index_stat_enable",
++ &SV::ndb_index_stat_enable);
++static sys_var_thd_ulong
++sys_ndb_index_stat_cache_entries(&vars, "ndb_index_stat_cache_entries",
++ &SV::ndb_index_stat_cache_entries);
++static sys_var_thd_ulong
++sys_ndb_index_stat_update_freq(&vars, "ndb_index_stat_update_freq",
++ &SV::ndb_index_stat_update_freq);
++static sys_var_long_ptr
++sys_ndb_extra_logging(&vars, "ndb_extra_logging", &ndb_extra_logging);
++static sys_var_thd_bool
++sys_ndb_use_copying_alter_table(&vars, "ndb_use_copying_alter_table", &SV::ndb_use_copying_alter_table);
++#endif //WITH_NDBCLUSTER_STORAGE_ENGINE
++
++/* Time/date/datetime formats */
++
++static sys_var_thd_date_time_format sys_time_format(&vars, "time_format",
++ &SV::time_format,
++ MYSQL_TIMESTAMP_TIME);
++static sys_var_thd_date_time_format sys_date_format(&vars, "date_format",
++ &SV::date_format,
++ MYSQL_TIMESTAMP_DATE);
++static sys_var_thd_date_time_format sys_datetime_format(&vars, "datetime_format",
++ &SV::datetime_format,
++ MYSQL_TIMESTAMP_DATETIME);
++
++/* Variables that are bits in THD */
++
++sys_var_thd_bit sys_autocommit(&vars, "autocommit", 0,
++ set_option_autocommit,
++ OPTION_NOT_AUTOCOMMIT,
++ 1);
++static sys_var_thd_bit sys_big_tables(&vars, "big_tables", 0,
++ set_option_bit,
++ OPTION_BIG_TABLES);
++#ifndef TO_BE_DELETED /* Alias for big_tables */
++static sys_var_thd_bit sys_sql_big_tables(&vars, "sql_big_tables", 0,
++ set_option_bit,
++ OPTION_BIG_TABLES);
++#endif
++static sys_var_thd_bit sys_big_selects(&vars, "sql_big_selects", 0,
++ set_option_bit,
++ OPTION_BIG_SELECTS);
++static sys_var_thd_bit sys_log_off(&vars, "sql_log_off",
++ check_log_update,
++ set_option_bit,
++ OPTION_LOG_OFF);
++static sys_var_thd_bit sys_log_update(&vars, "sql_log_update",
++ check_log_update,
++ set_log_update,
++ OPTION_BIN_LOG);
++static sys_var_thd_bit sys_log_binlog(&vars, "sql_log_bin",
++ check_log_update,
++ set_option_log_bin_bit,
++ OPTION_BIN_LOG);
++static sys_var_thd_bit sys_sql_warnings(&vars, "sql_warnings", 0,
++ set_option_bit,
++ OPTION_WARNINGS);
++static sys_var_thd_bit sys_sql_notes(&vars, "sql_notes", 0,
++ set_option_bit,
++ OPTION_SQL_NOTES);
++static sys_var_thd_bit sys_auto_is_null(&vars, "sql_auto_is_null", 0,
++ set_option_bit,
++ OPTION_AUTO_IS_NULL, 0,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_thd_bit sys_safe_updates(&vars, "sql_safe_updates", 0,
++ set_option_bit,
++ OPTION_SAFE_UPDATES);
++static sys_var_thd_bit sys_buffer_results(&vars, "sql_buffer_result", 0,
++ set_option_bit,
++ OPTION_BUFFER_RESULT);
++static sys_var_thd_bit sys_quote_show_create(&vars, "sql_quote_show_create", 0,
++ set_option_bit,
++ OPTION_QUOTE_SHOW_CREATE);
++static sys_var_thd_bit sys_foreign_key_checks(&vars, "foreign_key_checks", 0,
++ set_option_bit,
++ OPTION_NO_FOREIGN_KEY_CHECKS,
++ 1, sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_thd_bit sys_unique_checks(&vars, "unique_checks", 0,
++ set_option_bit,
++ OPTION_RELAXED_UNIQUE_CHECKS,
++ 1,
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++static sys_var_thd_bit sys_profiling(&vars, "profiling", NULL,
++ set_option_bit,
++ ulonglong(OPTION_PROFILING));
++static sys_var_thd_ulong sys_profiling_history_size(&vars, "profiling_history_size",
++ &SV::profiling_history_size);
++#endif
++
++/* Local state variables */
++
++static sys_var_thd_ha_rows sys_select_limit(&vars, "sql_select_limit",
++ &SV::select_limit);
++static sys_var_timestamp sys_timestamp(&vars, "timestamp",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_last_insert_id
++sys_last_insert_id(&vars, "last_insert_id",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++/*
++ identity is an alias for last_insert_id(), so that we are compatible
++ with Sybase
++*/
++static sys_var_last_insert_id
++sys_identity(&vars, "identity", sys_var::SESSION_VARIABLE_IN_BINLOG);
++
++static sys_var_thd_lc_time_names
++sys_lc_time_names(&vars, "lc_time_names", sys_var::SESSION_VARIABLE_IN_BINLOG);
++
++/*
++ insert_id should *not* be marked as written to the binlog (i.e., it
++ should *not* have binlog_status==SESSION_VARIABLE_IN_BINLOG),
++ because we want any statement that refers to insert_id explicitly to
++ be unsafe. (By "explicitly", we mean using @@session.insert_id,
++ whereas insert_id is used "implicitly" when NULL value is inserted
++ into an auto_increment column).
++
++ We want statements referring explicitly to @@session.insert_id to be
++ unsafe, because insert_id is modified internally by the slave sql
++ thread when NULL values are inserted in an AUTO_INCREMENT column.
++ This modification interfers with the value of the
++ @@session.insert_id variable if @@session.insert_id is referred
++ explicitly by an insert statement (as is seen by executing "SET
++ @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
++ AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
++ statement-based logging mode: t will be different on master and
++ slave).
++*/
++static sys_var_insert_id sys_insert_id(&vars, "insert_id");
++static sys_var_readonly sys_error_count(&vars, "error_count",
++ OPT_SESSION,
++ SHOW_LONG,
++ get_error_count);
++static sys_var_readonly sys_warning_count(&vars, "warning_count",
++ OPT_SESSION,
++ SHOW_LONG,
++ get_warning_count);
++
++static sys_var_rand_seed1 sys_rand_seed1(&vars, "rand_seed1",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++static sys_var_rand_seed2 sys_rand_seed2(&vars, "rand_seed2",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++
++static sys_var_thd_ulong sys_default_week_format(&vars, "default_week_format",
++ &SV::default_week_format);
++
++sys_var_thd_ulong sys_group_concat_max_len(&vars, "group_concat_max_len",
++ &SV::group_concat_max_len);
++
++sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
++ sys_var::SESSION_VARIABLE_IN_BINLOG);
++
++/* Global read-only variable containing hostname */
++static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
++
++#ifndef EMBEDDED_LIBRARY
++static sys_var_const_str_ptr sys_repl_report_host(&vars, "report_host", &report_host);
++static sys_var_const_str_ptr sys_repl_report_user(&vars, "report_user", &report_user);
++static sys_var_const_str_ptr sys_repl_report_password(&vars, "report_password", &report_password);
++
++static uchar *slave_get_report_port(THD *thd)
++{
++ thd->sys_var_tmp.long_value= report_port;
++ return (uchar*) &thd->sys_var_tmp.long_value;
++}
++
++static sys_var_readonly sys_repl_report_port(&vars, "report_port", OPT_GLOBAL, SHOW_LONG, slave_get_report_port);
++
++#endif
++
++sys_var_thd_bool sys_keep_files_on_create(&vars, "keep_files_on_create",
++ &SV::keep_files_on_create);
++/* Read only variables */
++
++static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
++static sys_var_have_variable sys_have_crypt(&vars, "have_crypt", &have_crypt);
++static sys_var_have_plugin sys_have_csv(&vars, "have_csv", C_STRING_WITH_LEN("csv"), MYSQL_STORAGE_ENGINE_PLUGIN);
++static sys_var_have_variable sys_have_dlopen(&vars, "have_dynamic_loading", &have_dlopen);
++static sys_var_have_variable sys_have_geometry(&vars, "have_geometry", &have_geometry);
++static sys_var_have_plugin sys_have_innodb(&vars, "have_innodb", C_STRING_WITH_LEN("innodb"), MYSQL_STORAGE_ENGINE_PLUGIN);
++static sys_var_have_plugin sys_have_ndbcluster(&vars, "have_ndbcluster", C_STRING_WITH_LEN("ndbcluster"), MYSQL_STORAGE_ENGINE_PLUGIN);
++static sys_var_have_variable sys_have_openssl(&vars, "have_openssl", &have_ssl);
++static sys_var_have_variable sys_have_ssl(&vars, "have_ssl", &have_ssl);
++static sys_var_have_plugin sys_have_partition_db(&vars, "have_partitioning", C_STRING_WITH_LEN("partition"), MYSQL_STORAGE_ENGINE_PLUGIN);
++static sys_var_have_variable sys_have_query_cache(&vars, "have_query_cache",
++ &have_query_cache);
++static sys_var_have_variable sys_have_community_features(&vars, "have_community_features", &have_community_features);
++static sys_var_have_variable sys_have_rtree_keys(&vars, "have_rtree_keys", &have_rtree_keys);
++static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
++/* Global read-only variable describing server license */
++static sys_var_const_str sys_license(&vars, "license", STRINGIFY_ARG(LICENSE));
++/* Global variables which enable|disable logging */
++static sys_var_log_state sys_var_general_log(&vars, "general_log", &opt_log,
++ QUERY_LOG_GENERAL);
++/* Synonym of "general_log" for consistency with SHOW VARIABLES output */
++static sys_var_log_state sys_var_log(&vars, "log", &opt_log,
++ QUERY_LOG_GENERAL);
++static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
++ QUERY_LOG_SLOW);
++/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
++static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
++ &opt_slow_log, QUERY_LOG_SLOW);
++sys_var_str sys_var_general_log_path(&vars, "general_log_file", sys_check_log_path,
++ sys_update_general_log_path,
++ sys_default_general_log_path,
++ opt_logname);
++sys_var_str sys_var_slow_log_path(&vars, "slow_query_log_file", sys_check_log_path,
++ sys_update_slow_log_path,
++ sys_default_slow_log_path,
++ opt_slow_logname);
++static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
++ &log_output_typelib, 0);
++static sys_var_readonly sys_myisam_mmap_size(&vars, "myisam_mmap_size",
++ OPT_GLOBAL,
++ SHOW_LONGLONG,
++ get_myisam_mmap_size);
++
++
++bool sys_var::check(THD *thd, set_var *var)
++{
++ var->save_result.ulonglong_value= var->value->val_int();
++ return 0;
++}
++
++bool sys_var_str::check(THD *thd, set_var *var)
++{
++ int res;
++ if (!check_func)
++ return 0;
++
++ if ((res=(*check_func)(thd, var)) < 0)
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
++ name, var->value->str_value.ptr());
++ return res;
++}
++
++/*
++ Functions to check and update variables
++*/
++
++
++/*
++ Update variables 'init_connect, init_slave'.
++
++ In case of 'DEFAULT' value
++ (for example: 'set GLOBAL init_connect=DEFAULT')
++ 'var' parameter is NULL pointer.
++*/
++
++bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
++ set_var *var)
++{
++ char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
++ uint new_length= (var ? var->value->str_value.length() : 0);
++ if (!old_value)
++ old_value= (char*) "";
++ if (!(res= my_strndup(old_value, new_length, MYF(0))))
++ return 1;
++ /*
++ Replace the old value in such a way that the any thread using
++ the value will work.
++ */
++ rw_wrlock(var_mutex);
++ old_value= var_str->value;
++ var_str->value= res;
++ var_str->value_length= new_length;
++ var_str->is_os_charset= FALSE;
++ rw_unlock(var_mutex);
++ my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
++ return 0;
++}
++
++
++static bool sys_update_init_connect(THD *thd, set_var *var)
++{
++ return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
++}
++
++
++static void sys_default_init_connect(THD* thd, enum_var_type type)
++{
++ update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
++}
++
++
++static bool sys_update_init_slave(THD *thd, set_var *var)
++{
++ return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
++}
++
++
++static void sys_default_init_slave(THD* thd, enum_var_type type)
++{
++ update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
++}
++
++static int sys_check_ftb_syntax(THD *thd, set_var *var)
++{
++ if (thd->security_ctx->master_access & SUPER_ACL)
++ return (ft_boolean_check_syntax_string((uchar*)
++ var->value->str_value.c_ptr()) ?
++ -1 : 0);
++ else
++ {
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
++ return 1;
++ }
++}
++
++static bool sys_update_ftb_syntax(THD *thd, set_var * var)
++{
++ strmake(ft_boolean_syntax, var->value->str_value.c_ptr(),
++ sizeof(ft_boolean_syntax)-1);
++
++#ifdef HAVE_QUERY_CACHE
++ query_cache.flush();
++#endif /* HAVE_QUERY_CACHE */
++
++ return 0;
++}
++
++static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
++{
++ strmake(ft_boolean_syntax, def_ft_boolean_syntax,
++ sizeof(ft_boolean_syntax)-1);
++}
++
++
++/**
++ If one sets the LOW_PRIORIY UPDATES flag, we also must change the
++ used lock type.
++*/
++
++static void fix_low_priority_updates(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ thr_upgraded_concurrent_insert_lock=
++ (global_system_variables.low_priority_updates ?
++ TL_WRITE_LOW_PRIORITY : TL_WRITE);
++ else
++ thd->update_lock_default= (thd->variables.low_priority_updates ?
++ TL_WRITE_LOW_PRIORITY : TL_WRITE);
++}
++
++
++static void
++fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
++{
++ myisam_max_temp_length=
++ (my_off_t) global_system_variables.myisam_max_sort_file_size;
++}
++
++/**
++ Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
++*/
++
++static void fix_max_join_size(THD *thd, enum_var_type type)
++{
++ if (type != OPT_GLOBAL)
++ {
++ if (thd->variables.max_join_size == HA_POS_ERROR)
++ thd->options|= OPTION_BIG_SELECTS;
++ else
++ thd->options&= ~OPTION_BIG_SELECTS;
++ }
++}
++
++
++/**
++ Can't change the 'next' tx_isolation while we are already in
++ a transaction
++*/
++static int check_tx_isolation(THD *thd, set_var *var)
++{
++ if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
++ {
++ my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
++ return 1;
++ }
++ return 0;
++}
++
++/*
++ If one doesn't use the SESSION modifier, the isolation level
++ is only active for the next command.
++*/
++static void fix_tx_isolation(THD *thd, enum_var_type type)
++{
++ if (type == OPT_SESSION)
++ thd->session_tx_isolation= ((enum_tx_isolation)
++ thd->variables.tx_isolation);
++}
++
++static void fix_completion_type(THD *thd __attribute__((unused)),
++ enum_var_type type __attribute__((unused))) {}
++
++static int check_completion_type(THD *thd, set_var *var)
++{
++ longlong val= var->value->val_int();
++ if (val < 0 || val > 2)
++ {
++ char buf[64];
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
++ return 1;
++ }
++ return 0;
++}
++
++
++/*
++ If we are changing the thread variable, we have to copy it to NET too
++*/
++
++#ifdef HAVE_REPLICATION
++static void fix_net_read_timeout(THD *thd, enum_var_type type)
++{
++ if (type != OPT_GLOBAL)
++ my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
++}
++
++
++static void fix_net_write_timeout(THD *thd, enum_var_type type)
++{
++ if (type != OPT_GLOBAL)
++ my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
++}
++
++static void fix_net_retry_count(THD *thd, enum_var_type type)
++{
++ if (type != OPT_GLOBAL)
++ thd->net.retry_count=thd->variables.net_retry_count;
++}
++#else /* HAVE_REPLICATION */
++static void fix_net_read_timeout(THD *thd __attribute__((unused)),
++ enum_var_type type __attribute__((unused)))
++{}
++static void fix_net_write_timeout(THD *thd __attribute__((unused)),
++ enum_var_type type __attribute__((unused)))
++{}
++static void fix_net_retry_count(THD *thd __attribute__((unused)),
++ enum_var_type type __attribute__((unused)))
++{}
++#endif /* HAVE_REPLICATION */
++
++
++static void fix_query_cache_size(THD *thd, enum_var_type type)
++{
++#ifdef HAVE_QUERY_CACHE
++ ulong new_cache_size= query_cache.resize(query_cache_size);
++
++ /*
++ Note: query_cache_size is a global variable reflecting the
++ requested cache size. See also query_cache_size_arg
++ */
++
++ if (query_cache_size != new_cache_size)
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
++ query_cache_size, new_cache_size);
++
++ query_cache_size= new_cache_size;
++#endif
++}
++
++
++#ifdef HAVE_QUERY_CACHE
++static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
++{
++ query_cache_min_res_unit=
++ query_cache.set_min_res_unit(query_cache_min_res_unit);
++}
++#endif
++
++
++extern void fix_delay_key_write(THD *thd, enum_var_type type)
++{
++ switch ((enum_delay_key_write) delay_key_write_options) {
++ case DELAY_KEY_WRITE_NONE:
++ myisam_delay_key_write=0;
++ break;
++ case DELAY_KEY_WRITE_ON:
++ myisam_delay_key_write=1;
++ break;
++ case DELAY_KEY_WRITE_ALL:
++ myisam_delay_key_write=1;
++ ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
++ break;
++ }
++}
++
++bool sys_var_set::update(THD *thd, set_var *var)
++{
++ *value= var->save_result.ulong_value;
++ return 0;
++}
++
++uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ char buff[256];
++ String tmp(buff, sizeof(buff), &my_charset_latin1);
++ ulong length;
++ ulong val= *value;
++
++ tmp.length(0);
++ for (uint i= 0; val; val>>= 1, i++)
++ {
++ if (val & 1)
++ {
++ tmp.append(enum_names->type_names[i],
++ enum_names->type_lengths[i]);
++ tmp.append(',');
++ }
++ }
++
++ if ((length= tmp.length()))
++ length--;
++ return (uchar*) thd->strmake(tmp.ptr(), length);
++}
++
++void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
++{
++ slave_exec_mode_options= SLAVE_EXEC_MODE_STRICT;
++}
++
++bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
++{
++ bool rc= sys_var_set::check(thd, var);
++ if (!rc && (var->save_result.ulong_value & SLAVE_EXEC_MODE_STRICT) &&
++ (var->save_result.ulong_value & SLAVE_EXEC_MODE_IDEMPOTENT))
++ {
++ rc= true;
++ my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
++ }
++ return rc;
++}
++
++bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
++{
++ bool rc;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ rc= sys_var_set::update(thd, var);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return rc;
++}
++
++void fix_slave_exec_mode(void)
++{
++ DBUG_ENTER("fix_slave_exec_mode");
++
++ if ((slave_exec_mode_options & SLAVE_EXEC_MODE_STRICT) &&
++ (slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
++ {
++ sql_print_error("Ambiguous slave modes combination. STRICT will be used");
++ slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT;
++ }
++ if (!(slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
++ slave_exec_mode_options|= SLAVE_EXEC_MODE_STRICT;
++ DBUG_VOID_RETURN;
++}
++
++
++bool sys_var_thd_binlog_format::check(THD *thd, set_var *var) {
++ /*
++ All variables that affect writing to binary log (either format or
++ turning logging on and off) use the same checking. We call the
++ superclass ::check function to assign the variable correctly, and
++ then check the value.
++ */
++ bool result= sys_var_thd_enum::check(thd, var);
++ if (!result)
++ result= check_log_update(thd, var);
++ return result;
++}
++
++
++bool sys_var_thd_binlog_format::is_readonly() const
++{
++ /*
++ Under certain circumstances, the variable is read-only (unchangeable):
++ */
++ THD *thd= current_thd;
++ /*
++ If RBR and open temporary tables, their CREATE TABLE may not be in the
++ binlog, so we can't toggle to SBR in this connection.
++ The test below will also prevent SET GLOBAL, well it was not easy to test
++ if global or not here.
++ And this test will also prevent switching from RBR to RBR (a no-op which
++ should not happen too often).
++
++ If we don't have row-based replication compiled in, the variable
++ is always read-only.
++ */
++ if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
++ thd->temporary_tables)
++ {
++ my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
++ return 1;
++ }
++ /*
++ if in a stored function/trigger, it's too late to change mode
++ */
++ if (thd->in_sub_stmt)
++ {
++ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
++ return 1;
++ }
++ return sys_var_thd_enum::is_readonly();
++}
++
++
++void fix_binlog_format_after_update(THD *thd, enum_var_type type)
++{
++ thd->reset_current_stmt_binlog_row_based();
++}
++
++
++static void fix_max_binlog_size(THD *thd, enum_var_type type)
++{
++ DBUG_ENTER("fix_max_binlog_size");
++ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
++ max_binlog_size, max_relay_log_size));
++ mysql_bin_log.set_max_size(max_binlog_size);
++#ifdef HAVE_REPLICATION
++ if (!max_relay_log_size)
++ active_mi->rli.relay_log.set_max_size(max_binlog_size);
++#endif
++ DBUG_VOID_RETURN;
++}
++
++static void fix_max_relay_log_size(THD *thd, enum_var_type type)
++{
++ DBUG_ENTER("fix_max_relay_log_size");
++ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
++ max_binlog_size, max_relay_log_size));
++#ifdef HAVE_REPLICATION
++ active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
++ max_relay_log_size: max_binlog_size);
++#endif
++ DBUG_VOID_RETURN;
++}
++
++
++static int check_max_delayed_threads(THD *thd, set_var *var)
++{
++ longlong val= var->value->val_int();
++ if (var->type != OPT_GLOBAL && val != 0 &&
++ val != (longlong) global_system_variables.max_insert_delayed_threads)
++ {
++ char buf[64];
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
++ return 1;
++ }
++ return 0;
++}
++
++static void fix_max_connections(THD *thd, enum_var_type type)
++{
++#ifndef EMBEDDED_LIBRARY
++ resize_thr_alarm(max_connections +
++ global_system_variables.max_insert_delayed_threads + 10);
++#endif
++}
++
++
++static void fix_thd_mem_root(THD *thd, enum_var_type type)
++{
++ if (type != OPT_GLOBAL)
++ reset_root_defaults(thd->mem_root,
++ thd->variables.query_alloc_block_size,
++ thd->variables.query_prealloc_size);
++}
++
++
++static void fix_trans_mem_root(THD *thd, enum_var_type type)
++{
++#ifdef USING_TRANSACTIONS
++ if (type != OPT_GLOBAL)
++ reset_root_defaults(&thd->transaction.mem_root,
++ thd->variables.trans_alloc_block_size,
++ thd->variables.trans_prealloc_size);
++#endif
++}
++
++
++static void fix_server_id(THD *thd, enum_var_type type)
++{
++ server_id_supplied = 1;
++ thd->server_id= server_id;
++}
++
++
++/**
++ Throw warning (error in STRICT mode) if value for variable needed bounding.
++ Only call from check(), not update(), because an error in update() would be
++ bad mojo. Plug-in interface also uses this.
++
++ @param thd thread handle
++ @param fixed did we have to correct the value? (throw warn/err if so)
++ @param unsignd is value's type unsigned?
++ @param name variable's name
++ @param val variable's value
++
++ @retval TRUE on error, FALSE otherwise (warning or OK)
++ */
++bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
++ const char *name, longlong val)
++{
++ if (fixed)
++ {
++ char buf[22];
++
++ if (unsignd)
++ ullstr((ulonglong) val, buf);
++ else
++ llstr(val, buf);
++
++ if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
++ return TRUE;
++ }
++
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_TRUNCATED_WRONG_VALUE,
++ ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
++ }
++ return FALSE;
++}
++
++
++/**
++ Get unsigned system-variable.
++ Negative value does not wrap around, but becomes zero.
++ Check user-supplied value for a systemvariable against bounds.
++ If we needed to adjust the value, throw a warning or error depending
++ on SQL-mode.
++
++ @param thd thread handle
++ @param var the system-variable to get
++ @param user_max a limit given with --maximum-variable-name=... or 0
++ @param var_type function will bound on systems where necessary.
++
++ @retval TRUE on error, FALSE otherwise (warning or OK)
++ */
++static bool get_unsigned(THD *thd, set_var *var, ulonglong user_max,
++ ulong var_type)
++{
++ int warnings= 0;
++ ulonglong unadjusted;
++ const struct my_option *limits= var->var->option_limits;
++ struct my_option fallback;
++
++ /* get_unsigned() */
++ if (var->value->unsigned_flag)
++ var->save_result.ulonglong_value= (ulonglong) var->value->val_int();
++ else
++ {
++ longlong v= var->value->val_int();
++ var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v);
++ if (v < 0)
++ {
++ warnings++;
++ if (throw_bounds_warning(thd, TRUE, FALSE, var->var->name, v))
++ return TRUE; /* warning was promoted to error, give up */
++ }
++ }
++
++ unadjusted= var->save_result.ulonglong_value;
++
++ /* max, if any */
++
++ if ((user_max > 0) && (unadjusted > user_max))
++ {
++ var->save_result.ulonglong_value= user_max;
++
++ if ((warnings == 0) && throw_bounds_warning(thd, TRUE, TRUE,
++ var->var->name,
++ (longlong) unadjusted))
++ return TRUE;
++
++ warnings++;
++ }
++
++ /*
++ if the sysvar doesn't have a proper bounds record but the check
++ function would like bounding to ULONG where its size differs from
++ that of ULONGLONG, we make up a bogus limits record here and let
++ the usual suspects handle the actual limiting.
++ */
++
++ if (!limits && var_type != GET_ULL)
++ {
++ bzero(&fallback, sizeof(fallback));
++ fallback.var_type= var_type;
++ limits= &fallback;
++ }
++
++ /* fix_unsigned() */
++ if (limits)
++ {
++ my_bool fixed;
++
++ var->save_result.ulonglong_value= getopt_ull_limit_value(var->save_result.
++ ulonglong_value,
++ limits, &fixed);
++
++ if ((warnings == 0) && throw_bounds_warning(thd, fixed, TRUE,
++ var->var->name,
++ (longlong) unadjusted))
++ return TRUE;
++ }
++
++ return FALSE;
++}
++
++
++sys_var_long_ptr::
++sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
++ sys_after_update_func after_update_arg)
++ :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
++ &LOCK_global_system_variables, after_update_arg)
++{}
++
++
++bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, 0, GET_ULONG);
++}
++
++bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
++{
++ pthread_mutex_lock(guard);
++ *value= (ulong) var->save_result.ulonglong_value;
++ pthread_mutex_unlock(guard);
++ return 0;
++}
++
++
++void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
++{
++ my_bool not_used;
++ pthread_mutex_lock(guard);
++ *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
++ option_limits, ¬_used);
++ pthread_mutex_unlock(guard);
++}
++
++
++bool sys_var_ulonglong_ptr::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, 0, GET_ULL);
++}
++
++
++bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
++{
++ ulonglong tmp= var->save_result.ulonglong_value;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ *value= (ulonglong) tmp;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return 0;
++}
++
++
++void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
++{
++ my_bool not_used;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
++ option_limits, ¬_used);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++
++bool sys_var_bool_ptr::update(THD *thd, set_var *var)
++{
++ *value= (my_bool) var->save_result.ulong_value;
++ return 0;
++}
++
++
++void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
++{
++ *value= (my_bool) option_limits->def_value;
++}
++
++
++bool sys_var_enum::update(THD *thd, set_var *var)
++{
++ *value= (uint) var->save_result.ulong_value;
++ return 0;
++}
++
++
++uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
++{
++ return (uchar*) enum_names->type_names[*value];
++}
++
++
++uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ return (uchar*) enum_names->type_names[global_system_variables.*offset];
++}
++
++bool sys_var_thd_ulong::check(THD *thd, set_var *var)
++{
++ if (get_unsigned(thd, var, max_system_variables.*offset, GET_ULONG))
++ return TRUE;
++ DBUG_ASSERT(var->save_result.ulonglong_value <= ULONG_MAX);
++ return ((check_func && (*check_func)(thd, var)));
++}
++
++bool sys_var_thd_ulong::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) var->save_result.ulonglong_value;
++ else
++ thd->variables.*offset= (ulong) var->save_result.ulonglong_value;
++
++ return 0;
++}
++
++
++void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ {
++ my_bool not_used;
++ /* We will not come here if option_limits is not set */
++ global_system_variables.*offset=
++ (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
++ option_limits, ¬_used);
++ }
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ return (uchar*) &(global_system_variables.*offset);
++ return (uchar*) &(thd->variables.*offset);
++}
++
++
++bool sys_var_thd_ha_rows::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, max_system_variables.*offset,
++#ifdef BIG_TABLES
++ GET_ULL
++#else
++ GET_ULONG
++#endif
++ );
++}
++
++
++bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ {
++ /* Lock is needed to make things safe on 32 bit systems */
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset= (ha_rows)
++ var->save_result.ulonglong_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= (ha_rows) var->save_result.ulonglong_value;
++ return 0;
++}
++
++
++void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ {
++ my_bool not_used;
++ /* We will not come here if option_limits is not set */
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset=
++ (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
++ option_limits, ¬_used);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ return (uchar*) &(global_system_variables.*offset);
++ return (uchar*) &(thd->variables.*offset);
++}
++
++bool sys_var_thd_ulonglong::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, max_system_variables.*offset, GET_ULL);
++}
++
++bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ {
++ /* Lock is needed to make things safe on 32 bit systems */
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset= (ulonglong)
++ var->save_result.ulonglong_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= (ulonglong) var->save_result.ulonglong_value;
++ return 0;
++}
++
++
++void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ {
++ my_bool not_used;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset=
++ getopt_ull_limit_value((ulonglong) option_limits->def_value,
++ option_limits, ¬_used);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++uchar *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ return (uchar*) &(global_system_variables.*offset);
++ return (uchar*) &(thd->variables.*offset);
++}
++
++
++bool sys_var_thd_bool::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
++ else
++ thd->variables.*offset= (my_bool) var->save_result.ulong_value;
++ return 0;
++}
++
++
++void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (my_bool) option_limits->def_value;
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++uchar *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ return (uchar*) &(global_system_variables.*offset);
++ return (uchar*) &(thd->variables.*offset);
++}
++
++
++bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ const char *value;
++ String str(buff, sizeof(buff), system_charset_info), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ if (!(res=var->value->val_str(&str)) ||
++ ((long) (var->save_result.ulong_value=
++ (ulong) find_type(enum_names, res->ptr(),
++ res->length(),1)-1)) < 0)
++ {
++ value= res ? res->c_ptr() : "NULL";
++ goto err;
++ }
++ }
++ else
++ {
++ ulonglong tmp=var->value->val_int();
++ if (tmp >= enum_names->count)
++ {
++ llstr(tmp,buff);
++ value=buff; // Wrong value is here
++ goto err;
++ }
++ var->save_result.ulong_value= (ulong) tmp; // Save for update
++ }
++ return 0;
++
++err:
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
++ return 1;
++}
++
++
++bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
++{
++ bool not_used;
++ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
++ uint error_len= 0;
++ String str(buff, sizeof(buff), system_charset_info), *res;
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ if (!(res= var->value->val_str(&str)))
++ {
++ strmov(buff, "NULL");
++ goto err;
++ }
++
++ if (!m_allow_empty_value &&
++ res->length() == 0)
++ {
++ buff[0]= 0;
++ goto err;
++ }
++
++ var->save_result.ulong_value= ((ulong)
++ find_set(enum_names, res->c_ptr_safe(),
++ res->length(),
++ NULL,
++ &error, &error_len,
++ ¬_used));
++ if (error_len)
++ {
++ strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ goto err;
++ }
++ }
++ else
++ {
++ ulonglong tmp= var->value->val_int();
++
++ if (!m_allow_empty_value &&
++ tmp == 0)
++ {
++ buff[0]= '0';
++ buff[1]= 0;
++ goto err;
++ }
++
++ /*
++ For when the enum is made to contain 64 elements, as 1ULL<<64 is
++ undefined, we guard with a "count<64" test.
++ */
++ if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
++ (enum_names->count < 64)))
++ {
++ llstr(tmp, buff);
++ goto err;
++ }
++ var->save_result.ulong_value= (ulong) tmp; // Save for update
++ }
++ return 0;
++
++err:
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
++ return 1;
++}
++
++
++CHARSET_INFO *sys_var::charset(THD *thd)
++{
++ return is_os_charset ? thd->variables.character_set_filesystem :
++ system_charset_info;
++}
++
++
++bool sys_var_thd_enum::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.ulong_value;
++ else
++ thd->variables.*offset= var->save_result.ulong_value;
++ return 0;
++}
++
++
++void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= (ulong) option_limits->def_value;
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ ulong tmp= ((type == OPT_GLOBAL) ?
++ global_system_variables.*offset :
++ thd->variables.*offset);
++ return (uchar*) enum_names->type_names[tmp];
++}
++
++bool sys_var_thd_bit::check(THD *thd, set_var *var)
++{
++ return (check_enum(thd, var, &bool_typelib) ||
++ (check_func && (*check_func)(thd, var)));
++}
++
++bool sys_var_thd_bit::update(THD *thd, set_var *var)
++{
++ int res= (*update_func)(thd, var);
++ return res;
++}
++
++
++uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ /*
++ If reverse is 0 (default) return 1 if bit is set.
++ If reverse is 1, return 0 if bit is set
++ */
++ thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
++ !reverse : reverse);
++ return (uchar*) &thd->sys_var_tmp.my_bool_value;
++}
++
++
++/** Update a date_time format variable based on given value. */
++
++void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
++ DATE_TIME_FORMAT *new_value)
++{
++ DATE_TIME_FORMAT *old;
++ DBUG_ENTER("sys_var_date_time_format::update2");
++ DBUG_DUMP("positions", (uchar*) new_value->positions,
++ sizeof(new_value->positions));
++
++ if (type == OPT_GLOBAL)
++ {
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ old= (global_system_variables.*offset);
++ (global_system_variables.*offset)= new_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ {
++ old= (thd->variables.*offset);
++ (thd->variables.*offset)= new_value;
++ }
++ my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR));
++ DBUG_VOID_RETURN;
++}
++
++
++bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
++{
++ DATE_TIME_FORMAT *new_value;
++ /* We must make a copy of the last value to get it into normal memory */
++ new_value= date_time_format_copy((THD*) 0,
++ var->save_result.date_time_format);
++ if (!new_value)
++ return 1; // Out of memory
++ update2(thd, var->type, new_value); // Can't fail
++ return 0;
++}
++
++
++bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ String str(buff,sizeof(buff), system_charset_info), *res;
++ DATE_TIME_FORMAT *format;
++
++ if (!(res=var->value->val_str(&str)))
++ res= &my_empty_string;
++
++ if (!(format= date_time_format_make(date_time_type,
++ res->ptr(), res->length())))
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
++ return 1;
++ }
++
++ /*
++ We must copy result to thread space to not get a memory leak if
++ update is aborted
++ */
++ var->save_result.date_time_format= date_time_format_copy(thd, format);
++ my_free((char*) format, MYF(0));
++ return var->save_result.date_time_format == 0;
++}
++
++
++void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type)
++{
++ DATE_TIME_FORMAT *res= 0;
++
++ if (type == OPT_GLOBAL)
++ {
++ const char *format;
++ if ((format= opt_date_time_formats[date_time_type]))
++ res= date_time_format_make(date_time_type, format, strlen(format));
++ }
++ else
++ {
++ /* Make copy with malloc */
++ res= date_time_format_copy((THD *) 0, global_system_variables.*offset);
++ }
++
++ if (res) // Should always be true
++ update2(thd, type, res);
++}
++
++
++uchar *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type == OPT_GLOBAL)
++ {
++ char *res;
++ /*
++ We do a copy here just to be sure things will work even if someone
++ is modifying the original string while the copy is accessed
++ (Can't happen now in SQL SHOW, but this is a good safety for the future)
++ */
++ res= thd->strmake((global_system_variables.*offset)->format.str,
++ (global_system_variables.*offset)->format.length);
++ return (uchar*) res;
++ }
++ return (uchar*) (thd->variables.*offset)->format.str;
++}
++
++
++typedef struct old_names_map_st
++{
++ const char *old_name;
++ const char *new_name;
++} my_old_conv;
++
++static my_old_conv old_conv[]=
++{
++ { "cp1251_koi8" , "cp1251" },
++ { "cp1250_latin2" , "cp1250" },
++ { "kam_latin2" , "keybcs2" },
++ { "mac_latin2" , "MacRoman" },
++ { "macce_latin2" , "MacCE" },
++ { "pc2_latin2" , "pclatin2" },
++ { "vga_latin2" , "pclatin1" },
++ { "koi8_cp1251" , "koi8r" },
++ { "win1251ukr_koi8_ukr" , "win1251ukr" },
++ { "koi8_ukr_win1251ukr" , "koi8u" },
++ { NULL , NULL }
++};
++
++CHARSET_INFO *get_old_charset_by_name(const char *name)
++{
++ my_old_conv *conv;
++
++ for (conv= old_conv; conv->old_name; conv++)
++ {
++ if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
++ return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0));
++ }
++ return NULL;
++}
++
++
++bool sys_var_collation::check(THD *thd, set_var *var)
++{
++ CHARSET_INFO *tmp;
++ LINT_INIT(tmp);
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ String str(buff,sizeof(buff), system_charset_info), *res;
++ if (!(res=var->value->val_str(&str)))
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
++ return 1;
++ }
++ if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
++ {
++ my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
++ return 1;
++ }
++ }
++ else // INT_RESULT
++ {
++ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
++ {
++ char buf[20];
++ int10_to_str((int) var->value->val_int(), buf, -10);
++ my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
++ return 1;
++ }
++ }
++ var->save_result.charset= tmp; // Save for update
++ return 0;
++}
++
++
++bool sys_var_character_set::check(THD *thd, set_var *var)
++{
++ CHARSET_INFO *tmp;
++ LINT_INIT(tmp);
++
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ String str(buff,sizeof(buff), system_charset_info), *res;
++ if (!(res=var->value->val_str(&str)))
++ {
++ if (!nullable)
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
++ return 1;
++ }
++ tmp= NULL;
++ }
++ else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
++ !(tmp=get_old_charset_by_name(res->c_ptr())))
++ {
++ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
++ return 1;
++ }
++ }
++ else // INT_RESULT
++ {
++ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
++ {
++ char buf[20];
++ int10_to_str((int) var->value->val_int(), buf, -10);
++ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
++ return 1;
++ }
++ }
++ var->save_result.charset= tmp; // Save for update
++ return 0;
++}
++
++
++bool sys_var_character_set::update(THD *thd, set_var *var)
++{
++ ci_ptr(thd,var->type)[0]= var->save_result.charset;
++ thd->update_charset();
++ return 0;
++}
++
++
++uchar *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ CHARSET_INFO *cs= ci_ptr(thd,type)[0];
++ return cs ? (uchar*) cs->csname : (uchar*) NULL;
++}
++
++
++void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= *global_default;
++ else
++ {
++ thd->variables.*offset= global_system_variables.*offset;
++ thd->update_charset();
++ }
++}
++CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ return &(global_system_variables.*offset);
++ else
++ return &(thd->variables.*offset);
++}
++
++
++bool sys_var_character_set_client::check(THD *thd, set_var *var)
++{
++ if (sys_var_character_set_sv::check(thd, var))
++ return 1;
++ /* Currently, UCS-2 cannot be used as a client character set */
++ if (!is_supported_parser_charset(var->save_result.charset))
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name,
++ var->save_result.charset->csname);
++ return 1;
++ }
++ return 0;
++}
++
++
++CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
++ enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ return &global_system_variables.collation_database;
++ else
++ return &thd->variables.collation_database;
++}
++
++
++void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.collation_database= default_charset_info;
++ else
++ {
++ thd->variables.collation_database= thd->db_charset;
++ thd->update_charset();
++ }
++}
++
++
++bool sys_var_collation_sv::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.*offset= var->save_result.charset;
++ else
++ {
++ thd->variables.*offset= var->save_result.charset;
++ thd->update_charset();
++ }
++ return 0;
++}
++
++
++void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= *global_default;
++ else
++ {
++ thd->variables.*offset= global_system_variables.*offset;
++ thd->update_charset();
++ }
++}
++
++
++uchar *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
++ global_system_variables.*offset : thd->variables.*offset);
++ return cs ? (uchar*) cs->name : (uchar*) "NULL";
++}
++
++
++LEX_STRING default_key_cache_base= {(char *) "default", 7 };
++
++static KEY_CACHE zero_key_cache;
++
++KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
++{
++ safe_mutex_assert_owner(&LOCK_global_system_variables);
++ if (!cache_name || ! cache_name->length)
++ cache_name= &default_key_cache_base;
++ return ((KEY_CACHE*) find_named(&key_caches,
++ cache_name->str, cache_name->length, 0));
++}
++
++
++uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ KEY_CACHE *key_cache= get_key_cache(base);
++ if (!key_cache)
++ key_cache= &zero_key_cache;
++ return (uchar*) key_cache + offset ;
++}
++
++
++bool sys_var_key_buffer_size::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, 0, GET_ULL);
++}
++
++
++bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
++{
++ ulonglong tmp= var->save_result.ulonglong_value;
++ LEX_STRING *base_name= &var->base;
++ KEY_CACHE *key_cache;
++ bool error= 0;
++
++ /* If no basename, assume it's for the key cache named 'default' */
++ if (!base_name->length)
++ base_name= &default_key_cache_base;
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ key_cache= get_key_cache(base_name);
++
++ if (!key_cache)
++ {
++ /* Key cache didn't exist */
++ if (!tmp) // Tried to delete cache
++ goto end; // Ok, nothing to do
++ if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
++ {
++ error= 1;
++ goto end;
++ }
++ }
++
++ /*
++ Abort if some other thread is changing the key cache
++ TODO: This should be changed so that we wait until the previous
++ assignment is done and then do the new assign
++ */
++ if (key_cache->in_init)
++ goto end;
++
++ if (!tmp) // Zero size means delete
++ {
++ if (key_cache == dflt_key_cache)
++ {
++ error= 1;
++ my_error(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, MYF(0));
++ goto end; // Ignore default key cache
++ }
++
++ if (key_cache->key_cache_inited) // If initied
++ {
++ /*
++ Move tables using this key cache to the default key cache
++ and clear the old key cache.
++ */
++ NAMED_LIST *list;
++ key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
++ base_name->length, &list);
++ key_cache->in_init= 1;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ key_cache->in_init= 0;
++ }
++ /*
++ We don't delete the key cache as some running threads my still be
++ in the key cache code with a pointer to the deleted (empty) key cache
++ */
++ goto end;
++ }
++
++ key_cache->param_buff_size= (ulonglong) tmp;
++
++ /* If key cache didn't exist initialize it, else resize it */
++ key_cache->in_init= 1;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ if (!key_cache->key_cache_inited)
++ error= (bool) (ha_init_key_cache("", key_cache));
++ else
++ error= (bool)(ha_resize_key_cache(key_cache));
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ key_cache->in_init= 0;
++
++end:
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ var->save_result.ulonglong_value = SIZE_T_MAX;
++
++ return error;
++}
++
++
++bool sys_var_key_cache_long::check(THD *thd, set_var *var)
++{
++ return get_unsigned(thd, var, 0, GET_ULONG);
++}
++
++
++/**
++ @todo
++ Abort if some other thread is changing the key cache.
++ This should be changed so that we wait until the previous
++ assignment is done and then do the new assign
++*/
++bool sys_var_key_cache_long::update(THD *thd, set_var *var)
++{
++ LEX_STRING *base_name= &var->base;
++ bool error= 0;
++
++ if (!base_name->length)
++ base_name= &default_key_cache_base;
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ KEY_CACHE *key_cache= get_key_cache(base_name);
++
++ if (!key_cache && !(key_cache= create_key_cache(base_name->str,
++ base_name->length)))
++ {
++ error= 1;
++ goto end;
++ }
++
++ /*
++ Abort if some other thread is changing the key cache
++ TODO: This should be changed so that we wait until the previous
++ assignment is done and then do the new assign
++ */
++ if (key_cache->in_init)
++ goto end;
++
++ *((ulong*) (((char*) key_cache) + offset))= (ulong)
++ var->save_result.ulonglong_value;
++
++ /*
++ Don't create a new key cache if it didn't exist
++ (key_caches are created only when the user sets block_size)
++ */
++ key_cache->in_init= 1;
++
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ error= (bool) (ha_resize_key_cache(key_cache));
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ key_cache->in_init= 0;
++
++end:
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return error;
++}
++
++
++bool sys_var_log_state::update(THD *thd, set_var *var)
++{
++ bool res;
++
++ if (this == &sys_var_log)
++ WARN_DEPRECATED(thd, "7.0", "@@log", "'@@general_log'");
++ else if (this == &sys_var_log_slow)
++ WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ if (!var->save_result.ulong_value)
++ {
++ logger.deactivate_log_handler(thd, log_type);
++ res= false;
++ }
++ else
++ res= logger.activate_log_handler(thd, log_type);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return res;
++}
++
++void sys_var_log_state::set_default(THD *thd, enum_var_type type)
++{
++ if (this == &sys_var_log)
++ WARN_DEPRECATED(thd, "7.0", "@@log", "'@@general_log'");
++ else if (this == &sys_var_log_slow)
++ WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ logger.deactivate_log_handler(thd, log_type);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++
++static int sys_check_log_path(THD *thd, set_var *var)
++{
++ char path[FN_REFLEN], buff[FN_REFLEN];
++ MY_STAT f_stat;
++ String str(buff, sizeof(buff), system_charset_info), *res;
++ const char *log_file_str;
++ size_t path_length;
++
++ if (!(res= var->value->val_str(&str)))
++ goto err;
++
++ log_file_str= res->c_ptr();
++ bzero(&f_stat, sizeof(MY_STAT));
++
++ path_length= unpack_filename(path, log_file_str);
++
++ if (!path_length)
++ {
++ /* File name is empty. */
++
++ goto err;
++ }
++
++ if (my_stat(path, &f_stat, MYF(0)))
++ {
++ /*
++ A file system object exists. Check if argument is a file and we have
++ 'write' permission.
++ */
++
++ if (!MY_S_ISREG(f_stat.st_mode) ||
++ !(f_stat.st_mode & MY_S_IWRITE))
++ goto err;
++
++ return 0;
++ }
++
++ /* Get dirname of the file path. */
++ (void) dirname_part(path, log_file_str, &path_length);
++
++ /* Dirname is empty if file path is relative. */
++ if (!path_length)
++ return 0;
++
++ /*
++ Check if directory exists and we have permission to create file and
++ write to file.
++ */
++ if (my_access(path, (F_OK|W_OK)))
++ goto err;
++
++ return 0;
++
++err:
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name,
++ res ? log_file_str : "NULL");
++ return 1;
++}
++
++
++bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
++ set_var *var, const char *log_ext,
++ bool log_state, uint log_type)
++{
++ MYSQL_QUERY_LOG *file_log;
++ char buff[FN_REFLEN];
++ char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
++ bool result= 0;
++ uint str_length= (var ? var->value->str_value.length() : 0);
++
++ switch (log_type) {
++ case QUERY_LOG_SLOW:
++ file_log= logger.get_slow_log_file_handler();
++ break;
++ case QUERY_LOG_GENERAL:
++ file_log= logger.get_log_file_handler();
++ break;
++ default:
++ MY_ASSERT_UNREACHABLE();
++ }
++
++ if (!old_value)
++ {
++ old_value= make_default_log_name(buff, log_ext);
++ str_length= strlen(old_value);
++ }
++ if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
++ {
++ result= 1;
++ goto err;
++ }
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ logger.lock_exclusive();
++
++ if (file_log && log_state)
++ file_log->close(0);
++ old_value= var_str->value;
++ var_str->value= res;
++ var_str->value_length= str_length;
++ my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
++ if (file_log && log_state)
++ {
++ switch (log_type) {
++ case QUERY_LOG_SLOW:
++ file_log->open_slow_log(sys_var_slow_log_path.value);
++ break;
++ case QUERY_LOG_GENERAL:
++ file_log->open_query_log(sys_var_general_log_path.value);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ }
++
++ logger.unlock();
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++err:
++ return result;
++}
++
++
++static bool sys_update_general_log_path(THD *thd, set_var * var)
++{
++ return update_sys_var_str_path(thd, &sys_var_general_log_path,
++ var, ".log", opt_log, QUERY_LOG_GENERAL);
++}
++
++
++static void sys_default_general_log_path(THD *thd, enum_var_type type)
++{
++ (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
++ 0, ".log", opt_log, QUERY_LOG_GENERAL);
++}
++
++
++static bool sys_update_slow_log_path(THD *thd, set_var * var)
++{
++ return update_sys_var_str_path(thd, &sys_var_slow_log_path,
++ var, "-slow.log", opt_slow_log,
++ QUERY_LOG_SLOW);
++}
++
++
++static void sys_default_slow_log_path(THD *thd, enum_var_type type)
++{
++ (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
++ 0, "-slow.log", opt_slow_log,
++ QUERY_LOG_SLOW);
++}
++
++
++bool sys_var_log_output::update(THD *thd, set_var *var)
++{
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ logger.lock_exclusive();
++ logger.init_slow_log(var->save_result.ulong_value);
++ logger.init_general_log(var->save_result.ulong_value);
++ *value= var->save_result.ulong_value;
++ logger.unlock();
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return 0;
++}
++
++
++void sys_var_log_output::set_default(THD *thd, enum_var_type type)
++{
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ logger.lock_exclusive();
++ logger.init_slow_log(LOG_FILE);
++ logger.init_general_log(LOG_FILE);
++ *value= LOG_FILE;
++ logger.unlock();
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++
++uchar *sys_var_log_output::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ char buff[256];
++ String tmp(buff, sizeof(buff), &my_charset_latin1);
++ ulong length;
++ ulong val= *value;
++
++ tmp.length(0);
++ for (uint i= 0; val; val>>= 1, i++)
++ {
++ if (val & 1)
++ {
++ tmp.append(log_output_typelib.type_names[i],
++ log_output_typelib.type_lengths[i]);
++ tmp.append(',');
++ }
++ }
++
++ if ((length= tmp.length()))
++ length--;
++ return (uchar*) thd->strmake(tmp.ptr(), length);
++}
++
++
++/*****************************************************************************
++ Functions to handle SET NAMES and SET CHARACTER SET
++*****************************************************************************/
++
++int set_var_collation_client::check(THD *thd)
++{
++ /* Currently, UCS-2 cannot be used as a client character set */
++ if (character_set_client->mbminlen > 1)
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
++ character_set_client->csname);
++ return 1;
++ }
++ return 0;
++}
++
++int set_var_collation_client::update(THD *thd)
++{
++ thd->variables.character_set_client= character_set_client;
++ thd->variables.character_set_results= character_set_results;
++ thd->variables.collation_connection= collation_connection;
++ thd->update_charset();
++ thd->protocol_text.init(thd);
++ thd->protocol_binary.init(thd);
++ return 0;
++}
++
++/****************************************************************************/
++
++bool sys_var_timestamp::check(THD *thd, set_var *var)
++{
++ longlong val;
++ var->save_result.ulonglong_value= var->value->val_int();
++ val= (longlong) var->save_result.ulonglong_value;
++ if (val != 0 && // this is how you set the default value
++ (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE))
++ {
++ char buf[64];
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", llstr(val, buf));
++ return TRUE;
++ }
++ return FALSE;
++}
++
++
++bool sys_var_timestamp::update(THD *thd, set_var *var)
++{
++ thd->set_time((time_t) var->save_result.ulonglong_value);
++ return FALSE;
++}
++
++
++void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
++{
++ thd->user_time=0;
++}
++
++
++uchar *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ thd->sys_var_tmp.long_value= (long) thd->start_time;
++ return (uchar*) &thd->sys_var_tmp.long_value;
++}
++
++
++bool sys_var_last_insert_id::update(THD *thd, set_var *var)
++{
++ thd->first_successful_insert_id_in_prev_stmt=
++ var->save_result.ulonglong_value;
++ return 0;
++}
++
++
++uchar *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ /*
++ this tmp var makes it robust againt change of type of
++ read_first_successful_insert_id_in_prev_stmt().
++ */
++ thd->sys_var_tmp.ulonglong_value=
++ thd->read_first_successful_insert_id_in_prev_stmt();
++ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
++}
++
++
++bool sys_var_insert_id::update(THD *thd, set_var *var)
++{
++ thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
++ return 0;
++}
++
++
++uchar *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ thd->sys_var_tmp.ulonglong_value=
++ thd->auto_inc_intervals_forced.minimum();
++ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
++}
++
++
++bool sys_var_rand_seed1::update(THD *thd, set_var *var)
++{
++ thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
++ return 0;
++}
++
++bool sys_var_rand_seed2::update(THD *thd, set_var *var)
++{
++ thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
++ return 0;
++}
++
++
++bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
++{
++ char buff[MAX_TIME_ZONE_NAME_LENGTH];
++ String str(buff, sizeof(buff), &my_charset_latin1);
++ String *res= var->value->val_str(&str);
++
++ if (!(var->save_result.time_zone= my_tz_find(thd, res)))
++ {
++ my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
++ return 1;
++ }
++ return 0;
++}
++
++
++bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
++{
++ /* We are using Time_zone object found during check() phase. */
++ if (var->type == OPT_GLOBAL)
++ {
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.time_zone= var->save_result.time_zone;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.time_zone= var->save_result.time_zone;
++ return 0;
++}
++
++
++uchar *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ /*
++ We can use ptr() instead of c_ptr() here because String contaning
++ time zone name is guaranteed to be zero ended.
++ */
++ if (type == OPT_GLOBAL)
++ return (uchar *)(global_system_variables.time_zone->get_name()->ptr());
++ else
++ {
++ /*
++ This is an ugly fix for replication: we don't replicate properly queries
++ invoking system variables' values to update tables; but
++ CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
++ replicable (i.e. we tell the binlog code to store the session
++ timezone). If it's the global value which was used we can't replicate
++ (binlog code stores session value only).
++ */
++ thd->time_zone_used= 1;
++ return (uchar *)(thd->variables.time_zone->get_name()->ptr());
++ }
++}
++
++
++void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
++{
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ if (type == OPT_GLOBAL)
++ {
++ if (default_tz_name)
++ {
++ String str(default_tz_name, &my_charset_latin1);
++ /*
++ We are guaranteed to find this time zone since its existence
++ is checked during start-up.
++ */
++ global_system_variables.time_zone= my_tz_find(thd, &str);
++ }
++ else
++ global_system_variables.time_zone= my_tz_SYSTEM;
++ }
++ else
++ thd->variables.time_zone= global_system_variables.time_zone;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++
++bool sys_var_max_user_conn::check(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ return sys_var_thd::check(thd, var);
++ else
++ {
++ /*
++ Per-session values of max_user_connections can't be set directly.
++ May be we should have a separate error message for this?
++ */
++ my_error(ER_GLOBAL_VARIABLE, MYF(0), name);
++ return TRUE;
++ }
++}
++
++bool sys_var_max_user_conn::update(THD *thd, set_var *var)
++{
++ DBUG_ASSERT(var->type == OPT_GLOBAL);
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ max_user_connections= (uint)var->save_result.ulonglong_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return 0;
++}
++
++
++void sys_var_max_user_conn::set_default(THD *thd, enum_var_type type)
++{
++ DBUG_ASSERT(type == OPT_GLOBAL);
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ max_user_connections= (ulong) option_limits->def_value;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++}
++
++
++uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ if (type != OPT_GLOBAL &&
++ thd->user_connect && thd->user_connect->user_resources.user_conn)
++ return (uchar*) &(thd->user_connect->user_resources.user_conn);
++ return (uchar*) &(max_user_connections);
++}
++
++
++bool sys_var_thd_ulong_session_readonly::check(THD *thd, set_var *var)
++{
++ if (var->type != OPT_GLOBAL)
++ {
++ my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION", name, "GLOBAL");
++ return TRUE;
++ }
++
++ return sys_var_thd_ulong::check(thd, var);
++}
++
++
++bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
++{
++ MY_LOCALE *locale_match;
++
++ if (var->value->result_type() == INT_RESULT)
++ {
++ if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
++ {
++ char buf[20];
++ int10_to_str((int) var->value->val_int(), buf, -10);
++ my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
++ return 1;
++ }
++ }
++ else // STRING_RESULT
++ {
++ char buff[6];
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++ if (!(res=var->value->val_str(&str)))
++ {
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
++ return 1;
++ }
++ const char *locale_str= res->c_ptr_safe();
++ if (!(locale_match= my_locale_by_name(locale_str)))
++ {
++ my_printf_error(ER_UNKNOWN_ERROR,
++ "Unknown locale: '%s'", MYF(0), locale_str);
++ return 1;
++ }
++ }
++
++ var->save_result.locale_value= locale_match;
++ return 0;
++}
++
++
++bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
++{
++ if (var->type == OPT_GLOBAL)
++ global_system_variables.lc_time_names= var->save_result.locale_value;
++ else
++ thd->variables.lc_time_names= var->save_result.locale_value;
++ return 0;
++}
++
++
++uchar *sys_var_thd_lc_time_names::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ return type == OPT_GLOBAL ?
++ (uchar *) global_system_variables.lc_time_names->name :
++ (uchar *) thd->variables.lc_time_names->name;
++}
++
++
++void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.lc_time_names= my_default_lc_time_names;
++ else
++ thd->variables.lc_time_names= global_system_variables.lc_time_names;
++}
++
++/*
++ Handling of microseoncds given as seconds.part_seconds
++
++ NOTES
++ The argument to long query time is in seconds in decimal
++ which is converted to ulonglong integer holding microseconds for storage.
++ This is used for handling long_query_time
++*/
++
++bool sys_var_microseconds::update(THD *thd, set_var *var)
++{
++ double num= var->value->val_real();
++ longlong microseconds;
++ if (num > (double) option_limits->max_value)
++ num= (double) option_limits->max_value;
++ if (num < (double) option_limits->min_value)
++ num= (double) option_limits->min_value;
++ microseconds= (longlong) (num * 1000000.0 + 0.5);
++ if (var->type == OPT_GLOBAL)
++ {
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ (global_system_variables.*offset)= microseconds;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= microseconds;
++ return 0;
++}
++
++
++void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
++{
++ longlong microseconds= (longlong) (option_limits->def_value * 1000000.0);
++ if (type == OPT_GLOBAL)
++ {
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ global_system_variables.*offset= microseconds;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ }
++ else
++ thd->variables.*offset= microseconds;
++}
++
++
++uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
++ global_system_variables.*offset :
++ thd->variables.*offset) / 1000000.0;
++ return (uchar*) &thd->tmp_double_value;
++}
++
++
++/*
++ Functions to update thd->options bits
++*/
++
++static bool set_option_bit(THD *thd, set_var *var)
++{
++ sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
++ if ((var->save_result.ulong_value != 0) == sys_var->reverse)
++ thd->options&= ~sys_var->bit_flag;
++ else
++ thd->options|= sys_var->bit_flag;
++ return 0;
++}
++
++/*
++ Functions to be only used to update thd->options OPTION_BIN_LOG bit
++*/
++static bool set_option_log_bin_bit(THD *thd, set_var *var)
++{
++ set_option_bit(thd, var);
++ if (!thd->in_sub_stmt)
++ thd->sql_log_bin_toplevel= thd->options & OPTION_BIN_LOG;
++ return 0;
++}
++
++static bool set_option_autocommit(THD *thd, set_var *var)
++{
++ /* The test is negative as the flag we use is NOT autocommit */
++
++ ulonglong org_options= thd->options;
++
++ if (var->save_result.ulong_value != 0)
++ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
++ else
++ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
++
++ if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
++ {
++ if ((org_options & OPTION_NOT_AUTOCOMMIT))
++ {
++ /* We changed to auto_commit mode */
++ if (thd->transaction.xid_state.xa_state != XA_NOTR)
++ {
++ thd->options= org_options;
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ return 1;
++ }
++ thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
++ if (ha_commit(thd))
++ return 1;
++ }
++ else
++ {
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
++ }
++ }
++ return 0;
++}
++
++static int check_log_update(THD *thd, set_var *var)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (!(thd->security_ctx->master_access & SUPER_ACL))
++ {
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
++ return 1;
++ }
++#endif
++ return 0;
++}
++
++static bool set_log_update(THD *thd, set_var *var)
++{
++ /*
++ The update log is not supported anymore since 5.0.
++ See sql/mysqld.cc/, comments in function init_server_components() for an
++ explaination of the different warnings we send below
++ */
++
++ if (opt_sql_bin_update)
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
++ ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
++ }
++ else
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_UPDATE_LOG_DEPRECATED_IGNORED,
++ ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
++ set_option_bit(thd, var);
++ return 0;
++}
++
++
++static int check_pseudo_thread_id(THD *thd, set_var *var)
++{
++ var->save_result.ulonglong_value= var->value->val_int();
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (thd->security_ctx->master_access & SUPER_ACL)
++ return 0;
++ else
++ {
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
++ return 1;
++ }
++#else
++ return 0;
++#endif
++}
++
++static uchar *get_warning_count(THD *thd)
++{
++ thd->sys_var_tmp.long_value=
++ (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
++ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
++ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
++ return (uchar*) &thd->sys_var_tmp.long_value;
++}
++
++static uchar *get_error_count(THD *thd)
++{
++ thd->sys_var_tmp.long_value=
++ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
++ return (uchar*) &thd->sys_var_tmp.long_value;
++}
++
++
++/**
++ Get the tmpdir that was specified or chosen by default.
++
++ This is necessary because if the user does not specify a temporary
++ directory via the command line, one is chosen based on the environment
++ or system defaults. But we can't just always use mysql_tmpdir, because
++ that is actually a call to my_tmpdir() which cycles among possible
++ temporary directories.
++
++ @param thd thread handle
++
++ @retval
++ ptr pointer to NUL-terminated string
++*/
++static uchar *get_tmpdir(THD *thd)
++{
++ if (opt_mysql_tmpdir)
++ return (uchar *)opt_mysql_tmpdir;
++ return (uchar*)mysql_tmpdir;
++}
++
++static uchar *get_myisam_mmap_size(THD *thd)
++{
++ return (uchar *)&myisam_mmap_size;
++}
++
++
++/****************************************************************************
++ Main handling of variables:
++ - Initialisation
++ - Searching during parsing
++ - Update loop
++****************************************************************************/
++
++/**
++ Find variable name in option my_getopt structure used for
++ command line args.
++
++ @param opt option structure array to search in
++ @param name variable name
++
++ @retval
++ 0 Error
++ @retval
++ ptr pointer to option structure
++*/
++
++static struct my_option *find_option(struct my_option *opt, const char *name)
++{
++ uint length=strlen(name);
++ for (; opt->name; opt++)
++ {
++ if (!getopt_compare_strings(opt->name, name, length) &&
++ !opt->name[length])
++ {
++ /*
++ Only accept the option if one can set values through it.
++ If not, there is no default value or limits in the option.
++ */
++ return (opt->value) ? opt : 0;
++ }
++ }
++ return 0;
++}
++
++
++/**
++ Return variable name and length for hashing of variables.
++*/
++
++static uchar *get_sys_var_length(const sys_var *var, size_t *length,
++ my_bool first)
++{
++ *length= var->name_length;
++ return (uchar*) var->name;
++}
++
++
++/*
++ Add variables to the dynamic hash of system variables
++
++ SYNOPSIS
++ mysql_add_sys_var_chain()
++ first Pointer to first system variable to add
++ long_opt (optional)command line arguments may be tied for limit checks.
++
++ RETURN VALUES
++ 0 SUCCESS
++ otherwise FAILURE
++*/
++
++
++int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
++{
++ sys_var *var;
++
++ /* A write lock should be held on LOCK_system_variables_hash */
++
++ for (var= first; var; var= var->next)
++ {
++ var->name_length= strlen(var->name);
++ /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
++ if (my_hash_insert(&system_variable_hash, (uchar*) var))
++ goto error;
++ if (long_options)
++ var->option_limits= find_option(long_options, var->name);
++ }
++ return 0;
++
++error:
++ for (; first != var; first= first->next)
++ hash_delete(&system_variable_hash, (uchar*) first);
++ return 1;
++}
++
++
++/*
++ Remove variables to the dynamic hash of system variables
++
++ SYNOPSIS
++ mysql_del_sys_var_chain()
++ first Pointer to first system variable to remove
++
++ RETURN VALUES
++ 0 SUCCESS
++ otherwise FAILURE
++*/
++
++int mysql_del_sys_var_chain(sys_var *first)
++{
++ int result= 0;
++
++ /* A write lock should be held on LOCK_system_variables_hash */
++
++ for (sys_var *var= first; var; var= var->next)
++ result|= hash_delete(&system_variable_hash, (uchar*) var);
++
++ return result;
++}
++
++
++static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
++{
++ return strcmp(a->name, b->name);
++}
++
++
++/*
++ Constructs an array of system variables for display to the user.
++
++ SYNOPSIS
++ enumerate_sys_vars()
++ thd current thread
++ sorted If TRUE, the system variables should be sorted
++
++ RETURN VALUES
++ pointer Array of SHOW_VAR elements for display
++ NULL FAILURE
++*/
++
++SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
++{
++ int count= system_variable_hash.records, i;
++ int size= sizeof(SHOW_VAR) * (count + 1);
++ SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size);
++
++ if (result)
++ {
++ SHOW_VAR *show= result;
++
++ for (i= 0; i < count; i++)
++ {
++ sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
++ show->name= var->name;
++ show->value= (char*) var;
++ show->type= SHOW_SYS;
++ show++;
++ }
++
++ /* sort into order */
++ if (sorted)
++ my_qsort(result, count, sizeof(SHOW_VAR),
++ (qsort_cmp) show_cmp);
++
++ /* make last element empty */
++ bzero(show, sizeof(SHOW_VAR));
++ }
++ return result;
++}
++
++
++/*
++ Initialize the system variables
++
++ SYNOPSIS
++ set_var_init()
++
++ RETURN VALUES
++ 0 SUCCESS
++ otherwise FAILURE
++*/
++
++int set_var_init()
++{
++ uint count= 0;
++ DBUG_ENTER("set_var_init");
++
++ for (sys_var *var=vars.first; var; var= var->next, count++) ;
++
++ if (hash_init(&system_variable_hash, system_charset_info, count, 0,
++ 0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
++ goto error;
++
++ vars.last->next= NULL;
++ if (mysql_add_sys_var_chain(vars.first, my_long_options))
++ goto error;
++
++ /*
++ Special cases
++ Needed because MySQL can't find the limits for a variable it it has
++ a different name than the command line option.
++ As these variables are deprecated, this code will disappear soon...
++ */
++ sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
++
++ DBUG_RETURN(0);
++
++error:
++ fprintf(stderr, "failed to initialize system variables");
++ DBUG_RETURN(1);
++}
++
++
++void set_var_free()
++{
++ hash_free(&system_variable_hash);
++}
++
++
++/**
++ Find a user set-table variable.
++
++ @param str Name of system variable to find
++ @param length Length of variable. zero means that we should use strlen()
++ on the variable
++ @param no_error Refuse to emit an error, even if one occurred.
++
++ @retval
++ pointer pointer to variable definitions
++ @retval
++ 0 Unknown variable (error message is given)
++*/
++
++sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
++{
++ sys_var *var;
++
++ /*
++ This function is only called from the sql_plugin.cc.
++ A lock on LOCK_system_variable_hash should be held
++ */
++ var= (sys_var*) hash_search(&system_variable_hash,
++ (uchar*) str, length ? length : strlen(str));
++ if (!(var || no_error))
++ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
++
++ return var;
++}
++
++
++/**
++ Execute update of all variables.
++
++ First run a check of all variables that all updates will go ok.
++ If yes, then execute all updates, returning an error if any one failed.
++
++ This should ensure that in all normal cases none all or variables are
++ updated.
++
++ @param THD Thread id
++ @param var_list List of variables to update
++
++ @retval
++ 0 ok
++ @retval
++ 1 ERROR, message sent (normally no variables was updated)
++ @retval
++ -1 ERROR, message not sent
++*/
++
++int sql_set_variables(THD *thd, List<set_var_base> *var_list)
++{
++ int error;
++ List_iterator_fast<set_var_base> it(*var_list);
++ DBUG_ENTER("sql_set_variables");
++
++ set_var_base *var;
++ while ((var=it++))
++ {
++ if ((error= var->check(thd)))
++ goto err;
++ }
++ if (!(error= test(thd->is_error())))
++ {
++ it.rewind();
++ while ((var= it++))
++ error|= var->update(thd); // Returns 0, -1 or 1
++ }
++
++err:
++ free_underlaid_joins(thd, &thd->lex->select_lex);
++ DBUG_RETURN(error);
++}
++
++
++/**
++ Say if all variables set by a SET support the ONE_SHOT keyword
++ (currently, only character set and collation do; later timezones
++ will).
++
++ @param var_list List of variables to update
++
++ @note
++ It has a "not_" because it makes faster tests (no need to "!")
++
++ @retval
++ 0 all variables of the list support ONE_SHOT
++ @retval
++ 1 at least one does not support ONE_SHOT
++*/
++
++bool not_all_support_one_shot(List<set_var_base> *var_list)
++{
++ List_iterator_fast<set_var_base> it(*var_list);
++ set_var_base *var;
++ while ((var= it++))
++ {
++ if (var->no_support_one_shot())
++ return 1;
++ }
++ return 0;
++}
++
++
++/*****************************************************************************
++ Functions to handle SET mysql_internal_variable=const_expr
++*****************************************************************************/
++
++int set_var::check(THD *thd)
++{
++ if (var->is_readonly())
++ {
++ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
++ return -1;
++ }
++ if (var->check_type(type))
++ {
++ int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
++ my_error(err, MYF(0), var->name);
++ return -1;
++ }
++ if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
++ return 1;
++ /* value is a NULL pointer if we are using SET ... = DEFAULT */
++ if (!value)
++ {
++ if (var->check_default(type))
++ {
++ my_error(ER_NO_DEFAULT, MYF(0), var->name);
++ return -1;
++ }
++ return 0;
++ }
++
++ if ((!value->fixed &&
++ value->fix_fields(thd, &value)) || value->check_cols(1))
++ return -1;
++ if (var->check_update_type(value->result_type()))
++ {
++ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
++ return -1;
++ }
++ return var->check(thd, this) ? -1 : 0;
++}
++
++
++/**
++ Check variable, but without assigning value (used by PS).
++
++ @param thd thread handler
++
++ @retval
++ 0 ok
++ @retval
++ 1 ERROR, message sent (normally no variables was updated)
++ @retval
++ -1 ERROR, message not sent
++*/
++int set_var::light_check(THD *thd)
++{
++ if (var->check_type(type))
++ {
++ int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
++ my_error(err, MYF(0), var->name);
++ return -1;
++ }
++ if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
++ return 1;
++
++ if (value && ((!value->fixed && value->fix_fields(thd, &value)) ||
++ value->check_cols(1)))
++ return -1;
++ return 0;
++}
++
++/**
++ Update variable
++
++ @param thd thread handler
++ @returns 0|1 ok or ERROR
++
++ @note ERROR can be only due to abnormal operations involving
++ the server's execution evironment such as
++ out of memory, hard disk failure or the computer blows up.
++ Consider set_var::check() method if there is a need to return
++ an error due to logics.
++*/
++int set_var::update(THD *thd)
++{
++ if (!value)
++ var->set_default(thd, type);
++ else if (var->update(thd, this))
++ return -1; // should never happen
++ if (var->after_update)
++ (*var->after_update)(thd, type);
++ return 0;
++}
++
++
++/*****************************************************************************
++ Functions to handle SET @user_variable=const_expr
++*****************************************************************************/
++
++int set_var_user::check(THD *thd)
++{
++ /*
++ Item_func_set_user_var can't substitute something else on its place =>
++ 0 can be passed as last argument (reference on item)
++ */
++ return (user_var_item->fix_fields(thd, (Item**) 0) ||
++ user_var_item->check(0)) ? -1 : 0;
++}
++
++
++/**
++ Check variable, but without assigning value (used by PS).
++
++ @param thd thread handler
++
++ @retval
++ 0 ok
++ @retval
++ 1 ERROR, message sent (normally no variables was updated)
++ @retval
++ -1 ERROR, message not sent
++*/
++int set_var_user::light_check(THD *thd)
++{
++ /*
++ Item_func_set_user_var can't substitute something else on its place =>
++ 0 can be passed as last argument (reference on item)
++ */
++ return (user_var_item->fix_fields(thd, (Item**) 0));
++}
++
++
++int set_var_user::update(THD *thd)
++{
++ if (user_var_item->update())
++ {
++ /* Give an error if it's not given already */
++ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
++ return -1;
++ }
++ return 0;
++}
++
++
++/*****************************************************************************
++ Functions to handle SET PASSWORD
++*****************************************************************************/
++
++int set_var_password::check(THD *thd)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (!user->host.str)
++ {
++ DBUG_ASSERT(thd->security_ctx->priv_host);
++ if (*thd->security_ctx->priv_host != 0)
++ {
++ user->host.str= (char *) thd->security_ctx->priv_host;
++ user->host.length= strlen(thd->security_ctx->priv_host);
++ }
++ else
++ {
++ user->host.str= (char *)"%";
++ user->host.length= 1;
++ }
++ }
++ if (!user->user.str)
++ {
++ DBUG_ASSERT(thd->security_ctx->priv_user);
++ user->user.str= (char *) thd->security_ctx->priv_user;
++ user->user.length= strlen(thd->security_ctx->priv_user);
++ }
++ /* Returns 1 as the function sends error to client */
++ return check_change_password(thd, user->host.str, user->user.str,
++ password, strlen(password)) ? 1 : 0;
++#else
++ return 0;
++#endif
++}
++
++int set_var_password::update(THD *thd)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ /* Returns 1 as the function sends error to client */
++ return change_password(thd, user->host.str, user->user.str, password) ?
++ 1 : 0;
++#else
++ return 0;
++#endif
++}
++
++/****************************************************************************
++ Functions to handle table_type
++****************************************************************************/
++
++/* Based upon sys_var::check_enum() */
++
++bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE];
++ const char *value;
++ String str(buff, sizeof(buff), &my_charset_latin1), *res;
++
++ var->save_result.plugin= NULL;
++ if (var->value->result_type() == STRING_RESULT)
++ {
++ LEX_STRING engine_name;
++ handlerton *hton;
++ if (!(res=var->value->val_str(&str)) ||
++ !(engine_name.str= (char *)res->ptr()) ||
++ !(engine_name.length= res->length()) ||
++ !(var->save_result.plugin= ha_resolve_by_name(thd, &engine_name)) ||
++ !(hton= plugin_data(var->save_result.plugin, handlerton *)) ||
++ ha_checktype(thd, ha_legacy_type(hton), 1, 0) != hton)
++ {
++ value= res ? res->c_ptr() : "NULL";
++ goto err;
++ }
++ return 0;
++ }
++ value= "unknown";
++
++err:
++ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
++ return 1;
++}
++
++
++uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ uchar* result;
++ handlerton *hton;
++ LEX_STRING *engine_name;
++ plugin_ref plugin= thd->variables.*offset;
++ if (type == OPT_GLOBAL)
++ plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
++ hton= plugin_data(plugin, handlerton*);
++ engine_name= &hton2plugin[hton->slot]->name;
++ result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
++ if (type == OPT_GLOBAL)
++ plugin_unlock(thd, plugin);
++ return result;
++}
++
++
++void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
++{
++ plugin_ref old_value, new_value, *value;
++ if (type == OPT_GLOBAL)
++ {
++ value= &(global_system_variables.*offset);
++ new_value= ha_lock_engine(NULL, myisam_hton);
++ }
++ else
++ {
++ value= &(thd->variables.*offset);
++ new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
++ }
++ DBUG_ASSERT(new_value);
++ old_value= *value;
++ *value= new_value;
++ plugin_unlock(NULL, old_value);
++}
++
++
++bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
++{
++ plugin_ref *value= &(global_system_variables.*offset), old_value;
++ if (var->type != OPT_GLOBAL)
++ value= &(thd->variables.*offset);
++ old_value= *value;
++ if (old_value != var->save_result.plugin)
++ {
++ *value= my_plugin_lock(NULL, &var->save_result.plugin);
++ plugin_unlock(NULL, old_value);
++ }
++ return 0;
++}
++
++void sys_var_thd_table_type::warn_deprecated(THD *thd)
++{
++ WARN_DEPRECATED(thd, "6.0", "@@table_type", "'@@storage_engine'");
++}
++
++void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type)
++{
++ warn_deprecated(thd);
++ sys_var_thd_storage_engine::set_default(thd, type);
++}
++
++bool sys_var_thd_table_type::update(THD *thd, set_var *var)
++{
++ warn_deprecated(thd);
++ return sys_var_thd_storage_engine::update(thd, var);
++}
++
++
++/****************************************************************************
++ Functions to handle sql_mode
++****************************************************************************/
++
++/**
++ Make string representation of mode.
++
++ @param[in] thd thread handler
++ @param[in] val sql_mode value
++ @param[out] len pointer on length of string
++
++ @return
++ pointer to string with sql_mode representation
++*/
++
++bool
++sys_var_thd_sql_mode::
++symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE*8];
++ String tmp(buff, sizeof(buff), &my_charset_latin1);
++
++ tmp.length(0);
++
++ for (uint i= 0; val; val>>= 1, i++)
++ {
++ if (val & 1)
++ {
++ tmp.append(sql_mode_typelib.type_names[i],
++ sql_mode_typelib.type_lengths[i]);
++ tmp.append(',');
++ }
++ }
++
++ if (tmp.length())
++ tmp.length(tmp.length() - 1); /* trim the trailing comma */
++
++ rep->str= thd->strmake(tmp.ptr(), tmp.length());
++
++ rep->length= rep->str ? tmp.length() : 0;
++
++ return rep->length != tmp.length();
++}
++
++
++uchar *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ LEX_STRING sql_mode;
++ ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ (void) symbolic_mode_representation(thd, val, &sql_mode);
++ return (uchar *) sql_mode.str;
++}
++
++
++void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= 0;
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++
++void fix_sql_mode_var(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.sql_mode=
++ fix_sql_mode(global_system_variables.sql_mode);
++ else
++ {
++ thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
++ /*
++ Update thd->server_status
++ */
++ if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
++ thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
++ else
++ thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
++ }
++}
++
++/** Map database specific bits to function bits. */
++
++ulong fix_sql_mode(ulong sql_mode)
++{
++ /*
++ Note that we dont set
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
++ to allow one to get full use of MySQL in this mode.
++ */
++
++ if (sql_mode & MODE_ANSI)
++ {
++ sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE);
++ /*
++ MODE_ONLY_FULL_GROUP_BY removed from ANSI mode because it is currently
++ overly restrictive (see BUG#8510).
++ */
++ }
++ if (sql_mode & MODE_ORACLE)
++ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE |
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
++ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
++ if (sql_mode & MODE_MSSQL)
++ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE |
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
++ MODE_NO_FIELD_OPTIONS);
++ if (sql_mode & MODE_POSTGRESQL)
++ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE |
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
++ MODE_NO_FIELD_OPTIONS);
++ if (sql_mode & MODE_DB2)
++ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE |
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
++ MODE_NO_FIELD_OPTIONS);
++ if (sql_mode & MODE_MAXDB)
++ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
++ MODE_IGNORE_SPACE |
++ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
++ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
++ if (sql_mode & MODE_MYSQL40)
++ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
++ if (sql_mode & MODE_MYSQL323)
++ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
++ if (sql_mode & MODE_TRADITIONAL)
++ sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
++ MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
++ MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER);
++ return sql_mode;
++}
++
++
++bool
++sys_var_thd_optimizer_switch::
++symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
++{
++ char buff[STRING_BUFFER_USUAL_SIZE*8];
++ String tmp(buff, sizeof(buff), &my_charset_latin1);
++ int i;
++ ulonglong bit;
++ tmp.length(0);
++
++ for (i= 0, bit=1; bit != OPTIMIZER_SWITCH_LAST; i++, bit= bit << 1)
++ {
++ tmp.append(optimizer_switch_typelib.type_names[i],
++ optimizer_switch_typelib.type_lengths[i]);
++ tmp.append('=');
++ tmp.append((val & bit)? "on":"off");
++ tmp.append(',');
++ }
++
++ if (tmp.length())
++ tmp.length(tmp.length() - 1); /* trim the trailing comma */
++
++ rep->str= thd->strmake(tmp.ptr(), tmp.length());
++
++ rep->length= rep->str ? tmp.length() : 0;
++
++ return rep->length != tmp.length();
++}
++
++
++uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ LEX_STRING opts;
++ ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
++ thd->variables.*offset);
++ (void) symbolic_mode_representation(thd, val, &opts);
++ return (uchar *) opts.str;
++}
++
++
++/*
++ Check (and actually parse) string representation of @@optimizer_switch.
++*/
++
++bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
++{
++ bool not_used;
++ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
++ uint error_len= 0;
++ String str(buff, sizeof(buff), system_charset_info), *res;
++
++ if (!(res= var->value->val_str(&str)))
++ {
++ strmov(buff, "NULL");
++ goto err;
++ }
++
++ if (res->length() == 0)
++ {
++ buff[0]= 0;
++ goto err;
++ }
++
++ var->save_result.ulong_value=
++ (ulong)find_set_from_flags(&optimizer_switch_typelib,
++ optimizer_switch_typelib.count,
++ thd->variables.optimizer_switch,
++ global_system_variables.optimizer_switch,
++ res->c_ptr_safe(), res->length(), NULL,
++ &error, &error_len, ¬_used);
++ if (error_len)
++ {
++ strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ goto err;
++ }
++ return FALSE;
++err:
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
++ return TRUE;
++}
++
++
++void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
++{
++ if (type == OPT_GLOBAL)
++ global_system_variables.*offset= OPTIMIZER_SWITCH_DEFAULT;
++ else
++ thd->variables.*offset= global_system_variables.*offset;
++}
++
++/****************************************************************************
++ Named list handling
++****************************************************************************/
++
++uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
++ NAMED_LIST **found)
++{
++ I_List_iterator<NAMED_LIST> it(*list);
++ NAMED_LIST *element;
++ while ((element= it++))
++ {
++ if (element->cmp(name, length))
++ {
++ if (found)
++ *found= element;
++ return element->data;
++ }
++ }
++ return 0;
++}
++
++
++void delete_elements(I_List<NAMED_LIST> *list,
++ void (*free_element)(const char *name, uchar*))
++{
++ NAMED_LIST *element;
++ DBUG_ENTER("delete_elements");
++ while ((element= list->get()))
++ {
++ (*free_element)(element->name, element->data);
++ delete element;
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/* Key cache functions */
++
++static KEY_CACHE *create_key_cache(const char *name, uint length)
++{
++ KEY_CACHE *key_cache;
++ DBUG_ENTER("create_key_cache");
++ DBUG_PRINT("enter",("name: %.*s", length, name));
++
++ if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
++ MYF(MY_ZEROFILL | MY_WME))))
++ {
++ if (!new NAMED_LIST(&key_caches, name, length, (uchar*) key_cache))
++ {
++ my_free((char*) key_cache, MYF(0));
++ key_cache= 0;
++ }
++ else
++ {
++ /*
++ Set default values for a key cache
++ The values in dflt_key_cache_var is set by my_getopt() at startup
++
++ We don't set 'buff_size' as this is used to enable the key cache
++ */
++ key_cache->param_block_size= dflt_key_cache_var.param_block_size;
++ key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
++ key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold;
++ }
++ }
++ DBUG_RETURN(key_cache);
++}
++
++
++KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
++{
++ LEX_STRING key_cache_name;
++ KEY_CACHE *key_cache;
++
++ key_cache_name.str= (char *) name;
++ key_cache_name.length= length;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ if (!(key_cache= get_key_cache(&key_cache_name)))
++ key_cache= create_key_cache(name, length);
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ return key_cache;
++}
++
++
++void free_key_cache(const char *name, KEY_CACHE *key_cache)
++{
++ ha_end_key_cache(key_cache);
++ my_free((char*) key_cache, MYF(0));
++}
++
++
++bool process_key_caches(process_key_cache_t func)
++{
++ I_List_iterator<NAMED_LIST> it(key_caches);
++ NAMED_LIST *element;
++
++ while ((element= it++))
++ {
++ KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
++ func(element->name, key_cache);
++ }
++ return 0;
++}
++
++
++void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
++{
++ WARN_DEPRECATED(thd, VER_CELOSIA, "@@log_bin_trust_routine_creators",
++ "'@@log_bin_trust_function_creators'");
++}
++
++void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
++{
++ warn_deprecated(thd);
++ sys_var_bool_ptr::set_default(thd, type);
++}
++
++bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
++{
++ warn_deprecated(thd);
++ return sys_var_bool_ptr::update(thd, var);
++}
++
++bool sys_var_opt_readonly::update(THD *thd, set_var *var)
++{
++ bool result;
++
++ DBUG_ENTER("sys_var_opt_readonly::update");
++
++ /* Prevent self dead-lock */
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
++ DBUG_RETURN(true);
++ }
++
++ if (thd->global_read_lock)
++ {
++ /*
++ This connection already holds the global read lock.
++ This can be the case with:
++ - FLUSH TABLES WITH READ LOCK
++ - SET GLOBAL READ_ONLY = 1
++ */
++ result= sys_var_bool_ptr::update(thd, var);
++ DBUG_RETURN(result);
++ }
++
++ /*
++ Perform a 'FLUSH TABLES WITH READ LOCK'.
++ This is a 3 step process:
++ - [1] lock_global_read_lock()
++ - [2] close_cached_tables()
++ - [3] make_global_read_lock_block_commit()
++ [1] prevents new connections from obtaining tables locked for write.
++ [2] waits until all existing connections close their tables.
++ [3] prevents transactions from being committed.
++ */
++
++ if (lock_global_read_lock(thd))
++ DBUG_RETURN(true);
++
++ /*
++ This call will be blocked by any connection holding a READ or WRITE lock.
++ Ideally, we want to wait only for pending WRITE locks, but since:
++ con 1> LOCK TABLE T FOR READ;
++ con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
++ con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
++ can cause to wait on a read lock, it's required for the client application
++ to unlock everything, and acceptable for the server to wait on all locks.
++ */
++ if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)))
++ goto end_with_read_lock;
++
++ if ((result= make_global_read_lock_block_commit(thd)))
++ goto end_with_read_lock;
++
++ /* Change the opt_readonly system variable, safe because the lock is held */
++ result= sys_var_bool_ptr::update(thd, var);
++
++end_with_read_lock:
++ /* Release the lock */
++ unlock_global_read_lock(thd);
++ DBUG_RETURN(result);
++}
++
++
++#ifndef DBUG_OFF
++/* even session variable here requires SUPER, because of -#o,file */
++bool sys_var_thd_dbug::check(THD *thd, set_var *var)
++{
++ return check_global_access(thd, SUPER_ACL);
++}
++
++bool sys_var_thd_dbug::update(THD *thd, set_var *var)
++{
++ char buf[256];
++ String str(buf, sizeof(buf), system_charset_info), *res;
++
++ res= var->value->val_str(&str);
++
++ if (var->type == OPT_GLOBAL)
++ DBUG_SET_INITIAL(res ? res->c_ptr() : "");
++ else
++ DBUG_SET(res ? res->c_ptr() : "");
++
++ return 0;
++}
++
++
++uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
++{
++ char buf[256];
++ if (type == OPT_GLOBAL)
++ DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
++ else
++ DBUG_EXPLAIN(buf, sizeof(buf));
++ return (uchar*) thd->strdup(buf);
++}
++#endif /* DBUG_OFF */
++
++
++#ifdef HAVE_EVENT_SCHEDULER
++bool sys_var_event_scheduler::check(THD *thd, set_var *var)
++{
++ return check_enum(thd, var, &Events::var_typelib);
++}
++
++/*
++ The update method of the global variable event_scheduler.
++ If event_scheduler is switched from 0 to 1 then the scheduler main
++ thread is resumed and if from 1 to 0 the scheduler thread is suspended
++
++ SYNOPSIS
++ sys_var_event_scheduler::update()
++ thd Thread context (unused)
++ var The new value
++
++ Returns
++ FALSE OK
++ TRUE Error
++*/
++
++bool
++sys_var_event_scheduler::update(THD *thd, set_var *var)
++{
++ int res;
++ /* here start the thread if not running. */
++ DBUG_ENTER("sys_var_event_scheduler::update");
++ DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
++
++ enum Events::enum_opt_event_scheduler
++ new_state=
++ (enum Events::enum_opt_event_scheduler) var->save_result.ulong_value;
++
++ res= Events::switch_event_scheduler_state(new_state);
++
++ DBUG_RETURN((bool) res);
++}
++
++
++uchar *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
++ LEX_STRING *base)
++{
++ return (uchar *) Events::get_opt_event_scheduler_str();
++}
++#endif
++
++
++int
++check_max_allowed_packet(THD *thd, set_var *var)
++{
++ longlong val= var->value->val_int();
++ if (val < (longlong) global_system_variables.net_buffer_length)
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_UNKNOWN_ERROR,
++ "The value of 'max_allowed_packet' should be no less than "
++ "the value of 'net_buffer_length'");
++ }
++ return 0;
++}
++
++
++int
++check_net_buffer_length(THD *thd, set_var *var)
++{
++ longlong val= var->value->val_int();
++ if (val > (longlong) global_system_variables.max_allowed_packet)
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_UNKNOWN_ERROR,
++ "The value of 'max_allowed_packet' should be no less than "
++ "the value of 'net_buffer_length'");
++ }
++ return 0;
++}
++
++/****************************************************************************
++ Used templates
++****************************************************************************/
++
++#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
++template class List<set_var_base>;
++template class List_iterator_fast<set_var_base>;
++template class I_List_iterator<NAMED_LIST>;
++#endif
+diff -urN mysql-old/sql/slave.cc mysql/sql/slave.cc
+--- mysql-old/sql/slave.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/slave.cc 2011-05-10 17:56:01.483349044 +0000
+@@ -1737,7 +1737,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2354,7 +2354,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4050,7 +4050,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -urN mysql-old/sql/spatial.h mysql/sql/spatial.h
+--- mysql-old/sql/spatial.h 2011-05-10 17:45:45.640015709 +0000
++++ mysql/sql/spatial.h 2011-05-10 17:56:01.486682377 +0000
+@@ -180,8 +180,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -urN mysql-old/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql-old/sql/sp_head.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sp_head.cc 2011-05-10 17:56:01.486682377 +0000
+@@ -2453,7 +2453,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2654,7 +2654,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -urN mysql-old/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql-old/sql/sql_acl.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/sql_acl.cc 2011-05-10 17:56:01.490015710 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -urN mysql-old/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql-old/sql/sql_analyse.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_analyse.cc 2011-05-10 17:56:01.493349043 +0000
+@@ -280,16 +280,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1043,7 +1043,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1068,7 +1068,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1185,7 +1185,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -urN mysql-old/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql-old/sql/sql_cache.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_cache.cc 2011-05-10 17:56:01.493349043 +0000
+@@ -1004,7 +1004,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2425,7 +2425,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2480,7 +2480,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2508,7 +2508,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2596,8 +2596,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2629,7 +2629,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2638,7 +2638,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3061,7 +3061,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -urN mysql-old/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql-old/sql/sql_class.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/sql_class.cc 2011-05-10 17:56:01.500015709 +0000
+@@ -416,7 +416,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -431,7 +431,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2082,7 +2082,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -urN mysql-old/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql-old/sql/sql_client.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_client.cc 2011-05-10 17:56:01.500015709 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -urN mysql-old/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql-old/sql/sql_connect.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/sql_connect.cc 2011-05-10 17:56:01.503349042 +0000
+@@ -789,7 +789,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -urN mysql-old/sql/sql_connect.cc.orig mysql/sql/sql_connect.cc.orig
+--- mysql-old/sql/sql_connect.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/sql_connect.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,1315 @@
++/* Copyright (C) 2007 MySQL AB
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++
++/*
++ Functions to autenticate and handle reqests for a connection
++*/
++
++#include "mysql_priv.h"
++
++#ifdef HAVE_OPENSSL
++/*
++ Without SSL the handshake consists of one packet. This packet
++ has both client capabilites and scrambled password.
++ With SSL the handshake might consist of two packets. If the first
++ packet (client capabilities) has CLIENT_SSL flag set, we have to
++ switch to SSL and read the second packet. The scrambled password
++ is in the second packet and client_capabilites field will be ignored.
++ Maybe it is better to accept flags other than CLIENT_SSL from the
++ second packet?
++*/
++#define SSL_HANDSHAKE_SIZE 2
++#define NORMAL_HANDSHAKE_SIZE 6
++#define MIN_HANDSHAKE_SIZE 2
++#else
++#define MIN_HANDSHAKE_SIZE 6
++#endif /* HAVE_OPENSSL */
++
++#ifdef __WIN__
++extern void win_install_sigabrt_handler();
++#endif
++
++/*
++ Get structure for logging connection data for the current user
++*/
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++static HASH hash_user_connections;
++
++static int get_or_create_user_conn(THD *thd, const char *user,
++ const char *host,
++ USER_RESOURCES *mqh)
++{
++ int return_val= 0;
++ size_t temp_len, user_len;
++ char temp_user[USER_HOST_BUFF_SIZE];
++ struct user_conn *uc;
++
++ DBUG_ASSERT(user != 0);
++ DBUG_ASSERT(host != 0);
++
++ user_len= strlen(user);
++ temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
++ (void) pthread_mutex_lock(&LOCK_user_conn);
++ if (!(uc = (struct user_conn *) hash_search(&hash_user_connections,
++ (uchar*) temp_user, temp_len)))
++ {
++ /* First connection for user; Create a user connection object */
++ if (!(uc= ((struct user_conn*)
++ my_malloc(sizeof(struct user_conn) + temp_len+1,
++ MYF(MY_WME)))))
++ {
++ /* MY_WME ensures an error is set in THD. */
++ return_val= 1;
++ goto end;
++ }
++ uc->user=(char*) (uc+1);
++ memcpy(uc->user,temp_user,temp_len+1);
++ uc->host= uc->user + user_len + 1;
++ uc->len= temp_len;
++ uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
++ uc->user_resources= *mqh;
++ uc->reset_utime= thd->thr_create_utime;
++ if (my_hash_insert(&hash_user_connections, (uchar*) uc))
++ {
++ /* The only possible error is out of memory, MY_WME sets an error. */
++ my_free((char*) uc,0);
++ return_val= 1;
++ goto end;
++ }
++ }
++ thd->user_connect=uc;
++ uc->connections++;
++end:
++ (void) pthread_mutex_unlock(&LOCK_user_conn);
++ return return_val;
++
++}
++
++
++/*
++ check if user has already too many connections
++
++ SYNOPSIS
++ check_for_max_user_connections()
++ thd Thread handle
++ uc User connect object
++
++ NOTES
++ If check fails, we decrease user connection count, which means one
++ shouldn't call decrease_user_connections() after this function.
++
++ RETURN
++ 0 ok
++ 1 error
++*/
++
++static
++int check_for_max_user_connections(THD *thd, USER_CONN *uc)
++{
++ int error=0;
++ DBUG_ENTER("check_for_max_user_connections");
++
++ (void) pthread_mutex_lock(&LOCK_user_conn);
++ if (max_user_connections && !uc->user_resources.user_conn &&
++ max_user_connections < (uint) uc->connections)
++ {
++ my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
++ error=1;
++ goto end;
++ }
++ time_out_user_resource_limits(thd, uc);
++ if (uc->user_resources.user_conn &&
++ uc->user_resources.user_conn < uc->connections)
++ {
++ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
++ "max_user_connections",
++ (long) uc->user_resources.user_conn);
++ error= 1;
++ goto end;
++ }
++ if (uc->user_resources.conn_per_hour &&
++ uc->user_resources.conn_per_hour <= uc->conn_per_hour)
++ {
++ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
++ "max_connections_per_hour",
++ (long) uc->user_resources.conn_per_hour);
++ error=1;
++ goto end;
++ }
++ uc->conn_per_hour++;
++
++end:
++ if (error)
++ uc->connections--; // no need for decrease_user_connections() here
++ (void) pthread_mutex_unlock(&LOCK_user_conn);
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Decrease user connection count
++
++ SYNOPSIS
++ decrease_user_connections()
++ uc User connection object
++
++ NOTES
++ If there is a n user connection object for a connection
++ (which only happens if 'max_user_connections' is defined or
++ if someone has created a resource grant for a user), then
++ the connection count is always incremented on connect.
++
++ The user connect object is not freed if some users has
++ 'max connections per hour' defined as we need to be able to hold
++ count over the lifetime of the connection.
++*/
++
++void decrease_user_connections(USER_CONN *uc)
++{
++ DBUG_ENTER("decrease_user_connections");
++ (void) pthread_mutex_lock(&LOCK_user_conn);
++ DBUG_ASSERT(uc->connections);
++ if (!--uc->connections && !mqh_used)
++ {
++ /* Last connection for user; Delete it */
++ (void) hash_delete(&hash_user_connections,(uchar*) uc);
++ }
++ (void) pthread_mutex_unlock(&LOCK_user_conn);
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Reset per-hour user resource limits when it has been more than
++ an hour since they were last checked
++
++ SYNOPSIS:
++ time_out_user_resource_limits()
++ thd Thread handler
++ uc User connection details
++
++ NOTE:
++ This assumes that the LOCK_user_conn mutex has been acquired, so it is
++ safe to test and modify members of the USER_CONN structure.
++*/
++
++void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
++{
++ ulonglong check_time= thd->start_utime;
++ DBUG_ENTER("time_out_user_resource_limits");
++
++ /* If more than a hour since last check, reset resource checking */
++ if (check_time - uc->reset_utime >= LL(3600000000))
++ {
++ uc->questions=1;
++ uc->updates=0;
++ uc->conn_per_hour=0;
++ uc->reset_utime= check_time;
++ }
++
++ DBUG_VOID_RETURN;
++}
++
++/*
++ Check if maximum queries per hour limit has been reached
++ returns 0 if OK.
++*/
++
++bool check_mqh(THD *thd, uint check_command)
++{
++ bool error= 0;
++ USER_CONN *uc=thd->user_connect;
++ DBUG_ENTER("check_mqh");
++ DBUG_ASSERT(uc != 0);
++
++ (void) pthread_mutex_lock(&LOCK_user_conn);
++
++ time_out_user_resource_limits(thd, uc);
++
++ /* Check that we have not done too many questions / hour */
++ if (uc->user_resources.questions &&
++ uc->questions++ >= uc->user_resources.questions)
++ {
++ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
++ (long) uc->user_resources.questions);
++ error=1;
++ goto end;
++ }
++ if (check_command < (uint) SQLCOM_END)
++ {
++ /* Check that we have not done too many updates / hour */
++ if (uc->user_resources.updates &&
++ (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
++ uc->updates++ >= uc->user_resources.updates)
++ {
++ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
++ (long) uc->user_resources.updates);
++ error=1;
++ goto end;
++ }
++ }
++end:
++ (void) pthread_mutex_unlock(&LOCK_user_conn);
++ DBUG_RETURN(error);
++}
++
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++
++
++/**
++ Check if user exist and password supplied is correct.
++
++ @param thd thread handle, thd->security_ctx->{host,user,ip} are used
++ @param command originator of the check: now check_user is called
++ during connect and change user procedures; used for
++ logging.
++ @param passwd scrambled password received from client
++ @param passwd_len length of scrambled password
++ @param db database name to connect to, may be NULL
++ @param check_count TRUE if establishing a new connection. In this case
++ check that we have not exceeded the global
++ max_connections limist
++
++ @note Host, user and passwd may point to communication buffer.
++ Current implementation does not depend on that, but future changes
++ should be done with this in mind; 'thd' is INOUT, all other params
++ are 'IN'.
++
++ @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
++ thd->db are updated; OK is sent to the client.
++ @retval 1 error, e.g. access denied or handshake error, not sent to
++ the client. A message is pushed into the error stack.
++*/
++
++int
++check_user(THD *thd, enum enum_server_command command,
++ const char *passwd, uint passwd_len, const char *db,
++ bool check_count)
++{
++ DBUG_ENTER("check_user");
++ LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
++
++ /*
++ Clear thd->db as it points to something, that will be freed when
++ connection is closed. We don't want to accidentally free a wrong
++ pointer if connect failed. Also in case of 'CHANGE USER' failure,
++ current database will be switched to 'no database selected'.
++ */
++ thd->reset_db(NULL, 0);
++
++#ifdef NO_EMBEDDED_ACCESS_CHECKS
++ thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
++ /* Change database if necessary */
++ if (db && db[0])
++ {
++ if (mysql_change_db(thd, &db_str, FALSE))
++ DBUG_RETURN(1);
++ }
++ my_ok(thd);
++ DBUG_RETURN(0);
++#else
++
++ my_bool opt_secure_auth_local;
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ opt_secure_auth_local= opt_secure_auth;
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ /*
++ If the server is running in secure auth mode, short scrambles are
++ forbidden.
++ */
++ if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
++ {
++ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
++ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
++ DBUG_RETURN(1);
++ }
++ if (passwd_len != 0 &&
++ passwd_len != SCRAMBLE_LENGTH &&
++ passwd_len != SCRAMBLE_LENGTH_323)
++ {
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ DBUG_RETURN(1);
++ }
++
++ USER_RESOURCES ur;
++ int res= acl_getroot(thd, &ur, passwd, passwd_len);
++#ifndef EMBEDDED_LIBRARY
++ if (res == -1)
++ {
++ /*
++ This happens when client (new) sends password scrambled with
++ scramble(), but database holds old value (scrambled with
++ scramble_323()). Here we please client to send scrambled_password
++ in old format.
++ */
++ NET *net= &thd->net;
++ if (opt_secure_auth_local)
++ {
++ my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip);
++ general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip);
++ DBUG_RETURN(1);
++ }
++ /* We have to read very specific packet size */
++ if (send_old_password_request(thd) ||
++ my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ DBUG_RETURN(1);
++ }
++ /* Final attempt to check the user based on reply */
++ /* So as passwd is short, errcode is always >= 0 */
++ res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
++ }
++#endif /*EMBEDDED_LIBRARY*/
++ /* here res is always >= 0 */
++ if (res == 0)
++ {
++ if (!(thd->main_security_ctx.master_access &
++ NO_ACCESS)) // authentication is OK
++ {
++ DBUG_PRINT("info",
++ ("Capabilities: %lu packet_length: %ld Host: '%s' "
++ "Login user: '%s' Priv_user: '%s' Using password: %s "
++ "Access: %lu db: '%s'",
++ thd->client_capabilities,
++ thd->max_client_packet_length,
++ thd->main_security_ctx.host_or_ip,
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.priv_user,
++ passwd_len ? "yes": "no",
++ thd->main_security_ctx.master_access,
++ (thd->db ? thd->db : "*none*")));
++
++ if (check_count)
++ {
++ pthread_mutex_lock(&LOCK_connection_count);
++ bool count_ok= connection_count <= max_connections ||
++ (thd->main_security_ctx.master_access & SUPER_ACL);
++ VOID(pthread_mutex_unlock(&LOCK_connection_count));
++
++ if (!count_ok)
++ { // too many connections
++ my_error(ER_CON_COUNT_ERROR, MYF(0));
++ DBUG_RETURN(1);
++ }
++ }
++
++ /*
++ Log the command before authentication checks, so that the user can
++ check the log for the tried login tried and also to detect
++ break-in attempts.
++ */
++ general_log_print(thd, command,
++ (thd->main_security_ctx.priv_user ==
++ thd->main_security_ctx.user ?
++ (char*) "%s@%s on %s" :
++ (char*) "%s@%s as anonymous on %s"),
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip,
++ db ? db : (char*) "");
++
++ /*
++ This is the default access rights for the current database. It's
++ set to 0 here because we don't have an active database yet (and we
++ may not have an active database to set.
++ */
++ thd->main_security_ctx.db_access=0;
++
++ /* Don't allow user to connect if he has done too many queries */
++ if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
++ max_user_connections) &&
++ get_or_create_user_conn(thd,
++ (opt_old_style_user_limits ? thd->main_security_ctx.user :
++ thd->main_security_ctx.priv_user),
++ (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
++ thd->main_security_ctx.priv_host),
++ &ur))
++ {
++ /* The error is set by get_or_create_user_conn(). */
++ DBUG_RETURN(1);
++ }
++ if (thd->user_connect &&
++ (thd->user_connect->user_resources.conn_per_hour ||
++ thd->user_connect->user_resources.user_conn ||
++ max_user_connections) &&
++ check_for_max_user_connections(thd, thd->user_connect))
++ {
++ /* The error is set in check_for_max_user_connections(). */
++ DBUG_RETURN(1);
++ }
++
++ /* Change database if necessary */
++ if (db && db[0])
++ {
++ if (mysql_change_db(thd, &db_str, FALSE))
++ {
++ /* mysql_change_db() has pushed the error message. */
++ if (thd->user_connect)
++ decrease_user_connections(thd->user_connect);
++ DBUG_RETURN(1);
++ }
++ }
++ my_ok(thd);
++ thd->password= test(passwd_len); // remember for error messages
++#ifndef EMBEDDED_LIBRARY
++ /*
++ Allow the network layer to skip big packets. Although a malicious
++ authenticated session might use this to trick the server to read
++ big packets indefinitely, this is a previously established behavior
++ that needs to be preserved as to not break backwards compatibility.
++ */
++ thd->net.skip_big_packet= TRUE;
++#endif
++ /* Ready to handle queries */
++ DBUG_RETURN(0);
++ }
++ }
++ else if (res == 2) // client gave short hash, server has long hash
++ {
++ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
++ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
++ DBUG_RETURN(1);
++ }
++ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip,
++ passwd_len ? ER(ER_YES) : ER(ER_NO));
++ general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
++ thd->main_security_ctx.user,
++ thd->main_security_ctx.host_or_ip,
++ passwd_len ? ER(ER_YES) : ER(ER_NO));
++ DBUG_RETURN(1);
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++}
++
++
++/*
++ Check for maximum allowable user connections, if the mysqld server is
++ started with corresponding variable that is greater then 0.
++*/
++
++extern "C" uchar *get_key_conn(user_conn *buff, size_t *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length= buff->len;
++ return (uchar*) buff->user;
++}
++
++
++extern "C" void free_user(struct user_conn *uc)
++{
++ my_free((char*) uc,MYF(0));
++}
++
++
++void init_max_user_conn(void)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
++ 0,0,
++ (hash_get_key) get_key_conn, (hash_free_key) free_user,
++ 0);
++#endif
++}
++
++
++void free_max_user_conn(void)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ hash_free(&hash_user_connections);
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++}
++
++
++void reset_mqh(LEX_USER *lu, bool get_them= 0)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ (void) pthread_mutex_lock(&LOCK_user_conn);
++ if (lu) // for GRANT
++ {
++ USER_CONN *uc;
++ uint temp_len=lu->user.length+lu->host.length+2;
++ char temp_user[USER_HOST_BUFF_SIZE];
++
++ memcpy(temp_user,lu->user.str,lu->user.length);
++ memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
++ temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
++ if ((uc = (struct user_conn *) hash_search(&hash_user_connections,
++ (uchar*) temp_user, temp_len)))
++ {
++ uc->questions=0;
++ get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
++ uc->updates=0;
++ uc->conn_per_hour=0;
++ }
++ }
++ else
++ {
++ /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */
++ for (uint idx=0;idx < hash_user_connections.records; idx++)
++ {
++ USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections,
++ idx);
++ if (get_them)
++ get_mqh(uc->user,uc->host,uc);
++ uc->questions=0;
++ uc->updates=0;
++ uc->conn_per_hour=0;
++ }
++ }
++ (void) pthread_mutex_unlock(&LOCK_user_conn);
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++}
++
++
++/**
++ Set thread character set variables from the given ID
++
++ @param thd thread handle
++ @param cs_number character set and collation ID
++
++ @retval 0 OK; character_set_client, collation_connection and
++ character_set_results are set to the new value,
++ or to the default global values.
++
++ @retval 1 error, e.g. the given ID is not supported by parser.
++ Corresponding SQL error is sent.
++*/
++
++bool thd_init_client_charset(THD *thd, uint cs_number)
++{
++ CHARSET_INFO *cs;
++ /*
++ Use server character set and collation if
++ - opt_character_set_client_handshake is not set
++ - client has not specified a character set
++ - client character set is the same as the servers
++ - client character set doesn't exists in server
++ */
++ if (!opt_character_set_client_handshake ||
++ !(cs= get_charset(cs_number, MYF(0))) ||
++ !my_strcasecmp(&my_charset_latin1,
++ global_system_variables.character_set_client->name,
++ cs->name))
++ {
++ thd->variables.character_set_client=
++ global_system_variables.character_set_client;
++ thd->variables.collation_connection=
++ global_system_variables.collation_connection;
++ thd->variables.character_set_results=
++ global_system_variables.character_set_results;
++ }
++ else
++ {
++ if (!is_supported_parser_charset(cs))
++ {
++ /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
++ cs->csname);
++ return true;
++ }
++ thd->variables.character_set_results=
++ thd->variables.collation_connection=
++ thd->variables.character_set_client= cs;
++ }
++ return false;
++}
++
++
++/*
++ Initialize connection threads
++*/
++
++bool init_new_connection_handler_thread()
++{
++ pthread_detach_this_thread();
++#if defined(__WIN__)
++ win_install_sigabrt_handler();
++#else
++ /* Win32 calls this in pthread_create */
++ if (my_thread_init())
++ return 1;
++#endif /* __WIN__ */
++ return 0;
++}
++
++#ifndef EMBEDDED_LIBRARY
++/**
++ Get a null character terminated string from a user-supplied buffer.
++
++ @param buffer[in, out] Pointer to the buffer to be scanned.
++ @param max_bytes_available[in, out] Limit the bytes to scan.
++ @param string_length[out] The number of characters scanned not including
++ the null character.
++
++ @remark The string_length does not include the terminating null character.
++ However, after the call, the buffer is increased by string_length+1
++ bytes, beyond the null character if there still available bytes to
++ scan.
++
++ @return pointer to beginning of the string scanned.
++ @retval NULL The buffer content is malformed
++*/
++
++static
++char *get_null_terminated_string(char **buffer,
++ size_t *max_bytes_available,
++ size_t *string_length)
++{
++ char *str= (char *)memchr(*buffer, '\0', *max_bytes_available);
++
++ if (str == NULL)
++ return NULL;
++
++ *string_length= (size_t)(str - *buffer);
++ *max_bytes_available-= *string_length + 1;
++ str= *buffer;
++ *buffer += *string_length + 1;
++
++ return str;
++}
++
++
++/**
++ Get a length encoded string from a user-supplied buffer.
++
++ @param buffer[in, out] The buffer to scan; updates position after scan.
++ @param max_bytes_available[in, out] Limit the number of bytes to scan
++ @param string_length[out] Number of characters scanned
++
++ @remark In case the length is zero, then the total size of the string is
++ considered to be 1 byte; the size byte.
++
++ @return pointer to first byte after the header in buffer.
++ @retval NULL The buffer content is malformed
++*/
++
++static
++char *get_length_encoded_string(char **buffer,
++ size_t *max_bytes_available,
++ size_t *string_length)
++{
++ if (*max_bytes_available == 0)
++ return NULL;
++
++ /* Do double cast to prevent overflow from signed / unsigned conversion */
++ size_t str_len= (size_t)(unsigned char)**buffer;
++
++ /*
++ If the length encoded string has the length 0
++ the total size of the string is only one byte long (the size byte)
++ */
++ if (str_len == 0)
++ {
++ ++*buffer;
++ *string_length= 0;
++ /*
++ Return a pointer to the 0 character so the return value will be
++ an empty string.
++ */
++ return *buffer-1;
++ }
++
++ if (str_len >= *max_bytes_available)
++ return NULL;
++
++ char *str= *buffer+1;
++ *string_length= str_len;
++ *max_bytes_available-= *string_length + 1;
++ *buffer+= *string_length + 1;
++ return str;
++}
++
++
++/*
++ Perform handshake, authorize client and update thd ACL variables.
++
++ SYNOPSIS
++ check_connection()
++ thd thread handle
++
++ RETURN
++ 0 success, OK is sent to user, thd is updated.
++ -1 error, which is sent to user
++ > 0 error code (not sent to user)
++*/
++
++static int check_connection(THD *thd)
++{
++ uint connect_errors= 0;
++ NET *net= &thd->net;
++ ulong pkt_len= 0;
++ char *end;
++
++ DBUG_PRINT("info",
++ ("New connection received on %s", vio_description(net->vio)));
++#ifdef SIGNAL_WITH_VIO_CLOSE
++ thd->set_active_vio(net->vio);
++#endif
++
++ if (!thd->main_security_ctx.host) // If TCP/IP connection
++ {
++ char ip[30];
++
++ if (vio_peer_addr(net->vio, ip, &thd->peer_port))
++ {
++ my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
++ return 1; /* The error is set by my_strdup(). */
++ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
++ vio_in_addr(net->vio,&thd->remote.sin_addr);
++ if (!(specialflag & SPECIAL_NO_RESOLVE))
++ {
++ vio_in_addr(net->vio,&thd->remote.sin_addr);
++ thd->main_security_ctx.host=
++ ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
++ /* Cut very long hostnames to avoid possible overflows */
++ if (thd->main_security_ctx.host)
++ {
++ if (thd->main_security_ctx.host != my_localhost)
++ thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ HOSTNAME_LENGTH)]= 0;
++ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
++ }
++ if (connect_errors > max_connect_errors)
++ {
++ my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ }
++ DBUG_PRINT("info",("Host: %s ip: %s",
++ (thd->main_security_ctx.host ?
++ thd->main_security_ctx.host : "unknown host"),
++ (thd->main_security_ctx.ip ?
++ thd->main_security_ctx.ip : "unknown ip")));
++ if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
++ {
++ my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),
++ thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ }
++ else /* Hostname given means that the connection was on a socket */
++ {
++ DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
++ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
++ thd->main_security_ctx.ip= 0;
++ /* Reset sin_addr */
++ bzero((char*) &thd->remote, sizeof(thd->remote));
++ }
++ vio_keepalive(net->vio, TRUE);
++
++ ulong server_capabilites;
++ {
++ /* buff[] needs to big enough to hold the server_version variable */
++ char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64];
++ server_capabilites= CLIENT_BASIC_FLAGS;
++
++ if (opt_using_transactions)
++ server_capabilites|= CLIENT_TRANSACTIONS;
++#ifdef HAVE_COMPRESS
++ server_capabilites|= CLIENT_COMPRESS;
++#endif /* HAVE_COMPRESS */
++#ifdef HAVE_OPENSSL
++ if (ssl_acceptor_fd)
++ {
++ server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */
++ server_capabilites |= CLIENT_SSL_VERIFY_SERVER_CERT;
++ }
++#endif /* HAVE_OPENSSL */
++
++ end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
++ int4store((uchar*) end, thd->thread_id);
++ end+= 4;
++ /*
++ So as check_connection is the only entry point to authorization
++ procedure, scramble is set here. This gives us new scramble for
++ each handshake.
++ */
++ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
++ /*
++ Old clients does not understand long scrambles, but can ignore packet
++ tail: that's why first part of the scramble is placed here, and second
++ part at the end of packet.
++ */
++ end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
++
++ int2store(end, server_capabilites);
++ /* write server characteristics: up to 16 bytes allowed */
++ end[2]=(char) default_charset_info->number;
++ int2store(end+3, thd->server_status);
++ bzero(end+5, 13);
++ end+= 18;
++ /* write scramble tail */
++ end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323,
++ SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
++
++ /* At this point we write connection message and read reply */
++ if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
++ (uchar*) buff, (size_t) (end-buff)) ||
++ (pkt_len= my_net_read(net)) == packet_error ||
++ pkt_len < MIN_HANDSHAKE_SIZE)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0),
++ thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ }
++#ifdef _CUSTOMCONFIG_
++#include "_cust_sql_parse.h"
++#endif
++ if (connect_errors)
++ reset_host_errors(&thd->remote.sin_addr);
++ if (thd->packet.alloc(thd->variables.net_buffer_length))
++ return 1; /* The error is set by alloc(). */
++
++ thd->client_capabilities= uint2korr(net->read_pos);
++ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
++ {
++ thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
++ thd->max_client_packet_length= uint4korr(net->read_pos+4);
++ DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
++ if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
++ return 1;
++ thd->update_charset();
++ end= (char*) net->read_pos+32;
++ }
++ else
++ {
++ thd->max_client_packet_length= uint3korr(net->read_pos+2);
++ end= (char*) net->read_pos+5;
++ }
++ /*
++ Disable those bits which are not supported by the server.
++ This is a precautionary measure, if the client lies. See Bug#27944.
++ */
++ thd->client_capabilities&= server_capabilites;
++
++ if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
++ thd->variables.sql_mode|= MODE_IGNORE_SPACE;
++#ifdef HAVE_OPENSSL
++ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
++ if (thd->client_capabilities & CLIENT_SSL)
++ {
++ /* Do the SSL layering. */
++ if (!ssl_acceptor_fd)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ DBUG_PRINT("info", ("IO layer change in progress..."));
++ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
++ {
++ DBUG_PRINT("error", ("Failed to accept new SSL connection"));
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ DBUG_PRINT("info", ("Reading user information over SSL layer"));
++ if ((pkt_len= my_net_read(net)) == packet_error ||
++ pkt_len < NORMAL_HANDSHAKE_SIZE)
++ {
++ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
++ pkt_len));
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ }
++#endif /* HAVE_OPENSSL */
++
++ if (end > (char *)net->read_pos + pkt_len)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++
++ if (thd->client_capabilities & CLIENT_INTERACTIVE)
++ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
++ if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
++ opt_using_transactions)
++ net->return_status= &thd->server_status;
++
++ /*
++ In order to safely scan a head for '\0' string terminators
++ we must keep track of how many bytes remain in the allocated
++ buffer or we might read past the end of the buffer.
++ */
++ size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
++
++ size_t user_len;
++ char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet,
++ &user_len);
++ if (user == NULL)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++
++ /*
++ Old clients send a null-terminated string as password; new clients send
++ the size (1 byte) + string (not null-terminated). Hence in case of empty
++ password both send '\0'.
++ */
++ size_t passwd_len= 0;
++ char *passwd= NULL;
++
++ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
++ {
++ /*
++ 4.1+ password. First byte is password length.
++ */
++ passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
++ &passwd_len);
++ }
++ else
++ {
++ /*
++ Old passwords are zero terminated strings.
++ */
++ passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet,
++ &passwd_len);
++ }
++
++ if (passwd == NULL)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++
++ size_t db_len= 0;
++ char *db= NULL;
++
++ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
++ {
++ db= get_null_terminated_string(&end, &bytes_remaining_in_packet,
++ &db_len);
++ if (db == NULL)
++ {
++ inc_host_errors(&thd->remote.sin_addr);
++ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
++ return 1;
++ }
++ }
++
++ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
++ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
++ uint dummy_errors;
++
++ /* Since 4.1 all database names are stored in utf8 */
++ if (db)
++ {
++ db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
++ system_charset_info,
++ db, db_len,
++ thd->charset(), &dummy_errors)]= 0;
++ db= db_buff;
++ }
++
++ user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
++ system_charset_info, user, user_len,
++ thd->charset(), &dummy_errors)]= '\0';
++ user= user_buff;
++
++ /* If username starts and ends in "'", chop them off */
++ if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
++ {
++ user[user_len-1]= 0;
++ user++;
++ user_len-= 2;
++ }
++
++ /*
++ Clip username to allowed length in characters (not bytes). This is
++ mostly for backward compatibility.
++ */
++ {
++ CHARSET_INFO *cs= system_charset_info;
++ int err;
++
++ user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len,
++ USERNAME_CHAR_LENGTH, &err);
++ user[user_len]= '\0';
++ }
++
++ if (thd->main_security_ctx.user)
++ x_free(thd->main_security_ctx.user);
++ if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
++ return 1; /* The error is set by my_strdup(). */
++ return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
++}
++
++
++/*
++ Setup thread to be used with the current thread
++
++ SYNOPSIS
++ bool setup_connection_thread_globals()
++ thd Thread/connection handler
++
++ RETURN
++ 0 ok
++ 1 Error (out of memory)
++ In this case we will close the connection and increment status
++*/
++
++bool setup_connection_thread_globals(THD *thd)
++{
++ if (thd->store_globals())
++ {
++ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
++ statistic_increment(aborted_connects,&LOCK_status);
++ thread_scheduler.end_thread(thd, 0);
++ return 1; // Error
++ }
++ return 0;
++}
++
++
++/*
++ Autenticate user, with error reporting
++
++ SYNOPSIS
++ login_connection()
++ thd Thread handler
++
++ NOTES
++ Connection is not closed in case of errors
++
++ RETURN
++ 0 ok
++ 1 error
++*/
++
++
++static bool login_connection(THD *thd)
++{
++ NET *net= &thd->net;
++ int error;
++ DBUG_ENTER("login_connection");
++ DBUG_PRINT("info", ("login_connection called by thread %lu",
++ thd->thread_id));
++
++ /* Use "connect_timeout" value during connection phase */
++ my_net_set_read_timeout(net, connect_timeout);
++ my_net_set_write_timeout(net, connect_timeout);
++
++ error= check_connection(thd);
++ net_end_statement(thd);
++
++ if (error)
++ { // Wrong permissions
++#ifdef __NT__
++ if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
++ my_sleep(1000); /* must wait after eof() */
++#endif
++ statistic_increment(aborted_connects,&LOCK_status);
++ DBUG_RETURN(1);
++ }
++ /* Connect completed, set read/write timeouts back to default */
++ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
++ my_net_set_write_timeout(net, thd->variables.net_write_timeout);
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Close an established connection
++
++ NOTES
++ This mainly updates status variables
++*/
++
++static void end_connection(THD *thd)
++{
++ NET *net= &thd->net;
++ plugin_thdvar_cleanup(thd);
++ if (thd->user_connect)
++ decrease_user_connections(thd->user_connect);
++
++ if (thd->killed || (net->error && net->vio != 0))
++ {
++ statistic_increment(aborted_threads,&LOCK_status);
++ }
++
++ if (net->error && net->vio != 0)
++ {
++ if (!thd->killed && thd->variables.log_warnings > 1)
++ {
++ Security_context *sctx= thd->security_ctx;
++
++ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
++ thd->thread_id,(thd->db ? thd->db : "unconnected"),
++ sctx->user ? sctx->user : "unauthenticated",
++ sctx->host_or_ip,
++ (thd->main_da.is_error() ? thd->main_da.message() :
++ ER(ER_UNKNOWN_ERROR)));
++ }
++ }
++}
++
++
++/*
++ Initialize THD to handle queries
++*/
++
++static void prepare_new_connection_state(THD* thd)
++{
++ Security_context *sctx= thd->security_ctx;
++
++#ifdef __NETWARE__
++ netware_reg_user(sctx->ip, sctx->user, "MySQL");
++#endif
++
++ if (thd->variables.max_join_size == HA_POS_ERROR)
++ thd->options |= OPTION_BIG_SELECTS;
++ if (thd->client_capabilities & CLIENT_COMPRESS)
++ thd->net.compress=1; // Use compression
++
++ /*
++ Much of this is duplicated in create_embedded_thd() for the
++ embedded server library.
++ TODO: refactor this to avoid code duplication there
++ */
++ thd->version= refresh_version;
++ thd->proc_info= 0;
++ thd->command= COM_SLEEP;
++ thd->set_time();
++ thd->init_for_queries();
++
++ if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
++ {
++ execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
++ if (thd->is_error())
++ {
++ thd->killed= THD::KILL_CONNECTION;
++ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
++ thd->thread_id,(thd->db ? thd->db : "unconnected"),
++ sctx->user ? sctx->user : "unauthenticated",
++ sctx->host_or_ip, "init_connect command failed");
++ sql_print_warning("%s", thd->main_da.message());
++ }
++ thd->proc_info=0;
++ thd->set_time();
++ thd->init_for_queries();
++ }
++}
++
++
++/*
++ Thread handler for a connection
++
++ SYNOPSIS
++ handle_one_connection()
++ arg Connection object (THD)
++
++ IMPLEMENTATION
++ This function (normally) does the following:
++ - Initialize thread
++ - Initialize THD to be used with this thread
++ - Authenticate user
++ - Execute all queries sent on the connection
++ - Take connection down
++ - End thread / Handle next connection using thread from thread cache
++*/
++
++pthread_handler_t handle_one_connection(void *arg)
++{
++ THD *thd= (THD*) arg;
++
++ thd->thr_create_utime= my_micro_time();
++
++ if (thread_scheduler.init_new_connection_thread())
++ {
++ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
++ statistic_increment(aborted_connects,&LOCK_status);
++ thread_scheduler.end_thread(thd,0);
++ return 0;
++ }
++
++ /*
++ If a thread was created to handle this connection:
++ increment slow_launch_threads counter if it took more than
++ slow_launch_time seconds to create the thread.
++ */
++ if (thd->prior_thr_create_utime)
++ {
++ ulong launch_time= (ulong) (thd->thr_create_utime -
++ thd->prior_thr_create_utime);
++ if (launch_time >= slow_launch_time*1000000L)
++ statistic_increment(slow_launch_threads, &LOCK_status);
++ thd->prior_thr_create_utime= 0;
++ }
++
++ /*
++ handle_one_connection() is normally the only way a thread would
++ start and would always be on the very high end of the stack ,
++ therefore, the thread stack always starts at the address of the
++ first local variable of handle_one_connection, which is thd. We
++ need to know the start of the stack so that we could check for
++ stack overruns.
++ */
++ thd->thread_stack= (char*) &thd;
++ if (setup_connection_thread_globals(thd))
++ return 0;
++
++ for (;;)
++ {
++ NET *net= &thd->net;
++
++ lex_start(thd);
++ if (login_connection(thd))
++ goto end_thread;
++
++ prepare_new_connection_state(thd);
++
++ while (!net->error && net->vio != 0 &&
++ !(thd->killed == THD::KILL_CONNECTION))
++ {
++ if (do_command(thd))
++ break;
++ }
++ end_connection(thd);
++
++end_thread:
++ close_connection(thd, 0, 1);
++ if (thread_scheduler.end_thread(thd,1))
++ return 0; // Probably no-threads
++
++ /*
++ If end_thread() returns, we are either running with
++ thread-handler=no-threads or this thread has been schedule to
++ handle the next connection.
++ */
++ thd= current_thd;
++ thd->thread_stack= (char*) &thd;
++ }
++}
++#endif /* EMBEDDED_LIBRARY */
+diff -urN mysql-old/sql/sql_load.cc mysql/sql/sql_load.cc
+--- mysql-old/sql/sql_load.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_load.cc 2011-05-10 17:56:01.503349042 +0000
+@@ -1109,7 +1109,7 @@
+
+
+ /* Set of a stack for unget if long terminators */
+- uint length=max(field_term_length,line_term_length)+1;
++ uint length=MYSQL_MAX(field_term_length,line_term_length)+1;
+ set_if_bigger(length,line_start.length());
+ stack=stack_pos=(int*) sql_alloc(sizeof(int)*length);
+
+diff -urN mysql-old/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql-old/sql/sql_parse.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/sql_parse.cc 2011-05-10 17:56:01.510015710 +0000
+@@ -5722,7 +5722,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7226,7 +7226,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -urN mysql-old/sql/sql_parse.cc.orig mysql/sql/sql_parse.cc.orig
+--- mysql-old/sql/sql_parse.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/sql_parse.cc.orig 2011-04-12 12:11:38.000000000 +0000
+@@ -0,0 +1,7997 @@
++/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++#define MYSQL_LEX 1
++#include "mysql_priv.h"
++#include "sql_repl.h"
++#include "rpl_filter.h"
++#include "repl_failsafe.h"
++#include <m_ctype.h>
++#include <myisam.h>
++#include <my_dir.h>
++
++#include "sp_head.h"
++#include "sp.h"
++#include "sp_cache.h"
++#include "events.h"
++#include "sql_trigger.h"
++#include "debug_sync.h"
++
++/**
++ @defgroup Runtime_Environment Runtime Environment
++ @{
++*/
++
++/* Used in error handling only */
++#define SP_TYPE_STRING(LP) \
++ ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
++#define SP_COM_STRING(LP) \
++ ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
++ (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
++ (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
++ (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
++ "FUNCTION" : "PROCEDURE")
++
++static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
++static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
++
++const char *any_db="*any*"; // Special symbol for check_access
++
++const LEX_STRING command_name[]={
++ { C_STRING_WITH_LEN("Sleep") },
++ { C_STRING_WITH_LEN("Quit") },
++ { C_STRING_WITH_LEN("Init DB") },
++ { C_STRING_WITH_LEN("Query") },
++ { C_STRING_WITH_LEN("Field List") },
++ { C_STRING_WITH_LEN("Create DB") },
++ { C_STRING_WITH_LEN("Drop DB") },
++ { C_STRING_WITH_LEN("Refresh") },
++ { C_STRING_WITH_LEN("Shutdown") },
++ { C_STRING_WITH_LEN("Statistics") },
++ { C_STRING_WITH_LEN("Processlist") },
++ { C_STRING_WITH_LEN("Connect") },
++ { C_STRING_WITH_LEN("Kill") },
++ { C_STRING_WITH_LEN("Debug") },
++ { C_STRING_WITH_LEN("Ping") },
++ { C_STRING_WITH_LEN("Time") },
++ { C_STRING_WITH_LEN("Delayed insert") },
++ { C_STRING_WITH_LEN("Change user") },
++ { C_STRING_WITH_LEN("Binlog Dump") },
++ { C_STRING_WITH_LEN("Table Dump") },
++ { C_STRING_WITH_LEN("Connect Out") },
++ { C_STRING_WITH_LEN("Register Slave") },
++ { C_STRING_WITH_LEN("Prepare") },
++ { C_STRING_WITH_LEN("Execute") },
++ { C_STRING_WITH_LEN("Long Data") },
++ { C_STRING_WITH_LEN("Close stmt") },
++ { C_STRING_WITH_LEN("Reset stmt") },
++ { C_STRING_WITH_LEN("Set option") },
++ { C_STRING_WITH_LEN("Fetch") },
++ { C_STRING_WITH_LEN("Daemon") },
++ { C_STRING_WITH_LEN("Error") } // Last command number
++};
++
++const char *xa_state_names[]={
++ "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
++};
++
++/**
++ Mark a XA transaction as rollback-only if the RM unilaterally
++ rolled back the transaction branch.
++
++ @note If a rollback was requested by the RM, this function sets
++ the appropriate rollback error code and transits the state
++ to XA_ROLLBACK_ONLY.
++
++ @return TRUE if transaction was rolled back or if the transaction
++ state is XA_ROLLBACK_ONLY. FALSE otherwise.
++*/
++static bool xa_trans_rolled_back(XID_STATE *xid_state)
++{
++ if (xid_state->rm_error)
++ {
++ switch (xid_state->rm_error) {
++ case ER_LOCK_WAIT_TIMEOUT:
++ my_error(ER_XA_RBTIMEOUT, MYF(0));
++ break;
++ case ER_LOCK_DEADLOCK:
++ my_error(ER_XA_RBDEADLOCK, MYF(0));
++ break;
++ default:
++ my_error(ER_XA_RBROLLBACK, MYF(0));
++ }
++ xid_state->xa_state= XA_ROLLBACK_ONLY;
++ }
++
++ return (xid_state->xa_state == XA_ROLLBACK_ONLY);
++}
++
++/**
++ Rollback work done on behalf of at ransaction branch.
++*/
++static bool xa_trans_rollback(THD *thd)
++{
++ /*
++ Resource Manager error is meaningless at this point, as we perform
++ explicit rollback request by user. We must reset rm_error before
++ calling ha_rollback(), so thd->transaction.xid structure gets reset
++ by ha_rollback()/THD::transaction::cleanup().
++ */
++ thd->transaction.xid_state.rm_error= 0;
++
++ bool status= test(ha_rollback(thd));
++
++ thd->options&= ~(ulong) OPTION_BEGIN;
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
++ xid_cache_delete(&thd->transaction.xid_state);
++ thd->transaction.xid_state.xa_state= XA_NOTR;
++
++ return status;
++}
++
++static void unlock_locked_tables(THD *thd)
++{
++ if (thd->locked_tables)
++ {
++ thd->lock=thd->locked_tables;
++ thd->locked_tables=0; // Will be automatically closed
++ close_thread_tables(thd); // Free tables
++ }
++}
++
++
++bool end_active_trans(THD *thd)
++{
++ int error=0;
++ DBUG_ENTER("end_active_trans");
++ if (unlikely(thd->in_sub_stmt))
++ {
++ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
++ DBUG_RETURN(1);
++ }
++ if (thd->transaction.xid_state.xa_state != XA_NOTR)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ DBUG_RETURN(1);
++ }
++ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
++ OPTION_TABLE_LOCK))
++ {
++ DBUG_PRINT("info",("options: 0x%llx", thd->options));
++ /* Safety if one did "drop table" on locked tables */
++ if (!thd->locked_tables)
++ thd->options&= ~OPTION_TABLE_LOCK;
++ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
++ if (ha_commit(thd))
++ error=1;
++ }
++ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ DBUG_RETURN(error);
++}
++
++
++bool begin_trans(THD *thd)
++{
++ int error=0;
++ if (unlikely(thd->in_sub_stmt))
++ {
++ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
++ return 1;
++ }
++ if (thd->locked_tables)
++ {
++ thd->lock=thd->locked_tables;
++ thd->locked_tables=0; // Will be automatically closed
++ close_thread_tables(thd); // Free tables
++ }
++ if (end_active_trans(thd))
++ error= -1;
++ else
++ {
++ thd->options|= OPTION_BEGIN;
++ thd->server_status|= SERVER_STATUS_IN_TRANS;
++ }
++ return error;
++}
++
++#ifdef HAVE_REPLICATION
++/**
++ Returns true if all tables should be ignored.
++*/
++inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
++{
++ return rpl_filter->is_on() && tables && !thd->spcont &&
++ !rpl_filter->tables_ok(thd->db, tables);
++}
++#endif
++
++
++static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
++{
++ for (TABLE_LIST *table= tables; table; table= table->next_global)
++ {
++ DBUG_ASSERT(table->db && table->table_name);
++ if (table->updating &&
++ !find_temporary_table(thd, table->db, table->table_name))
++ return 1;
++ }
++ return 0;
++}
++
++
++/**
++ Mark all commands that somehow changes a table.
++
++ This is used to check number of updates / hour.
++
++ sql_command is actually set to SQLCOM_END sometimes
++ so we need the +1 to include it in the array.
++
++ See COMMAND_FLAG_xxx for different type of commands
++ 2 - query that returns meaningful ROW_COUNT() -
++ a number of modified rows
++*/
++
++uint sql_command_flags[SQLCOM_END+1];
++
++void init_update_queries(void)
++{
++ bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
++
++ sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
++ sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
++ sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
++ sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
++
++ sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
++ CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE;
++
++ sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
++ sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
++
++ sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
++ CF_SHOW_TABLE_COMMAND |
++ CF_REEXECUTION_FRAGILE);
++ sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
++ CF_SHOW_TABLE_COMMAND |
++ CF_REEXECUTION_FRAGILE);
++
++ /*
++ The following is used to preserver CF_ROW_COUNT during the
++ a CALL or EXECUTE statement, so the value generated by the
++ last called (or executed) statement is preserved.
++ See mysql_execute_command() for how CF_ROW_COUNT is used.
++ */
++ sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
++ sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
++
++ /*
++ The following admin table operations are allowed
++ on log tables.
++ */
++ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
++ sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
++ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
++}
++
++
++bool is_update_query(enum enum_sql_command command)
++{
++ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
++ return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
++}
++
++/**
++ Check if a sql command is allowed to write to log tables.
++ @param command The SQL command
++ @return true if writing is allowed
++*/
++bool is_log_table_write_query(enum enum_sql_command command)
++{
++ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
++ return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
++}
++
++void execute_init_command(THD *thd, sys_var_str *init_command_var,
++ rw_lock_t *var_mutex)
++{
++ Vio* save_vio;
++ ulong save_client_capabilities;
++
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.start_new_query();
++ thd->profiling.set_query_source(init_command_var->value,
++ init_command_var->value_length);
++#endif
++
++ thd_proc_info(thd, "Execution of init_command");
++ /*
++ We need to lock init_command_var because
++ during execution of init_command_var query
++ values of init_command_var can't be changed
++ */
++ rw_rdlock(var_mutex);
++ save_client_capabilities= thd->client_capabilities;
++ thd->client_capabilities|= CLIENT_MULTI_QUERIES;
++ /*
++ We don't need return result of execution to client side.
++ To forbid this we should set thd->net.vio to 0.
++ */
++ save_vio= thd->net.vio;
++ thd->net.vio= 0;
++ dispatch_command(COM_QUERY, thd,
++ init_command_var->value,
++ init_command_var->value_length);
++ rw_unlock(var_mutex);
++ thd->client_capabilities= save_client_capabilities;
++ thd->net.vio= save_vio;
++
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.finish_current_query();
++#endif
++}
++
++
++static void handle_bootstrap_impl(THD *thd)
++{
++ FILE *file=bootstrap_file;
++ char *buff;
++ const char* found_semicolon= NULL;
++
++ DBUG_ENTER("handle_bootstrap");
++
++#ifndef EMBEDDED_LIBRARY
++ pthread_detach_this_thread();
++ thd->thread_stack= (char*) &thd;
++#endif /* EMBEDDED_LIBRARY */
++
++ if (thd->variables.max_join_size == HA_POS_ERROR)
++ thd->options |= OPTION_BIG_SELECTS;
++
++ thd_proc_info(thd, 0);
++ thd->version=refresh_version;
++ thd->security_ctx->priv_user=
++ thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
++ thd->security_ctx->priv_host[0]=0;
++ /*
++ Make the "client" handle multiple results. This is necessary
++ to enable stored procedures with SELECTs and Dynamic SQL
++ in init-file.
++ */
++ thd->client_capabilities|= CLIENT_MULTI_RESULTS;
++
++ buff= (char*) thd->net.buff;
++ thd->init_for_queries();
++ while (fgets(buff, thd->net.max_packet, file))
++ {
++ char *query, *res;
++ /* strlen() can't be deleted because fgets() doesn't return length */
++ ulong length= (ulong) strlen(buff);
++ while (buff[length-1] != '\n' && !feof(file))
++ {
++ /*
++ We got only a part of the current string. Will try to increase
++ net buffer then read the rest of the current string.
++ */
++ /* purecov: begin tested */
++ if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
++ {
++ net_end_statement(thd);
++ bootstrap_error= 1;
++ break;
++ }
++ buff= (char*) thd->net.buff;
++ res= fgets(buff + length, thd->net.max_packet - length, file);
++ if (!res && !feof(file))
++ {
++ net_end_statement(thd);
++ bootstrap_error= 1;
++ break;
++ }
++ length+= (ulong) strlen(buff + length);
++ /* purecov: end */
++ }
++ if (bootstrap_error)
++ break; /* purecov: inspected */
++
++ while (length && (my_isspace(thd->charset(), buff[length-1]) ||
++ buff[length-1] == ';'))
++ length--;
++ buff[length]=0;
++
++ /* Skip lines starting with delimiter */
++ if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
++ continue;
++
++ query= (char *) thd->memdup_w_gap(buff, length + 1,
++ thd->db_length + 1 +
++ QUERY_CACHE_FLAGS_SIZE);
++ thd->set_query(query, length);
++ DBUG_PRINT("query",("%-.4096s", thd->query()));
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.start_new_query();
++ thd->profiling.set_query_source(thd->query(), length);
++#endif
++
++ /*
++ We don't need to obtain LOCK_thread_count here because in bootstrap
++ mode we have only one thread.
++ */
++ thd->query_id=next_query_id();
++ thd->set_time();
++ mysql_parse(thd, thd->query(), length, & found_semicolon);
++ close_thread_tables(thd); // Free tables
++
++ bootstrap_error= thd->is_error();
++ net_end_statement(thd);
++
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.finish_current_query();
++#endif
++
++ if (bootstrap_error)
++ break;
++
++ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
++#ifdef USING_TRANSACTIONS
++ free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
++#endif
++ }
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Execute commands from bootstrap_file.
++
++ Used when creating the initial grant tables.
++*/
++
++pthread_handler_t handle_bootstrap(void *arg)
++{
++ THD *thd=(THD*) arg;
++
++ /* The following must be called before DBUG_ENTER */
++ thd->thread_stack= (char*) &thd;
++ if (my_thread_init() || thd->store_globals())
++ {
++#ifndef EMBEDDED_LIBRARY
++ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
++#endif
++ thd->fatal_error();
++ goto end;
++ }
++
++ handle_bootstrap_impl(thd);
++
++end:
++ net_end(&thd->net);
++ thd->cleanup();
++ delete thd;
++
++#ifndef EMBEDDED_LIBRARY
++ (void) pthread_mutex_lock(&LOCK_thread_count);
++ thread_count--;
++ in_bootstrap= FALSE;
++ (void) pthread_cond_broadcast(&COND_thread_count);
++ (void) pthread_mutex_unlock(&LOCK_thread_count);
++ my_thread_end();
++ pthread_exit(0);
++#endif
++
++ return 0;
++}
++
++
++/**
++ @brief Check access privs for a MERGE table and fix children lock types.
++
++ @param[in] thd thread handle
++ @param[in] db database name
++ @param[in,out] table_list list of child tables (merge_list)
++ lock_type and optionally db set per table
++
++ @return status
++ @retval 0 OK
++ @retval != 0 Error
++
++ @detail
++ This function is used for write access to MERGE tables only
++ (CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
++ every child. Set 'db' for every child if not present.
++*/
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++static bool check_merge_table_access(THD *thd, char *db,
++ TABLE_LIST *table_list)
++{
++ int error= 0;
++
++ if (table_list)
++ {
++ /* Check that all tables use the current database */
++ TABLE_LIST *tlist;
++
++ for (tlist= table_list; tlist; tlist= tlist->next_local)
++ {
++ if (!tlist->db || !tlist->db[0])
++ tlist->db= db; /* purecov: inspected */
++ }
++ error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
++ table_list, UINT_MAX, FALSE);
++ }
++ return error;
++}
++#endif
++
++/* This works because items are allocated with sql_alloc() */
++
++void free_items(Item *item)
++{
++ Item *next;
++ DBUG_ENTER("free_items");
++ for (; item ; item=next)
++ {
++ next=item->next;
++ item->delete_self();
++ }
++ DBUG_VOID_RETURN;
++}
++
++/**
++ This works because items are allocated with sql_alloc().
++ @note The function also handles null pointers (empty list).
++*/
++void cleanup_items(Item *item)
++{
++ DBUG_ENTER("cleanup_items");
++ for (; item ; item=item->next)
++ item->cleanup();
++ DBUG_VOID_RETURN;
++}
++
++/**
++ Handle COM_TABLE_DUMP command.
++
++ @param thd thread handle
++ @param db database name or an empty string. If empty,
++ the current database of the connection is used
++ @param tbl_name name of the table to dump
++
++ @note
++ This function is written to handle one specific command only.
++
++ @retval
++ 0 success
++ @retval
++ 1 error, the error message is set in THD
++*/
++
++static
++int mysql_table_dump(THD *thd, LEX_STRING *db, LEX_STRING *table_name)
++{
++ TABLE* table;
++ TABLE_LIST* table_list;
++ int error = 0;
++ DBUG_ENTER("mysql_table_dump");
++ if (db->length == 0)
++ {
++ db->str= thd->db; /* purecov: inspected */
++ db->length= thd->db_length; /* purecov: inspected */
++ }
++ if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
++ DBUG_RETURN(1); // out of memory
++ table_list->db= db->str;
++ table_list->table_name= table_list->alias= table_name->str;
++ table_list->lock_type= TL_READ_NO_INSERT;
++ table_list->prev_global= &table_list; // can be removed after merge with 4.1
++
++ if (check_db_name(db))
++ {
++ /* purecov: begin inspected */
++ my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
++ goto err;
++ /* purecov: end */
++ }
++ if (!table_name->length ||
++ check_table_name(table_name->str, table_name->length, TRUE))
++ {
++ my_error(ER_WRONG_TABLE_NAME, MYF(0),
++ table_name->str ? table_name->str : "NULL");
++ error= 1;
++ goto err;
++ }
++ if (lower_case_table_names)
++ my_casedn_str(files_charset_info, table_name->str);
++
++ if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT, 0)))
++ DBUG_RETURN(1);
++
++ if (check_one_table_access(thd, SELECT_ACL, table_list))
++ goto err;
++ thd->free_list = 0;
++ thd->set_query(table_name->str, table_name->length);
++ if ((error = mysqld_dump_create_info(thd, table_list, -1)))
++ {
++ my_error(ER_GET_ERRNO, MYF(0), my_errno);
++ goto err;
++ }
++ net_flush(&thd->net);
++ if ((error= table->file->dump(thd,-1)))
++ my_error(ER_GET_ERRNO, MYF(0), error);
++
++err:
++ DBUG_RETURN(error);
++}
++
++/**
++ Ends the current transaction and (maybe) begin the next.
++
++ @param thd Current thread
++ @param completion Completion type
++
++ @retval
++ 0 OK
++*/
++
++int end_trans(THD *thd, enum enum_mysql_completiontype completion)
++{
++ bool do_release= 0;
++ int res= 0;
++ DBUG_ENTER("end_trans");
++
++ if (unlikely(thd->in_sub_stmt))
++ {
++ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
++ DBUG_RETURN(1);
++ }
++ if (thd->transaction.xid_state.xa_state != XA_NOTR)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ DBUG_RETURN(1);
++ }
++ switch (completion) {
++ case COMMIT:
++ /*
++ We don't use end_active_trans() here to ensure that this works
++ even if there is a problem with the OPTION_AUTO_COMMIT flag
++ (Which of course should never happen...)
++ */
++ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
++ res= ha_commit(thd);
++ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ break;
++ case COMMIT_RELEASE:
++ do_release= 1; /* fall through */
++ case COMMIT_AND_CHAIN:
++ res= end_active_trans(thd);
++ if (!res && completion == COMMIT_AND_CHAIN)
++ res= begin_trans(thd);
++ break;
++ case ROLLBACK_RELEASE:
++ do_release= 1; /* fall through */
++ case ROLLBACK:
++ case ROLLBACK_AND_CHAIN:
++ {
++ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
++ if (ha_rollback(thd))
++ res= -1;
++ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ if (!res && (completion == ROLLBACK_AND_CHAIN))
++ res= begin_trans(thd);
++ break;
++ }
++ default:
++ res= -1;
++ my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
++ DBUG_RETURN(-1);
++ }
++
++ if (res < 0)
++ my_error(thd->killed_errno(), MYF(0));
++ else if ((res == 0) && do_release)
++ thd->killed= THD::KILL_CONNECTION;
++
++ DBUG_RETURN(res);
++}
++
++#ifndef EMBEDDED_LIBRARY
++
++/**
++ Read one command from connection and execute it (query or simple command).
++ This function is called in loop from thread function.
++
++ For profiling to work, it must never be called recursively.
++
++ @retval
++ 0 success
++ @retval
++ 1 request of thread shutdown (see dispatch_command() description)
++*/
++
++bool do_command(THD *thd)
++{
++ bool return_value;
++ char *packet= 0;
++ ulong packet_length;
++ NET *net= &thd->net;
++ enum enum_server_command command;
++ DBUG_ENTER("do_command");
++
++ /*
++ indicator of uninitialized lex => normal flow of errors handling
++ (see my_message_sql)
++ */
++ thd->lex->current_select= 0;
++
++ /*
++ This thread will do a blocking read from the client which
++ will be interrupted when the next command is received from
++ the client, the connection is closed or "net_wait_timeout"
++ number of seconds has passed
++ */
++ my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
++
++ /*
++ XXX: this code is here only to clear possible errors of init_connect.
++ Consider moving to init_connect() instead.
++ */
++ thd->clear_error(); // Clear error message
++ thd->main_da.reset_diagnostics_area();
++
++ net_new_transaction(net);
++
++ packet_length= my_net_read(net);
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.start_new_query();
++#endif
++ if (packet_length == packet_error)
++ {
++ DBUG_PRINT("info",("Got error %d reading command from socket %s",
++ net->error,
++ vio_description(net->vio)));
++
++ /* Check if we can continue without closing the connection */
++
++ /* The error must be set. */
++ DBUG_ASSERT(thd->is_error());
++ net_end_statement(thd);
++
++ if (net->error != 3)
++ {
++ return_value= TRUE; // We have to close it.
++ goto out;
++ }
++
++ net->error= 0;
++ return_value= FALSE;
++ goto out;
++ }
++
++ packet= (char*) net->read_pos;
++ /*
++ 'packet_length' contains length of data, as it was stored in packet
++ header. In case of malformed header, my_net_read returns zero.
++ If packet_length is not zero, my_net_read ensures that the returned
++ number of bytes was actually read from network.
++ There is also an extra safety measure in my_net_read:
++ it sets packet[packet_length]= 0, but only for non-zero packets.
++ */
++ if (packet_length == 0) /* safety */
++ {
++ /* Initialize with COM_SLEEP packet */
++ packet[0]= (uchar) COM_SLEEP;
++ packet_length= 1;
++ }
++ /* Do not rely on my_net_read, extra safety against programming errors. */
++ packet[packet_length]= '\0'; /* safety */
++
++ command= (enum enum_server_command) (uchar) packet[0];
++
++ if (command >= COM_END)
++ command= COM_END; // Wrong command
++
++ DBUG_PRINT("info",("Command on %s = %d (%s)",
++ vio_description(net->vio), command,
++ command_name[command].str));
++
++ /* Restore read timeout value */
++ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
++
++ DBUG_ASSERT(packet_length);
++ return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
++
++out:
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.finish_current_query();
++#endif
++ DBUG_RETURN(return_value);
++}
++#endif /* EMBEDDED_LIBRARY */
++
++/**
++ @brief Determine if an attempt to update a non-temporary table while the
++ read-only option was enabled has been made.
++
++ This is a helper function to mysql_execute_command.
++
++ @note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
++
++ @see mysql_execute_command
++ @returns Status code
++ @retval TRUE The statement should be denied.
++ @retval FALSE The statement isn't updating any relevant tables.
++*/
++
++static my_bool deny_updates_if_read_only_option(THD *thd,
++ TABLE_LIST *all_tables)
++{
++ DBUG_ENTER("deny_updates_if_read_only_option");
++
++ if (!opt_readonly)
++ DBUG_RETURN(FALSE);
++
++ LEX *lex= thd->lex;
++
++ const my_bool user_is_super=
++ ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
++ (ulong)SUPER_ACL);
++
++ if (user_is_super)
++ DBUG_RETURN(FALSE);
++
++ if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
++ DBUG_RETURN(FALSE);
++
++ /* Multi update is an exception and is dealt with later. */
++ if (lex->sql_command == SQLCOM_UPDATE_MULTI)
++ DBUG_RETURN(FALSE);
++
++ const my_bool create_temp_tables=
++ (lex->sql_command == SQLCOM_CREATE_TABLE) &&
++ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
++
++ const my_bool drop_temp_tables=
++ (lex->sql_command == SQLCOM_DROP_TABLE) &&
++ lex->drop_temporary;
++
++ const my_bool update_real_tables=
++ some_non_temp_table_to_be_updated(thd, all_tables) &&
++ !(create_temp_tables || drop_temp_tables);
++
++
++ const my_bool create_or_drop_databases=
++ (lex->sql_command == SQLCOM_CREATE_DB) ||
++ (lex->sql_command == SQLCOM_DROP_DB);
++
++ if (update_real_tables || create_or_drop_databases)
++ {
++ /*
++ An attempt was made to modify one or more non-temporary tables.
++ */
++ DBUG_RETURN(TRUE);
++ }
++
++
++ /* Assuming that only temporary tables are modified. */
++ DBUG_RETURN(FALSE);
++}
++
++/**
++ Perform one connection-level (COM_XXXX) command.
++
++ @param command type of command to perform
++ @param thd connection handle
++ @param packet data for the command, packet is always null-terminated
++ @param packet_length length of packet + 1 (to show that data is
++ null-terminated) except for COM_SLEEP, where it
++ can be zero.
++
++ @todo
++ set thd->lex->sql_command to SQLCOM_END here.
++ @todo
++ The following has to be changed to an 8 byte integer
++
++ @retval
++ 0 ok
++ @retval
++ 1 request of thread shutdown, i. e. if command is
++ COM_QUIT/COM_SHUTDOWN
++*/
++bool dispatch_command(enum enum_server_command command, THD *thd,
++ char* packet, uint packet_length)
++{
++ NET *net= &thd->net;
++ bool error= 0;
++ DBUG_ENTER("dispatch_command");
++ DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
++
++ thd->command=command;
++ /*
++ Commands which always take a long time are logged into
++ the slow log only if opt_log_slow_admin_statements is set.
++ */
++ thd->enable_slow_log= TRUE;
++ thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
++ thd->set_time();
++ if (!thd->is_valid_time())
++ {
++ /*
++ If the time has got past 2038 we need to shut this server down
++ We do this by making sure every command is a shutdown and we
++ have enough privileges to shut the server down
++
++ TODO: remove this when we have full 64 bit my_time_t support
++ */
++ thd->security_ctx->master_access|= SHUTDOWN_ACL;
++ command= COM_SHUTDOWN;
++ }
++
++ VOID(pthread_mutex_lock(&LOCK_thread_count));
++ thd->query_id= global_query_id;
++
++ switch( command ) {
++ /* Ignore these statements. */
++ case COM_STATISTICS:
++ case COM_PING:
++ break;
++ /* Only increase id on these statements but don't count them. */
++ case COM_STMT_PREPARE:
++ case COM_STMT_CLOSE:
++ case COM_STMT_RESET:
++ next_query_id();
++ break;
++ /* Increase id and count all other statements. */
++ default:
++ statistic_increment(thd->status_var.questions, &LOCK_status);
++ next_query_id();
++ }
++
++ thread_running++;
++ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++
++ /**
++ Clear the set of flags that are expected to be cleared at the
++ beginning of each command.
++ */
++ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
++ switch (command) {
++ case COM_INIT_DB:
++ {
++ LEX_STRING tmp;
++ status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
++ thd->convert_string(&tmp, system_charset_info,
++ packet, packet_length, thd->charset());
++ if (!mysql_change_db(thd, &tmp, FALSE))
++ {
++ general_log_write(thd, command, thd->db, thd->db_length);
++ my_ok(thd);
++ }
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ case COM_REGISTER_SLAVE:
++ {
++ if (!register_slave(thd, (uchar*)packet, packet_length))
++ my_ok(thd);
++ break;
++ }
++#endif
++ case COM_TABLE_DUMP:
++ {
++ LEX_STRING db, table;
++ /* Safe because there is always a trailing \0 at the end of the packet */
++ uint db_len= *(uchar*) packet;
++ if (db_len + 1 > packet_length || db_len > NAME_LEN)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++ /* Safe because there is always a trailing \0 at the end of the packet */
++ uint tbl_len= *(uchar*) (packet + db_len + 1);
++ if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++
++ status_var_increment(thd->status_var.com_other);
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ db.str= (char*) thd->alloc(db_len + tbl_len + 2);
++ if (!db.str)
++ {
++ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
++ break;
++ }
++ db.length= db_len;
++ table.length= tbl_len;
++ table.str= strmake(db.str, packet + 1, db_len) + 1;
++ strmake(table.str, packet + db_len + 2, tbl_len);
++ if (mysql_table_dump(thd, &db, &table) == 0)
++ thd->main_da.disable_status();
++ break;
++ }
++ case COM_CHANGE_USER:
++ {
++ status_var_increment(thd->status_var.com_other);
++ char *user= (char*) packet, *packet_end= packet + packet_length;
++ /* Safe because there is always a trailing \0 at the end of the packet */
++ char *passwd= strend(user)+1;
++
++ thd->change_user();
++ thd->clear_error(); // if errors from rollback
++
++ /*
++ Old clients send null-terminated string ('\0' for empty string) for
++ password. New clients send the size (1 byte) + string (not null
++ terminated, so also '\0' for empty string).
++
++ Cast *passwd to an unsigned char, so that it doesn't extend the sign
++ for *passwd > 127 and become 2**32-127 after casting to uint.
++ */
++ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
++ char *db= passwd;
++ char *save_db;
++ /*
++ If there is no password supplied, the packet must contain '\0',
++ in any type of handshake (4.1 or pre-4.1).
++ */
++ if (passwd >= packet_end)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
++ (uchar)(*passwd++) : strlen(passwd));
++ uint dummy_errors, save_db_length, db_length;
++ int res;
++ Security_context save_security_ctx= *thd->security_ctx;
++ USER_CONN *save_user_connect;
++
++ db+= passwd_len + 1;
++ /*
++ Database name is always NUL-terminated, so in case of empty database
++ the packet must contain at least the trailing '\0'.
++ */
++ if (db >= packet_end)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++ db_length= strlen(db);
++
++ char *ptr= db + db_length + 1;
++ uint cs_number= 0;
++
++ if (ptr < packet_end)
++ {
++ CHARSET_INFO *cs;
++ if (ptr + 2 > packet_end)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++
++ if ((cs_number= uint2korr(ptr)) &&
++ (cs= get_charset(cs_number, MYF(0))) &&
++ !is_supported_parser_charset(cs))
++ {
++ /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
++ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
++ cs->csname);
++ break;
++ }
++ }
++
++ /* Convert database name to utf8 */
++ db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
++ system_charset_info, db, db_length,
++ thd->charset(), &dummy_errors)]= 0;
++ db= db_buff;
++
++ /* Save user and privileges */
++ save_db_length= thd->db_length;
++ save_db= thd->db;
++ save_user_connect= thd->user_connect;
++
++ if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
++ {
++ thd->security_ctx->user= save_security_ctx.user;
++ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
++ break;
++ }
++
++ /* Clear variables that are allocated */
++ thd->user_connect= 0;
++ thd->security_ctx->priv_user= thd->security_ctx->user;
++ res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
++
++ if (res)
++ {
++ x_free(thd->security_ctx->user);
++ *thd->security_ctx= save_security_ctx;
++ thd->user_connect= save_user_connect;
++ thd->db= save_db;
++ thd->db_length= save_db_length;
++ }
++ else
++ {
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ /* we've authenticated new user */
++ if (save_user_connect)
++ decrease_user_connections(save_user_connect);
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++ x_free(save_db);
++ x_free(save_security_ctx.user);
++
++ if (cs_number)
++ {
++ /*
++ We have checked charset earlier,
++ so thd_init_client_charset cannot fail.
++ */
++ if (thd_init_client_charset(thd, cs_number))
++ DBUG_ASSERT(0);
++ thd->update_charset();
++ }
++ }
++ break;
++ }
++ case COM_STMT_EXECUTE:
++ {
++ mysqld_stmt_execute(thd, packet, packet_length);
++ break;
++ }
++ case COM_STMT_FETCH:
++ {
++ mysqld_stmt_fetch(thd, packet, packet_length);
++ break;
++ }
++ case COM_STMT_SEND_LONG_DATA:
++ {
++ mysql_stmt_get_longdata(thd, packet, packet_length);
++ break;
++ }
++ case COM_STMT_PREPARE:
++ {
++ mysqld_stmt_prepare(thd, packet, packet_length);
++ break;
++ }
++ case COM_STMT_CLOSE:
++ {
++ mysqld_stmt_close(thd, packet);
++ break;
++ }
++ case COM_STMT_RESET:
++ {
++ mysqld_stmt_reset(thd, packet);
++ break;
++ }
++ case COM_QUERY:
++ {
++ if (alloc_query(thd, packet, packet_length))
++ break; // fatal error is set
++ char *packet_end= thd->query() + thd->query_length();
++ /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
++ const char* end_of_stmt= NULL;
++
++ general_log_write(thd, command, thd->query(), thd->query_length());
++ DBUG_PRINT("query",("%-.4096s",thd->query()));
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.set_query_source(thd->query(), thd->query_length());
++#endif
++
++ if (!(specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_setprio(pthread_self(),QUERY_PRIOR);
++
++ mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
++
++ while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
++ {
++ char *beginning_of_next_stmt= (char*) end_of_stmt;
++
++ net_end_statement(thd);
++ query_cache_end_of_result(thd);
++ /*
++ Multiple queries exits, execute them individually
++ */
++ close_thread_tables(thd);
++ ulong length= (ulong)(packet_end - beginning_of_next_stmt);
++
++ log_slow_statement(thd);
++
++ /* Remove garbage at start of query */
++ while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
++ {
++ beginning_of_next_stmt++;
++ length--;
++ }
++
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.finish_current_query();
++ thd->profiling.start_new_query("continuing");
++ thd->profiling.set_query_source(beginning_of_next_stmt, length);
++#endif
++
++ thd->set_query(beginning_of_next_stmt, length);
++ VOID(pthread_mutex_lock(&LOCK_thread_count));
++ /*
++ Count each statement from the client.
++ */
++ statistic_increment(thd->status_var.questions, &LOCK_status);
++ thd->query_id= next_query_id();
++ thd->set_time(); /* Reset the query start time. */
++ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
++ }
++
++ if (!(specialflag & SPECIAL_NO_PRIOR))
++ my_pthread_setprio(pthread_self(),WAIT_PRIOR);
++ DBUG_PRINT("info",("query ready"));
++ break;
++ }
++ case COM_FIELD_LIST: // This isn't actually needed
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
++ MYF(0)); /* purecov: inspected */
++ break;
++#else
++ {
++ char *fields, *packet_end= packet + packet_length, *arg_end;
++ /* Locked closure of all tables */
++ TABLE_LIST table_list;
++ LEX_STRING conv_name;
++
++ /* used as fields initializator */
++ lex_start(thd);
++
++ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
++ bzero((char*) &table_list,sizeof(table_list));
++ if (thd->copy_db_to(&table_list.db, &table_list.db_length))
++ break;
++ /*
++ We have name + wildcard in packet, separated by endzero
++ */
++ arg_end= strend(packet);
++ uint arg_length= arg_end - packet;
++
++ /* Check given table name length. */
++ if (arg_length >= packet_length || arg_length > NAME_LEN)
++ {
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++ thd->convert_string(&conv_name, system_charset_info,
++ packet, arg_length, thd->charset());
++ if (check_table_name(conv_name.str, conv_name.length, FALSE))
++ {
++ /* this is OK due to convert_string() null-terminating the string */
++ my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
++ break;
++ }
++
++ table_list.alias= table_list.table_name= conv_name.str;
++ packet= arg_end + 1;
++
++ if (is_schema_db(table_list.db, table_list.db_length))
++ {
++ ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
++ if (schema_table)
++ table_list.schema_table= schema_table;
++ }
++
++ uint query_length= (uint) (packet_end - packet); // Don't count end \0
++ if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
++ break;
++ thd->set_query(fields, query_length);
++ general_log_print(thd, command, "%s %s", table_list.table_name, fields);
++ if (lower_case_table_names)
++ my_casedn_str(files_charset_info, table_list.table_name);
++
++ if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
++ 0, 0, test(table_list.schema_table)))
++ break;
++ if (check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
++ break;
++ /* init structures for VIEW processing */
++ table_list.select_lex= &(thd->lex->select_lex);
++
++ lex_start(thd);
++ mysql_reset_thd_for_next_command(thd);
++
++ thd->lex->
++ select_lex.table_list.link_in_list(&table_list,
++ &table_list.next_local);
++ thd->lex->add_to_query_tables(&table_list);
++
++ /* switch on VIEW optimisation: do not fill temporary tables */
++ thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
++ mysqld_list_fields(thd,&table_list,fields);
++ thd->lex->unit.cleanup();
++ thd->cleanup_after_query();
++ break;
++ }
++#endif
++ case COM_QUIT:
++ /* We don't calculate statistics for this command */
++ general_log_print(thd, command, NullS);
++ net->error=0; // Don't give 'abort' message
++ thd->main_da.disable_status(); // Don't send anything back
++ error=TRUE; // End server
++ break;
++
++#ifdef REMOVED
++ case COM_CREATE_DB: // QQ: To be removed
++ {
++ LEX_STRING db, alias;
++ HA_CREATE_INFO create_info;
++
++ status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
++ if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
++ thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
++ check_db_name(&db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
++ break;
++ }
++ if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
++ is_schema_db(db.str, db.length)))
++ break;
++ general_log_print(thd, command, "%.*s", db.length, db.str);
++ bzero(&create_info, sizeof(create_info));
++ mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
++ &create_info, 0);
++ break;
++ }
++ case COM_DROP_DB: // QQ: To be removed
++ {
++ status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
++ LEX_STRING db;
++
++ if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
++ check_db_name(&db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
++ break;
++ }
++ if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
++ is_schema_db(db.str, db.length)))
++ break;
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ break;
++ }
++ general_log_write(thd, command, "%.*s", db.length, db.str);
++ mysql_rm_db(thd, db.str, 0, 0);
++ break;
++ }
++#endif
++#ifndef EMBEDDED_LIBRARY
++ case COM_BINLOG_DUMP:
++ {
++ ulong pos;
++ ushort flags;
++ uint32 slave_server_id;
++
++ status_var_increment(thd->status_var.com_other);
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ if (check_global_access(thd, REPL_SLAVE_ACL))
++ break;
++
++ /* TODO: The following has to be changed to an 8 byte integer */
++ pos = uint4korr(packet);
++ flags = uint2korr(packet + 4);
++ thd->server_id=0; /* avoid suicide */
++ if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
++ kill_zombie_dump_threads(slave_server_id);
++ thd->server_id = slave_server_id;
++
++ general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
++ (long) pos);
++ mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
++ unregister_slave(thd,1,1);
++ /* fake COM_QUIT -- if we get here, the thread needs to terminate */
++ error = TRUE;
++ break;
++ }
++#endif
++ case COM_REFRESH:
++ {
++ int not_used;
++ status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
++ ulong options= (ulong) (uchar) packet[0];
++ if (check_global_access(thd,RELOAD_ACL))
++ break;
++ general_log_print(thd, command, NullS);
++#ifndef DBUG_OFF
++ bool debug_simulate= FALSE;
++ DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
++ if (debug_simulate)
++ {
++ /*
++ Simulate a reload without a attached thread session.
++ Provides a environment similar to that of when the
++ server receives a SIGHUP signal and reloads caches
++ and flushes tables.
++ */
++ bool res;
++ my_pthread_setspecific_ptr(THR_THD, NULL);
++ res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
++ NULL, ¬_used);
++ my_pthread_setspecific_ptr(THR_THD, thd);
++ if (!res)
++ my_ok(thd);
++ break;
++ }
++#endif
++ if (!reload_acl_and_cache(thd, options, NULL, ¬_used))
++ my_ok(thd);
++ break;
++ }
++#ifndef EMBEDDED_LIBRARY
++ case COM_SHUTDOWN:
++ {
++ status_var_increment(thd->status_var.com_other);
++ if (check_global_access(thd,SHUTDOWN_ACL))
++ break; /* purecov: inspected */
++ /*
++ If the client is < 4.1.3, it is going to send us no argument; then
++ packet_length is 0, packet[0] is the end 0 of the packet. Note that
++ SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
++ packet[0].
++ */
++ enum mysql_enum_shutdown_level level;
++ if (!thd->is_valid_time())
++ level= SHUTDOWN_DEFAULT;
++ else
++ level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
++ if (level == SHUTDOWN_DEFAULT)
++ level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
++ else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
++ {
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
++ break;
++ }
++ DBUG_PRINT("quit",("Got shutdown command for level %u", level));
++ general_log_print(thd, command, NullS);
++ my_eof(thd);
++ close_thread_tables(thd); // Free before kill
++ kill_mysql();
++ error=TRUE;
++ break;
++ }
++#endif
++ case COM_STATISTICS:
++ {
++ STATUS_VAR current_global_status_var;
++ ulong uptime;
++ uint length __attribute__((unused));
++ ulonglong queries_per_second1000;
++ char buff[250];
++ uint buff_len= sizeof(buff);
++
++ general_log_print(thd, command, NullS);
++ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
++ calc_sum_of_all_status(¤t_global_status_var);
++ if (!(uptime= (ulong) (thd->start_time - server_start_time)))
++ queries_per_second1000= 0;
++ else
++ queries_per_second1000= thd->query_id * LL(1000) / uptime;
++
++ length= my_snprintf(buff, buff_len - 1,
++ "Uptime: %lu Threads: %d Questions: %lu "
++ "Slow queries: %lu Opens: %lu Flush tables: %lu "
++ "Open tables: %u Queries per second avg: %u.%u",
++ uptime,
++ (int) thread_count, (ulong) thd->query_id,
++ current_global_status_var.long_query_count,
++ current_global_status_var.opened_tables,
++ refresh_version,
++ cached_open_tables(),
++ (uint) (queries_per_second1000 / 1000),
++ (uint) (queries_per_second1000 % 1000));
++#ifdef SAFEMALLOC
++ if (sf_malloc_cur_memory) // Using SAFEMALLOC
++ {
++ char *end= buff + length;
++ length+= my_snprintf(end, buff_len - length - 1,
++ end," Memory in use: %ldK Max memory used: %ldK",
++ (sf_malloc_cur_memory+1023L)/1024L,
++ (sf_malloc_max_memory+1023L)/1024L);
++ }
++#endif
++#ifndef EMBEDDED_LIBRARY
++ VOID(my_net_write(net, (uchar*) buff, length));
++ VOID(net_flush(net));
++ thd->main_da.disable_status();
++#else
++ /* Store the buffer in permanent memory */
++ my_ok(thd, 0, 0, buff);
++#endif
++ break;
++ }
++ case COM_PING:
++ status_var_increment(thd->status_var.com_other);
++ my_ok(thd); // Tell client we are alive
++ break;
++ case COM_PROCESS_INFO:
++ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
++ if (!thd->security_ctx->priv_user[0] &&
++ check_global_access(thd, PROCESS_ACL))
++ break;
++ general_log_print(thd, command, NullS);
++ mysqld_list_processes(thd,
++ thd->security_ctx->master_access & PROCESS_ACL ?
++ NullS : thd->security_ctx->priv_user, 0);
++ break;
++ case COM_PROCESS_KILL:
++ {
++ status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
++ ulong id=(ulong) uint4korr(packet);
++ sql_kill(thd,id,false);
++ break;
++ }
++ case COM_SET_OPTION:
++ {
++ status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
++ uint opt_command= uint2korr(packet);
++
++ switch (opt_command) {
++ case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
++ thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
++ my_eof(thd);
++ break;
++ case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
++ thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
++ my_eof(thd);
++ break;
++ default:
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++ break;
++ }
++ case COM_DEBUG:
++ status_var_increment(thd->status_var.com_other);
++ if (check_global_access(thd, SUPER_ACL))
++ break; /* purecov: inspected */
++ mysql_print_status();
++ general_log_print(thd, command, NullS);
++ my_eof(thd);
++ break;
++ case COM_SLEEP:
++ case COM_CONNECT: // Impossible here
++ case COM_TIME: // Impossible from client
++ case COM_DELAYED_INSERT:
++ case COM_END:
++ default:
++ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
++ break;
++ }
++
++ /* report error issued during command execution */
++ if (thd->killed_errno())
++ {
++ if (! thd->main_da.is_set())
++ thd->send_kill_message();
++ }
++ if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
++ {
++ thd->killed= THD::NOT_KILLED;
++ thd->mysys_var->abort= 0;
++ }
++
++ /* If commit fails, we should be able to reset the OK status. */
++ thd->main_da.can_overwrite_status= TRUE;
++ ha_autocommit_or_rollback(thd, thd->is_error());
++ thd->main_da.can_overwrite_status= FALSE;
++
++ thd->transaction.stmt.reset();
++
++ net_end_statement(thd);
++ query_cache_end_of_result(thd);
++
++ thd->proc_info= "closing tables";
++ /* Free tables */
++ close_thread_tables(thd);
++
++ log_slow_statement(thd);
++
++ thd_proc_info(thd, "cleaning up");
++ thd->set_query(NULL, 0);
++ thd->command=COM_SLEEP;
++ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
++ thread_running--;
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ thd_proc_info(thd, 0);
++ thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
++ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
++ DBUG_RETURN(error);
++}
++
++
++void log_slow_statement(THD *thd)
++{
++ DBUG_ENTER("log_slow_statement");
++
++ /*
++ The following should never be true with our current code base,
++ but better to keep this here so we don't accidently try to log a
++ statement in a trigger or stored function
++ */
++ if (unlikely(thd->in_sub_stmt))
++ DBUG_VOID_RETURN; // Don't set time for sub stmt
++
++ /*
++ Do not log administrative statements unless the appropriate option is
++ set.
++ */
++ if (thd->enable_slow_log)
++ {
++ ulonglong end_utime_of_query= thd->current_utime();
++ thd_proc_info(thd, "logging slow query");
++
++ if (((end_utime_of_query - thd->utime_after_lock) >
++ thd->variables.long_query_time ||
++ ((thd->server_status &
++ (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
++ opt_log_queries_not_using_indexes &&
++ !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
++ thd->examined_row_count >= thd->variables.min_examined_row_limit)
++ {
++ thd_proc_info(thd, "logging slow query");
++ thd->status_var.long_query_count++;
++ slow_log_print(thd, thd->query(), thd->query_length(),
++ end_utime_of_query);
++ }
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
++
++ This function is used in the parser to convert a SHOW or DESCRIBE
++ table_name command to a SELECT from INFORMATION_SCHEMA.
++ It prepares a SELECT_LEX and a TABLE_LIST object to represent the
++ given command as a SELECT parse tree.
++
++ @param thd thread handle
++ @param lex current lex
++ @param table_ident table alias if it's used
++ @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
++ created
++
++ @note
++ Due to the way this function works with memory and LEX it cannot
++ be used outside the parser (parse tree transformations outside
++ the parser break PS and SP).
++
++ @retval
++ 0 success
++ @retval
++ 1 out of memory or SHOW commands are not allowed
++ in this version of the server.
++*/
++
++int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
++ enum enum_schema_tables schema_table_idx)
++{
++ SELECT_LEX *schema_select_lex= NULL;
++ DBUG_ENTER("prepare_schema_table");
++
++ switch (schema_table_idx) {
++ case SCH_SCHEMATA:
++#if defined(DONT_ALLOW_SHOW_COMMANDS)
++ my_message(ER_NOT_ALLOWED_COMMAND,
++ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(1);
++#else
++ break;
++#endif
++
++ case SCH_TABLE_NAMES:
++ case SCH_TABLES:
++ case SCH_VIEWS:
++ case SCH_TRIGGERS:
++ case SCH_EVENTS:
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND,
++ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(1);
++#else
++ {
++ LEX_STRING db;
++ size_t dummy;
++ if (lex->select_lex.db == NULL &&
++ lex->copy_db_to(&lex->select_lex.db, &dummy))
++ {
++ DBUG_RETURN(1);
++ }
++ schema_select_lex= new SELECT_LEX();
++ db.str= schema_select_lex->db= lex->select_lex.db;
++ schema_select_lex->table_list.first= NULL;
++ db.length= strlen(db.str);
++
++ if (check_db_name(&db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
++ DBUG_RETURN(1);
++ }
++ break;
++ }
++#endif
++ case SCH_COLUMNS:
++ case SCH_STATISTICS:
++ {
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND,
++ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(1);
++#else
++ DBUG_ASSERT(table_ident);
++ TABLE_LIST **query_tables_last= lex->query_tables_last;
++ schema_select_lex= new SELECT_LEX();
++ /* 'parent_lex' is used in init_query() so it must be before it. */
++ schema_select_lex->parent_lex= lex;
++ schema_select_lex->init_query();
++ if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
++ DBUG_RETURN(1);
++ lex->query_tables_last= query_tables_last;
++ break;
++ }
++#endif
++ case SCH_PROFILES:
++ /*
++ Mark this current profiling record to be discarded. We don't
++ wish to have SHOW commands show up in profiling.
++ */
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.discard_current_query();
++#endif
++ break;
++ case SCH_OPEN_TABLES:
++ case SCH_VARIABLES:
++ case SCH_STATUS:
++ case SCH_PROCEDURES:
++ case SCH_CHARSETS:
++ case SCH_ENGINES:
++ case SCH_COLLATIONS:
++ case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
++ case SCH_USER_PRIVILEGES:
++ case SCH_SCHEMA_PRIVILEGES:
++ case SCH_TABLE_PRIVILEGES:
++ case SCH_COLUMN_PRIVILEGES:
++ case SCH_TABLE_CONSTRAINTS:
++ case SCH_KEY_COLUMN_USAGE:
++ default:
++ break;
++ }
++
++ SELECT_LEX *select_lex= lex->current_select;
++ if (make_schema_select(thd, select_lex, schema_table_idx))
++ {
++ DBUG_RETURN(1);
++ }
++ TABLE_LIST *table_list= select_lex->table_list.first;
++ table_list->schema_select_lex= schema_select_lex;
++ table_list->schema_table_reformed= 1;
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Read query from packet and store in thd->query.
++ Used in COM_QUERY and COM_STMT_PREPARE.
++
++ Sets the following THD variables:
++ - query
++ - query_length
++
++ @retval
++ FALSE ok
++ @retval
++ TRUE error; In this case thd->fatal_error is set
++*/
++
++bool alloc_query(THD *thd, const char *packet, uint packet_length)
++{
++ char *query;
++ /* Remove garbage at start and end of query */
++ while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
++ {
++ packet++;
++ packet_length--;
++ }
++ const char *pos= packet + packet_length; // Point at end null
++ while (packet_length > 0 &&
++ (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
++ {
++ pos--;
++ packet_length--;
++ }
++ /* We must allocate some extra memory for query cache */
++ if (! (query= (char*) thd->memdup_w_gap(packet,
++ packet_length,
++ 1 + thd->db_length +
++ QUERY_CACHE_FLAGS_SIZE)))
++ return TRUE;
++ query[packet_length]= '\0';
++ thd->set_query(query, packet_length);
++
++ /* Reclaim some memory */
++ thd->packet.shrink(thd->variables.net_buffer_length);
++ thd->convert_buffer.shrink(thd->variables.net_buffer_length);
++
++ return FALSE;
++}
++
++static void reset_one_shot_variables(THD *thd)
++{
++ thd->variables.character_set_client=
++ global_system_variables.character_set_client;
++ thd->variables.collation_connection=
++ global_system_variables.collation_connection;
++ thd->variables.collation_database=
++ global_system_variables.collation_database;
++ thd->variables.collation_server=
++ global_system_variables.collation_server;
++ thd->update_charset();
++ thd->variables.time_zone=
++ global_system_variables.time_zone;
++ thd->variables.lc_time_names= &my_locale_en_US;
++ thd->one_shot_set= 0;
++}
++
++
++static
++bool sp_process_definer(THD *thd)
++{
++ DBUG_ENTER("sp_process_definer");
++
++ LEX *lex= thd->lex;
++
++ /*
++ If the definer is not specified, this means that CREATE-statement missed
++ DEFINER-clause. DEFINER-clause can be missed in two cases:
++
++ - The user submitted a statement w/o the clause. This is a normal
++ case, we should assign CURRENT_USER as definer.
++
++ - Our slave received an updated from the master, that does not
++ replicate definer for stored rountines. We should also assign
++ CURRENT_USER as definer here, but also we should mark this routine
++ as NON-SUID. This is essential for the sake of backward
++ compatibility.
++
++ The problem is the slave thread is running under "special" user (@),
++ that actually does not exist. In the older versions we do not fail
++ execution of a stored routine if its definer does not exist and
++ continue the execution under the authorization of the invoker
++ (BUG#13198). And now if we try to switch to slave-current-user (@),
++ we will fail.
++
++ Actually, this leads to the inconsistent state of master and
++ slave (different definers, different SUID behaviour), but it seems,
++ this is the best we can do.
++ */
++
++ if (!lex->definer)
++ {
++ Query_arena original_arena;
++ Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
++
++ lex->definer= create_default_definer(thd);
++
++ if (ps_arena)
++ thd->restore_active_arena(ps_arena, &original_arena);
++
++ /* Error has been already reported. */
++ if (lex->definer == NULL)
++ DBUG_RETURN(TRUE);
++
++ if (thd->slave_thread && lex->sphead)
++ lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
++ }
++ else
++ {
++ /*
++ If the specified definer differs from the current user, we
++ should check that the current user has SUPER privilege (in order
++ to create a stored routine under another user one must have
++ SUPER privilege).
++ */
++ if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
++ my_strcasecmp(system_charset_info, lex->definer->host.str,
++ thd->security_ctx->priv_host)) &&
++ check_global_access(thd, SUPER_ACL))
++ {
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
++ DBUG_RETURN(TRUE);
++ }
++ }
++
++ /* Check that the specified definer exists. Emit a warning if not. */
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
++ {
++ push_warning_printf(thd,
++ MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_NO_SUCH_USER,
++ ER(ER_NO_SUCH_USER),
++ lex->definer->user.str,
++ lex->definer->host.str);
++ }
++#endif /* NO_EMBEDDED_ACCESS_CHECKS */
++
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Execute command saved in thd and lex->sql_command.
++
++ Before every operation that can request a write lock for a table
++ wait if a global read lock exists. However do not wait if this
++ thread has locked tables already. No new locks can be requested
++ until the other locks are released. The thread that requests the
++ global read lock waits for write locked tables to become unlocked.
++
++ Note that wait_if_global_read_lock() sets a protection against a new
++ global read lock when it succeeds. This needs to be released by
++ start_waiting_global_read_lock() after the operation.
++
++ @param thd Thread handle
++
++ @todo
++ - Invalidate the table in the query cache if something changed
++ after unlocking when changes become visible.
++ TODO: this is workaround. right way will be move invalidating in
++ the unlock procedure.
++ - TODO: use check_change_password()
++ - JOIN is not supported yet. TODO
++ - SUSPEND and FOR MIGRATE are not supported yet. TODO
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE Error
++*/
++
++int
++mysql_execute_command(THD *thd)
++{
++ int res= FALSE;
++ bool need_start_waiting= FALSE; // have protection against global read lock
++ int up_result= 0;
++ LEX *lex= thd->lex;
++ /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
++ SELECT_LEX *select_lex= &lex->select_lex;
++ /* first table of first SELECT_LEX */
++ TABLE_LIST *first_table= select_lex->table_list.first;
++ /* list of all tables in query */
++ TABLE_LIST *all_tables;
++ /* most outer SELECT_LEX_UNIT of query */
++ SELECT_LEX_UNIT *unit= &lex->unit;
++#ifdef HAVE_REPLICATION
++ /* have table map for update for multi-update statement (BUG#37051) */
++ bool have_table_map_for_update= FALSE;
++#endif
++ /* Saved variable value */
++ DBUG_ENTER("mysql_execute_command");
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ thd->work_part_info= 0;
++#endif
++
++ /*
++ In many cases first table of main SELECT_LEX have special meaning =>
++ check that it is first table in global list and relink it first in
++ queries_tables list if it is necessary (we need such relinking only
++ for queries with subqueries in select list, in this case tables of
++ subqueries will go to global list first)
++
++ all_tables will differ from first_table only if most upper SELECT_LEX
++ do not contain tables.
++
++ Because of above in place where should be at least one table in most
++ outer SELECT_LEX we have following check:
++ DBUG_ASSERT(first_table == all_tables);
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ */
++ lex->first_lists_tables_same();
++ /* should be assigned after making first tables same */
++ all_tables= lex->query_tables;
++ /* set context for commands which do not use setup_tables */
++ select_lex->
++ context.resolve_in_table_list_only(select_lex->
++ table_list.first);
++
++ /*
++ Reset warning count for each query that uses tables
++ A better approach would be to reset this for any commands
++ that is not a SHOW command or a select that only access local
++ variables, but for now this is probably good enough.
++ Don't reset warnings when executing a stored routine.
++ */
++ if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont)
++ mysql_reset_errors(thd, 0);
++
++#ifdef HAVE_REPLICATION
++ if (unlikely(thd->slave_thread))
++ {
++ if (lex->sql_command == SQLCOM_DROP_TRIGGER)
++ {
++ /*
++ When dropping a trigger, we need to load its table name
++ before checking slave filter rules.
++ */
++ add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
++
++ if (!all_tables)
++ {
++ /*
++ If table name cannot be loaded,
++ it means the trigger does not exists possibly because
++ CREATE TRIGGER was previously skipped for this trigger
++ according to slave filtering rules.
++ Returning success without producing any errors in this case.
++ */
++ DBUG_RETURN(0);
++ }
++
++ // force searching in slave.cc:tables_ok()
++ all_tables->updating= 1;
++ }
++
++ /*
++ For fix of BUG#37051, the master stores the table map for update
++ in the Query_log_event, and the value is assigned to
++ thd->variables.table_map_for_update before executing the update
++ query.
++
++ If thd->variables.table_map_for_update is set, then we are
++ replicating from a new master, we can use this value to apply
++ filter rules without opening all the tables. However If
++ thd->variables.table_map_for_update is not set, then we are
++ replicating from an old master, so we just skip this and
++ continue with the old method. And of course, the bug would still
++ exist for old masters.
++ */
++ if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
++ thd->table_map_for_update)
++ {
++ have_table_map_for_update= TRUE;
++ table_map table_map_for_update= thd->table_map_for_update;
++ uint nr= 0;
++ TABLE_LIST *table;
++ for (table=all_tables; table; table=table->next_global, nr++)
++ {
++ if (table_map_for_update & ((table_map)1 << nr))
++ table->updating= TRUE;
++ else
++ table->updating= FALSE;
++ }
++
++ if (all_tables_not_ok(thd, all_tables))
++ {
++ /* we warn the slave SQL thread */
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ if (thd->one_shot_set)
++ reset_one_shot_variables(thd);
++ DBUG_RETURN(0);
++ }
++
++ for (table=all_tables; table; table=table->next_global)
++ table->updating= TRUE;
++ }
++
++ /*
++ Check if statment should be skipped because of slave filtering
++ rules
++
++ Exceptions are:
++ - UPDATE MULTI: For this statement, we want to check the filtering
++ rules later in the code
++ - SET: we always execute it (Not that many SET commands exists in
++ the binary log anyway -- only 4.1 masters write SET statements,
++ in 5.0 there are no SET statements in the binary log)
++ - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
++ have stale files on slave caused by exclusion of one tmp table).
++ */
++ if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
++ !(lex->sql_command == SQLCOM_SET_OPTION) &&
++ !(lex->sql_command == SQLCOM_DROP_TABLE &&
++ lex->drop_temporary && lex->drop_if_exists) &&
++ all_tables_not_ok(thd, all_tables))
++ {
++ /* we warn the slave SQL thread */
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ if (thd->one_shot_set)
++ {
++ /*
++ It's ok to check thd->one_shot_set here:
++
++ The charsets in a MySQL 5.0 slave can change by both a binlogged
++ SET ONE_SHOT statement and the event-internal charset setting,
++ and these two ways to change charsets do not seems to work
++ together.
++
++ At least there seems to be problems in the rli cache for
++ charsets if we are using ONE_SHOT. Note that this is normally no
++ problem because either the >= 5.0 slave reads a 4.1 binlog (with
++ ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
++ */
++ reset_one_shot_variables(thd);
++ }
++ DBUG_RETURN(0);
++ }
++ }
++ else
++ {
++#endif /* HAVE_REPLICATION */
++ /*
++ When option readonly is set deny operations which change non-temporary
++ tables. Except for the replication thread and the 'super' users.
++ */
++ if (deny_updates_if_read_only_option(thd, all_tables))
++ {
++ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
++ DBUG_RETURN(-1);
++ }
++#ifdef HAVE_REPLICATION
++ } /* endif unlikely slave */
++#endif
++ status_var_increment(thd->status_var.com_stat[lex->sql_command]);
++
++ DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
++
++ switch (lex->sql_command) {
++
++ case SQLCOM_SHOW_EVENTS:
++#ifndef HAVE_EVENT_SCHEDULER
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
++ break;
++#endif
++ case SQLCOM_SHOW_STATUS_PROC:
++ case SQLCOM_SHOW_STATUS_FUNC:
++ if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
++ res= execute_sqlcom_select(thd, all_tables);
++ break;
++ case SQLCOM_SHOW_STATUS:
++ {
++ system_status_var old_status_var= thd->status_var;
++ thd->initial_status_var= &old_status_var;
++ if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
++ res= execute_sqlcom_select(thd, all_tables);
++ /* Don't log SHOW STATUS commands to slow query log */
++ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
++ SERVER_QUERY_NO_GOOD_INDEX_USED);
++ /*
++ restore status variables, as we don't want 'show status' to cause
++ changes
++ */
++ pthread_mutex_lock(&LOCK_status);
++ add_diff_to_status(&global_status_var, &thd->status_var,
++ &old_status_var);
++ thd->status_var= old_status_var;
++ pthread_mutex_unlock(&LOCK_status);
++ break;
++ }
++ case SQLCOM_SHOW_DATABASES:
++ case SQLCOM_SHOW_TABLES:
++ case SQLCOM_SHOW_TRIGGERS:
++ case SQLCOM_SHOW_TABLE_STATUS:
++ case SQLCOM_SHOW_OPEN_TABLES:
++ case SQLCOM_SHOW_PLUGINS:
++ case SQLCOM_SHOW_FIELDS:
++ case SQLCOM_SHOW_KEYS:
++ case SQLCOM_SHOW_VARIABLES:
++ case SQLCOM_SHOW_CHARSETS:
++ case SQLCOM_SHOW_COLLATIONS:
++ case SQLCOM_SHOW_STORAGE_ENGINES:
++ case SQLCOM_SHOW_PROFILE:
++ case SQLCOM_SELECT:
++ thd->status_var.last_query_cost= 0.0;
++ if (all_tables)
++ {
++ res= check_table_access(thd,
++ lex->exchange ? SELECT_ACL | FILE_ACL :
++ SELECT_ACL,
++ all_tables, UINT_MAX, FALSE);
++ }
++ else
++ res= check_access(thd,
++ lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
++ any_db, 0, 0, 0, 0);
++
++ if (res)
++ break;
++
++ if (!thd->locked_tables && lex->protect_against_global_read_lock &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ break;
++
++ res= execute_sqlcom_select(thd, all_tables);
++ break;
++ case SQLCOM_PREPARE:
++ {
++ mysql_sql_stmt_prepare(thd);
++ break;
++ }
++ case SQLCOM_EXECUTE:
++ {
++ mysql_sql_stmt_execute(thd);
++ break;
++ }
++ case SQLCOM_DEALLOCATE_PREPARE:
++ {
++ mysql_sql_stmt_close(thd);
++ break;
++ }
++ case SQLCOM_DO:
++ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
++ open_and_lock_tables(thd, all_tables))
++ goto error;
++
++ res= mysql_do(thd, *lex->insert_list);
++ break;
++
++ case SQLCOM_EMPTY_QUERY:
++ my_ok(thd);
++ break;
++
++ case SQLCOM_HELP:
++ res= mysqld_help(thd,lex->help_arg);
++ break;
++
++#ifndef EMBEDDED_LIBRARY
++ case SQLCOM_PURGE:
++ {
++ if (check_global_access(thd, SUPER_ACL))
++ goto error;
++ /* PURGE MASTER LOGS TO 'file' */
++ res = purge_master_logs(thd, lex->to_log);
++ break;
++ }
++ case SQLCOM_PURGE_BEFORE:
++ {
++ Item *it;
++
++ if (check_global_access(thd, SUPER_ACL))
++ goto error;
++ /* PURGE MASTER LOGS BEFORE 'data' */
++ it= (Item *)lex->value_list.head();
++ if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
++ it->check_cols(1))
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
++ goto error;
++ }
++ it= new Item_func_unix_timestamp(it);
++ /*
++ it is OK only emulate fix_fieds, because we need only
++ value of constant
++ */
++ it->quick_fix_field();
++ res = purge_master_logs_before_date(thd, (ulong)it->val_int());
++ break;
++ }
++#endif
++ case SQLCOM_SHOW_WARNS:
++ {
++ res= mysqld_show_warnings(thd, (ulong)
++ ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
++ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
++ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
++ ));
++ break;
++ }
++ case SQLCOM_SHOW_ERRORS:
++ {
++ res= mysqld_show_warnings(thd, (ulong)
++ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
++ break;
++ }
++ case SQLCOM_SHOW_PROFILES:
++ {
++#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
++ thd->profiling.discard_current_query();
++ res= thd->profiling.show_profiles();
++ if (res)
++ goto error;
++#else
++ my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
++ goto error;
++#endif
++ break;
++ }
++ case SQLCOM_SHOW_NEW_MASTER:
++ {
++ if (check_global_access(thd, REPL_SLAVE_ACL))
++ goto error;
++ /* This query don't work now. See comment in repl_failsafe.cc */
++#ifndef WORKING_NEW_MASTER
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER");
++ goto error;
++#else
++ res = show_new_master(thd);
++ break;
++#endif
++ }
++
++#ifdef HAVE_REPLICATION
++ case SQLCOM_SHOW_SLAVE_HOSTS:
++ {
++ if (check_global_access(thd, REPL_SLAVE_ACL))
++ goto error;
++ res = show_slave_hosts(thd);
++ break;
++ }
++ case SQLCOM_SHOW_BINLOG_EVENTS:
++ {
++ if (check_global_access(thd, REPL_SLAVE_ACL))
++ goto error;
++ res = mysql_show_binlog_events(thd);
++ break;
++ }
++#endif
++
++ case SQLCOM_BACKUP_TABLE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
++ check_global_access(thd, FILE_ACL))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res = mysql_backup_table(thd, first_table);
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++ case SQLCOM_RESTORE_TABLE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) ||
++ check_global_access(thd, FILE_ACL))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res = mysql_restore_table(thd, first_table);
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++ case SQLCOM_ASSIGN_TO_KEYCACHE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_access(thd, INDEX_ACL, first_table->db,
++ &first_table->grant.privilege, 0, 0,
++ test(first_table->schema_table)))
++ goto error;
++ res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
++ break;
++ }
++ case SQLCOM_PRELOAD_KEYS:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_access(thd, INDEX_ACL, first_table->db,
++ &first_table->grant.privilege, 0, 0,
++ test(first_table->schema_table)))
++ goto error;
++ res = mysql_preload_keys(thd, first_table);
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ case SQLCOM_CHANGE_MASTER:
++ {
++ if (check_global_access(thd, SUPER_ACL))
++ goto error;
++ pthread_mutex_lock(&LOCK_active_mi);
++ res = change_master(thd,active_mi);
++ pthread_mutex_unlock(&LOCK_active_mi);
++ break;
++ }
++ case SQLCOM_SHOW_SLAVE_STAT:
++ {
++ /* Accept one of two privileges */
++ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
++ goto error;
++ pthread_mutex_lock(&LOCK_active_mi);
++ if (active_mi != NULL)
++ {
++ res = show_master_info(thd, active_mi);
++ }
++ else
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
++ my_ok(thd);
++ }
++ pthread_mutex_unlock(&LOCK_active_mi);
++ break;
++ }
++ case SQLCOM_SHOW_MASTER_STAT:
++ {
++ /* Accept one of two privileges */
++ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
++ goto error;
++ res = show_binlog_info(thd);
++ break;
++ }
++
++ case SQLCOM_LOAD_MASTER_DATA: // sync with master
++ if (check_global_access(thd, SUPER_ACL))
++ goto error;
++ if (end_active_trans(thd))
++ goto error;
++ res = load_master_data(thd);
++ break;
++#endif /* HAVE_REPLICATION */
++ case SQLCOM_SHOW_ENGINE_STATUS:
++ {
++ if (check_global_access(thd, PROCESS_ACL))
++ goto error;
++ res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
++ break;
++ }
++ case SQLCOM_SHOW_ENGINE_MUTEX:
++ {
++ if (check_global_access(thd, PROCESS_ACL))
++ goto error;
++ res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ case SQLCOM_LOAD_MASTER_TABLE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ DBUG_ASSERT(first_table->db); /* Must be set in the parser */
++
++ if (check_access(thd, CREATE_ACL, first_table->db,
++ &first_table->grant.privilege, 0, 0,
++ test(first_table->schema_table)))
++ goto error; /* purecov: inspected */
++ /* Check that the first table has CREATE privilege */
++ if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
++ goto error;
++
++ pthread_mutex_lock(&LOCK_active_mi);
++ /*
++ fetch_master_table will send the error to the client on failure.
++ Give error if the table already exists.
++ */
++ if (!fetch_master_table(thd, first_table->db, first_table->table_name,
++ active_mi, 0, 0))
++ {
++ my_ok(thd);
++ }
++ pthread_mutex_unlock(&LOCK_active_mi);
++ break;
++ }
++#endif /* HAVE_REPLICATION */
++
++ case SQLCOM_CREATE_TABLE:
++ {
++ /* If CREATE TABLE of non-temporary table, do implicit commit */
++ if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ if (end_active_trans(thd))
++ {
++ res= -1;
++ break;
++ }
++ }
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ bool link_to_local;
++ // Skip first table, which is the table we are creating
++ TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
++ TABLE_LIST *select_tables= lex->query_tables;
++ /*
++ Code below (especially in mysql_create_table() and select_create
++ methods) may modify HA_CREATE_INFO structure in LEX, so we have to
++ use a copy of this structure to make execution prepared statement-
++ safe. A shallow copy is enough as this code won't modify any memory
++ referenced from this structure.
++ */
++ HA_CREATE_INFO create_info(lex->create_info);
++ /*
++ We need to copy alter_info for the same reasons of re-execution
++ safety, only in case of Alter_info we have to do (almost) a deep
++ copy.
++ */
++ Alter_info alter_info(lex->alter_info, thd->mem_root);
++
++ if (thd->is_fatal_error)
++ {
++ /* If out of memory when creating a copy of alter_info. */
++ res= 1;
++ goto end_with_restore_list;
++ }
++
++ if ((res= create_table_precheck(thd, select_tables, create_table)))
++ goto end_with_restore_list;
++
++ /* Might have been updated in create_table_precheck */
++ create_info.alias= create_table->alias;
++
++#ifdef HAVE_READLINK
++ /* Fix names if symlinked tables */
++ if (append_file_to_dir(thd, &create_info.data_file_name,
++ create_table->table_name) ||
++ append_file_to_dir(thd, &create_info.index_file_name,
++ create_table->table_name))
++ goto end_with_restore_list;
++#endif
++ /*
++ If we are using SET CHARSET without DEFAULT, add an implicit
++ DEFAULT to not confuse old users. (This may change).
++ */
++ if ((create_info.used_fields &
++ (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
++ HA_CREATE_USED_CHARSET)
++ {
++ create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
++ create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
++ create_info.default_table_charset= create_info.table_charset;
++ create_info.table_charset= 0;
++ }
++ /*
++ The create-select command will open and read-lock the select table
++ and then create, open and write-lock the new table. If a global
++ read lock steps in, we get a deadlock. The write lock waits for
++ the global read lock, while the global read lock waits for the
++ select table to be closed. So we wait until the global readlock is
++ gone before starting both steps. Note that
++ wait_if_global_read_lock() sets a protection against a new global
++ read lock when it succeeds. This needs to be released by
++ start_waiting_global_read_lock(). We protect the normal CREATE
++ TABLE in the same way. That way we avoid that a new table is
++ created during a gobal read lock.
++ */
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ goto end_with_restore_list;
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ {
++ partition_info *part_info= thd->lex->part_info;
++ if (part_info && !(part_info= thd->lex->part_info->get_clone()))
++ {
++ res= -1;
++ goto end_with_restore_list;
++ }
++ thd->work_part_info= part_info;
++ }
++#endif
++ if (select_lex->item_list.elements) // With select
++ {
++ select_result *result;
++
++ /*
++ If:
++ a) we inside an SP and there was NAME_CONST substitution,
++ b) binlogging is on (STMT mode),
++ c) we log the SP as separate statements
++ raise a warning, as it may cause problems
++ (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
++ */
++ if (thd->query_name_consts &&
++ mysql_bin_log.is_open() &&
++ thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
++ !mysql_bin_log.is_query_in_union(thd, thd->query_id))
++ {
++ List_iterator_fast<Item> it(select_lex->item_list);
++ Item *item;
++ uint splocal_refs= 0;
++ /* Count SP local vars in the top-level SELECT list */
++ while ((item= it++))
++ {
++ if (item->is_splocal())
++ splocal_refs++;
++ }
++ /*
++ If it differs from number of NAME_CONST substitution applied,
++ we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
++ that may cause a problem with binary log (see BUG#35383),
++ raise a warning.
++ */
++ if (splocal_refs != thd->query_name_consts)
++ push_warning(thd,
++ MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_UNKNOWN_ERROR,
++"Invoked routine ran a statement that may cause problems with "
++"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
++"section of the manual.");
++ }
++
++ select_lex->options|= SELECT_NO_UNLOCK;
++ unit->set_limit(select_lex);
++
++ /*
++ Disable non-empty MERGE tables with CREATE...SELECT. Too
++ complicated. See Bug #26379. Empty MERGE tables are read-only
++ and don't allow CREATE...SELECT anyway.
++ */
++ if (create_info.used_fields & HA_CREATE_USED_UNION)
++ {
++ my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
++ create_table->table_name, "BASE TABLE");
++ res= 1;
++ goto end_with_restore_list;
++ }
++
++ if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ lex->link_first_table_back(create_table, link_to_local);
++ create_table->create= TRUE;
++ /* Base table and temporary table are not in the same name space. */
++ create_table->skip_temporary= 1;
++ }
++
++ if (!(res= open_and_lock_tables(thd, lex->query_tables)))
++ {
++ /*
++ Is table which we are changing used somewhere in other parts
++ of query
++ */
++ if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ TABLE_LIST *duplicate;
++ create_table= lex->unlink_first_table(&link_to_local);
++
++ if (create_table->view)
++ {
++ if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ {
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_TABLE_EXISTS_ERROR,
++ ER(ER_TABLE_EXISTS_ERROR),
++ create_info.alias);
++ my_ok(thd);
++ }
++ else
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias);
++ res= 1;
++ }
++ goto end_with_restore_list;
++ }
++
++ if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
++ {
++ update_non_unique_table_error(create_table, "CREATE", duplicate);
++ res= 1;
++ goto end_with_restore_list;
++ }
++ }
++ /* If we create merge table, we have to test tables in merge, too */
++ if (create_info.used_fields & HA_CREATE_USED_UNION)
++ {
++ TABLE_LIST *tab;
++ for (tab= create_info.merge_list.first;
++ tab;
++ tab= tab->next_local)
++ {
++ TABLE_LIST *duplicate;
++ if ((duplicate= unique_table(thd, tab, select_tables, 0)))
++ {
++ update_non_unique_table_error(tab, "CREATE", duplicate);
++ res= 1;
++ goto end_with_restore_list;
++ }
++ }
++ }
++
++ /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
++ if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
++ thd->options|= OPTION_KEEP_LOG;
++
++ /*
++ select_create is currently not re-execution friendly and
++ needs to be created for every execution of a PS/SP.
++ */
++ if ((result= new select_create(create_table,
++ &create_info,
++ &alter_info,
++ select_lex->item_list,
++ lex->duplicates,
++ lex->ignore,
++ select_tables)))
++ {
++ /*
++ CREATE from SELECT give its SELECT_LEX for SELECT,
++ and item_list belong to SELECT
++ */
++ res= handle_select(thd, lex, result, 0);
++ delete result;
++ }
++ }
++ else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
++ create_table= lex->unlink_first_table(&link_to_local);
++
++ }
++ else
++ {
++ /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
++ if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
++ thd->options|= OPTION_KEEP_LOG;
++ /* regular create */
++ if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
++ res= mysql_create_like_table(thd, create_table, select_tables,
++ &create_info);
++ else
++ {
++ res= mysql_create_table(thd, create_table->db,
++ create_table->table_name, &create_info,
++ &alter_info, 0, 0);
++ }
++ if (!res)
++ my_ok(thd);
++ }
++
++ /* put tables back for PS rexecuting */
++end_with_restore_list:
++ lex->link_first_table_back(create_table, link_to_local);
++ break;
++ }
++ case SQLCOM_CREATE_INDEX:
++ /* Fall through */
++ case SQLCOM_DROP_INDEX:
++ /*
++ CREATE INDEX and DROP INDEX are implemented by calling ALTER
++ TABLE with proper arguments.
++
++ In the future ALTER TABLE will notice that the request is to
++ only add indexes and create these one by one for the existing
++ table without having to do a full rebuild.
++ */
++ {
++ /* Prepare stack copies to be re-execution safe */
++ HA_CREATE_INFO create_info;
++ Alter_info alter_info(lex->alter_info, thd->mem_root);
++
++ if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
++ goto error;
++
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_one_table_access(thd, INDEX_ACL, all_tables))
++ goto error; /* purecov: inspected */
++ if (end_active_trans(thd))
++ goto error;
++ /*
++ Currently CREATE INDEX or DROP INDEX cause a full table rebuild
++ and thus classify as slow administrative statements just like
++ ALTER TABLE.
++ */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++
++ bzero((char*) &create_info, sizeof(create_info));
++ create_info.db_type= 0;
++ create_info.row_type= ROW_TYPE_NOT_USED;
++ create_info.default_table_charset= thd->variables.collation_database;
++
++ res= mysql_alter_table(thd, first_table->db, first_table->table_name,
++ &create_info, first_table, &alter_info,
++ 0, (ORDER*) 0, 0);
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ case SQLCOM_SLAVE_START:
++ {
++ pthread_mutex_lock(&LOCK_active_mi);
++ start_slave(thd,active_mi,1 /* net report*/);
++ pthread_mutex_unlock(&LOCK_active_mi);
++ break;
++ }
++ case SQLCOM_SLAVE_STOP:
++ /*
++ If the client thread has locked tables, a deadlock is possible.
++ Assume that
++ - the client thread does LOCK TABLE t READ.
++ - then the master updates t.
++ - then the SQL slave thread wants to update t,
++ so it waits for the client thread because t is locked by it.
++ - then the client thread does SLAVE STOP.
++ SLAVE STOP waits for the SQL slave thread to terminate its
++ update t, which waits for the client thread because t is locked by it.
++ To prevent that, refuse SLAVE STOP if the
++ client thread has locked tables
++ */
++ if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ goto error;
++ }
++ {
++ pthread_mutex_lock(&LOCK_active_mi);
++ stop_slave(thd,active_mi,1/* net report*/);
++ pthread_mutex_unlock(&LOCK_active_mi);
++ break;
++ }
++#endif /* HAVE_REPLICATION */
++
++ case SQLCOM_ALTER_TABLE:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ {
++ ulong priv=0;
++ ulong priv_needed= ALTER_ACL;
++ /*
++ Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
++ so we have to use a copy of this structure to make execution
++ prepared statement- safe. A shallow copy is enough as no memory
++ referenced from this structure will be modified.
++ */
++ HA_CREATE_INFO create_info(lex->create_info);
++ Alter_info alter_info(lex->alter_info, thd->mem_root);
++
++ if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
++ goto error;
++ /*
++ We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
++ as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
++ */
++ if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
++ priv_needed|= DROP_ACL;
++
++ /* Must be set in the parser */
++ DBUG_ASSERT(select_lex->db);
++ if (check_access(thd, priv_needed, first_table->db,
++ &first_table->grant.privilege, 0, 0,
++ test(first_table->schema_table)) ||
++ check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
++ is_schema_db(select_lex->db))||
++ check_merge_table_access(thd, first_table->db,
++ create_info.merge_list.first))
++ goto error; /* purecov: inspected */
++ if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
++ goto error;
++ if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
++ { // Rename of table
++ TABLE_LIST tmp_table;
++ bzero((char*) &tmp_table,sizeof(tmp_table));
++ tmp_table.table_name= lex->name.str;
++ tmp_table.db=select_lex->db;
++ tmp_table.grant.privilege=priv;
++ if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
++ UINT_MAX, 0))
++ goto error;
++ }
++
++ /* Don't yet allow changing of symlinks with ALTER TABLE */
++ if (create_info.data_file_name)
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
++ "DATA DIRECTORY");
++ if (create_info.index_file_name)
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
++ "INDEX DIRECTORY");
++ create_info.data_file_name= create_info.index_file_name= NULL;
++ /* ALTER TABLE ends previous transaction */
++ if (end_active_trans(thd))
++ goto error;
++
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ break;
++ }
++
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res= mysql_alter_table(thd, select_lex->db, lex->name.str,
++ &create_info,
++ first_table,
++ &alter_info,
++ select_lex->order_list.elements,
++ (ORDER *) select_lex->order_list.first,
++ lex->ignore);
++ break;
++ }
++ case SQLCOM_RENAME_TABLE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ TABLE_LIST *table;
++ for (table= first_table; table; table= table->next_local->next_local)
++ {
++ if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
++ &table->grant.privilege,0,0, test(table->schema_table)) ||
++ check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
++ &table->next_local->grant.privilege, 0, 0,
++ test(table->next_local->schema_table)))
++ goto error;
++ TABLE_LIST old_list, new_list;
++ /*
++ we do not need initialize old_list and new_list because we will
++ come table[0] and table->next[0] there
++ */
++ old_list= table[0];
++ new_list= table->next_local[0];
++ if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
++ (!test_all_bits(table->next_local->grant.privilege,
++ INSERT_ACL | CREATE_ACL) &&
++ check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
++ goto error;
++ }
++
++ if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
++ goto error;
++ break;
++ }
++#ifndef EMBEDDED_LIBRARY
++ case SQLCOM_SHOW_BINLOGS:
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
++ MYF(0)); /* purecov: inspected */
++ goto error;
++#else
++ {
++ if (check_global_access(thd, SUPER_ACL))
++ goto error;
++ res = show_binlogs(thd);
++ break;
++ }
++#endif
++#endif /* EMBEDDED_LIBRARY */
++ case SQLCOM_SHOW_CREATE:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
++ MYF(0)); /* purecov: inspected */
++ goto error;
++#else
++ {
++ /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
++ if (lex->only_view)
++ first_table->skip_temporary= 1;
++ if (check_show_create_table_access(thd, first_table))
++ goto error;
++ res= mysqld_show_create(thd, first_table);
++ break;
++ }
++#endif
++ case SQLCOM_CHECKSUM:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables,
++ UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ res = mysql_checksum_table(thd, first_table, &lex->check_opt);
++ break;
++ }
++ case SQLCOM_REPAIR:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
++ UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res= mysql_repair_table(thd, first_table, &lex->check_opt);
++ /* ! we write after unlocking the table */
++ if (!res && !lex->no_write_to_binlog)
++ {
++ /*
++ Presumably, REPAIR and binlog writing doesn't require synchronization
++ */
++ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ }
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++ case SQLCOM_CHECK:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables,
++ UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res = mysql_check_table(thd, first_table, &lex->check_opt);
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++ case SQLCOM_ANALYZE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
++ UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res= mysql_analyze_table(thd, first_table, &lex->check_opt);
++ /* ! we write after unlocking the table */
++ if (!res && !lex->no_write_to_binlog)
++ {
++ /*
++ Presumably, ANALYZE and binlog writing doesn't require synchronization
++ */
++ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ }
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++
++ case SQLCOM_OPTIMIZE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
++ UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ thd->enable_slow_log= opt_log_slow_admin_statements;
++ res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
++ mysql_recreate_table(thd, first_table) :
++ mysql_optimize_table(thd, first_table, &lex->check_opt);
++ /* ! we write after unlocking the table */
++ if (!res && !lex->no_write_to_binlog)
++ {
++ /*
++ Presumably, OPTIMIZE and binlog writing doesn't require synchronization
++ */
++ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ }
++ select_lex->table_list.first= first_table;
++ lex->query_tables=all_tables;
++ break;
++ }
++ case SQLCOM_UPDATE:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (update_precheck(thd, all_tables))
++ break;
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ goto error;
++ DBUG_ASSERT(select_lex->offset_limit == 0);
++ unit->set_limit(select_lex);
++ res= (up_result= mysql_update(thd, all_tables,
++ select_lex->item_list,
++ lex->value_list,
++ select_lex->where,
++ select_lex->order_list.elements,
++ select_lex->order_list.first,
++ unit->select_limit_cnt,
++ lex->duplicates, lex->ignore));
++ /* mysql_update return 2 if we need to switch to multi-update */
++ if (up_result != 2)
++ break;
++ /* Fall through */
++ case SQLCOM_UPDATE_MULTI:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ /* if we switched from normal update, rights are checked */
++ if (up_result != 2)
++ {
++ if ((res= multi_update_precheck(thd, all_tables)))
++ break;
++ }
++ else
++ res= 0;
++
++ /*
++ Protection might have already been risen if its a fall through
++ from the SQLCOM_UPDATE case above.
++ */
++ if (!thd->locked_tables &&
++ lex->sql_command == SQLCOM_UPDATE_MULTI &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ goto error;
++
++ res= mysql_multi_update_prepare(thd);
++
++#ifdef HAVE_REPLICATION
++ /* Check slave filtering rules */
++ if (unlikely(thd->slave_thread && !have_table_map_for_update))
++ {
++ if (all_tables_not_ok(thd, all_tables))
++ {
++ if (res!= 0)
++ {
++ res= 0; /* don't care of prev failure */
++ thd->clear_error(); /* filters are of highest prior */
++ }
++ /* we warn the slave SQL thread */
++ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
++ break;
++ }
++ if (res)
++ break;
++ }
++ else
++ {
++#endif /* HAVE_REPLICATION */
++ if (res)
++ break;
++ if (opt_readonly &&
++ !(thd->security_ctx->master_access & SUPER_ACL) &&
++ some_non_temp_table_to_be_updated(thd, all_tables))
++ {
++ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ } /* unlikely */
++#endif
++
++ res= mysql_multi_update(thd, all_tables,
++ &select_lex->item_list,
++ &lex->value_list,
++ select_lex->where,
++ select_lex->options,
++ lex->duplicates, lex->ignore, unit, select_lex);
++ break;
++ }
++ case SQLCOM_REPLACE:
++#ifndef DBUG_OFF
++ if (mysql_bin_log.is_open())
++ {
++ /*
++ Generate an incident log event before writing the real event
++ to the binary log. We put this event is before the statement
++ since that makes it simpler to check that the statement was
++ not executed on the slave (since incidents usually stop the
++ slave).
++
++ Observe that any row events that are generated will be
++ generated before.
++
++ This is only for testing purposes and will not be present in a
++ release build.
++ */
++
++ Incident incident= INCIDENT_NONE;
++ DBUG_PRINT("debug", ("Just before generate_incident()"));
++ DBUG_EXECUTE_IF("incident_database_resync_on_replace",
++ incident= INCIDENT_LOST_EVENTS;);
++ if (incident)
++ {
++ Incident_log_event ev(thd, incident);
++ (void) mysql_bin_log.write(&ev); /* error is ignored */
++ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
++ {
++ res= 1;
++ break;
++ }
++ }
++ DBUG_PRINT("debug", ("Just after generate_incident()"));
++ }
++#endif
++ case SQLCOM_INSERT:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if ((res= insert_precheck(thd, all_tables)))
++ break;
++
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ break;
++ }
++
++ res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
++ lex->update_list, lex->value_list,
++ lex->duplicates, lex->ignore);
++
++ /*
++ If we have inserted into a VIEW, and the base table has
++ AUTO_INCREMENT column, but this column is not accessible through
++ a view, then we should restore LAST_INSERT_ID to the value it
++ had before the statement.
++ */
++ if (first_table->view && !first_table->contain_auto_increment)
++ thd->first_successful_insert_id_in_cur_stmt=
++ thd->first_successful_insert_id_in_prev_stmt;
++
++ DBUG_EXECUTE_IF("after_mysql_insert",
++ {
++ const char act[]=
++ "now "
++ "wait_for signal.continue";
++ DBUG_ASSERT(opt_debug_sync_timeout > 0);
++ DBUG_ASSERT(!debug_sync_set_action(current_thd,
++ STRING_WITH_LEN(act)));
++ };);
++ break;
++ }
++ case SQLCOM_REPLACE_SELECT:
++ case SQLCOM_INSERT_SELECT:
++ {
++ select_result *sel_result;
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if ((res= insert_precheck(thd, all_tables)))
++ break;
++
++ /* Fix lock for first table */
++ if (first_table->lock_type == TL_WRITE_DELAYED)
++ first_table->lock_type= TL_WRITE;
++
++ /* Don't unlock tables until command is written to binary log */
++ select_lex->options|= SELECT_NO_UNLOCK;
++
++ unit->set_limit(select_lex);
++
++ if (! thd->locked_tables &&
++ ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ break;
++ }
++
++ if (!(res= open_and_lock_tables(thd, all_tables)))
++ {
++ /* Skip first table, which is the table we are inserting in */
++ TABLE_LIST *second_table= first_table->next_local;
++ select_lex->table_list.first= second_table;
++ select_lex->context.table_list=
++ select_lex->context.first_name_resolution_table= second_table;
++ res= mysql_insert_select_prepare(thd);
++ if (!res && (sel_result= new select_insert(first_table,
++ first_table->table,
++ &lex->field_list,
++ &lex->update_list,
++ &lex->value_list,
++ lex->duplicates,
++ lex->ignore)))
++ {
++ res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
++ /*
++ Invalidate the table in the query cache if something changed
++ after unlocking when changes become visible.
++ TODO: this is workaround. right way will be move invalidating in
++ the unlock procedure.
++ */
++ if (!res && first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
++ thd->lock)
++ {
++ /* INSERT ... SELECT should invalidate only the very first table */
++ TABLE_LIST *save_table= first_table->next_local;
++ first_table->next_local= 0;
++ query_cache_invalidate3(thd, first_table, 1);
++ first_table->next_local= save_table;
++ }
++ delete sel_result;
++ }
++ /* revert changes for SP */
++ select_lex->table_list.first= first_table;
++ }
++
++ /*
++ If we have inserted into a VIEW, and the base table has
++ AUTO_INCREMENT column, but this column is not accessible through
++ a view, then we should restore LAST_INSERT_ID to the value it
++ had before the statement.
++ */
++ if (first_table->view && !first_table->contain_auto_increment)
++ thd->first_successful_insert_id_in_cur_stmt=
++ thd->first_successful_insert_id_in_prev_stmt;
++
++ break;
++ }
++ case SQLCOM_TRUNCATE:
++ if (end_active_trans(thd))
++ {
++ res= -1;
++ break;
++ }
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_one_table_access(thd, DROP_ACL, all_tables))
++ goto error;
++ /*
++ Don't allow this within a transaction because we want to use
++ re-generate table
++ */
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ goto error;
++ }
++ if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ goto error;
++ res= mysql_truncate(thd, first_table, 0);
++ break;
++ case SQLCOM_DELETE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if ((res= delete_precheck(thd, all_tables)))
++ break;
++ DBUG_ASSERT(select_lex->offset_limit == 0);
++ unit->set_limit(select_lex);
++
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ break;
++ }
++
++ res = mysql_delete(thd, all_tables, select_lex->where,
++ &select_lex->order_list,
++ unit->select_limit_cnt, select_lex->options,
++ FALSE);
++ break;
++ }
++ case SQLCOM_DELETE_MULTI:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
++ multi_delete *del_result;
++
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ {
++ res= 1;
++ break;
++ }
++
++ if ((res= multi_delete_precheck(thd, all_tables)))
++ break;
++
++ /* condition will be TRUE on SP re-excuting */
++ if (select_lex->item_list.elements != 0)
++ select_lex->item_list.empty();
++ if (add_item_to_list(thd, new Item_null()))
++ goto error;
++
++ thd_proc_info(thd, "init");
++ if ((res= open_and_lock_tables(thd, all_tables)))
++ break;
++
++ if ((res= mysql_multi_delete_prepare(thd)))
++ goto error;
++
++ if (!thd->is_fatal_error &&
++ (del_result= new multi_delete(aux_tables, lex->table_count)))
++ {
++ res= mysql_select(thd, &select_lex->ref_pointer_array,
++ select_lex->get_table_list(),
++ select_lex->with_wild,
++ select_lex->item_list,
++ select_lex->where,
++ 0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
++ (ORDER *)NULL,
++ (select_lex->options | thd->options |
++ SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
++ OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
++ del_result, unit, select_lex);
++ res|= thd->is_error();
++ if (res)
++ del_result->abort();
++ delete del_result;
++ }
++ else
++ res= TRUE; // Error
++ break;
++ }
++ case SQLCOM_DROP_TABLE:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (!lex->drop_temporary)
++ {
++ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE))
++ goto error; /* purecov: inspected */
++ if (end_active_trans(thd))
++ goto error;
++ }
++ else
++ {
++ /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
++ thd->options|= OPTION_KEEP_LOG;
++ }
++ /* DDL and binlog write order protected by LOCK_open */
++ res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
++ lex->drop_temporary);
++ }
++ break;
++ case SQLCOM_SHOW_PROCESSLIST:
++ if (!thd->security_ctx->priv_user[0] &&
++ check_global_access(thd,PROCESS_ACL))
++ break;
++ mysqld_list_processes(thd,
++ (thd->security_ctx->master_access & PROCESS_ACL ?
++ NullS :
++ thd->security_ctx->priv_user),
++ lex->verbose);
++ break;
++ case SQLCOM_SHOW_AUTHORS:
++ res= mysqld_show_authors(thd);
++ break;
++ case SQLCOM_SHOW_CONTRIBUTORS:
++ res= mysqld_show_contributors(thd);
++ break;
++ case SQLCOM_SHOW_PRIVILEGES:
++ res= mysqld_show_privileges(thd);
++ break;
++ case SQLCOM_SHOW_COLUMN_TYPES:
++ res= mysqld_show_column_types(thd);
++ break;
++ case SQLCOM_SHOW_ENGINE_LOGS:
++#ifdef DONT_ALLOW_SHOW_COMMANDS
++ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
++ MYF(0)); /* purecov: inspected */
++ goto error;
++#else
++ {
++ if (check_access(thd, FILE_ACL, any_db,0,0,0,0))
++ goto error;
++ res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
++ break;
++ }
++#endif
++ case SQLCOM_CHANGE_DB:
++ {
++ LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
++
++ if (!mysql_change_db(thd, &db_str, FALSE))
++ my_ok(thd);
++
++ break;
++ }
++
++ case SQLCOM_LOAD:
++ {
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ uint privilege= (lex->duplicates == DUP_REPLACE ?
++ INSERT_ACL | DELETE_ACL : INSERT_ACL) |
++ (lex->local_file ? 0 : FILE_ACL);
++
++ if (lex->local_file)
++ {
++ if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
++ !opt_local_infile)
++ {
++ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
++ goto error;
++ }
++ }
++
++ if (check_one_table_access(thd, privilege, all_tables))
++ goto error;
++
++ if (!thd->locked_tables &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ goto error;
++
++ res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
++ lex->update_list, lex->value_list, lex->duplicates,
++ lex->ignore, (bool) lex->local_file);
++ break;
++ }
++
++ case SQLCOM_SET_OPTION:
++ {
++ List<set_var_base> *lex_var_list= &lex->var_list;
++
++ if (lex->autocommit && end_active_trans(thd))
++ goto error;
++
++ if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
++ open_and_lock_tables(thd, all_tables)))
++ goto error;
++ if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
++ {
++ my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
++ goto error;
++ }
++ if (!(res= sql_set_variables(thd, lex_var_list)))
++ {
++ /*
++ If the previous command was a SET ONE_SHOT, we don't want to forget
++ about the ONE_SHOT property of that SET. So we use a |= instead of = .
++ */
++ thd->one_shot_set|= lex->one_shot_set;
++ my_ok(thd);
++ }
++ else
++ {
++ /*
++ We encountered some sort of error, but no message was sent.
++ Send something semi-generic here since we don't know which
++ assignment in the list caused the error.
++ */
++ if (!thd->is_error())
++ my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
++ goto error;
++ }
++
++ break;
++ }
++
++ case SQLCOM_UNLOCK_TABLES:
++ /*
++ It is critical for mysqldump --single-transaction --master-data that
++ UNLOCK TABLES does not implicitely commit a connection which has only
++ done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
++ false, mysqldump will not work.
++ */
++ unlock_locked_tables(thd);
++ if (thd->options & OPTION_TABLE_LOCK)
++ {
++ end_active_trans(thd);
++ thd->options&= ~(OPTION_TABLE_LOCK);
++ }
++ if (thd->global_read_lock)
++ unlock_global_read_lock(thd);
++ my_ok(thd);
++ break;
++ case SQLCOM_LOCK_TABLES:
++ unlock_locked_tables(thd);
++ /* we must end the trasaction first, regardless of anything */
++ if (end_active_trans(thd))
++ goto error;
++ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
++ UINT_MAX, FALSE))
++ goto error;
++ if (lex->protect_against_global_read_lock &&
++ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
++ goto error;
++ thd->in_lock_tables=1;
++ thd->options|= OPTION_TABLE_LOCK;
++
++ if (!(res= simple_open_n_lock_tables(thd, all_tables)))
++ {
++#ifdef HAVE_QUERY_CACHE
++ if (thd->variables.query_cache_wlock_invalidate)
++ query_cache.invalidate_locked_for_write(first_table);
++#endif /*HAVE_QUERY_CACHE*/
++ thd->locked_tables=thd->lock;
++ thd->lock=0;
++ my_ok(thd);
++ }
++ else
++ {
++ /*
++ Need to end the current transaction, so the storage engine (InnoDB)
++ can free its locks if LOCK TABLES locked some tables before finding
++ that it can't lock a table in its list
++ */
++ ha_autocommit_or_rollback(thd, 1);
++ end_active_trans(thd);
++ thd->options&= ~(OPTION_TABLE_LOCK);
++ }
++ thd->in_lock_tables=0;
++ break;
++ case SQLCOM_CREATE_DB:
++ {
++ /*
++ As mysql_create_db() may modify HA_CREATE_INFO structure passed to
++ it, we need to use a copy of LEX::create_info to make execution
++ prepared statement- safe.
++ */
++ HA_CREATE_INFO create_info(lex->create_info);
++ if (end_active_trans(thd))
++ {
++ res= -1;
++ break;
++ }
++ char *alias;
++ if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
++ check_db_name(&lex->name))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
++ break;
++ }
++ /*
++ If in a slave thread :
++ CREATE DATABASE DB was certainly not preceded by USE DB.
++ For that reason, db_ok() in sql/slave.cc did not check the
++ do_db/ignore_db. And as this query involves no tables, tables_ok()
++ above was not called. So we have to check rules again here.
++ */
++#ifdef HAVE_REPLICATION
++ if (thd->slave_thread &&
++ (!rpl_filter->db_ok(lex->name.str) ||
++ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
++ {
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ break;
++ }
++#endif
++ if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
++ is_schema_db(lex->name.str, lex->name.length)))
++ break;
++ res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
++ lex->name.str), &create_info, 0);
++ break;
++ }
++ case SQLCOM_DROP_DB:
++ {
++ if (end_active_trans(thd))
++ {
++ res= -1;
++ break;
++ }
++ if (check_db_name(&lex->name))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
++ break;
++ }
++ /*
++ If in a slave thread :
++ DROP DATABASE DB may not be preceded by USE DB.
++ For that reason, maybe db_ok() in sql/slave.cc did not check the
++ do_db/ignore_db. And as this query involves no tables, tables_ok()
++ above was not called. So we have to check rules again here.
++ */
++#ifdef HAVE_REPLICATION
++ if (thd->slave_thread &&
++ (!rpl_filter->db_ok(lex->name.str) ||
++ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
++ {
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ break;
++ }
++#endif
++ if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
++ is_schema_db(lex->name.str, lex->name.length)))
++ break;
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ goto error;
++ }
++ res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
++ break;
++ }
++ case SQLCOM_ALTER_DB_UPGRADE:
++ {
++ LEX_STRING *db= & lex->name;
++ if (end_active_trans(thd))
++ {
++ res= 1;
++ break;
++ }
++#ifdef HAVE_REPLICATION
++ if (thd->slave_thread &&
++ (!rpl_filter->db_ok(db->str) ||
++ !rpl_filter->db_ok_with_wild_table(db->str)))
++ {
++ res= 1;
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ break;
++ }
++#endif
++ if (check_db_name(db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
++ break;
++ }
++ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
++ is_schema_db(db->str, db->length)) ||
++ check_access(thd, DROP_ACL, db->str, 0, 1, 0,
++ is_schema_db(db->str, db->length)) ||
++ check_access(thd, CREATE_ACL, db->str, 0, 1, 0,
++ is_schema_db(db->str, db->length)))
++ {
++ res= 1;
++ break;
++ }
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ res= 1;
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ goto error;
++ }
++
++ res= mysql_upgrade_db(thd, db);
++ if (!res)
++ my_ok(thd);
++ break;
++ }
++ case SQLCOM_ALTER_DB:
++ {
++ LEX_STRING *db= &lex->name;
++ HA_CREATE_INFO create_info(lex->create_info);
++ if (check_db_name(db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
++ break;
++ }
++ /*
++ If in a slave thread :
++ ALTER DATABASE DB may not be preceded by USE DB.
++ For that reason, maybe db_ok() in sql/slave.cc did not check the
++ do_db/ignore_db. And as this query involves no tables, tables_ok()
++ above was not called. So we have to check rules again here.
++ */
++#ifdef HAVE_REPLICATION
++ if (thd->slave_thread &&
++ (!rpl_filter->db_ok(db->str) ||
++ !rpl_filter->db_ok_with_wild_table(db->str)))
++ {
++ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
++ break;
++ }
++#endif
++ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
++ is_schema_db(db->str, db->length)))
++ break;
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ goto error;
++ }
++ res= mysql_alter_db(thd, db->str, &create_info);
++ break;
++ }
++ case SQLCOM_SHOW_CREATE_DB:
++ {
++ DBUG_EXECUTE_IF("4x_server_emul",
++ my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
++ if (check_db_name(&lex->name))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
++ break;
++ }
++ res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
++ break;
++ }
++ case SQLCOM_CREATE_EVENT:
++ case SQLCOM_ALTER_EVENT:
++ #ifdef HAVE_EVENT_SCHEDULER
++ do
++ {
++ DBUG_ASSERT(lex->event_parse_data);
++ if (lex->table_or_sp_used())
++ {
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
++ "function calls as part of this statement");
++ break;
++ }
++
++ res= sp_process_definer(thd);
++ if (res)
++ break;
++
++ switch (lex->sql_command) {
++ case SQLCOM_CREATE_EVENT:
++ {
++ bool if_not_exists= (lex->create_info.options &
++ HA_LEX_CREATE_IF_NOT_EXISTS);
++ res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
++ break;
++ }
++ case SQLCOM_ALTER_EVENT:
++ res= Events::update_event(thd, lex->event_parse_data,
++ lex->spname ? &lex->spname->m_db : NULL,
++ lex->spname ? &lex->spname->m_name : NULL);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ DBUG_PRINT("info",("DDL error code=%d", res));
++ if (!res)
++ my_ok(thd);
++
++ } while (0);
++ /* Don't do it, if we are inside a SP */
++ if (!thd->spcont)
++ {
++ delete lex->sphead;
++ lex->sphead= NULL;
++ }
++ /* lex->unit.cleanup() is called outside, no need to call it here */
++ break;
++ case SQLCOM_SHOW_CREATE_EVENT:
++ res= Events::show_create_event(thd, lex->spname->m_db,
++ lex->spname->m_name);
++ break;
++ case SQLCOM_DROP_EVENT:
++ if (!(res= Events::drop_event(thd,
++ lex->spname->m_db, lex->spname->m_name,
++ lex->drop_if_exists)))
++ my_ok(thd);
++ break;
++#else
++ my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
++ break;
++#endif
++ case SQLCOM_CREATE_FUNCTION: // UDF function
++ {
++ if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
++ break;
++#ifdef HAVE_DLOPEN
++ if (!(res = mysql_create_function(thd, &lex->udf)))
++ my_ok(thd);
++#else
++ my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
++ res= TRUE;
++#endif
++ break;
++ }
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ case SQLCOM_CREATE_USER:
++ {
++ if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
++ check_global_access(thd,CREATE_USER_ACL))
++ break;
++ if (end_active_trans(thd))
++ goto error;
++ /* Conditionally writes to binlog */
++ if (!(res= mysql_create_user(thd, lex->users_list)))
++ my_ok(thd);
++ break;
++ }
++ case SQLCOM_DROP_USER:
++ {
++ if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
++ check_global_access(thd,CREATE_USER_ACL))
++ break;
++ if (end_active_trans(thd))
++ goto error;
++ /* Conditionally writes to binlog */
++ if (!(res= mysql_drop_user(thd, lex->users_list)))
++ my_ok(thd);
++ break;
++ }
++ case SQLCOM_RENAME_USER:
++ {
++ if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
++ check_global_access(thd,CREATE_USER_ACL))
++ break;
++ if (end_active_trans(thd))
++ goto error;
++ /* Conditionally writes to binlog */
++ if (!(res= mysql_rename_user(thd, lex->users_list)))
++ my_ok(thd);
++ break;
++ }
++ case SQLCOM_REVOKE_ALL:
++ {
++ if (end_active_trans(thd))
++ goto error;
++ if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
++ check_global_access(thd,CREATE_USER_ACL))
++ break;
++
++ /* Replicate current user as grantor */
++ thd->binlog_invoker();
++
++ /* Conditionally writes to binlog */
++ if (!(res = mysql_revoke_all(thd, lex->users_list)))
++ my_ok(thd);
++ break;
++ }
++ case SQLCOM_REVOKE:
++ case SQLCOM_GRANT:
++ {
++ if (end_active_trans(thd))
++ goto error;
++
++ if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
++ first_table ? first_table->db : select_lex->db,
++ first_table ? &first_table->grant.privilege : 0,
++ first_table ? 0 : 1, 0,
++ first_table ? (bool) first_table->schema_table :
++ select_lex->db ?
++ is_schema_db(select_lex->db) : 0))
++ goto error;
++
++ /* Replicate current user as grantor */
++ thd->binlog_invoker();
++
++ if (thd->security_ctx->user) // If not replication
++ {
++ LEX_USER *user, *tmp_user;
++
++ List_iterator <LEX_USER> user_list(lex->users_list);
++ while ((tmp_user= user_list++))
++ {
++ if (!(user= get_current_user(thd, tmp_user)))
++ goto error;
++ if (specialflag & SPECIAL_NO_RESOLVE &&
++ hostname_requires_resolving(user->host.str))
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARN_HOSTNAME_WONT_WORK,
++ ER(ER_WARN_HOSTNAME_WONT_WORK),
++ user->host.str);
++ // Are we trying to change a password of another user
++ DBUG_ASSERT(user->host.str != 0);
++ if (strcmp(thd->security_ctx->user, user->user.str) ||
++ my_strcasecmp(system_charset_info,
++ user->host.str, thd->security_ctx->host_or_ip))
++ {
++ // TODO: use check_change_password()
++ if (is_acl_user(user->host.str, user->user.str) &&
++ user->password.str &&
++ check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
++ {
++ my_message(ER_PASSWORD_NOT_ALLOWED,
++ ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
++ goto error;
++ }
++ }
++ }
++ }
++ if (first_table)
++ {
++ if (lex->type == TYPE_ENUM_PROCEDURE ||
++ lex->type == TYPE_ENUM_FUNCTION)
++ {
++ uint grants= lex->all_privileges
++ ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
++ : lex->grant;
++ if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
++ lex->type == TYPE_ENUM_PROCEDURE, 0))
++ goto error;
++ /* Conditionally writes to binlog */
++ res= mysql_routine_grant(thd, all_tables,
++ lex->type == TYPE_ENUM_PROCEDURE,
++ lex->users_list, grants,
++ lex->sql_command == SQLCOM_REVOKE, TRUE);
++ if (!res)
++ my_ok(thd);
++ }
++ else
++ {
++ if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
++ all_tables, 0, UINT_MAX, 0))
++ goto error;
++ /* Conditionally writes to binlog */
++ res= mysql_table_grant(thd, all_tables, lex->users_list,
++ lex->columns, lex->grant,
++ lex->sql_command == SQLCOM_REVOKE);
++ }
++ }
++ else
++ {
++ if (lex->columns.elements || lex->type)
++ {
++ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
++ MYF(0));
++ goto error;
++ }
++ else
++ /* Conditionally writes to binlog */
++ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
++ lex->sql_command == SQLCOM_REVOKE);
++ if (!res)
++ {
++ if (lex->sql_command == SQLCOM_GRANT)
++ {
++ List_iterator <LEX_USER> str_list(lex->users_list);
++ LEX_USER *user, *tmp_user;
++ while ((tmp_user=str_list++))
++ {
++ if (!(user= get_current_user(thd, tmp_user)))
++ goto error;
++ reset_mqh(user, 0);
++ }
++ }
++ }
++ }
++ break;
++ }
++#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
++ case SQLCOM_RESET:
++ /*
++ RESET commands are never written to the binary log, so we have to
++ initialize this variable because RESET shares the same code as FLUSH
++ */
++ lex->no_write_to_binlog= 1;
++ case SQLCOM_FLUSH:
++ {
++ int write_to_binlog;
++ if (check_global_access(thd,RELOAD_ACL))
++ goto error;
++
++ /*
++ reload_acl_and_cache() will tell us if we are allowed to write to the
++ binlog or not.
++ */
++ if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
++ {
++ /*
++ We WANT to write and we CAN write.
++ ! we write after unlocking the table.
++ */
++ /*
++ Presumably, RESET and binlog writing doesn't require synchronization
++ */
++
++ if (write_to_binlog > 0) // we should write
++ {
++ if (!lex->no_write_to_binlog)
++ res= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
++ } else if (write_to_binlog < 0)
++ {
++ /*
++ We should not write, but rather report error because
++ reload_acl_and_cache binlog interactions failed
++ */
++ res= 1;
++ }
++
++ if (!res)
++ my_ok(thd);
++ }
++
++ break;
++ }
++ case SQLCOM_KILL:
++ {
++ Item *it= (Item *)lex->value_list.head();
++
++ if (lex->table_or_sp_used())
++ {
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
++ "function calls as part of this statement");
++ break;
++ }
++
++ if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
++ {
++ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
++ MYF(0));
++ goto error;
++ }
++ sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
++ break;
++ }
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ case SQLCOM_SHOW_GRANTS:
++ {
++ LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
++ if (!grant_user)
++ goto error;
++ if ((thd->security_ctx->priv_user &&
++ !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
++ !check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
++ {
++ res = mysql_show_grants(thd, grant_user);
++ }
++ break;
++ }
++#endif
++ case SQLCOM_HA_OPEN:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))
++ goto error;
++ res= mysql_ha_open(thd, first_table, 0);
++ break;
++ case SQLCOM_HA_CLOSE:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ res= mysql_ha_close(thd, first_table);
++ break;
++ case SQLCOM_HA_READ:
++ DBUG_ASSERT(first_table == all_tables && first_table != 0);
++ /*
++ There is no need to check for table permissions here, because
++ if a user has no permissions to read a table, he won't be
++ able to open it (with SQLCOM_HA_OPEN) in the first place.
++ */
++ unit->set_limit(select_lex);
++ res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
++ lex->insert_list, lex->ha_rkey_mode, select_lex->where,
++ unit->select_limit_cnt, unit->offset_limit_cnt);
++ break;
++
++ case SQLCOM_BEGIN:
++ if (thd->transaction.xid_state.xa_state != XA_NOTR)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ if (begin_trans(thd))
++ goto error;
++ if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
++ {
++ if (ha_start_consistent_snapshot(thd))
++ goto error;
++ }
++ my_ok(thd);
++ break;
++ case SQLCOM_COMMIT:
++ if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
++ lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
++ goto error;
++ my_ok(thd);
++ break;
++ case SQLCOM_ROLLBACK:
++ if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
++ lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
++ goto error;
++ my_ok(thd);
++ break;
++ case SQLCOM_RELEASE_SAVEPOINT:
++ {
++ SAVEPOINT *sv;
++ for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
++ {
++ if (my_strnncoll(system_charset_info,
++ (uchar *)lex->ident.str, lex->ident.length,
++ (uchar *)sv->name, sv->length) == 0)
++ break;
++ }
++ if (sv)
++ {
++ if (ha_release_savepoint(thd, sv))
++ res= TRUE; // cannot happen
++ else
++ my_ok(thd);
++ thd->transaction.savepoints=sv->prev;
++ }
++ else
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
++ break;
++ }
++ case SQLCOM_ROLLBACK_TO_SAVEPOINT:
++ {
++ SAVEPOINT *sv;
++ for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
++ {
++ if (my_strnncoll(system_charset_info,
++ (uchar *)lex->ident.str, lex->ident.length,
++ (uchar *)sv->name, sv->length) == 0)
++ break;
++ }
++ if (sv)
++ {
++ if (ha_rollback_to_savepoint(thd, sv))
++ res= TRUE; // cannot happen
++ else
++ {
++ if (((thd->options & OPTION_KEEP_LOG) ||
++ thd->transaction.all.modified_non_trans_table) &&
++ !thd->slave_thread)
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_WARNING_NOT_COMPLETE_ROLLBACK,
++ ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
++ my_ok(thd);
++ }
++ thd->transaction.savepoints=sv;
++ }
++ else
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
++ break;
++ }
++ case SQLCOM_SAVEPOINT:
++ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
++ thd->in_sub_stmt) || !opt_using_transactions)
++ my_ok(thd);
++ else
++ {
++ SAVEPOINT **sv, *newsv;
++ for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
++ {
++ if (my_strnncoll(system_charset_info,
++ (uchar *)lex->ident.str, lex->ident.length,
++ (uchar *)(*sv)->name, (*sv)->length) == 0)
++ break;
++ }
++ if (*sv) /* old savepoint of the same name exists */
++ {
++ newsv=*sv;
++ ha_release_savepoint(thd, *sv); // it cannot fail
++ *sv=(*sv)->prev;
++ }
++ else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
++ savepoint_alloc_size)) == 0)
++ {
++ my_error(ER_OUT_OF_RESOURCES, MYF(0));
++ break;
++ }
++ newsv->name=strmake_root(&thd->transaction.mem_root,
++ lex->ident.str, lex->ident.length);
++ newsv->length=lex->ident.length;
++ /*
++ if we'll get an error here, don't add new savepoint to the list.
++ we'll lose a little bit of memory in transaction mem_root, but it'll
++ be free'd when transaction ends anyway
++ */
++ if (ha_savepoint(thd, newsv))
++ res= TRUE;
++ else
++ {
++ newsv->prev=thd->transaction.savepoints;
++ thd->transaction.savepoints=newsv;
++ my_ok(thd);
++ }
++ }
++ break;
++ case SQLCOM_CREATE_PROCEDURE:
++ case SQLCOM_CREATE_SPFUNCTION:
++ {
++ uint namelen;
++ char *name;
++ int sp_result= SP_INTERNAL_ERROR;
++
++ DBUG_ASSERT(lex->sphead != 0);
++ DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
++ /*
++ Verify that the database name is allowed, optionally
++ lowercase it.
++ */
++ if (check_db_name(&lex->sphead->m_db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
++ goto create_sp_error;
++ }
++
++ /*
++ Check that a database directory with this name
++ exists. Design note: This won't work on virtual databases
++ like information_schema.
++ */
++ if (check_db_dir_existence(lex->sphead->m_db.str))
++ {
++ my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
++ goto create_sp_error;
++ }
++
++ if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
++ is_schema_db(lex->sphead->m_db.str,
++ lex->sphead->m_db.length)))
++ goto create_sp_error;
++
++ if (end_active_trans(thd))
++ goto create_sp_error;
++
++ name= lex->sphead->name(&namelen);
++#ifdef HAVE_DLOPEN
++ if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
++ {
++ udf_func *udf = find_udf(name, namelen);
++
++ if (udf)
++ {
++ my_error(ER_UDF_EXISTS, MYF(0), name);
++ goto create_sp_error;
++ }
++ }
++#endif
++
++ if (sp_process_definer(thd))
++ goto create_sp_error;
++
++ res= (sp_result= lex->sphead->create(thd));
++ switch (sp_result) {
++ case SP_OK: {
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ /* only add privileges if really neccessary */
++
++ Security_context security_context;
++ bool restore_backup_context= false;
++ Security_context *backup= NULL;
++ LEX_USER *definer= thd->lex->definer;
++ /*
++ Check if the definer exists on slave,
++ then use definer privilege to insert routine privileges to mysql.procs_priv.
++
++ For current user of SQL thread has GLOBAL_ACL privilege,
++ which doesn't any check routine privileges,
++ so no routine privilege record will insert into mysql.procs_priv.
++ */
++ if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
++ {
++ security_context.change_security_context(thd,
++ &thd->lex->definer->user,
++ &thd->lex->definer->host,
++ &thd->lex->sphead->m_db,
++ &backup);
++ restore_backup_context= true;
++ }
++
++ if (sp_automatic_privileges && !opt_noacl &&
++ check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
++ lex->sphead->m_db.str, name,
++ lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
++ {
++ if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
++ lex->sql_command == SQLCOM_CREATE_PROCEDURE))
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_PROC_AUTO_GRANT_FAIL,
++ ER(ER_PROC_AUTO_GRANT_FAIL));
++ }
++
++ /*
++ Restore current user with GLOBAL_ACL privilege of SQL thread
++ */
++ if (restore_backup_context)
++ {
++ DBUG_ASSERT(thd->slave_thread == 1);
++ thd->security_ctx->restore_security_context(thd, backup);
++ }
++
++#endif
++ break;
++ }
++ case SP_WRITE_ROW_FAILED:
++ my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
++ break;
++ case SP_BAD_IDENTIFIER:
++ my_error(ER_TOO_LONG_IDENT, MYF(0), name);
++ break;
++ case SP_BODY_TOO_LONG:
++ my_error(ER_TOO_LONG_BODY, MYF(0), name);
++ break;
++ case SP_FLD_STORE_FAILED:
++ my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
++ break;
++ default:
++ my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
++ break;
++ } /* end switch */
++
++ /*
++ Capture all errors within this CASE and
++ clean up the environment.
++ */
++create_sp_error:
++ if (sp_result != SP_OK )
++ goto error;
++ my_ok(thd);
++ break; /* break super switch */
++ } /* end case group bracket */
++ case SQLCOM_CALL:
++ {
++ sp_head *sp;
++
++ /*
++ This will cache all SP and SF and open and lock all tables
++ required for execution.
++ */
++ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
++ open_and_lock_tables(thd, all_tables))
++ goto error;
++
++ /*
++ By this moment all needed SPs should be in cache so no need to look
++ into DB.
++ */
++ if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
++ &thd->sp_proc_cache, TRUE)))
++ {
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
++ lex->spname->m_qname.str);
++ goto error;
++ }
++ else
++ {
++ ha_rows select_limit;
++ /* bits that should be cleared in thd->server_status */
++ uint bits_to_be_cleared= 0;
++ /*
++ Check that the stored procedure doesn't contain Dynamic SQL
++ and doesn't return result sets: such stored procedures can't
++ be called from a function or trigger.
++ */
++ if (thd->in_sub_stmt)
++ {
++ const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
++ "trigger" : "function");
++ if (sp->is_not_allowed_in_function(where))
++ goto error;
++ }
++
++ if (sp->m_flags & sp_head::MULTI_RESULTS)
++ {
++ if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
++ {
++ /*
++ The client does not support multiple result sets being sent
++ back
++ */
++ my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
++ goto error;
++ }
++ /*
++ If SERVER_MORE_RESULTS_EXISTS is not set,
++ then remember that it should be cleared
++ */
++ bits_to_be_cleared= (~thd->server_status &
++ SERVER_MORE_RESULTS_EXISTS);
++ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
++ }
++
++ if (check_routine_access(thd, EXECUTE_ACL,
++ sp->m_db.str, sp->m_name.str, TRUE, FALSE))
++ {
++ goto error;
++ }
++ select_limit= thd->variables.select_limit;
++ thd->variables.select_limit= HA_POS_ERROR;
++
++ /*
++ We never write CALL statements into binlog:
++ - If the mode is non-prelocked, each statement will be logged
++ separately.
++ - If the mode is prelocked, the invoking statement will care
++ about writing into binlog.
++ So just execute the statement.
++ */
++ res= sp->execute_procedure(thd, &lex->value_list);
++ /*
++ If warnings have been cleared, we have to clear total_warn_count
++ too, otherwise the clients get confused.
++ */
++ if (thd->warn_list.is_empty())
++ thd->total_warn_count= 0;
++
++ thd->variables.select_limit= select_limit;
++
++ thd->server_status&= ~bits_to_be_cleared;
++
++ if (!res)
++ my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
++ thd->row_count_func));
++ else
++ {
++ DBUG_ASSERT(thd->is_error() || thd->killed);
++ goto error; // Substatement should already have sent error
++ }
++ }
++ break;
++ }
++ case SQLCOM_ALTER_PROCEDURE:
++ case SQLCOM_ALTER_FUNCTION:
++ {
++ int sp_result;
++ sp_head *sp;
++ st_sp_chistics chistics;
++
++ memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
++ if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
++ sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
++ &thd->sp_proc_cache, FALSE);
++ else
++ sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
++ &thd->sp_func_cache, FALSE);
++ mysql_reset_errors(thd, 0);
++ if (! sp)
++ {
++ if (lex->spname->m_db.str)
++ sp_result= SP_KEY_NOT_FOUND;
++ else
++ {
++ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
++ goto error;
++ }
++ }
++ else
++ {
++ if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
++ sp->m_name.str,
++ lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
++ goto error;
++
++ if (end_active_trans(thd))
++ goto error;
++ memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
++ if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
++ !trust_function_creators && mysql_bin_log.is_open() &&
++ !sp->m_chistics->detistic &&
++ (chistics.daccess == SP_CONTAINS_SQL ||
++ chistics.daccess == SP_MODIFIES_SQL_DATA))
++ {
++ my_message(ER_BINLOG_UNSAFE_ROUTINE,
++ ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
++ sp_result= SP_INTERNAL_ERROR;
++ }
++ else
++ {
++ /*
++ Note that if you implement the capability of ALTER FUNCTION to
++ alter the body of the function, this command should be made to
++ follow the restrictions that log-bin-trust-function-creators=0
++ already puts on CREATE FUNCTION.
++ */
++ /* Conditionally writes to binlog */
++
++ int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
++ TYPE_ENUM_PROCEDURE :
++ TYPE_ENUM_FUNCTION;
++
++ sp_result= sp_update_routine(thd,
++ type,
++ lex->spname,
++ &lex->sp_chistics);
++ }
++ }
++ switch (sp_result)
++ {
++ case SP_OK:
++ my_ok(thd);
++ break;
++ case SP_KEY_NOT_FOUND:
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_qname.str);
++ goto error;
++ default:
++ my_error(ER_SP_CANT_ALTER, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_qname.str);
++ goto error;
++ }
++ break;
++ }
++ case SQLCOM_DROP_PROCEDURE:
++ case SQLCOM_DROP_FUNCTION:
++ {
++ int sp_result;
++ int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
++ TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
++
++ sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
++ mysql_reset_errors(thd, 0);
++ if (sp_result == SP_OK)
++ {
++ char *db= lex->spname->m_db.str;
++ char *name= lex->spname->m_name.str;
++
++ if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
++ lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
++ goto error;
++
++ if (end_active_trans(thd))
++ goto error;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (sp_automatic_privileges && !opt_noacl &&
++ sp_revoke_privileges(thd, db, name,
++ lex->sql_command == SQLCOM_DROP_PROCEDURE))
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_PROC_AUTO_REVOKE_FAIL,
++ ER(ER_PROC_AUTO_REVOKE_FAIL));
++ }
++#endif
++ /* Conditionally writes to binlog */
++
++ int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ?
++ TYPE_ENUM_PROCEDURE :
++ TYPE_ENUM_FUNCTION;
++
++ sp_result= sp_drop_routine(thd, type, lex->spname);
++ }
++ else
++ {
++#ifdef HAVE_DLOPEN
++ if (lex->sql_command == SQLCOM_DROP_FUNCTION)
++ {
++ udf_func *udf = find_udf(lex->spname->m_name.str,
++ lex->spname->m_name.length);
++ if (udf)
++ {
++ if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
++ goto error;
++
++ if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
++ {
++ my_ok(thd);
++ break;
++ }
++ }
++ }
++#endif
++ if (lex->spname->m_db.str)
++ sp_result= SP_KEY_NOT_FOUND;
++ else
++ {
++ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
++ goto error;
++ }
++ }
++ res= sp_result;
++ switch (sp_result) {
++ case SP_OK:
++ my_ok(thd);
++ break;
++ case SP_KEY_NOT_FOUND:
++ if (lex->drop_if_exists)
++ {
++ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
++ SP_COM_STRING(lex), lex->spname->m_name.str);
++ if (!res)
++ my_ok(thd);
++ break;
++ }
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_qname.str);
++ goto error;
++ default:
++ my_error(ER_SP_DROP_FAILED, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_qname.str);
++ goto error;
++ }
++ break;
++ }
++ case SQLCOM_SHOW_CREATE_PROC:
++ {
++ if (sp_show_create_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname))
++ {
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_name.str);
++ goto error;
++ }
++ break;
++ }
++ case SQLCOM_SHOW_CREATE_FUNC:
++ {
++ if (sp_show_create_routine(thd, TYPE_ENUM_FUNCTION, lex->spname))
++ {
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_name.str);
++ goto error;
++ }
++ break;
++ }
++#ifndef DBUG_OFF
++ case SQLCOM_SHOW_PROC_CODE:
++ case SQLCOM_SHOW_FUNC_CODE:
++ {
++ sp_head *sp;
++
++ if (lex->sql_command == SQLCOM_SHOW_PROC_CODE)
++ sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
++ &thd->sp_proc_cache, FALSE);
++ else
++ sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
++ &thd->sp_func_cache, FALSE);
++ if (!sp || sp->show_routine_code(thd))
++ {
++ /* We don't distinguish between errors for now */
++ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
++ SP_COM_STRING(lex), lex->spname->m_name.str);
++ goto error;
++ }
++ break;
++ }
++#endif // ifndef DBUG_OFF
++ case SQLCOM_SHOW_CREATE_TRIGGER:
++ {
++ if (lex->spname->m_name.length > NAME_LEN)
++ {
++ my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
++ goto error;
++ }
++
++ if (show_create_trigger(thd, lex->spname))
++ goto error; /* Error has been already logged. */
++
++ break;
++ }
++ case SQLCOM_CREATE_VIEW:
++ {
++ /*
++ Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
++ as specified through the thd->lex->create_view_mode flag.
++ */
++ if (end_active_trans(thd))
++ goto error;
++
++ res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
++ break;
++ }
++ case SQLCOM_DROP_VIEW:
++ {
++ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) ||
++ end_active_trans(thd))
++ goto error;
++ /* Conditionally writes to binlog. */
++ res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
++ break;
++ }
++ case SQLCOM_CREATE_TRIGGER:
++ {
++ if (end_active_trans(thd))
++ goto error;
++
++ /* Conditionally writes to binlog. */
++ res= mysql_create_or_drop_trigger(thd, all_tables, 1);
++
++ break;
++ }
++ case SQLCOM_DROP_TRIGGER:
++ {
++ if (end_active_trans(thd))
++ goto error;
++
++ /* Conditionally writes to binlog. */
++ res= mysql_create_or_drop_trigger(thd, all_tables, 0);
++ break;
++ }
++ case SQLCOM_XA_START:
++ if (thd->transaction.xid_state.xa_state == XA_IDLE &&
++ thd->lex->xa_opt == XA_RESUME)
++ {
++ if (! thd->transaction.xid_state.xid.eq(thd->lex->xid))
++ {
++ my_error(ER_XAER_NOTA, MYF(0));
++ break;
++ }
++ thd->transaction.xid_state.xa_state= XA_ACTIVE;
++ my_ok(thd);
++ break;
++ }
++ if (thd->lex->xa_opt != XA_NONE)
++ { // JOIN is not supported yet. TODO
++ my_error(ER_XAER_INVAL, MYF(0));
++ break;
++ }
++ if (thd->transaction.xid_state.xa_state != XA_NOTR)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ if (thd->active_transaction() || thd->locked_tables)
++ {
++ my_error(ER_XAER_OUTSIDE, MYF(0));
++ break;
++ }
++ DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
++ thd->transaction.xid_state.xa_state= XA_ACTIVE;
++ thd->transaction.xid_state.rm_error= 0;
++ thd->transaction.xid_state.xid.set(thd->lex->xid);
++ if (xid_cache_insert(&thd->transaction.xid_state))
++ {
++ thd->transaction.xid_state.xa_state= XA_NOTR;
++ thd->transaction.xid_state.xid.null();
++ break;
++ }
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
++ thd->server_status|= SERVER_STATUS_IN_TRANS;
++ my_ok(thd);
++ break;
++ case SQLCOM_XA_END:
++ /* fake it */
++ if (thd->lex->xa_opt != XA_NONE)
++ { // SUSPEND and FOR MIGRATE are not supported yet. TODO
++ my_error(ER_XAER_INVAL, MYF(0));
++ break;
++ }
++ if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
++ {
++ my_error(ER_XAER_NOTA, MYF(0));
++ break;
++ }
++ if (xa_trans_rolled_back(&thd->transaction.xid_state))
++ break;
++ thd->transaction.xid_state.xa_state=XA_IDLE;
++ my_ok(thd);
++ break;
++ case SQLCOM_XA_PREPARE:
++ if (thd->transaction.xid_state.xa_state != XA_IDLE)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
++ {
++ my_error(ER_XAER_NOTA, MYF(0));
++ break;
++ }
++ if (ha_prepare(thd))
++ {
++ my_error(ER_XA_RBROLLBACK, MYF(0));
++ xid_cache_delete(&thd->transaction.xid_state);
++ thd->transaction.xid_state.xa_state=XA_NOTR;
++ break;
++ }
++ thd->transaction.xid_state.xa_state=XA_PREPARED;
++ my_ok(thd);
++ break;
++ case SQLCOM_XA_COMMIT:
++ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
++ {
++ /*
++ xid_state.in_thd is always true beside of xa recovery
++ procedure. Note, that there is no race condition here
++ between xid_cache_search and xid_cache_delete, since we're always
++ deleting our own XID (thd->lex->xid == thd->transaction.xid_state.xid).
++ The only case when thd->lex->xid != thd->transaction.xid_state.xid
++ and xid_state->in_thd == 0 is in ha_recover() functionality,
++ which is called before starting client connections, and thus is
++ always single-threaded.
++ */
++ XID_STATE *xs=xid_cache_search(thd->lex->xid);
++ if (!xs || xs->in_thd)
++ my_error(ER_XAER_NOTA, MYF(0));
++ else if (xa_trans_rolled_back(xs))
++ {
++ ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
++ xid_cache_delete(xs);
++ break;
++ }
++ else
++ {
++ ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
++ xid_cache_delete(xs);
++ my_ok(thd);
++ }
++ break;
++ }
++ if (xa_trans_rolled_back(&thd->transaction.xid_state))
++ {
++ xa_trans_rollback(thd);
++ break;
++ }
++ if (thd->transaction.xid_state.xa_state == XA_IDLE &&
++ thd->lex->xa_opt == XA_ONE_PHASE)
++ {
++ int r;
++ if ((r= ha_commit(thd)))
++ my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
++ else
++ my_ok(thd);
++ }
++ else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
++ thd->lex->xa_opt == XA_NONE)
++ {
++ if (wait_if_global_read_lock(thd, 0, 0))
++ {
++ ha_rollback(thd);
++ my_error(ER_XAER_RMERR, MYF(0));
++ }
++ else
++ {
++ if (ha_commit_one_phase(thd, 1))
++ my_error(ER_XAER_RMERR, MYF(0));
++ else
++ my_ok(thd);
++ start_waiting_global_read_lock(thd);
++ }
++ }
++ else
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
++ xid_cache_delete(&thd->transaction.xid_state);
++ thd->transaction.xid_state.xa_state=XA_NOTR;
++ break;
++ case SQLCOM_XA_ROLLBACK:
++ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
++ {
++ XID_STATE *xs=xid_cache_search(thd->lex->xid);
++ if (!xs || xs->in_thd)
++ my_error(ER_XAER_NOTA, MYF(0));
++ else
++ {
++ bool ok= !xa_trans_rolled_back(xs);
++ ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
++ xid_cache_delete(xs);
++ if (ok)
++ my_ok(thd);
++ }
++ break;
++ }
++ if (thd->transaction.xid_state.xa_state != XA_IDLE &&
++ thd->transaction.xid_state.xa_state != XA_PREPARED &&
++ thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY)
++ {
++ my_error(ER_XAER_RMFAIL, MYF(0),
++ xa_state_names[thd->transaction.xid_state.xa_state]);
++ break;
++ }
++ if (xa_trans_rollback(thd))
++ my_error(ER_XAER_RMERR, MYF(0));
++ else
++ my_ok(thd);
++ break;
++ case SQLCOM_XA_RECOVER:
++ res= mysql_xa_recover(thd);
++ break;
++ case SQLCOM_ALTER_TABLESPACE:
++ if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0,
++ thd->db ? is_schema_db(thd->db, thd->db_length) : 0))
++ break;
++ if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
++ my_ok(thd);
++ break;
++ case SQLCOM_INSTALL_PLUGIN:
++ if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
++ &thd->lex->ident)))
++ my_ok(thd);
++ break;
++ case SQLCOM_UNINSTALL_PLUGIN:
++ if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
++ my_ok(thd);
++ break;
++ case SQLCOM_BINLOG_BASE64_EVENT:
++ {
++#ifndef EMBEDDED_LIBRARY
++ mysql_client_binlog_statement(thd);
++#else /* EMBEDDED_LIBRARY */
++ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
++#endif /* EMBEDDED_LIBRARY */
++ break;
++ }
++ case SQLCOM_CREATE_SERVER:
++ {
++ int error;
++ LEX *lex= thd->lex;
++ DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER"));
++
++ if (check_global_access(thd, SUPER_ACL))
++ break;
++
++ if ((error= create_server(thd, &lex->server_options)))
++ {
++ DBUG_PRINT("info", ("problem creating server <%s>",
++ lex->server_options.server_name));
++ my_error(error, MYF(0), lex->server_options.server_name);
++ break;
++ }
++ my_ok(thd, 1);
++ break;
++ }
++ case SQLCOM_ALTER_SERVER:
++ {
++ int error;
++ LEX *lex= thd->lex;
++ DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER"));
++
++ if (check_global_access(thd, SUPER_ACL))
++ break;
++
++ if ((error= alter_server(thd, &lex->server_options)))
++ {
++ DBUG_PRINT("info", ("problem altering server <%s>",
++ lex->server_options.server_name));
++ my_error(error, MYF(0), lex->server_options.server_name);
++ break;
++ }
++ my_ok(thd, 1);
++ break;
++ }
++ case SQLCOM_DROP_SERVER:
++ {
++ int err_code;
++ LEX *lex= thd->lex;
++ DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER"));
++
++ if (check_global_access(thd, SUPER_ACL))
++ break;
++
++ if ((err_code= drop_server(thd, &lex->server_options)))
++ {
++ if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
++ {
++ DBUG_PRINT("info", ("problem dropping server %s",
++ lex->server_options.server_name));
++ my_error(err_code, MYF(0), lex->server_options.server_name);
++ }
++ else
++ {
++ my_ok(thd, 0);
++ }
++ break;
++ }
++ my_ok(thd, 1);
++ break;
++ }
++ default:
++#ifndef EMBEDDED_LIBRARY
++ DBUG_ASSERT(0); /* Impossible */
++#endif
++ my_ok(thd);
++ break;
++ }
++ thd_proc_info(thd, "query end");
++
++ /*
++ Binlog-related cleanup:
++ Reset system variables temporarily modified by SET ONE SHOT.
++
++ Exception: If this is a SET, do nothing. This is to allow
++ mysqlbinlog to print many SET commands (in this case we want the
++ charset temp setting to live until the real query). This is also
++ needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
++ immediately.
++ */
++ if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
++ reset_one_shot_variables(thd);
++
++ /*
++ The return value for ROW_COUNT() is "implementation dependent" if the
++ statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
++ wants. We also keep the last value in case of SQLCOM_CALL or
++ SQLCOM_EXECUTE.
++ */
++ if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
++ thd->row_count_func= -1;
++
++ goto finish;
++
++error:
++ res= TRUE;
++
++finish:
++ if (need_start_waiting)
++ {
++ /*
++ Release the protection against the global read lock and wake
++ everyone, who might want to set a global read lock.
++ */
++ start_waiting_global_read_lock(thd);
++ }
++ DBUG_RETURN(res || thd->is_error());
++}
++
++
++static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
++{
++ LEX *lex= thd->lex;
++ select_result *result=lex->result;
++ bool res;
++ /* assign global limit variable if limit is not given */
++ {
++ SELECT_LEX *param= lex->unit.global_parameters;
++ if (!param->explicit_limit)
++ param->select_limit=
++ new Item_int((ulonglong) thd->variables.select_limit);
++ }
++ if (!(res= open_and_lock_tables(thd, all_tables)))
++ {
++ if (lex->describe)
++ {
++ /*
++ We always use select_send for EXPLAIN, even if it's an EXPLAIN
++ for SELECT ... INTO OUTFILE: a user application should be able
++ to prepend EXPLAIN to any query and receive output for it,
++ even if the query itself redirects the output.
++ */
++ if (!(result= new select_send()))
++ return 1; /* purecov: inspected */
++ thd->send_explain_fields(result);
++ res= mysql_explain_union(thd, &thd->lex->unit, result);
++ if (lex->describe & DESCRIBE_EXTENDED)
++ {
++ char buff[1024];
++ String str(buff,(uint32) sizeof(buff), system_charset_info);
++ str.length(0);
++ thd->lex->unit.print(&str, QT_ORDINARY);
++ str.append('\0');
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_YES, str.ptr());
++ }
++ if (res)
++ result->abort();
++ else
++ result->send_eof();
++ delete result;
++ }
++ else
++ {
++ if (!result && !(result= new select_send()))
++ return 1; /* purecov: inspected */
++ query_cache_store_query(thd, all_tables);
++ res= handle_select(thd, lex, result, 0);
++ if (result != lex->result)
++ delete result;
++ }
++ }
++ return res;
++}
++
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++/**
++ Check grants for commands which work only with one table.
++
++ @param thd Thread handler
++ @param privilege requested privilege
++ @param all_tables global table list of query
++ @param no_errors FALSE/TRUE - report/don't report error to
++ the client (using my_error() call).
++
++ @retval
++ 0 OK
++ @retval
++ 1 access denied, error is sent to client
++*/
++
++bool check_single_table_access(THD *thd, ulong privilege,
++ TABLE_LIST *all_tables, bool no_errors)
++{
++ Security_context * backup_ctx= thd->security_ctx;
++
++ /* we need to switch to the saved context (if any) */
++ if (all_tables->security_ctx)
++ thd->security_ctx= all_tables->security_ctx;
++
++ const char *db_name;
++ if ((all_tables->view || all_tables->field_translation) &&
++ !all_tables->schema_table)
++ db_name= all_tables->view_db.str;
++ else
++ db_name= all_tables->db;
++
++ if (check_access(thd, privilege, db_name,
++ &all_tables->grant.privilege, 0, no_errors,
++ test(all_tables->schema_table)))
++ goto deny;
++
++ /* Show only 1 table for check_grant */
++ if (!(all_tables->belong_to_view &&
++ (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
++ check_grant(thd, privilege, all_tables, 0, 1, no_errors))
++ goto deny;
++
++ thd->security_ctx= backup_ctx;
++ return 0;
++
++deny:
++ thd->security_ctx= backup_ctx;
++ return 1;
++}
++
++/**
++ Check grants for commands which work only with one table and all other
++ tables belonging to subselects or implicitly opened tables.
++
++ @param thd Thread handler
++ @param privilege requested privilege
++ @param all_tables global table list of query
++
++ @retval
++ 0 OK
++ @retval
++ 1 access denied, error is sent to client
++*/
++
++bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
++{
++ if (check_single_table_access (thd,privilege,all_tables, FALSE))
++ return 1;
++
++ /* Check rights on tables of subselects and implictly opened tables */
++ TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
++ if ((subselects_tables= all_tables->next_global))
++ {
++ /*
++ Access rights asked for the first table of a view should be the same
++ as for the view
++ */
++ if (view && subselects_tables->belong_to_view == view)
++ {
++ if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
++ return 1;
++ subselects_tables= subselects_tables->next_global;
++ }
++ if (subselects_tables &&
++ (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE)))
++ return 1;
++ }
++ return 0;
++}
++
++
++/**
++ Get the user (global) and database privileges for all used tables.
++
++ @param save_priv In this we store global and db level grants for the
++ table. Note that we don't store db level grants if the
++ global grants is enough to satisfy the request and the
++ global grants contains a SELECT grant.
++
++ @note
++ The idea of EXTRA_ACL is that one will be granted access to the table if
++ one has the asked privilege on any column combination of the table; For
++ example to be able to check a table one needs to have SELECT privilege on
++ any column of the table.
++
++ @retval
++ 0 ok
++ @retval
++ 1 If we can't get the privileges and we don't use table/column
++ grants.
++*/
++bool
++check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
++ bool dont_check_global_grants, bool no_errors, bool schema_db)
++{
++ Security_context *sctx= thd->security_ctx;
++ ulong db_access;
++ /*
++ GRANT command:
++ In case of database level grant the database name may be a pattern,
++ in case of table|column level grant the database name can not be a pattern.
++ We use 'dont_check_global_grants' as a flag to determine
++ if it's database level grant command
++ (see SQLCOM_GRANT case, mysql_execute_command() function) and
++ set db_is_pattern according to 'dont_check_global_grants' value.
++ */
++ bool db_is_pattern= (test(want_access & GRANT_ACL) &&
++ dont_check_global_grants);
++ ulong dummy;
++ DBUG_ENTER("check_access");
++ DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
++ db ? db : "", want_access, sctx->master_access));
++ if (save_priv)
++ *save_priv=0;
++ else
++ save_priv= &dummy;
++
++ thd_proc_info(thd, "checking permissions");
++ if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
++ {
++ DBUG_PRINT("error",("No database"));
++ if (!no_errors)
++ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
++ MYF(0)); /* purecov: tested */
++ DBUG_RETURN(TRUE); /* purecov: tested */
++ }
++
++ if (schema_db)
++ {
++ if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) ||
++ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
++ {
++ if (!no_errors)
++ {
++ const char *db_name= db ? db : thd->db;
++ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
++ sctx->priv_user, sctx->priv_host, db_name);
++ }
++ DBUG_RETURN(TRUE);
++ }
++ else
++ {
++ *save_priv= SELECT_ACL;
++ DBUG_RETURN(FALSE);
++ }
++ }
++
++ if ((sctx->master_access & want_access) == want_access)
++ {
++ /*
++ If we don't have a global SELECT privilege, we have to get the database
++ specific access rights to be able to handle queries of type
++ UPDATE t1 SET a=1 WHERE b > 0
++ */
++ db_access= sctx->db_access;
++ if (!(sctx->master_access & SELECT_ACL) &&
++ (db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
++ db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
++ db_is_pattern);
++ *save_priv=sctx->master_access | db_access;
++ DBUG_RETURN(FALSE);
++ }
++ if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
++ (! db && dont_check_global_grants))
++ { // We can never grant this
++ DBUG_PRINT("error",("No possible access"));
++ if (!no_errors)
++ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
++ sctx->priv_user,
++ sctx->priv_host,
++ (thd->password ?
++ ER(ER_YES) :
++ ER(ER_NO))); /* purecov: tested */
++ DBUG_RETURN(TRUE); /* purecov: tested */
++ }
++
++ if (db == any_db)
++ DBUG_RETURN(FALSE); // Allow select on anything
++
++ if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
++ db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
++ db_is_pattern);
++ else
++ db_access= sctx->db_access;
++ DBUG_PRINT("info",("db_access: %lu", db_access));
++ /* Remove SHOW attribute and access rights we already have */
++ want_access &= ~(sctx->master_access | EXTRA_ACL);
++ DBUG_PRINT("info",("db_access: %lu want_access: %lu",
++ db_access, want_access));
++ db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
++
++ if (db_access == want_access ||
++ (!dont_check_global_grants &&
++ !(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS))))
++ DBUG_RETURN(FALSE); /* Ok */
++
++ DBUG_PRINT("error",("Access denied"));
++ if (!no_errors)
++ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
++ sctx->priv_user, sctx->priv_host,
++ (db ? db : (thd->db ?
++ thd->db :
++ "unknown"))); /* purecov: tested */
++ DBUG_RETURN(TRUE); /* purecov: tested */
++}
++
++
++static bool check_show_access(THD *thd, TABLE_LIST *table)
++{
++ switch (get_schema_table_idx(table->schema_table)) {
++ case SCH_SCHEMATA:
++ return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
++ check_global_access(thd, SHOW_DB_ACL);
++
++ case SCH_TABLE_NAMES:
++ case SCH_TABLES:
++ case SCH_VIEWS:
++ case SCH_TRIGGERS:
++ case SCH_EVENTS:
++ {
++ const char *dst_db_name= table->schema_select_lex->db;
++
++ DBUG_ASSERT(dst_db_name);
++
++ if (check_access(thd, SELECT_ACL, dst_db_name,
++ &thd->col_access, FALSE, FALSE,
++ is_schema_db(dst_db_name)))
++ return TRUE;
++
++ if (!thd->col_access && check_grant_db(thd, dst_db_name))
++ {
++ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
++ thd->security_ctx->priv_user,
++ thd->security_ctx->priv_host,
++ dst_db_name);
++ return TRUE;
++ }
++
++ return FALSE;
++ }
++
++ case SCH_COLUMNS:
++ case SCH_STATISTICS:
++ {
++ TABLE_LIST *dst_table;
++ dst_table= table->schema_select_lex->table_list.first;
++
++ DBUG_ASSERT(dst_table);
++
++ if (check_access(thd, SELECT_ACL | EXTRA_ACL,
++ dst_table->db,
++ &dst_table->grant.privilege,
++ FALSE, FALSE,
++ test(dst_table->schema_table)))
++ return FALSE;
++
++ return (check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE));
++ }
++ default:
++ break;
++ }
++
++ return FALSE;
++}
++
++
++/**
++ Check the privilege for all used tables.
++
++ @param thd Thread context
++ @param want_access Privileges requested
++ @param tables List of tables to be checked
++ @param number Check at most this number of tables.
++ @param no_errors FALSE/TRUE - report/don't report error to
++ the client (using my_error() call).
++
++ @note
++ Table privileges are cached in the table list for GRANT checking.
++ This functions assumes that table list used and
++ thd->lex->query_tables_own_last value correspond to each other
++ (the latter should be either 0 or point to next_global member
++ of one of elements of this table list).
++
++ @retval FALSE OK
++ @retval TRUE Access denied
++*/
++
++bool
++check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
++ uint number, bool no_errors)
++{
++ TABLE_LIST *org_tables= tables;
++ TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
++ uint i= 0;
++ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
++ /*
++ The check that first_not_own_table is not reached is for the case when
++ the given table list refers to the list for prelocking (contains tables
++ of other queries). For simple queries first_not_own_table is 0.
++ */
++ for (; i < number && tables != first_not_own_table;
++ tables= tables->next_global, i++)
++ {
++ if (tables->security_ctx)
++ sctx= tables->security_ctx;
++ else
++ sctx= backup_ctx;
++
++ if (tables->schema_table &&
++ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
++ {
++ if (!no_errors)
++ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
++ sctx->priv_user, sctx->priv_host,
++ INFORMATION_SCHEMA_NAME.str);
++ return TRUE;
++ }
++ /*
++ Register access for view underlying table.
++ Remove SHOW_VIEW_ACL, because it will be checked during making view
++ */
++ tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
++
++ if (tables->schema_table_reformed)
++ {
++ if (check_show_access(thd, tables))
++ goto deny;
++
++ continue;
++ }
++
++ if (tables->is_anonymous_derived_table() ||
++ (tables->table && (int)tables->table->s->tmp_table))
++ continue;
++ thd->security_ctx= sctx;
++ if ((sctx->master_access & want_access) ==
++ (want_access & ~EXTRA_ACL) &&
++ thd->db)
++ tables->grant.privilege= want_access;
++ else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
++ {
++ if (check_access(thd, want_access, tables->get_db_name(),
++ &tables->grant.privilege, 0, no_errors,
++ test(tables->schema_table)))
++ goto deny; // Access denied
++ }
++ else if (check_access(thd, want_access, tables->get_db_name(),
++ &tables->grant.privilege, 0, no_errors,
++ test(tables->schema_table)))
++ goto deny;
++ }
++ thd->security_ctx= backup_ctx;
++ return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
++ test(want_access & EXTRA_ACL), number, no_errors);
++deny:
++ thd->security_ctx= backup_ctx;
++ return TRUE;
++}
++
++
++bool
++check_routine_access(THD *thd, ulong want_access,char *db, char *name,
++ bool is_proc, bool no_errors)
++{
++ TABLE_LIST tables[1];
++
++ bzero((char *)tables, sizeof(TABLE_LIST));
++ tables->db= db;
++ tables->table_name= tables->alias= name;
++
++ /*
++ The following test is just a shortcut for check_access() (to avoid
++ calculating db_access) under the assumption that it's common to
++ give persons global right to execute all stored SP (but not
++ necessary to create them).
++ */
++ if ((thd->security_ctx->master_access & want_access) == want_access)
++ tables->grant.privilege= want_access;
++ else if (check_access(thd,want_access,db,&tables->grant.privilege,
++ 0, no_errors, 0))
++ return TRUE;
++
++ return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
++}
++
++
++/**
++ Check if the routine has any of the routine privileges.
++
++ @param thd Thread handler
++ @param db Database name
++ @param name Routine name
++
++ @retval
++ 0 ok
++ @retval
++ 1 error
++*/
++
++bool check_some_routine_access(THD *thd, const char *db, const char *name,
++ bool is_proc)
++{
++ ulong save_priv;
++ if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
++ return FALSE;
++ /*
++ There are no routines in information_schema db. So we can safely
++ pass zero to last paramter of check_access function
++ */
++ if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
++ (save_priv & SHOW_PROC_ACLS))
++ return FALSE;
++ return check_routine_level_acl(thd, db, name, is_proc);
++}
++
++
++/*
++ Check if the given table has any of the asked privileges
++
++ @param thd Thread handler
++ @param want_access Bitmap of possible privileges to check for
++
++ @retval
++ 0 ok
++ @retval
++ 1 error
++*/
++
++bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
++{
++ ulong access;
++ DBUG_ENTER("check_some_access");
++
++ /* This loop will work as long as we have less than 32 privileges */
++ for (access= 1; access < want_access ; access<<= 1)
++ {
++ if (access & want_access)
++ {
++ if (!check_access(thd, access, table->db,
++ &table->grant.privilege, 0, 1,
++ test(table->schema_table)) &&
++ !check_grant(thd, access, table, 0, 1, 1))
++ DBUG_RETURN(0);
++ }
++ }
++ DBUG_PRINT("exit",("no matching access rights"));
++ DBUG_RETURN(1);
++}
++
++#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
++
++
++/**
++ check for global access and give descriptive error message if it fails.
++
++ @param thd Thread handler
++ @param want_access Use should have any of these global rights
++
++ @warning
++ One gets access right if one has ANY of the rights in want_access.
++ This is useful as one in most cases only need one global right,
++ but in some case we want to check if the user has SUPER or
++ REPL_CLIENT_ACL rights.
++
++ @retval
++ 0 ok
++ @retval
++ 1 Access denied. In this case an error is sent to the client
++*/
++
++bool check_global_access(THD *thd, ulong want_access)
++{
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ char command[128];
++ if ((thd->security_ctx->master_access & want_access))
++ return 0;
++ get_privilege_desc(command, sizeof(command), want_access);
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
++ return 1;
++#else
++ return 0;
++#endif
++}
++
++/****************************************************************************
++ Check stack size; Send error if there isn't enough stack to continue
++****************************************************************************/
++
++#ifndef EMBEDDED_LIBRARY
++
++#if STACK_DIRECTION < 0
++#define used_stack(A,B) (long) (A - B)
++#else
++#define used_stack(A,B) (long) (B - A)
++#endif
++
++#ifndef DBUG_OFF
++long max_stack_used;
++#endif
++
++/**
++ @note
++ Note: The 'buf' parameter is necessary, even if it is unused here.
++ - fix_fields functions has a "dummy" buffer large enough for the
++ corresponding exec. (Thus we only have to check in fix_fields.)
++ - Passing to check_stack_overrun() prevents the compiler from removing it.
++*/
++bool check_stack_overrun(THD *thd, long margin,
++ uchar *buf __attribute__((unused)))
++{
++ long stack_used;
++ DBUG_ASSERT(thd == current_thd);
++ if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
++ (long) (my_thread_stack_size - margin))
++ {
++ char ebuff[MYSQL_ERRMSG_SIZE];
++ my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
++ stack_used, my_thread_stack_size, margin);
++ my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
++ thd->fatal_error();
++ return 1;
++ }
++#ifndef DBUG_OFF
++ max_stack_used= max(max_stack_used, stack_used);
++#endif
++ return 0;
++}
++#endif /* EMBEDDED_LIBRARY */
++
++#define MY_YACC_INIT 1000 // Start with big alloc
++#define MY_YACC_MAX 32000 // Because of 'short'
++
++bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
++{
++ Yacc_state *state= & current_thd->m_parser_state->m_yacc;
++ ulong old_info=0;
++ DBUG_ASSERT(state);
++ if ((uint) *yystacksize >= MY_YACC_MAX)
++ return 1;
++ if (!state->yacc_yyvs)
++ old_info= *yystacksize;
++ *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
++ if (!(state->yacc_yyvs= (uchar*)
++ my_realloc(state->yacc_yyvs,
++ *yystacksize*sizeof(**yyvs),
++ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
++ !(state->yacc_yyss= (uchar*)
++ my_realloc(state->yacc_yyss,
++ *yystacksize*sizeof(**yyss),
++ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
++ return 1;
++ if (old_info)
++ {
++ /*
++ Only copy the old stack on the first call to my_yyoverflow(),
++ when replacing a static stack (YYINITDEPTH) by a dynamic stack.
++ For subsequent calls, my_realloc already did preserve the old stack.
++ */
++ memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
++ memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
++ }
++ *yyss= (short*) state->yacc_yyss;
++ *yyvs= (YYSTYPE*) state->yacc_yyvs;
++ return 0;
++}
++
++
++/**
++ Reset THD part responsible for command processing state.
++
++ This needs to be called before execution of every statement
++ (prepared or conventional).
++ It is not called by substatements of routines.
++
++ @todo
++ Make it a method of THD and align its name with the rest of
++ reset/end/start/init methods.
++ @todo
++ Call it after we use THD for queries, not before.
++*/
++
++void mysql_reset_thd_for_next_command(THD *thd)
++{
++ DBUG_ENTER("mysql_reset_thd_for_next_command");
++ DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
++ DBUG_ASSERT(! thd->in_sub_stmt);
++ thd->free_list= 0;
++ thd->select_number= 1;
++ /*
++ Those two lines below are theoretically unneeded as
++ THD::cleanup_after_query() should take care of this already.
++ */
++ thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
++ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
++
++ thd->query_start_used= 0;
++ thd->is_fatal_error= thd->time_zone_used= 0;
++ /*
++ Clear the status flag that are expected to be cleared at the
++ beginning of each SQL statement.
++ */
++ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
++ /*
++ If in autocommit mode and not in a transaction, reset
++ OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
++ in ha_rollback_trans() about some tables couldn't be rolled back.
++ */
++ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
++ {
++ thd->options&= ~OPTION_KEEP_LOG;
++ thd->transaction.all.modified_non_trans_table= FALSE;
++ }
++ DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
++ thd->thread_specific_used= FALSE;
++
++ if (opt_bin_log)
++ {
++ reset_dynamic(&thd->user_var_events);
++ thd->user_var_events_alloc= thd->mem_root;
++ }
++ thd->clear_error();
++ thd->main_da.reset_diagnostics_area();
++ thd->total_warn_count=0; // Warnings for this query
++ thd->rand_used= 0;
++ thd->sent_row_count= thd->examined_row_count= 0;
++
++ /*
++ Because we come here only for start of top-statements, binlog format is
++ constant inside a complex statement (using stored functions) etc.
++ */
++ thd->reset_current_stmt_binlog_row_based();
++
++ DBUG_PRINT("debug",
++ ("current_stmt_binlog_row_based: %d",
++ thd->current_stmt_binlog_row_based));
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Resets the lex->current_select object.
++ @note It is assumed that lex->current_select != NULL
++
++ This function is a wrapper around select_lex->init_select() with an added
++ check for the special situation when using INTO OUTFILE and LOAD DATA.
++*/
++
++void
++mysql_init_select(LEX *lex)
++{
++ SELECT_LEX *select_lex= lex->current_select;
++ select_lex->init_select();
++ lex->wild= 0;
++ if (select_lex == &lex->select_lex)
++ {
++ DBUG_ASSERT(lex->result == 0);
++ lex->exchange= 0;
++ }
++}
++
++
++/**
++ Used to allocate a new SELECT_LEX object on the current thd mem_root and
++ link it into the relevant lists.
++
++ This function is always followed by mysql_init_select.
++
++ @see mysql_init_select
++
++ @retval TRUE An error occurred
++ @retval FALSE The new SELECT_LEX was successfully allocated.
++*/
++
++bool
++mysql_new_select(LEX *lex, bool move_down)
++{
++ SELECT_LEX *select_lex;
++ THD *thd= lex->thd;
++ DBUG_ENTER("mysql_new_select");
++
++ if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
++ DBUG_RETURN(1);
++ select_lex->select_number= ++thd->select_number;
++ select_lex->parent_lex= lex; /* Used in init_query. */
++ select_lex->init_query();
++ select_lex->init_select();
++ lex->nest_level++;
++ if (lex->nest_level > (int) MAX_SELECT_NESTING)
++ {
++ my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
++ DBUG_RETURN(1);
++ }
++ select_lex->nest_level= lex->nest_level;
++ if (move_down)
++ {
++ SELECT_LEX_UNIT *unit;
++ lex->subqueries= TRUE;
++ /* first select_lex of subselect or derived table */
++ if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
++ DBUG_RETURN(1);
++
++ unit->init_query();
++ unit->init_select();
++ unit->thd= thd;
++ unit->include_down(lex->current_select);
++ unit->link_next= 0;
++ unit->link_prev= 0;
++ unit->return_to= lex->current_select;
++ select_lex->include_down(unit);
++ /*
++ By default we assume that it is usual subselect and we have outer name
++ resolution context, if no we will assign it to 0 later
++ */
++ select_lex->context.outer_context= &select_lex->outer_select()->context;
++ }
++ else
++ {
++ if (lex->current_select->order_list.first && !lex->current_select->braces)
++ {
++ my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
++ DBUG_RETURN(1);
++ }
++ select_lex->include_neighbour(lex->current_select);
++ SELECT_LEX_UNIT *unit= select_lex->master_unit();
++ if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
++ DBUG_RETURN(1);
++ select_lex->context.outer_context=
++ unit->first_select()->context.outer_context;
++ }
++
++ select_lex->master_unit()->global_parameters= select_lex;
++ select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
++ lex->current_select= select_lex;
++ /*
++ in subquery is SELECT query and we allow resolution of names in SELECT
++ list
++ */
++ select_lex->context.resolve_in_select_list= TRUE;
++ DBUG_RETURN(0);
++}
++
++/**
++ Create a select to return the same output as 'SELECT @@var_name'.
++
++ Used for SHOW COUNT(*) [ WARNINGS | ERROR].
++
++ This will crash with a core dump if the variable doesn't exists.
++
++ @param var_name Variable name
++*/
++
++void create_select_for_variable(const char *var_name)
++{
++ THD *thd;
++ LEX *lex;
++ LEX_STRING tmp, null_lex_string;
++ Item *var;
++ char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
++ DBUG_ENTER("create_select_for_variable");
++
++ thd= current_thd;
++ lex= thd->lex;
++ mysql_init_select(lex);
++ lex->sql_command= SQLCOM_SELECT;
++ tmp.str= (char*) var_name;
++ tmp.length=strlen(var_name);
++ bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
++ /*
++ We set the name of Item to @@session.var_name because that then is used
++ as the column name in the output.
++ */
++ if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
++ {
++ end= strxmov(buff, "@@session.", var_name, NullS);
++ var->set_name(buff, end-buff, system_charset_info);
++ add_item_to_list(thd, var);
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++void mysql_init_multi_delete(LEX *lex)
++{
++ lex->sql_command= SQLCOM_DELETE_MULTI;
++ mysql_init_select(lex);
++ lex->select_lex.select_limit= 0;
++ lex->unit.select_limit_cnt= HA_POS_ERROR;
++ lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
++ lex->lock_option= TL_READ_DEFAULT;
++ lex->query_tables= 0;
++ lex->query_tables_last= &lex->query_tables;
++}
++
++
++/*
++ When you modify mysql_parse(), you may need to mofify
++ mysql_test_parse_for_slave() in this same file.
++*/
++
++/**
++ Parse a query.
++
++ @param thd Current thread
++ @param rawbuf Begining of the query text
++ @param length Length of the query text
++ @param[out] found_semicolon For multi queries, position of the character of
++ the next query in the query text.
++*/
++
++void mysql_parse(THD *thd, char *rawbuf, uint length,
++ const char ** found_semicolon)
++{
++ DBUG_ENTER("mysql_parse");
++
++ DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
++
++ /*
++ Warning.
++ The purpose of query_cache_send_result_to_client() is to lookup the
++ query in the query cache first, to avoid parsing and executing it.
++ So, the natural implementation would be to:
++ - first, call query_cache_send_result_to_client,
++ - second, if caching failed, initialise the lexical and syntactic parser.
++ The problem is that the query cache depends on a clean initialization
++ of (among others) lex->safe_to_cache_query and thd->server_status,
++ which are reset respectively in
++ - lex_start()
++ - mysql_reset_thd_for_next_command()
++ So, initializing the lexical analyser *before* using the query cache
++ is required for the cache to work properly.
++ FIXME: cleanup the dependencies in the code to simplify this.
++ */
++ lex_start(thd);
++ mysql_reset_thd_for_next_command(thd);
++
++ if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
++ {
++ LEX *lex= thd->lex;
++
++ sp_cache_flush_obsolete(&thd->sp_proc_cache);
++ sp_cache_flush_obsolete(&thd->sp_func_cache);
++
++ Parser_state parser_state;
++ bool err;
++ if (!(err= parser_state.init(thd, rawbuf, length)))
++ {
++ err= parse_sql(thd, & parser_state, NULL);
++ *found_semicolon= parser_state.m_lip.found_semicolon;
++ }
++ else
++ *found_semicolon= NULL;
++
++ if (!err)
++ {
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (mqh_used && thd->user_connect &&
++ check_mqh(thd, lex->sql_command))
++ {
++ thd->net.error = 0;
++ }
++ else
++#endif
++ {
++ if (! thd->is_error())
++ {
++ /*
++ Binlog logs a string starting from thd->query and having length
++ thd->query_length; so we set thd->query_length correctly (to not
++ log several statements in one event, when we executed only first).
++ We set it to not see the ';' (otherwise it would get into binlog
++ and Query_log_event::print() would give ';;' output).
++ This also helps display only the current query in SHOW
++ PROCESSLIST.
++ Note that we don't need LOCK_thread_count to modify query_length.
++ */
++ if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
++ thd->set_query_inner(thd->query(),
++ (uint32) (*found_semicolon -
++ thd->query() - 1));
++ /* Actually execute the query */
++ if (*found_semicolon)
++ {
++ lex->safe_to_cache_query= 0;
++ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
++ }
++ lex->set_trg_event_type_for_tables();
++ mysql_execute_command(thd);
++ }
++ }
++ }
++ else
++ {
++ DBUG_ASSERT(thd->is_error());
++ DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
++ thd->is_fatal_error));
++
++ query_cache_abort(&thd->net);
++ }
++ if (thd->lex->sphead)
++ {
++ delete thd->lex->sphead;
++ thd->lex->sphead= 0;
++ }
++ lex->unit.cleanup();
++ thd_proc_info(thd, "freeing items");
++ thd->end_statement();
++ thd->cleanup_after_query();
++ DBUG_ASSERT(thd->change_list.is_empty());
++ }
++ else
++ {
++ /* There are no multi queries in the cache. */
++ *found_semicolon= NULL;
++ }
++
++ DBUG_VOID_RETURN;
++}
++
++
++#ifdef HAVE_REPLICATION
++/*
++ Usable by the replication SQL thread only: just parse a query to know if it
++ can be ignored because of replicate-*-table rules.
++
++ @retval
++ 0 cannot be ignored
++ @retval
++ 1 can be ignored
++*/
++
++bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
++{
++ LEX *lex= thd->lex;
++ bool error= 0;
++ DBUG_ENTER("mysql_test_parse_for_slave");
++
++ Parser_state parser_state;
++ if (!(error= parser_state.init(thd, rawbuf, length)))
++ {
++ lex_start(thd);
++ mysql_reset_thd_for_next_command(thd);
++
++ if (!parse_sql(thd, & parser_state, NULL) &&
++ all_tables_not_ok(thd, lex->select_lex.table_list.first))
++ error= 1; /* Ignore question */
++ thd->end_statement();
++ }
++ thd->cleanup_after_query();
++ DBUG_RETURN(error);
++}
++#endif
++
++
++
++/**
++ Store field definition for create.
++
++ @return
++ Return 0 if ok
++*/
++
++bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
++ char *length, char *decimals,
++ uint type_modifier,
++ Item *default_value, Item *on_update_value,
++ LEX_STRING *comment,
++ char *change,
++ List<String> *interval_list, CHARSET_INFO *cs,
++ uint uint_geom_type)
++{
++ register Create_field *new_field;
++ LEX *lex= thd->lex;
++ DBUG_ENTER("add_field_to_list");
++
++ if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
++ system_charset_info, 1))
++ {
++ my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
++ DBUG_RETURN(1); /* purecov: inspected */
++ }
++ if (type_modifier & PRI_KEY_FLAG)
++ {
++ Key *key;
++ lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
++ key= new Key(Key::PRIMARY, NullS,
++ &default_key_create_info,
++ 0, lex->col_list);
++ lex->alter_info.key_list.push_back(key);
++ lex->col_list.empty();
++ }
++ if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
++ {
++ Key *key;
++ lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
++ key= new Key(Key::UNIQUE, NullS,
++ &default_key_create_info, 0,
++ lex->col_list);
++ lex->alter_info.key_list.push_back(key);
++ lex->col_list.empty();
++ }
++
++ if (default_value)
++ {
++ /*
++ Default value should be literal => basic constants =>
++ no need fix_fields()
++
++ We allow only one function as part of default value -
++ NOW() as default for TIMESTAMP type.
++ */
++ if (default_value->type() == Item::FUNC_ITEM &&
++ !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
++ type == MYSQL_TYPE_TIMESTAMP))
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
++ DBUG_RETURN(1);
++ }
++ else if (default_value->type() == Item::NULL_ITEM)
++ {
++ default_value= 0;
++ if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
++ NOT_NULL_FLAG)
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
++ DBUG_RETURN(1);
++ }
++ }
++ else if (type_modifier & AUTO_INCREMENT_FLAG)
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
++ DBUG_RETURN(1);
++ }
++ }
++
++ if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
++ {
++ my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
++ DBUG_RETURN(1);
++ }
++
++ if (type == MYSQL_TYPE_TIMESTAMP && length)
++ {
++ /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
++ In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
++ and so on, the display width is ignored.
++ */
++ char buf[32];
++ my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
++ WARN_DEPRECATED(thd, "6.0", buf, "'TIMESTAMP'");
++ }
++
++ if (!(new_field= new Create_field()) ||
++ new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
++ default_value, on_update_value, comment, change,
++ interval_list, cs, uint_geom_type))
++ DBUG_RETURN(1);
++
++ lex->alter_info.create_list.push_back(new_field);
++ lex->last_field=new_field;
++ DBUG_RETURN(0);
++}
++
++
++/** Store position for column in ALTER TABLE .. ADD column. */
++
++void store_position_for_column(const char *name)
++{
++ current_thd->lex->last_field->after=my_const_cast(char*) (name);
++}
++
++bool
++add_proc_to_list(THD* thd, Item *item)
++{
++ ORDER *order;
++ Item **item_ptr;
++
++ if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
++ return 1;
++ item_ptr = (Item**) (order+1);
++ *item_ptr= item;
++ order->item=item_ptr;
++ order->free_me=0;
++ thd->lex->proc_list.link_in_list(order, &order->next);
++ return 0;
++}
++
++
++/**
++ save order by and tables in own lists.
++*/
++
++bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
++{
++ ORDER *order;
++ DBUG_ENTER("add_to_list");
++ if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
++ DBUG_RETURN(1);
++ order->item_ptr= item;
++ order->item= &order->item_ptr;
++ order->asc = asc;
++ order->free_me=0;
++ order->used=0;
++ order->counter_used= 0;
++ list.link_in_list(order, &order->next);
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Add a table to list of used tables.
++
++ @param table Table to add
++ @param alias alias for table (or null if no alias)
++ @param table_options A set of the following bits:
++ - TL_OPTION_UPDATING : Table will be updated
++ - TL_OPTION_FORCE_INDEX : Force usage of index
++ - TL_OPTION_ALIAS : an alias in multi table DELETE
++ @param lock_type How table should be locked
++ @param use_index List of indexed used in USE INDEX
++ @param ignore_index List of indexed used in IGNORE INDEX
++
++ @retval
++ 0 Error
++ @retval
++ \# Pointer to TABLE_LIST element added to the total table list
++*/
++
++TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
++ Table_ident *table,
++ LEX_STRING *alias,
++ ulong table_options,
++ thr_lock_type lock_type,
++ List<Index_hint> *index_hints_arg,
++ LEX_STRING *option)
++{
++ register TABLE_LIST *ptr;
++ TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
++ char *alias_str;
++ LEX *lex= thd->lex;
++ DBUG_ENTER("add_table_to_list");
++ LINT_INIT(previous_table_ref);
++
++ if (!table)
++ DBUG_RETURN(0); // End of memory
++ alias_str= alias ? alias->str : table->table.str;
++ if (!test(table_options & TL_OPTION_ALIAS) &&
++ check_table_name(table->table.str, table->table.length, FALSE))
++ {
++ my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
++ DBUG_RETURN(0);
++ }
++
++ if (table->is_derived_table() == FALSE && table->db.str &&
++ check_db_name(&table->db))
++ {
++ my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
++ DBUG_RETURN(0);
++ }
++
++ if (!alias) /* Alias is case sensitive */
++ {
++ if (table->sel)
++ {
++ my_message(ER_DERIVED_MUST_HAVE_ALIAS,
++ ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
++ DBUG_RETURN(0);
++ }
++ if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
++ DBUG_RETURN(0);
++ }
++ if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
++ DBUG_RETURN(0); /* purecov: inspected */
++ if (table->db.str)
++ {
++ ptr->db= table->db.str;
++ ptr->db_length= table->db.length;
++ }
++ else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
++ DBUG_RETURN(0);
++
++ ptr->alias= alias_str;
++ if (lower_case_table_names && table->table.length)
++ table->table.length= my_casedn_str(files_charset_info, table->table.str);
++ ptr->table_name=table->table.str;
++ ptr->table_name_length=table->table.length;
++ ptr->lock_type= lock_type;
++ ptr->updating= test(table_options & TL_OPTION_UPDATING);
++ /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
++ ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
++ ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
++ ptr->derived= table->sel;
++ if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length))
++ {
++ ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
++ if (!schema_table ||
++ (schema_table->hidden &&
++ ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
++ /*
++ this check is used for show columns|keys from I_S hidden table
++ */
++ lex->sql_command == SQLCOM_SHOW_FIELDS ||
++ lex->sql_command == SQLCOM_SHOW_KEYS)))
++ {
++ my_error(ER_UNKNOWN_TABLE, MYF(0),
++ ptr->table_name, INFORMATION_SCHEMA_NAME.str);
++ DBUG_RETURN(0);
++ }
++ ptr->schema_table_name= ptr->table_name;
++ ptr->schema_table= schema_table;
++ }
++ ptr->select_lex= lex->current_select;
++ ptr->cacheable_table= 1;
++ ptr->index_hints= index_hints_arg;
++ ptr->option= option ? option->str : 0;
++ /* check that used name is unique */
++ if (lock_type != TL_IGNORE)
++ {
++ TABLE_LIST *first_table= table_list.first;
++ if (lex->sql_command == SQLCOM_CREATE_VIEW)
++ first_table= first_table ? first_table->next_local : NULL;
++ for (TABLE_LIST *tables= first_table ;
++ tables ;
++ tables=tables->next_local)
++ {
++ if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
++ !strcmp(ptr->db, tables->db))
++ {
++ my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
++ DBUG_RETURN(0); /* purecov: tested */
++ }
++ }
++ }
++ /* Store the table reference preceding the current one. */
++ if (table_list.elements > 0)
++ {
++ /*
++ table_list.next points to the last inserted TABLE_LIST->next_local'
++ element
++ We don't use the offsetof() macro here to avoid warnings from gcc
++ */
++ previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
++ ((char*) &(ptr->next_local) -
++ (char*) ptr));
++ /*
++ Set next_name_resolution_table of the previous table reference to point
++ to the current table reference. In effect the list
++ TABLE_LIST::next_name_resolution_table coincides with
++ TABLE_LIST::next_local. Later this may be changed in
++ store_top_level_join_columns() for NATURAL/USING joins.
++ */
++ previous_table_ref->next_name_resolution_table= ptr;
++ }
++
++ /*
++ Link the current table reference in a local list (list for current select).
++ Notice that as a side effect here we set the next_local field of the
++ previous table reference to 'ptr'. Here we also add one element to the
++ list 'table_list'.
++ */
++ table_list.link_in_list(ptr, &ptr->next_local);
++ ptr->next_name_resolution_table= NULL;
++ /* Link table in global list (all used tables) */
++ lex->add_to_query_tables(ptr);
++ DBUG_RETURN(ptr);
++}
++
++
++/**
++ Initialize a new table list for a nested join.
++
++ The function initializes a structure of the TABLE_LIST type
++ for a nested join. It sets up its nested join list as empty.
++ The created structure is added to the front of the current
++ join list in the st_select_lex object. Then the function
++ changes the current nest level for joins to refer to the newly
++ created empty list after having saved the info on the old level
++ in the initialized structure.
++
++ @param thd current thread
++
++ @retval
++ 0 if success
++ @retval
++ 1 otherwise
++*/
++
++bool st_select_lex::init_nested_join(THD *thd)
++{
++ TABLE_LIST *ptr;
++ NESTED_JOIN *nested_join;
++ DBUG_ENTER("init_nested_join");
++
++ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
++ sizeof(NESTED_JOIN))))
++ DBUG_RETURN(1);
++ nested_join= ptr->nested_join=
++ ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
++
++ join_list->push_front(ptr);
++ ptr->embedding= embedding;
++ ptr->join_list= join_list;
++ ptr->alias= (char*) "(nested_join)";
++ embedding= ptr;
++ join_list= &nested_join->join_list;
++ join_list->empty();
++ DBUG_RETURN(0);
++}
++
++
++/**
++ End a nested join table list.
++
++ The function returns to the previous join nest level.
++ If the current level contains only one member, the function
++ moves it one level up, eliminating the nest.
++
++ @param thd current thread
++
++ @return
++ - Pointer to TABLE_LIST element added to the total table list, if success
++ - 0, otherwise
++*/
++
++TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
++{
++ TABLE_LIST *ptr;
++ NESTED_JOIN *nested_join;
++ DBUG_ENTER("end_nested_join");
++
++ DBUG_ASSERT(embedding);
++ ptr= embedding;
++ join_list= ptr->join_list;
++ embedding= ptr->embedding;
++ nested_join= ptr->nested_join;
++ if (nested_join->join_list.elements == 1)
++ {
++ TABLE_LIST *embedded= nested_join->join_list.head();
++ join_list->pop();
++ embedded->join_list= join_list;
++ embedded->embedding= embedding;
++ join_list->push_front(embedded);
++ ptr= embedded;
++ }
++ else if (nested_join->join_list.elements == 0)
++ {
++ join_list->pop();
++ ptr= 0; // return value
++ }
++ DBUG_RETURN(ptr);
++}
++
++
++/**
++ Nest last join operation.
++
++ The function nest last join operation as if it was enclosed in braces.
++
++ @param thd current thread
++
++ @retval
++ 0 Error
++ @retval
++ \# Pointer to TABLE_LIST element created for the new nested join
++*/
++
++TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
++{
++ TABLE_LIST *ptr;
++ NESTED_JOIN *nested_join;
++ List<TABLE_LIST> *embedded_list;
++ DBUG_ENTER("nest_last_join");
++
++ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
++ sizeof(NESTED_JOIN))))
++ DBUG_RETURN(0);
++ nested_join= ptr->nested_join=
++ ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
++
++ ptr->embedding= embedding;
++ ptr->join_list= join_list;
++ ptr->alias= (char*) "(nest_last_join)";
++ embedded_list= &nested_join->join_list;
++ embedded_list->empty();
++
++ for (uint i=0; i < 2; i++)
++ {
++ TABLE_LIST *table= join_list->pop();
++ table->join_list= embedded_list;
++ table->embedding= ptr;
++ embedded_list->push_back(table);
++ if (table->natural_join)
++ {
++ ptr->is_natural_join= TRUE;
++ /*
++ If this is a JOIN ... USING, move the list of joined fields to the
++ table reference that describes the join.
++ */
++ if (prev_join_using)
++ ptr->join_using_fields= prev_join_using;
++ }
++ }
++ join_list->push_front(ptr);
++ nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
++ DBUG_RETURN(ptr);
++}
++
++
++/**
++ Add a table to the current join list.
++
++ The function puts a table in front of the current join list
++ of st_select_lex object.
++ Thus, joined tables are put into this list in the reverse order
++ (the most outer join operation follows first).
++
++ @param table the table to add
++
++ @return
++ None
++*/
++
++void st_select_lex::add_joined_table(TABLE_LIST *table)
++{
++ DBUG_ENTER("add_joined_table");
++ join_list->push_front(table);
++ table->join_list= join_list;
++ table->embedding= embedding;
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Convert a right join into equivalent left join.
++
++ The function takes the current join list t[0],t[1] ... and
++ effectively converts it into the list t[1],t[0] ...
++ Although the outer_join flag for the new nested table contains
++ JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
++ operation.
++
++ EXAMPLES
++ @verbatim
++ SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
++ SELECT * FROM t2 LEFT JOIN t1 ON on_expr
++
++ SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
++ SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
++
++ SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
++ SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
++
++ SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
++ SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
++ @endverbatim
++
++ @param thd current thread
++
++ @return
++ - Pointer to the table representing the inner table, if success
++ - 0, otherwise
++*/
++
++TABLE_LIST *st_select_lex::convert_right_join()
++{
++ TABLE_LIST *tab2= join_list->pop();
++ TABLE_LIST *tab1= join_list->pop();
++ DBUG_ENTER("convert_right_join");
++
++ join_list->push_front(tab2);
++ join_list->push_front(tab1);
++ tab1->outer_join|= JOIN_TYPE_RIGHT;
++
++ DBUG_RETURN(tab1);
++}
++
++/**
++ Set lock for all tables in current select level.
++
++ @param lock_type Lock to set for tables
++
++ @note
++ If lock is a write lock, then tables->updating is set 1
++ This is to get tables_ok to know that the table is updated by the
++ query
++*/
++
++void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
++{
++ bool for_update= lock_type >= TL_READ_NO_INSERT;
++ DBUG_ENTER("set_lock_for_tables");
++ DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
++ for_update));
++ for (TABLE_LIST *tables= table_list.first;
++ tables;
++ tables= tables->next_local)
++ {
++ tables->lock_type= lock_type;
++ tables->updating= for_update;
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Create a fake SELECT_LEX for a unit.
++
++ The method create a fake SELECT_LEX object for a unit.
++ This object is created for any union construct containing a union
++ operation and also for any single select union construct of the form
++ @verbatim
++ (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
++ @endvarbatim
++ or of the form
++ @varbatim
++ (SELECT ... ORDER BY LIMIT n) ORDER BY ...
++ @endvarbatim
++
++ @param thd_arg thread handle
++
++ @note
++ The object is used to retrieve rows from the temporary table
++ where the result on the union is obtained.
++
++ @retval
++ 1 on failure to create the object
++ @retval
++ 0 on success
++*/
++
++bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
++{
++ SELECT_LEX *first_sl= first_select();
++ DBUG_ENTER("add_fake_select_lex");
++ DBUG_ASSERT(!fake_select_lex);
++
++ if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
++ DBUG_RETURN(1);
++ fake_select_lex->include_standalone(this,
++ (SELECT_LEX_NODE**)&fake_select_lex);
++ fake_select_lex->select_number= INT_MAX;
++ fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
++ fake_select_lex->make_empty_select();
++ fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
++ fake_select_lex->select_limit= 0;
++
++ fake_select_lex->context.outer_context=first_sl->context.outer_context;
++ /* allow item list resolving in fake select for ORDER BY */
++ fake_select_lex->context.resolve_in_select_list= TRUE;
++ fake_select_lex->context.select_lex= fake_select_lex;
++
++ if (!is_union())
++ {
++ /*
++ This works only for
++ (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
++ (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
++ just before the parser starts processing order_list
++ */
++ global_parameters= fake_select_lex;
++ fake_select_lex->no_table_names_allowed= 1;
++ thd_arg->lex->current_select= fake_select_lex;
++ }
++ thd_arg->lex->pop_context();
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Push a new name resolution context for a JOIN ... ON clause to the
++ context stack of a query block.
++
++ Create a new name resolution context for a JOIN ... ON clause,
++ set the first and last leaves of the list of table references
++ to be used for name resolution, and push the newly created
++ context to the stack of contexts of the query.
++
++ @param thd pointer to current thread
++ @param left_op left operand of the JOIN
++ @param right_op rigth operand of the JOIN
++
++ @retval
++ FALSE if all is OK
++ @retval
++ TRUE if a memory allocation error occured
++*/
++
++bool
++push_new_name_resolution_context(THD *thd,
++ TABLE_LIST *left_op, TABLE_LIST *right_op)
++{
++ Name_resolution_context *on_context;
++ if (!(on_context= new (thd->mem_root) Name_resolution_context))
++ return TRUE;
++ on_context->init();
++ on_context->first_name_resolution_table=
++ left_op->first_leaf_for_name_resolution();
++ on_context->last_name_resolution_table=
++ right_op->last_leaf_for_name_resolution();
++ return thd->lex->push_context(on_context);
++}
++
++
++/**
++ Add an ON condition to the second operand of a JOIN ... ON.
++
++ Add an ON condition to the right operand of a JOIN ... ON clause.
++
++ @param b the second operand of a JOIN ... ON
++ @param expr the condition to be added to the ON clause
++
++ @retval
++ FALSE if there was some error
++ @retval
++ TRUE if all is OK
++*/
++
++void add_join_on(TABLE_LIST *b, Item *expr)
++{
++ if (expr)
++ {
++ if (!b->on_expr)
++ b->on_expr= expr;
++ else
++ {
++ /*
++ If called from the parser, this happens if you have both a
++ right and left join. If called later, it happens if we add more
++ than one condition to the ON clause.
++ */
++ b->on_expr= new Item_cond_and(b->on_expr,expr);
++ }
++ b->on_expr->top_level_item();
++ }
++}
++
++
++/**
++ Mark that there is a NATURAL JOIN or JOIN ... USING between two
++ tables.
++
++ This function marks that table b should be joined with a either via
++ a NATURAL JOIN or via JOIN ... USING. Both join types are special
++ cases of each other, so we treat them together. The function
++ setup_conds() creates a list of equal condition between all fields
++ of the same name for NATURAL JOIN or the fields in 'using_fields'
++ for JOIN ... USING. The list of equality conditions is stored
++ either in b->on_expr, or in JOIN::conds, depending on whether there
++ was an outer join.
++
++ EXAMPLE
++ @verbatim
++ SELECT * FROM t1 NATURAL LEFT JOIN t2
++ <=>
++ SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
++
++ SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
++ <=>
++ SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
++
++ SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
++ <=>
++ SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
++ @endverbatim
++
++ @param a Left join argument
++ @param b Right join argument
++ @param using_fields Field names from USING clause
++*/
++
++void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
++ SELECT_LEX *lex)
++{
++ b->natural_join= a;
++ lex->prev_join_using= using_fields;
++}
++
++
++/**
++ Reload/resets privileges and the different caches.
++
++ @param thd Thread handler (can be NULL!)
++ @param options What should be reset/reloaded (tables, privileges, slave...)
++ @param tables Tables to flush (if any)
++ @param write_to_binlog < 0 if there was an error while interacting with the binary log inside
++ reload_acl_and_cache,
++ 0 if we should not write to the binary log,
++ > 0 if we can write to the binlog.
++
++ @note Depending on 'options', it may be very bad to write the
++ query to the binlog (e.g. FLUSH SLAVE); this is a
++ pointer where reload_acl_and_cache() will put 0 if
++ it thinks we really should not write to the binlog.
++ Otherwise it will put 1.
++
++ @return Error status code
++ @retval 0 Ok
++ @retval !=0 Error; thd->killed is set or thd->is_error() is true
++*/
++
++bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
++ int *write_to_binlog)
++{
++ bool result=0;
++ select_errors=0; /* Write if more errors */
++ int tmp_write_to_binlog= *write_to_binlog= 1;
++
++ DBUG_ASSERT(!thd || !thd->in_sub_stmt);
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (options & REFRESH_GRANT)
++ {
++ THD *tmp_thd= 0;
++ /*
++ If reload_acl_and_cache() is called from SIGHUP handler we have to
++ allocate temporary THD for execution of acl_reload()/grant_reload().
++ */
++ if (!thd && (thd= (tmp_thd= new THD)))
++ {
++ thd->thread_stack= (char*) &tmp_thd;
++ thd->store_globals();
++ lex_start(thd);
++ }
++
++ if (thd)
++ {
++ bool reload_acl_failed= acl_reload(thd);
++ bool reload_grants_failed= grant_reload(thd);
++ bool reload_servers_failed= servers_reload(thd);
++
++ if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
++ {
++ result= 1;
++ /*
++ When an error is returned, my_message may have not been called and
++ the client will hang waiting for a response.
++ */
++ my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
++ }
++ }
++
++ if (tmp_thd)
++ {
++ delete tmp_thd;
++ /* Remember that we don't have a THD */
++ my_pthread_setspecific_ptr(THR_THD, 0);
++ thd= 0;
++ }
++ reset_mqh((LEX_USER *)NULL, TRUE);
++ }
++#endif
++ if (options & REFRESH_LOG)
++ {
++ /*
++ Flush the normal query log, the update log, the binary log,
++ the slow query log, the relay log (if it exists) and the log
++ tables.
++ */
++
++ /*
++ Writing this command to the binlog may result in infinite loops
++ when doing mysqlbinlog|mysql, and anyway it does not really make
++ sense to log it automatically (would cause more trouble to users
++ than it would help them)
++ */
++ tmp_write_to_binlog= 0;
++ if( mysql_bin_log.is_open() )
++ {
++ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
++ *write_to_binlog= -1;
++ }
++#ifdef HAVE_REPLICATION
++ int rotate_error= 0;
++ pthread_mutex_lock(&LOCK_active_mi);
++ rotate_error= rotate_relay_log(active_mi);
++ pthread_mutex_unlock(&LOCK_active_mi);
++ if (rotate_error)
++ *write_to_binlog= -1;
++#endif
++
++ /* flush slow and general logs */
++ logger.flush_logs(thd);
++
++ if (ha_flush_logs(NULL))
++ result=1;
++ if (flush_error_log())
++ result=1;
++ }
++#ifdef HAVE_QUERY_CACHE
++ if (options & REFRESH_QUERY_CACHE_FREE)
++ {
++ query_cache.pack(); // FLUSH QUERY CACHE
++ options &= ~REFRESH_QUERY_CACHE; // Don't flush cache, just free memory
++ }
++ if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
++ {
++ query_cache.flush(); // RESET QUERY CACHE
++ }
++#endif /*HAVE_QUERY_CACHE*/
++ /*
++ Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
++ (see sql_yacc.yy)
++ */
++ if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
++ {
++ if ((options & REFRESH_READ_LOCK) && thd)
++ {
++ /*
++ We must not try to aspire a global read lock if we have a write
++ locked table. This would lead to a deadlock when trying to
++ reopen (and re-lock) the table after the flush.
++ */
++ if (thd->locked_tables)
++ {
++ THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
++ THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
++
++ for (; lock_p < end_p; lock_p++)
++ {
++ if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
++ {
++ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
++ return 1;
++ }
++ }
++ }
++ /*
++ Writing to the binlog could cause deadlocks, as we don't log
++ UNLOCK TABLES
++ */
++ tmp_write_to_binlog= 0;
++ if (lock_global_read_lock(thd))
++ return 1; // Killed
++ if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
++ FALSE : TRUE, TRUE))
++ result= 1;
++
++ if (make_global_read_lock_block_commit(thd)) // Killed
++ {
++ /* Don't leave things in a half-locked state */
++ unlock_global_read_lock(thd);
++ return 1;
++ }
++ }
++ else
++ {
++ if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
++ FALSE : TRUE, FALSE))
++ result= 1;
++ }
++ my_dbopt_cleanup();
++ }
++ if (options & REFRESH_HOSTS)
++ hostname_cache_refresh();
++ if (thd && (options & REFRESH_STATUS))
++ refresh_status(thd);
++ if (options & REFRESH_THREADS)
++ flush_thread_cache();
++#ifdef HAVE_REPLICATION
++ if (options & REFRESH_MASTER)
++ {
++ DBUG_ASSERT(thd);
++ tmp_write_to_binlog= 0;
++ if (reset_master(thd))
++ {
++ result=1;
++ }
++ }
++#endif
++#ifdef OPENSSL
++ if (options & REFRESH_DES_KEY_FILE)
++ {
++ if (des_key_file && load_des_key_file(des_key_file))
++ result= 1;
++ }
++#endif
++#ifdef HAVE_REPLICATION
++ if (options & REFRESH_SLAVE)
++ {
++ tmp_write_to_binlog= 0;
++ pthread_mutex_lock(&LOCK_active_mi);
++ if (reset_slave(thd, active_mi))
++ result=1;
++ pthread_mutex_unlock(&LOCK_active_mi);
++ }
++#endif
++ if (options & REFRESH_USER_RESOURCES)
++ reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
++ if (*write_to_binlog != -1)
++ *write_to_binlog= tmp_write_to_binlog;
++ /*
++ If the query was killed then this function must fail.
++ */
++ return result || (thd ? thd->killed : 0);
++}
++
++
++/**
++ kill on thread.
++
++ @param thd Thread class
++ @param id Thread id
++ @param only_kill_query Should it kill the query or the connection
++
++ @note
++ This is written such that we have a short lock on LOCK_thread_count
++*/
++
++uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
++{
++ THD *tmp;
++ uint error=ER_NO_SUCH_THREAD;
++ DBUG_ENTER("kill_one_thread");
++ DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
++ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
++ I_List_iterator<THD> it(threads);
++ while ((tmp=it++))
++ {
++ if (tmp->command == COM_DAEMON)
++ continue;
++ if (tmp->thread_id == id)
++ {
++ pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
++ break;
++ }
++ }
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ if (tmp)
++ {
++
++ /*
++ If we're SUPER, we can KILL anything, including system-threads.
++ No further checks.
++
++ KILLer: thd->security_ctx->user could in theory be NULL while
++ we're still in "unauthenticated" state. This is a theoretical
++ case (the code suggests this could happen, so we play it safe).
++
++ KILLee: tmp->security_ctx->user will be NULL for system threads.
++ We need to check so Jane Random User doesn't crash the server
++ when trying to kill a) system threads or b) unauthenticated users'
++ threads (Bug#43748).
++
++ If user of both killer and killee are non-NULL, proceed with
++ slayage if both are string-equal.
++ */
++
++ if ((thd->security_ctx->master_access & SUPER_ACL) ||
++ thd->security_ctx->user_matches(tmp->security_ctx))
++ {
++ tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
++ error=0;
++ }
++ else
++ error=ER_KILL_DENIED_ERROR;
++ pthread_mutex_unlock(&tmp->LOCK_thd_data);
++ }
++ DBUG_PRINT("exit", ("%d", error));
++ DBUG_RETURN(error);
++}
++
++
++/*
++ kills a thread and sends response
++
++ SYNOPSIS
++ sql_kill()
++ thd Thread class
++ id Thread id
++ only_kill_query Should it kill the query or the connection
++*/
++
++void sql_kill(THD *thd, ulong id, bool only_kill_query)
++{
++ uint error;
++ if (!(error= kill_one_thread(thd, id, only_kill_query)))
++ my_ok(thd);
++ else
++ my_error(error, MYF(0), id);
++}
++
++
++/** If pointer is not a null pointer, append filename to it. */
++
++bool append_file_to_dir(THD *thd, const char **filename_ptr,
++ const char *table_name)
++{
++ char buff[FN_REFLEN],*ptr, *end;
++ if (!*filename_ptr)
++ return 0; // nothing to do
++
++ /* Check that the filename is not too long and it's a hard path */
++ if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
++ !test_if_hard_path(*filename_ptr))
++ {
++ my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
++ return 1;
++ }
++ /* Fix is using unix filename format on dos */
++ strmov(buff,*filename_ptr);
++ end=convert_dirname(buff, *filename_ptr, NullS);
++ if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
++ return 1; // End of memory
++ *filename_ptr=ptr;
++ strxmov(ptr,buff,table_name,NullS);
++ return 0;
++}
++
++
++/**
++ Check if the select is a simple select (not an union).
++
++ @retval
++ 0 ok
++ @retval
++ 1 error ; In this case the error messege is sent to the client
++*/
++
++bool check_simple_select()
++{
++ THD *thd= current_thd;
++ LEX *lex= thd->lex;
++ if (lex->current_select != &lex->select_lex)
++ {
++ char command[80];
++ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
++ strmake(command, lip->yylval->symbol.str,
++ min(lip->yylval->symbol.length, sizeof(command)-1));
++ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
++ return 1;
++ }
++ return 0;
++}
++
++
++Comp_creator *comp_eq_creator(bool invert)
++{
++ return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
++}
++
++
++Comp_creator *comp_ge_creator(bool invert)
++{
++ return invert?(Comp_creator *)<_creator:(Comp_creator *)&ge_creator;
++}
++
++
++Comp_creator *comp_gt_creator(bool invert)
++{
++ return invert?(Comp_creator *)&le_creator:(Comp_creator *)>_creator;
++}
++
++
++Comp_creator *comp_le_creator(bool invert)
++{
++ return invert?(Comp_creator *)>_creator:(Comp_creator *)&le_creator;
++}
++
++
++Comp_creator *comp_lt_creator(bool invert)
++{
++ return invert?(Comp_creator *)&ge_creator:(Comp_creator *)<_creator;
++}
++
++
++Comp_creator *comp_ne_creator(bool invert)
++{
++ return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
++}
++
++
++/**
++ Construct ALL/ANY/SOME subquery Item.
++
++ @param left_expr pointer to left expression
++ @param cmp compare function creator
++ @param all true if we create ALL subquery
++ @param select_lex pointer on parsed subquery structure
++
++ @return
++ constructed Item (or 0 if out of memory)
++*/
++Item * all_any_subquery_creator(Item *left_expr,
++ chooser_compare_func_creator cmp,
++ bool all,
++ SELECT_LEX *select_lex)
++{
++ if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
++ return new Item_in_subselect(left_expr, select_lex);
++
++ if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
++ return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
++
++ Item_allany_subselect *it=
++ new Item_allany_subselect(left_expr, cmp, select_lex, all);
++ if (all)
++ return it->upper_item= new Item_func_not_all(it); /* ALL */
++
++ return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
++}
++
++
++/**
++ Multi update query pre-check.
++
++ @param thd Thread handler
++ @param tables Global/local table list (have to be the same)
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE Error
++*/
++
++bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
++{
++ const char *msg= 0;
++ TABLE_LIST *table;
++ LEX *lex= thd->lex;
++ SELECT_LEX *select_lex= &lex->select_lex;
++ DBUG_ENTER("multi_update_precheck");
++
++ if (select_lex->item_list.elements != lex->value_list.elements)
++ {
++ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ /*
++ Ensure that we have UPDATE or SELECT privilege for each table
++ The exact privilege is checked in mysql_multi_update()
++ */
++ for (table= tables; table; table= table->next_local)
++ {
++ if (table->derived)
++ table->grant.privilege= SELECT_ACL;
++ else if ((check_access(thd, UPDATE_ACL, table->db,
++ &table->grant.privilege, 0, 1,
++ test(table->schema_table)) ||
++ check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
++ (check_access(thd, SELECT_ACL, table->db,
++ &table->grant.privilege, 0, 0,
++ test(table->schema_table)) ||
++ check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
++ DBUG_RETURN(TRUE);
++
++ table->table_in_first_from_clause= 1;
++ }
++ /*
++ Is there tables of subqueries?
++ */
++ if (&lex->select_lex != lex->all_selects_list)
++ {
++ DBUG_PRINT("info",("Checking sub query list"));
++ for (table= tables; table; table= table->next_global)
++ {
++ if (!table->table_in_first_from_clause)
++ {
++ if (check_access(thd, SELECT_ACL, table->db,
++ &table->grant.privilege, 0, 0,
++ test(table->schema_table)) ||
++ check_grant(thd, SELECT_ACL, table, 0, 1, 0))
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++
++ if (select_lex->order_list.elements)
++ msg= "ORDER BY";
++ else if (select_lex->select_limit)
++ msg= "LIMIT";
++ if (msg)
++ {
++ my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++/**
++ Multi delete query pre-check.
++
++ @param thd Thread handler
++ @param tables Global/local table list
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE error
++*/
++
++bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
++{
++ SELECT_LEX *select_lex= &thd->lex->select_lex;
++ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
++ TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
++ DBUG_ENTER("multi_delete_precheck");
++
++ /* sql_yacc guarantees that tables and aux_tables are not zero */
++ DBUG_ASSERT(aux_tables != 0);
++ if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
++ DBUG_RETURN(TRUE);
++
++ /*
++ Since aux_tables list is not part of LEX::query_tables list we
++ have to juggle with LEX::query_tables_own_last value to be able
++ call check_table_access() safely.
++ */
++ thd->lex->query_tables_own_last= 0;
++ if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE))
++ {
++ thd->lex->query_tables_own_last= save_query_tables_own_last;
++ DBUG_RETURN(TRUE);
++ }
++ thd->lex->query_tables_own_last= save_query_tables_own_last;
++
++ if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
++ {
++ my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
++ ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Link tables in auxilary table list of multi-delete with corresponding
++ elements in main table list, and set proper locks for them.
++
++ @param lex pointer to LEX representing multi-delete
++
++ @retval
++ FALSE success
++ @retval
++ TRUE error
++*/
++
++bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
++{
++ TABLE_LIST *tables= lex->select_lex.table_list.first;
++ TABLE_LIST *target_tbl;
++ DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
++
++ lex->table_count= 0;
++
++ for (target_tbl= lex->auxiliary_table_list.first;
++ target_tbl; target_tbl= target_tbl->next_local)
++ {
++ lex->table_count++;
++ /* All tables in aux_tables must be found in FROM PART */
++ TABLE_LIST *walk;
++ for (walk= tables; walk; walk= walk->next_local)
++ {
++ if (!my_strcasecmp(table_alias_charset,
++ target_tbl->alias, walk->alias) &&
++ !strcmp(walk->db, target_tbl->db))
++ break;
++ }
++ if (!walk)
++ {
++ my_error(ER_UNKNOWN_TABLE, MYF(0),
++ target_tbl->table_name, "MULTI DELETE");
++ DBUG_RETURN(TRUE);
++ }
++ if (!walk->derived)
++ {
++ target_tbl->table_name= walk->table_name;
++ target_tbl->table_name_length= walk->table_name_length;
++ }
++ walk->updating= target_tbl->updating;
++ walk->lock_type= target_tbl->lock_type;
++ target_tbl->correspondent_table= walk; // Remember corresponding table
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ simple UPDATE query pre-check.
++
++ @param thd Thread handler
++ @param tables Global table list
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE Error
++*/
++
++bool update_precheck(THD *thd, TABLE_LIST *tables)
++{
++ DBUG_ENTER("update_precheck");
++ if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
++ {
++ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
++}
++
++
++/**
++ simple DELETE query pre-check.
++
++ @param thd Thread handler
++ @param tables Global table list
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE error
++*/
++
++bool delete_precheck(THD *thd, TABLE_LIST *tables)
++{
++ DBUG_ENTER("delete_precheck");
++ if (check_one_table_access(thd, DELETE_ACL, tables))
++ DBUG_RETURN(TRUE);
++ /* Set privilege for the WHERE clause */
++ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ simple INSERT query pre-check.
++
++ @param thd Thread handler
++ @param tables Global table list
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE error
++*/
++
++bool insert_precheck(THD *thd, TABLE_LIST *tables)
++{
++ LEX *lex= thd->lex;
++ DBUG_ENTER("insert_precheck");
++
++ /*
++ Check that we have modify privileges for the first table and
++ select privileges for the rest
++ */
++ ulong privilege= (INSERT_ACL |
++ (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
++ (lex->value_list.elements ? UPDATE_ACL : 0));
++
++ if (check_one_table_access(thd, privilege, tables))
++ DBUG_RETURN(TRUE);
++
++ if (lex->update_list.elements != lex->value_list.elements)
++ {
++ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ @brief Check privileges for SHOW CREATE TABLE statement.
++
++ @param thd Thread context
++ @param table Target table
++
++ @retval TRUE Failure
++ @retval FALSE Success
++*/
++
++static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
++{
++ return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db,
++ &table->grant.privilege, 0, 0,
++ test(table->schema_table)) ||
++ check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0);
++}
++
++
++/**
++ CREATE TABLE query pre-check.
++
++ @param thd Thread handler
++ @param tables Global table list
++ @param create_table Table which will be created
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE Error
++*/
++
++bool create_table_precheck(THD *thd, TABLE_LIST *tables,
++ TABLE_LIST *create_table)
++{
++ LEX *lex= thd->lex;
++ SELECT_LEX *select_lex= &lex->select_lex;
++ ulong want_priv;
++ bool error= TRUE; // Error message is given
++ DBUG_ENTER("create_table_precheck");
++
++ /*
++ Require CREATE [TEMPORARY] privilege on new table; for
++ CREATE TABLE ... SELECT, also require INSERT.
++ */
++
++ want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
++ CREATE_TMP_ACL : CREATE_ACL) |
++ (select_lex->item_list.elements ? INSERT_ACL : 0);
++
++ if (check_access(thd, want_priv, create_table->db,
++ &create_table->grant.privilege, 0, 0,
++ test(create_table->schema_table)) ||
++ check_merge_table_access(thd, create_table->db,
++ lex->create_info.merge_list.first))
++ goto err;
++ if (want_priv != CREATE_TMP_ACL &&
++ check_grant(thd, want_priv, create_table, 0, 1, 0))
++ goto err;
++
++ if (select_lex->item_list.elements)
++ {
++ /* Check permissions for used tables in CREATE TABLE ... SELECT */
++
++#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
++ /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
++ /*
++ Only do the check for PS, because we on execute we have to check that
++ 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->stmt_arena->is_stmt_prepare_or_first_sp_execute())
++ {
++ /*
++ For temporary tables we don't have to check if the created table exists
++ */
++ if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
++ find_table_in_global_list(tables, create_table->db,
++ create_table->table_name))
++ {
++ error= FALSE;
++ goto err;
++ }
++ }
++#endif
++ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
++ goto err;
++ }
++ else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
++ {
++ if (check_show_create_table_access(thd, tables))
++ goto err;
++ }
++ error= FALSE;
++
++err:
++ DBUG_RETURN(error);
++}
++
++
++/**
++ negate given expression.
++
++ @param thd thread handler
++ @param expr expression for negation
++
++ @return
++ negated expression
++*/
++
++Item *negate_expression(THD *thd, Item *expr)
++{
++ Item *negated;
++ if (expr->type() == Item::FUNC_ITEM &&
++ ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
++ {
++ /* it is NOT(NOT( ... )) */
++ Item *arg= ((Item_func *) expr)->arguments()[0];
++ enum_parsing_place place= thd->lex->current_select->parsing_place;
++ if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
++ return arg;
++ /*
++ if it is not boolean function then we have to emulate value of
++ not(not(a)), it will be a != 0
++ */
++ return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
++ }
++
++ if ((negated= expr->neg_transformer(thd)) != 0)
++ return negated;
++ return new Item_func_not(expr);
++}
++
++/**
++ Set the specified definer to the default value, which is the
++ current user in the thread.
++
++ @param[in] thd thread handler
++ @param[out] definer definer
++*/
++
++void get_default_definer(THD *thd, LEX_USER *definer)
++{
++ const Security_context *sctx= thd->security_ctx;
++
++ definer->user.str= (char *) sctx->priv_user;
++ definer->user.length= strlen(definer->user.str);
++
++ definer->host.str= (char *) sctx->priv_host;
++ definer->host.length= strlen(definer->host.str);
++
++ definer->password.str= NULL;
++ definer->password.length= 0;
++}
++
++
++/**
++ Create default definer for the specified THD.
++
++ @param[in] thd thread handler
++
++ @return
++ - On success, return a valid pointer to the created and initialized
++ LEX_USER, which contains definer information.
++ - On error, return 0.
++*/
++
++LEX_USER *create_default_definer(THD *thd)
++{
++ LEX_USER *definer;
++
++ if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
++ return 0;
++
++ thd->get_definer(definer);
++
++ return definer;
++}
++
++
++/**
++ Create definer with the given user and host names.
++
++ @param[in] thd thread handler
++ @param[in] user_name user name
++ @param[in] host_name host name
++
++ @return
++ - On success, return a valid pointer to the created and initialized
++ LEX_USER, which contains definer information.
++ - On error, return 0.
++*/
++
++LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
++{
++ LEX_USER *definer;
++
++ /* Create and initialize. */
++
++ if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
++ return 0;
++
++ definer->user= *user_name;
++ definer->host= *host_name;
++ definer->password.str= NULL;
++ definer->password.length= 0;
++
++ return definer;
++}
++
++
++/**
++ Retuns information about user or current user.
++
++ @param[in] thd thread handler
++ @param[in] user user
++
++ @return
++ - On success, return a valid pointer to initialized
++ LEX_USER, which contains user information.
++ - On error, return 0.
++*/
++
++LEX_USER *get_current_user(THD *thd, LEX_USER *user)
++{
++ if (!user->user.str) // current_user
++ return create_default_definer(thd);
++
++ return user;
++}
++
++
++/**
++ Check that byte length of a string does not exceed some limit.
++
++ @param str string to be checked
++ @param err_msg error message to be displayed if the string is too long
++ @param max_length max length
++
++ @retval
++ FALSE the passed string is not longer than max_length
++ @retval
++ TRUE the passed string is longer than max_length
++
++ NOTE
++ The function is not used in existing code but can be useful later?
++*/
++
++bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
++ uint max_byte_length)
++{
++ if (str->length <= max_byte_length)
++ return FALSE;
++
++ my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
++
++ return TRUE;
++}
++
++
++/*
++ Check that char length of a string does not exceed some limit.
++
++ SYNOPSIS
++ check_string_char_length()
++ str string to be checked
++ err_msg error message to be displayed if the string is too long
++ max_char_length max length in symbols
++ cs string charset
++
++ RETURN
++ FALSE the passed string is not longer than max_char_length
++ TRUE the passed string is longer than max_char_length
++*/
++
++
++bool check_string_char_length(LEX_STRING *str, const char *err_msg,
++ uint max_char_length, CHARSET_INFO *cs,
++ bool no_error)
++{
++ int well_formed_error;
++ uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
++ max_char_length, &well_formed_error);
++
++ if (!well_formed_error && str->length == res)
++ return FALSE;
++
++ if (!no_error)
++ my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
++ return TRUE;
++}
++
++
++/*
++ Check if path does not contain mysql data home directory
++ SYNOPSIS
++ test_if_data_home_dir()
++ dir directory
++ conv_home_dir converted data home directory
++ home_dir_len converted data home directory length
++
++ RETURN VALUES
++ 0 ok
++ 1 error
++*/
++C_MODE_START
++
++int test_if_data_home_dir(const char *dir)
++{
++ char path[FN_REFLEN];
++ int dir_len;
++ DBUG_ENTER("test_if_data_home_dir");
++
++ if (!dir)
++ DBUG_RETURN(0);
++
++ (void) fn_format(path, dir, "", "",
++ (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
++ dir_len= strlen(path);
++ if (mysql_unpacked_real_data_home_len<= dir_len)
++ {
++ if (dir_len > mysql_unpacked_real_data_home_len &&
++ path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
++ DBUG_RETURN(0);
++
++ if (lower_case_file_system)
++ {
++ if (!my_strnncoll(default_charset_info, (const uchar*) path,
++ mysql_unpacked_real_data_home_len,
++ (const uchar*) mysql_unpacked_real_data_home,
++ mysql_unpacked_real_data_home_len))
++ DBUG_RETURN(1);
++ }
++ else if (!memcmp(path, mysql_unpacked_real_data_home,
++ mysql_unpacked_real_data_home_len))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++}
++
++C_MODE_END
++
++
++/**
++ Check that host name string is valid.
++
++ @param[in] str string to be checked
++
++ @return Operation status
++ @retval FALSE host name is ok
++ @retval TRUE host name string is longer than max_length or
++ has invalid symbols
++*/
++
++bool check_host_name(LEX_STRING *str)
++{
++ const char *name= str->str;
++ const char *end= str->str + str->length;
++ if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
++ return TRUE;
++
++ while (name != end)
++ {
++ if (*name == '@')
++ {
++ my_printf_error(ER_UNKNOWN_ERROR,
++ "Malformed hostname (illegal symbol: '%c')", MYF(0),
++ *name);
++ return TRUE;
++ }
++ name++;
++ }
++ return FALSE;
++}
++
++
++extern int MYSQLparse(void *thd); // from sql_yacc.cc
++
++
++/**
++ This is a wrapper of MYSQLparse(). All the code should call parse_sql()
++ instead of MYSQLparse().
++
++ @param thd Thread context.
++ @param parser_state Parser state.
++ @param creation_ctx Object creation context.
++
++ @return Error status.
++ @retval FALSE on success.
++ @retval TRUE on parsing error.
++*/
++
++bool parse_sql(THD *thd,
++ Parser_state *parser_state,
++ Object_creation_ctx *creation_ctx)
++{
++ DBUG_ASSERT(thd->m_parser_state == NULL);
++
++ /* Backup creation context. */
++
++ Object_creation_ctx *backup_ctx= NULL;
++
++ if (creation_ctx)
++ backup_ctx= creation_ctx->set_n_backup(thd);
++
++ /* Set parser state. */
++
++ thd->m_parser_state= parser_state;
++
++ /* Parse the query. */
++
++ bool mysql_parse_status= MYSQLparse(thd) != 0;
++
++ /* Check that if MYSQLparse() failed, thd->is_error() is set. */
++
++ DBUG_ASSERT(!mysql_parse_status ||
++ (mysql_parse_status && thd->is_error()));
++
++ /* Reset parser state. */
++
++ thd->m_parser_state= NULL;
++
++ /* Restore creation context. */
++
++ if (creation_ctx)
++ creation_ctx->restore_env(thd, backup_ctx);
++
++ /* That's it. */
++
++ return mysql_parse_status || thd->is_fatal_error;
++}
++
++/**
++ @} (end of group Runtime_Environment)
++*/
+diff -urN mysql-old/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql-old/sql/sql_partition.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/sql_partition.cc 2011-05-10 17:56:01.513349044 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -urN mysql-old/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql-old/sql/sql_plugin.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_plugin.cc 2011-05-10 17:56:01.516682377 +0000
+@@ -508,7 +508,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2124,7 +2124,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -urN mysql-old/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql-old/sql/sql_prepare.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/sql_prepare.cc 2011-05-10 17:56:01.520015710 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -urN mysql-old/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql-old/sql/sql_profile.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/sql_profile.cc 2011-05-10 17:56:01.520015710 +0000
+@@ -252,7 +252,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -urN mysql-old/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql-old/sql/sql_repl.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_repl.cc 2011-05-10 17:56:01.523349043 +0000
+@@ -1297,12 +1297,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1474,7 +1474,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1745,14 +1745,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1761,7 +1761,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -urN mysql-old/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql-old/sql/sql_select.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/sql_select.cc 2011-05-10 17:56:01.526682376 +0000
+@@ -3002,7 +3002,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3938,7 +3938,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3961,7 +3961,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4124,7 +4124,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4444,7 +4444,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4611,7 +4611,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5561,7 +5561,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10477,7 +10477,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13649,7 +13649,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13661,7 +13661,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14359,7 +14359,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14481,7 +14481,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -urN mysql-old/sql/sql_select.cc.orig mysql/sql/sql_select.cc.orig
+--- mysql-old/sql/sql_select.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/sql_select.cc.orig 2011-04-12 12:11:38.000000000 +0000
+@@ -0,0 +1,17352 @@
++/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
++
++/**
++ @file
++
++ @brief
++ mysql_select and join optimization
++
++
++ @defgroup Query_Optimizer Query Optimizer
++ @{
++*/
++
++#ifdef USE_PRAGMA_IMPLEMENTATION
++#pragma implementation // gcc: Class implementation
++#endif
++
++#include "mysql_priv.h"
++#include "sql_select.h"
++#include "sql_cursor.h"
++
++#include <m_ctype.h>
++#include <my_bit.h>
++#include <hash.h>
++#include <ft_global.h>
++
++const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
++ "MAYBE_REF","ALL","range","index","fulltext",
++ "ref_or_null","unique_subquery","index_subquery",
++ "index_merge"
++};
++
++struct st_sargable_param;
++
++static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
++static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
++ DYNAMIC_ARRAY *keyuse);
++static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
++ JOIN_TAB *join_tab,
++ uint tables, COND *conds,
++ COND_EQUAL *cond_equal,
++ table_map table_map, SELECT_LEX *select_lex,
++ st_sargable_param **sargables);
++static int sort_keyuse(KEYUSE *a,KEYUSE *b);
++static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
++static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
++ table_map used_tables);
++static bool choose_plan(JOIN *join,table_map join_tables);
++
++static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
++ table_map remaining_tables, uint idx,
++ double record_count, double read_time);
++static void optimize_straight_join(JOIN *join, table_map join_tables);
++static bool greedy_search(JOIN *join, table_map remaining_tables,
++ uint depth, uint prune_level);
++static bool best_extension_by_limited_search(JOIN *join,
++ table_map remaining_tables,
++ uint idx, double record_count,
++ double read_time, uint depth,
++ uint prune_level);
++static uint determine_search_depth(JOIN* join);
++static int join_tab_cmp(const void* ptr1, const void* ptr2);
++static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
++/*
++ TODO: 'find_best' is here only temporarily until 'greedy_search' is
++ tested and approved.
++*/
++static bool find_best(JOIN *join,table_map rest_tables,uint index,
++ double record_count,double read_time);
++static uint cache_record_length(JOIN *join,uint index);
++static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
++static bool get_best_combination(JOIN *join);
++static store_key *get_store_key(THD *thd,
++ KEYUSE *keyuse, table_map used_tables,
++ KEY_PART_INFO *key_part, uchar *key_buff,
++ uint maybe_null);
++static void make_outerjoin_info(JOIN *join);
++static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
++static void make_join_readinfo(JOIN *join, ulonglong options);
++static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
++static void update_depend_map(JOIN *join);
++static void update_depend_map(JOIN *join, ORDER *order);
++static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
++ bool change_list, bool *simple_order);
++static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
++ List<Item> &fields, bool send_row,
++ ulonglong select_options, const char *info,
++ Item *having);
++static COND *build_equal_items(THD *thd, COND *cond,
++ COND_EQUAL *inherited,
++ List<TABLE_LIST> *join_list,
++ COND_EQUAL **cond_equal_ref);
++static COND* substitute_for_best_equal_field(COND *cond,
++ COND_EQUAL *cond_equal,
++ void *table_join_idx);
++static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
++ COND *conds, bool top);
++static bool check_interleaving_with_nj(JOIN_TAB *next);
++static void restore_prev_nj_state(JOIN_TAB *last);
++static void reset_nj_counters(List<TABLE_LIST> *join_list);
++static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
++ uint first_unused);
++
++static COND *optimize_cond(JOIN *join, COND *conds,
++ List<TABLE_LIST> *join_list,
++ Item::cond_result *cond_value);
++static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
++static bool open_tmp_table(TABLE *table);
++static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
++ ulonglong options);
++static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
++ Procedure *proc);
++
++static enum_nested_loop_state
++evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
++ int error);
++static enum_nested_loop_state
++evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
++static enum_nested_loop_state
++flush_cached_records(JOIN *join, JOIN_TAB *join_tab, bool skip_last);
++static enum_nested_loop_state
++end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++static enum_nested_loop_state
++end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++static enum_nested_loop_state
++end_write(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++static enum_nested_loop_state
++end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++static enum_nested_loop_state
++end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++static enum_nested_loop_state
++end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
++
++static int test_if_group_changed(List<Cached_item> &list);
++static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
++static int join_read_system(JOIN_TAB *tab);
++static int join_read_const(JOIN_TAB *tab);
++static int join_read_key(JOIN_TAB *tab);
++static void join_read_key_unlock_row(st_join_table *tab);
++static int join_read_always_key(JOIN_TAB *tab);
++static int join_read_last_key(JOIN_TAB *tab);
++static int join_no_more_records(READ_RECORD *info);
++static int join_read_next(READ_RECORD *info);
++static int join_init_quick_read_record(JOIN_TAB *tab);
++static int test_if_quick_select(JOIN_TAB *tab);
++static int join_init_read_record(JOIN_TAB *tab);
++static int join_read_first(JOIN_TAB *tab);
++static int join_read_next(READ_RECORD *info);
++static int join_read_next_same(READ_RECORD *info);
++static int join_read_last(JOIN_TAB *tab);
++static int join_read_prev_same(READ_RECORD *info);
++static int join_read_prev(READ_RECORD *info);
++static int join_ft_read_first(JOIN_TAB *tab);
++static int join_ft_read_next(READ_RECORD *info);
++int join_read_always_key_or_null(JOIN_TAB *tab);
++int join_read_next_same_or_null(READ_RECORD *info);
++static COND *make_cond_for_table(COND *cond,table_map table,
++ table_map used_table);
++static Item* part_of_refkey(TABLE *form,Field *field);
++uint find_shortest_key(TABLE *table, const key_map *usable_keys);
++static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
++ ha_rows select_limit, bool no_changes,
++ key_map *map);
++static bool list_contains_unique_index(TABLE *table,
++ bool (*find_func) (Field *, void *), void *data);
++static bool find_field_in_item_list (Field *field, void *data);
++static bool find_field_in_order_list (Field *field, void *data);
++static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
++ ha_rows filesort_limit, ha_rows select_limit,
++ bool is_order_by);
++static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
++ Item *having);
++static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
++ ulong offset,Item *having);
++static int remove_dup_with_hash_index(THD *thd,TABLE *table,
++ uint field_count, Field **first_field,
++
++ ulong key_length,Item *having);
++static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
++static ulong used_blob_length(CACHE_FIELD **ptr);
++static bool store_record_in_cache(JOIN_CACHE *cache);
++static void reset_cache_read(JOIN_CACHE *cache);
++static void reset_cache_write(JOIN_CACHE *cache);
++static void read_cached_record(JOIN_TAB *tab);
++static bool cmp_buffer_with_ref(JOIN_TAB *tab);
++static bool setup_new_fields(THD *thd, List<Item> &fields,
++ List<Item> &all_fields, ORDER *new_order);
++static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
++ ORDER *order, List<Item> &fields,
++ List<Item> &all_fields,
++ bool *all_order_by_fields_used);
++static bool test_if_subpart(ORDER *a,ORDER *b);
++static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
++static void calc_group_buffer(JOIN *join,ORDER *group);
++static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
++static bool alloc_group_fields(JOIN *join,ORDER *group);
++// Create list for using with tempory table
++static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
++ List<Item> &new_list1,
++ List<Item> &new_list2,
++ uint elements, List<Item> &items);
++// Create list for using with tempory table
++static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
++ List<Item> &new_list1,
++ List<Item> &new_list2,
++ uint elements, List<Item> &items);
++static void init_tmptable_sum_functions(Item_sum **func);
++static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table);
++static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
++static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
++static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
++static bool init_sum_functions(Item_sum **func, Item_sum **end);
++static bool update_sum_func(Item_sum **func);
++static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
++ bool distinct, const char *message=NullS);
++static Item *remove_additional_cond(Item* conds);
++static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
++static bool test_if_ref(Item_field *left_item,Item *right_item);
++
++
++/**
++ This handles SELECT with and without UNION.
++*/
++
++bool handle_select(THD *thd, LEX *lex, select_result *result,
++ ulong setup_tables_done_option)
++{
++ bool res;
++ register SELECT_LEX *select_lex = &lex->select_lex;
++ DBUG_ENTER("handle_select");
++
++ if (select_lex->master_unit()->is_union() ||
++ select_lex->master_unit()->fake_select_lex)
++ res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
++ else
++ {
++ SELECT_LEX_UNIT *unit= &lex->unit;
++ unit->set_limit(unit->global_parameters);
++ /*
++ 'options' of mysql_select will be set in JOIN, as far as JOIN for
++ every PS/SP execution new, we will not need reset this flag if
++ setup_tables_done_option changed for next rexecution
++ */
++ res= mysql_select(thd, &select_lex->ref_pointer_array,
++ select_lex->table_list.first,
++ select_lex->with_wild, select_lex->item_list,
++ select_lex->where,
++ select_lex->order_list.elements +
++ select_lex->group_list.elements,
++ select_lex->order_list.first,
++ select_lex->group_list.first,
++ select_lex->having,
++ lex->proc_list.first,
++ select_lex->options | thd->options |
++ setup_tables_done_option,
++ result, unit, select_lex);
++ }
++ DBUG_PRINT("info",("res: %d report_error: %d", res,
++ thd->is_error()));
++ res|= thd->is_error();
++ if (unlikely(res))
++ result->abort();
++
++ DBUG_RETURN(res);
++}
++
++
++/**
++ Fix fields referenced from inner selects.
++
++ @param thd Thread handle
++ @param all_fields List of all fields used in select
++ @param select Current select
++ @param ref_pointer_array Array of references to Items used in current select
++ @param group_list GROUP BY list (is NULL by default)
++
++ @details
++ The function serves 3 purposes
++
++ - adds fields referenced from inner query blocks to the current select list
++
++ - Decides which class to use to reference the items (Item_ref or
++ Item_direct_ref)
++
++ - fixes references (Item_ref objects) to these fields.
++
++ If a field isn't already on the select list and the ref_pointer_array
++ is provided then it is added to the all_fields list and the pointer to
++ it is saved in the ref_pointer_array.
++
++ The class to access the outer field is determined by the following rules:
++
++ -#. If the outer field isn't used under an aggregate function then the
++ Item_ref class should be used.
++
++ -#. If the outer field is used under an aggregate function and this
++ function is, in turn, aggregated in the query block where the outer
++ field was resolved or some query nested therein, then the
++ Item_direct_ref class should be used. Also it should be used if we are
++ grouping by a subquery containing the outer field.
++
++ The resolution is done here and not at the fix_fields() stage as
++ it can be done only after aggregate functions are fixed and pulled up to
++ selects where they are to be aggregated.
++
++ When the class is chosen it substitutes the original field in the
++ Item_outer_ref object.
++
++ After this we proceed with fixing references (Item_outer_ref objects) to
++ this field from inner subqueries.
++
++ @return Status
++ @retval true An error occured.
++ @retval false OK.
++ */
++
++bool
++fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
++ Item **ref_pointer_array, ORDER *group_list)
++{
++ Item_outer_ref *ref;
++
++ List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
++ while ((ref= ref_it++))
++ {
++ bool direct_ref= false;
++ Item *item= ref->outer_ref;
++ Item **item_ref= ref->ref;
++ Item_ref *new_ref;
++ /*
++ TODO: this field item already might be present in the select list.
++ In this case instead of adding new field item we could use an
++ existing one. The change will lead to less operations for copying fields,
++ smaller temporary tables and less data passed through filesort.
++ */
++ if (ref_pointer_array && !ref->found_in_select_list)
++ {
++ int el= all_fields.elements;
++ ref_pointer_array[el]= item;
++ /* Add the field item to the select list of the current select. */
++ all_fields.push_front(item);
++ /*
++ If it's needed reset each Item_ref item that refers this field with
++ a new reference taken from ref_pointer_array.
++ */
++ item_ref= ref_pointer_array + el;
++ }
++
++ if (ref->in_sum_func)
++ {
++ Item_sum *sum_func;
++ if (ref->in_sum_func->nest_level > select->nest_level)
++ direct_ref= TRUE;
++ else
++ {
++ for (sum_func= ref->in_sum_func; sum_func &&
++ sum_func->aggr_level >= select->nest_level;
++ sum_func= sum_func->in_sum_func)
++ {
++ if (sum_func->aggr_level == select->nest_level)
++ {
++ direct_ref= TRUE;
++ break;
++ }
++ }
++ }
++ }
++ else
++ {
++ /*
++ Check if GROUP BY item trees contain the outer ref:
++ in this case we have to use Item_direct_ref instead of Item_ref.
++ */
++ for (ORDER *group= group_list; group; group= group->next)
++ {
++ if ((*group->item)->walk(&Item::find_item_processor, TRUE,
++ (uchar *) ref))
++ {
++ direct_ref= TRUE;
++ break;
++ }
++ }
++ }
++ new_ref= direct_ref ?
++ new Item_direct_ref(ref->context, item_ref, ref->table_name,
++ ref->field_name, ref->alias_name_used) :
++ new Item_ref(ref->context, item_ref, ref->table_name,
++ ref->field_name, ref->alias_name_used);
++ if (!new_ref)
++ return TRUE;
++ ref->outer_ref= new_ref;
++ ref->ref= &ref->outer_ref;
++
++ if (!ref->fixed && ref->fix_fields(thd, 0))
++ return TRUE;
++ thd->used_tables|= item->used_tables();
++ }
++ return false;
++}
++
++/**
++ Function to setup clauses without sum functions.
++*/
++inline int setup_without_group(THD *thd, Item **ref_pointer_array,
++ TABLE_LIST *tables,
++ TABLE_LIST *leaves,
++ List<Item> &fields,
++ List<Item> &all_fields,
++ COND **conds,
++ ORDER *order,
++ ORDER *group, bool *hidden_group_fields)
++{
++ int res;
++ nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
++ /*
++ Need to save the value, so we can turn off only the new NON_AGG_FIELD
++ additions coming from the WHERE
++ */
++ uint8 saved_flag= thd->lex->current_select->full_group_by_flag;
++ DBUG_ENTER("setup_without_group");
++
++ thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
++ res= setup_conds(thd, tables, leaves, conds);
++
++ /* it's not wrong to have non-aggregated columns in a WHERE */
++ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
++ thd->lex->current_select->full_group_by_flag= saved_flag |
++ (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED);
++
++ thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
++ res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
++ order);
++ thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
++ res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
++ group, hidden_group_fields);
++ thd->lex->allow_sum_func= save_allow_sum_func;
++ DBUG_RETURN(res);
++}
++
++/*****************************************************************************
++ Check fields, find best join, do the select and output fields.
++ mysql_select assumes that all tables are already opened
++*****************************************************************************/
++
++/**
++ Prepare of whole select (including sub queries in future).
++
++ @todo
++ Add check of calculation of GROUP functions and fields:
++ SELECT COUNT(*)+table.col1 from table1;
++
++ @retval
++ -1 on error
++ @retval
++ 0 on success
++*/
++int
++JOIN::prepare(Item ***rref_pointer_array,
++ TABLE_LIST *tables_init,
++ uint wild_num, COND *conds_init, uint og_num,
++ ORDER *order_init, ORDER *group_init,
++ Item *having_init,
++ ORDER *proc_param_init, SELECT_LEX *select_lex_arg,
++ SELECT_LEX_UNIT *unit_arg)
++{
++ DBUG_ENTER("JOIN::prepare");
++
++ // to prevent double initialization on EXPLAIN
++ if (optimized)
++ DBUG_RETURN(0);
++
++ conds= conds_init;
++ order= order_init;
++ group_list= group_init;
++ having= having_init;
++ proc_param= proc_param_init;
++ tables_list= tables_init;
++ select_lex= select_lex_arg;
++ select_lex->join= this;
++ join_list= &select_lex->top_join_list;
++ union_part= unit_arg->is_union();
++
++ thd->lex->current_select->is_item_list_lookup= 1;
++ /*
++ If we have already executed SELECT, then it have not sense to prevent
++ its table from update (see unique_table())
++ */
++ if (thd->derived_tables_processing)
++ select_lex->exclude_from_table_unique_test= TRUE;
++
++ /* Check that all tables, fields, conds and order are ok */
++
++ if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
++ setup_tables_and_check_access(thd, &select_lex->context, join_list,
++ tables_list, &select_lex->leaf_tables,
++ FALSE, SELECT_ACL, SELECT_ACL))
++ DBUG_RETURN(-1);
++
++ TABLE_LIST *table_ptr;
++ for (table_ptr= select_lex->leaf_tables;
++ table_ptr;
++ table_ptr= table_ptr->next_leaf)
++ tables++;
++
++ if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
++ select_lex->setup_ref_array(thd, og_num) ||
++ setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
++ &all_fields, 1) ||
++ setup_without_group(thd, (*rref_pointer_array), tables_list,
++ select_lex->leaf_tables, fields_list,
++ all_fields, &conds, order, group_list,
++ &hidden_group_fields))
++ DBUG_RETURN(-1); /* purecov: inspected */
++
++ ref_pointer_array= *rref_pointer_array;
++
++ if (having)
++ {
++ nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
++ thd->where="having clause";
++ thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
++ select_lex->having_fix_field= 1;
++ bool having_fix_rc= (!having->fixed &&
++ (having->fix_fields(thd, &having) ||
++ having->check_cols(1)));
++ select_lex->having_fix_field= 0;
++ if (having_fix_rc || thd->is_error())
++ DBUG_RETURN(-1); /* purecov: inspected */
++ thd->lex->allow_sum_func= save_allow_sum_func;
++ }
++
++ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
++ !(select_options & SELECT_DESCRIBE))
++ {
++ Item_subselect *subselect;
++ /* Is it subselect? */
++ if ((subselect= select_lex->master_unit()->item))
++ {
++ Item_subselect::trans_res res;
++ if ((res= subselect->select_transformer(this)) !=
++ Item_subselect::RES_OK)
++ {
++ select_lex->fix_prepare_information(thd, &conds, &having);
++ DBUG_RETURN((res == Item_subselect::RES_ERROR));
++ }
++ }
++ }
++
++ select_lex->fix_prepare_information(thd, &conds, &having);
++
++ if (order)
++ {
++ bool real_order= FALSE;
++ ORDER *ord;
++ for (ord= order; ord; ord= ord->next)
++ {
++ Item *item= *ord->item;
++ /*
++ Disregard sort order if there's only
++ zero length NOT NULL fields (e.g. {VAR}CHAR(0) NOT NULL") or
++ zero length NOT NULL string functions there.
++ Such tuples don't contain any data to sort.
++ */
++ if (!real_order &&
++ /* Not a zero length NOT NULL field */
++ ((item->type() != Item::FIELD_ITEM ||
++ ((Item_field *) item)->field->maybe_null() ||
++ ((Item_field *) item)->field->sort_length()) &&
++ /* AND not a zero length NOT NULL string function. */
++ (item->type() != Item::FUNC_ITEM ||
++ item->maybe_null ||
++ item->result_type() != STRING_RESULT ||
++ item->max_length)))
++ real_order= TRUE;
++
++ if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
++ item->split_sum_func(thd, ref_pointer_array, all_fields);
++ }
++ if (!real_order)
++ order= NULL;
++ }
++
++ if (having && having->with_sum_func)
++ having->split_sum_func2(thd, ref_pointer_array, all_fields,
++ &having, TRUE);
++ if (select_lex->inner_sum_func_list)
++ {
++ Item_sum *end=select_lex->inner_sum_func_list;
++ Item_sum *item_sum= end;
++ do
++ {
++ item_sum= item_sum->next;
++ item_sum->split_sum_func2(thd, ref_pointer_array,
++ all_fields, item_sum->ref_by, FALSE);
++ } while (item_sum != end);
++ }
++
++ if (select_lex->inner_refs_list.elements &&
++ fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array,
++ group_list))
++ DBUG_RETURN(-1);
++
++ if (group_list)
++ {
++ /*
++ Because HEAP tables can't index BIT fields we need to use an
++ additional hidden field for grouping because later it will be
++ converted to a LONG field. Original field will remain of the
++ BIT type and will be returned to a client.
++ */
++ for (ORDER *ord= group_list; ord; ord= ord->next)
++ {
++ if ((*ord->item)->type() == Item::FIELD_ITEM &&
++ (*ord->item)->field_type() == MYSQL_TYPE_BIT)
++ {
++ Item_field *field= new Item_field(thd, *(Item_field**)ord->item);
++ int el= all_fields.elements;
++ ref_pointer_array[el]= field;
++ all_fields.push_front(field);
++ ord->item= ref_pointer_array + el;
++ }
++ }
++ }
++
++ if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
++ DBUG_RETURN(-1);
++
++
++ /*
++ Check if there are references to un-aggregated columns when computing
++ aggregate functions with implicit grouping (there is no GROUP BY).
++ */
++ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
++ select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
++ {
++ my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
++ ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
++ DBUG_RETURN(-1);
++ }
++ {
++ /* Caclulate the number of groups */
++ send_group_parts= 0;
++ for (ORDER *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
++ send_group_parts++;
++ }
++
++ procedure= setup_procedure(thd, proc_param, result, fields_list, &error);
++ if (error)
++ goto err; /* purecov: inspected */
++ if (procedure)
++ {
++ if (setup_new_fields(thd, fields_list, all_fields,
++ procedure->param_fields))
++ goto err; /* purecov: inspected */
++ if (procedure->group)
++ {
++ if (!test_if_subpart(procedure->group,group_list))
++ { /* purecov: inspected */
++ my_message(ER_DIFF_GROUPS_PROC, ER(ER_DIFF_GROUPS_PROC),
++ MYF(0)); /* purecov: inspected */
++ goto err; /* purecov: inspected */
++ }
++ }
++ if (order && (procedure->flags & PROC_NO_SORT))
++ { /* purecov: inspected */
++ my_message(ER_ORDER_WITH_PROC, ER(ER_ORDER_WITH_PROC),
++ MYF(0)); /* purecov: inspected */
++ goto err; /* purecov: inspected */
++ }
++ if (thd->lex->derived_tables)
++ {
++ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE",
++ thd->lex->derived_tables & DERIVED_VIEW ?
++ "view" : "subquery");
++ goto err;
++ }
++ if (thd->lex->sql_command != SQLCOM_SELECT)
++ {
++ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "non-SELECT");
++ goto err;
++ }
++ }
++
++ if (!procedure && result && result->prepare(fields_list, unit_arg))
++ goto err; /* purecov: inspected */
++
++ /* Init join struct */
++ count_field_types(select_lex, &tmp_table_param, all_fields, 0);
++ ref_pointer_array_size= all_fields.elements*sizeof(Item*);
++ this->group= group_list != 0;
++ unit= unit_arg;
++
++ if (tmp_table_param.sum_func_count && !group_list)
++ implicit_grouping= TRUE;
++
++#ifdef RESTRICTED_GROUP
++ if (implicit_grouping)
++ {
++ my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
++ goto err;
++ }
++#endif
++ if (select_lex->olap == ROLLUP_TYPE && rollup_init())
++ goto err;
++ if (alloc_func_list())
++ goto err;
++
++ DBUG_RETURN(0); // All OK
++
++err:
++ delete procedure; /* purecov: inspected */
++ procedure= 0;
++ DBUG_RETURN(-1); /* purecov: inspected */
++}
++
++
++/*
++ Remove the predicates pushed down into the subquery
++
++ SYNOPSIS
++ JOIN::remove_subq_pushed_predicates()
++ where IN Must be NULL
++ OUT The remaining WHERE condition, or NULL
++
++ DESCRIPTION
++ Given that this join will be executed using (unique|index)_subquery,
++ without "checking NULL", remove the predicates that were pushed down
++ into the subquery.
++
++ If the subquery compares scalar values, we can remove the condition that
++ was wrapped into trig_cond (it will be checked when needed by the subquery
++ engine)
++
++ If the subquery compares row values, we need to keep the wrapped
++ equalities in the WHERE clause: when the left (outer) tuple has both NULL
++ and non-NULL values, we'll do a full table scan and will rely on the
++ equalities corresponding to non-NULL parts of left tuple to filter out
++ non-matching records.
++
++ TODO: We can remove the equalities that will be guaranteed to be true by the
++ fact that subquery engine will be using index lookup. This must be done only
++ for cases where there are no conversion errors of significance, e.g. 257
++ that is searched in a byte. But this requires homogenization of the return
++ codes of all Field*::store() methods.
++*/
++
++void JOIN::remove_subq_pushed_predicates(Item **where)
++{
++ if (conds->type() == Item::FUNC_ITEM &&
++ ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
++ ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
++ ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
++ test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
++ ((Item_func *)conds)->arguments()[0]))
++ {
++ *where= 0;
++ return;
++ }
++}
++
++
++/*
++ Index lookup-based subquery: save some flags for EXPLAIN output
++
++ SYNOPSIS
++ save_index_subquery_explain_info()
++ join_tab Subquery's join tab (there is only one as index lookup is
++ only used for subqueries that are single-table SELECTs)
++ where Subquery's WHERE clause
++
++ DESCRIPTION
++ For index lookup-based subquery (i.e. one executed with
++ subselect_uniquesubquery_engine or subselect_indexsubquery_engine),
++ check its EXPLAIN output row should contain
++ "Using index" (TAB_INFO_FULL_SCAN_ON_NULL)
++ "Using Where" (TAB_INFO_USING_WHERE)
++ "Full scan on NULL key" (TAB_INFO_FULL_SCAN_ON_NULL)
++ and set appropriate flags in join_tab->packed_info.
++*/
++
++static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
++{
++ join_tab->packed_info= TAB_INFO_HAVE_VALUE;
++ if (join_tab->table->covering_keys.is_set(join_tab->ref.key))
++ join_tab->packed_info |= TAB_INFO_USING_INDEX;
++ if (where)
++ join_tab->packed_info |= TAB_INFO_USING_WHERE;
++ for (uint i = 0; i < join_tab->ref.key_parts; i++)
++ {
++ if (join_tab->ref.cond_guards[i])
++ {
++ join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
++ break;
++ }
++ }
++}
++
++
++/**
++ global select optimisation.
++
++ @note
++ error code saved in field 'error'
++
++ @retval
++ 0 success
++ @retval
++ 1 error
++*/
++
++int
++JOIN::optimize()
++{
++ DBUG_ENTER("JOIN::optimize");
++ // to prevent double initialization on EXPLAIN
++ if (optimized)
++ DBUG_RETURN(0);
++ optimized= 1;
++
++ thd_proc_info(thd, "optimizing");
++ row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
++ unit->select_limit_cnt);
++ /* select_limit is used to decide if we are likely to scan the whole table */
++ select_limit= unit->select_limit_cnt;
++ if (having || (select_options & OPTION_FOUND_ROWS))
++ select_limit= HA_POS_ERROR;
++ do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
++ // Ignore errors of execution if option IGNORE present
++ if (thd->lex->ignore)
++ thd->lex->current_select->no_error= 1;
++#ifdef HAVE_REF_TO_FIELDS // Not done yet
++ /* Add HAVING to WHERE if possible */
++ if (having && !group_list && !sum_func_count)
++ {
++ if (!conds)
++ {
++ conds= having;
++ having= 0;
++ }
++ else if ((conds=new Item_cond_and(conds,having)))
++ {
++ /*
++ Item_cond_and can't be fixed after creation, so we do not check
++ conds->fixed
++ */
++ conds->fix_fields(thd, &conds);
++ conds->change_ref_to_fields(thd, tables_list);
++ conds->top_level_item();
++ having= 0;
++ }
++ }
++#endif
++ SELECT_LEX *sel= thd->lex->current_select;
++ if (sel->first_cond_optimization)
++ {
++ /*
++ The following code will allocate the new items in a permanent
++ MEMROOT for prepared statements and stored procedures.
++ */
++
++ Query_arena *arena= thd->stmt_arena, backup;
++ if (arena->is_conventional())
++ arena= 0; // For easier test
++ else
++ thd->set_n_backup_active_arena(arena, &backup);
++
++ sel->first_cond_optimization= 0;
++
++ /* Convert all outer joins to inner joins if possible */
++ conds= simplify_joins(this, join_list, conds, TRUE);
++ build_bitmap_for_nested_joins(join_list, 0);
++
++ sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
++
++ if (arena)
++ thd->restore_active_arena(arena, &backup);
++ }
++
++ conds= optimize_cond(this, conds, join_list, &cond_value);
++ if (thd->is_error())
++ {
++ error= 1;
++ DBUG_PRINT("error",("Error from optimize_cond"));
++ DBUG_RETURN(1);
++ }
++
++ {
++ having= optimize_cond(this, having, join_list, &having_value);
++ if (thd->is_error())
++ {
++ error= 1;
++ DBUG_PRINT("error",("Error from optimize_cond"));
++ DBUG_RETURN(1);
++ }
++ if (select_lex->where)
++ select_lex->cond_value= cond_value;
++ if (select_lex->having)
++ select_lex->having_value= having_value;
++
++ if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
++ (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
++ { /* Impossible cond */
++ DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
++ "Impossible HAVING" : "Impossible WHERE"));
++ zero_result_cause= having_value == Item::COND_FALSE ?
++ "Impossible HAVING" : "Impossible WHERE";
++ tables= 0;
++ error= 0;
++ DBUG_RETURN(0);
++ }
++ }
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ {
++ TABLE_LIST *tbl;
++ for (tbl= select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
++ {
++ /*
++ If tbl->embedding!=NULL that means that this table is in the inner
++ part of the nested outer join, and we can't do partition pruning
++ (TODO: check if this limitation can be lifted)
++ */
++ if (!tbl->embedding)
++ {
++ Item *prune_cond= tbl->on_expr? tbl->on_expr : conds;
++ tbl->table->no_partitions_used= prune_partitions(thd, tbl->table,
++ prune_cond);
++ }
++ }
++ }
++#endif
++
++ /*
++ Try to optimize count(*), min() and max() to const fields if
++ there is implicit grouping (aggregate functions but no
++ group_list). In this case, the result set shall only contain one
++ row.
++ */
++ if (tables_list && implicit_grouping)
++ {
++ int res;
++ /*
++ opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
++ to the WHERE conditions,
++ or 1 if all items were resolved (optimized away),
++ or 0, or an error number HA_ERR_...
++
++ If all items were resolved by opt_sum_query, there is no need to
++ open any tables.
++ */
++ if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
++ {
++ if (res == HA_ERR_KEY_NOT_FOUND)
++ {
++ DBUG_PRINT("info",("No matching min/max row"));
++ zero_result_cause= "No matching min/max row";
++ tables= 0;
++ error=0;
++ DBUG_RETURN(0);
++ }
++ if (res > 1)
++ {
++ error= res;
++ DBUG_PRINT("error",("Error from opt_sum_query"));
++ DBUG_RETURN(1);
++ }
++ if (res < 0)
++ {
++ DBUG_PRINT("info",("No matching min/max row"));
++ zero_result_cause= "No matching min/max row";
++ tables= 0;
++ error=0;
++ DBUG_RETURN(0);
++ }
++ DBUG_PRINT("info",("Select tables optimized away"));
++ zero_result_cause= "Select tables optimized away";
++ tables_list= 0; // All tables resolved
++ const_tables= tables;
++ /*
++ Extract all table-independent conditions and replace the WHERE
++ clause with them. All other conditions were computed by opt_sum_query
++ and the MIN/MAX/COUNT function(s) have been replaced by constants,
++ so there is no need to compute the whole WHERE clause again.
++ Notice that make_cond_for_table() will always succeed to remove all
++ computed conditions, because opt_sum_query() is applicable only to
++ conjunctions.
++ Preserve conditions for EXPLAIN.
++ */
++ if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
++ {
++ COND *table_independent_conds=
++ make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0);
++ DBUG_EXECUTE("where",
++ print_where(table_independent_conds,
++ "where after opt_sum_query()",
++ QT_ORDINARY););
++ conds= table_independent_conds;
++ }
++ }
++ }
++ if (!tables_list)
++ {
++ DBUG_PRINT("info",("No tables"));
++ error= 0;
++ DBUG_RETURN(0);
++ }
++ error= -1; // Error is sent to client
++ sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
++
++ /* Calculate how to do the join */
++ thd_proc_info(thd, "statistics");
++ if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
++ thd->is_fatal_error)
++ {
++ DBUG_PRINT("error",("Error: make_join_statistics() failed"));
++ DBUG_RETURN(1);
++ }
++
++ if (rollup.state != ROLLUP::STATE_NONE)
++ {
++ if (rollup_process_const_fields())
++ {
++ DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
++ DBUG_RETURN(1);
++ }
++ }
++ else
++ {
++ /* Remove distinct if only const tables */
++ select_distinct= select_distinct && (const_tables != tables);
++ }
++
++ thd_proc_info(thd, "preparing");
++ if (result->initialize_tables(this))
++ {
++ DBUG_PRINT("error",("Error: initialize_tables() failed"));
++ DBUG_RETURN(1); // error == -1
++ }
++ if (const_table_map != found_const_table_map &&
++ !(select_options & SELECT_DESCRIBE) &&
++ (!conds ||
++ !(conds->used_tables() & RAND_TABLE_BIT) ||
++ select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
++ {
++ zero_result_cause= "no matching row in const table";
++ DBUG_PRINT("error",("Error: %s", zero_result_cause));
++ error= 0;
++ DBUG_RETURN(0);
++ }
++ if (!(thd->options & OPTION_BIG_SELECTS) &&
++ best_read > (double) thd->variables.max_join_size &&
++ !(select_options & SELECT_DESCRIBE))
++ { /* purecov: inspected */
++ my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
++ error= -1;
++ DBUG_RETURN(1);
++ }
++ if (const_tables && !thd->locked_tables &&
++ !(select_options & SELECT_NO_UNLOCK))
++ mysql_unlock_some_tables(thd, table, const_tables);
++ if (!conds && outer_join)
++ {
++ /* Handle the case where we have an OUTER JOIN without a WHERE */
++ conds=new Item_int((longlong) 1,1); // Always true
++ }
++ select= make_select(*table, const_table_map,
++ const_table_map, conds, 1, &error);
++ if (error)
++ { /* purecov: inspected */
++ error= -1; /* purecov: inspected */
++ DBUG_PRINT("error",("Error: make_select() failed"));
++ DBUG_RETURN(1);
++ }
++
++ reset_nj_counters(join_list);
++ make_outerjoin_info(this);
++
++ /*
++ Among the equal fields belonging to the same multiple equality
++ choose the one that is to be retrieved first and substitute
++ all references to these in where condition for a reference for
++ the selected field.
++ */
++ if (conds)
++ {
++ conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
++ conds->update_used_tables();
++ DBUG_EXECUTE("where",
++ print_where(conds,
++ "after substitute_best_equal",
++ QT_ORDINARY););
++ }
++
++ /*
++ Permorm the the optimization on fields evaluation mentioned above
++ for all on expressions.
++ */
++ for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
++ {
++ if (*tab->on_expr_ref)
++ {
++ *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
++ tab->cond_equal,
++ map2table);
++ (*tab->on_expr_ref)->update_used_tables();
++ }
++ }
++
++ if (conds && const_table_map != found_const_table_map &&
++ (select_options & SELECT_DESCRIBE))
++ {
++ conds=new Item_int((longlong) 0,1); // Always false
++ }
++
++ /*
++ It's necessary to check const part of HAVING cond as
++ there is a chance that some cond parts may become
++ const items after make_join_statisctics(for example
++ when Item is a reference to cost table field from
++ outer join).
++ This check is performed only for those conditions
++ which do not use aggregate functions. In such case
++ temporary table may not be used and const condition
++ elements may be lost during further having
++ condition transformation in JOIN::exec.
++ */
++ if (having && const_table_map && !having->with_sum_func)
++ {
++ having->update_used_tables();
++ having= remove_eq_conds(thd, having, &having_value);
++ if (having_value == Item::COND_FALSE)
++ {
++ having= new Item_int((longlong) 0,1);
++ zero_result_cause= "Impossible HAVING noticed after reading const tables";
++ DBUG_RETURN(0);
++ }
++ }
++
++ if (make_join_select(this, select, conds))
++ {
++ zero_result_cause=
++ "Impossible WHERE noticed after reading const tables";
++ DBUG_RETURN(0); // error == 0
++ }
++
++ error= -1; /* if goto err */
++
++ /* Optimize distinct away if possible */
++ {
++ ORDER *org_order= order;
++ order=remove_const(this, order,conds,1, &simple_order);
++ if (thd->is_error())
++ {
++ error= 1;
++ DBUG_PRINT("error",("Error from remove_const"));
++ DBUG_RETURN(1);
++ }
++
++ /*
++ If we are using ORDER BY NULL or ORDER BY const_expression,
++ return result in any order (even if we are using a GROUP BY)
++ */
++ if (!order && org_order)
++ skip_sort_order= 1;
++ }
++ /*
++ Check if we can optimize away GROUP BY/DISTINCT.
++ We can do that if there are no aggregate functions, the
++ fields in DISTINCT clause (if present) and/or columns in GROUP BY
++ (if present) contain direct references to all key parts of
++ an unique index (in whatever order) and if the key parts of the
++ unique index cannot contain NULLs.
++ Note that the unique keys for DISTINCT and GROUP BY should not
++ be the same (as long as they are unique).
++
++ The FROM clause must contain a single non-constant table.
++ */
++ if (tables - const_tables == 1 && (group_list || select_distinct) &&
++ !tmp_table_param.sum_func_count &&
++ (!join_tab[const_tables].select ||
++ !join_tab[const_tables].select->quick ||
++ join_tab[const_tables].select->quick->get_type() !=
++ QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
++ {
++ if (group_list && rollup.state == ROLLUP::STATE_NONE &&
++ list_contains_unique_index(join_tab[const_tables].table,
++ find_field_in_order_list,
++ (void *) group_list))
++ {
++ /*
++ We have found that grouping can be removed since groups correspond to
++ only one row anyway, but we still have to guarantee correct result
++ order. The line below effectively rewrites the query from GROUP BY
++ <fields> to ORDER BY <fields>. There are two exceptions:
++ - if skip_sort_order is set (see above), then we can simply skip
++ GROUP BY;
++ - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
++ with the GROUP BY ones, i.e. either one is a prefix of another.
++ We only check if the ORDER BY is a prefix of GROUP BY. In this case
++ test_if_subpart() copies the ASC/DESC attributes from the original
++ ORDER BY fields.
++ If GROUP BY is a prefix of ORDER BY, then it is safe to leave
++ 'order' as is.
++ */
++ if (!order || test_if_subpart(group_list, order))
++ order= skip_sort_order ? 0 : group_list;
++ /*
++ If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
++ rewritten to IGNORE INDEX FOR ORDER BY(fields).
++ */
++ join_tab->table->keys_in_use_for_order_by=
++ join_tab->table->keys_in_use_for_group_by;
++ group_list= 0;
++ group= 0;
++ }
++ if (select_distinct &&
++ list_contains_unique_index(join_tab[const_tables].table,
++ find_field_in_item_list,
++ (void *) &fields_list))
++ {
++ select_distinct= 0;
++ }
++ }
++ if (group_list || tmp_table_param.sum_func_count)
++ {
++ if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
++ select_distinct=0;
++ }
++ else if (select_distinct && tables - const_tables == 1 &&
++ rollup.state == ROLLUP::STATE_NONE)
++ {
++ /*
++ We are only using one table. In this case we change DISTINCT to a
++ GROUP BY query if:
++ - The GROUP BY can be done through indexes (no sort) and the ORDER
++ BY only uses selected fields.
++ (In this case we can later optimize away GROUP BY and ORDER BY)
++ - We are scanning the whole table without LIMIT
++ This can happen if:
++ - We are using CALC_FOUND_ROWS
++ - We are using an ORDER BY that can't be optimized away.
++
++ We don't want to use this optimization when we are using LIMIT
++ because in this case we can just create a temporary table that
++ holds LIMIT rows and stop when this table is full.
++ */
++ JOIN_TAB *tab= &join_tab[const_tables];
++ bool all_order_fields_used;
++ if (order)
++ skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
++ &tab->table->keys_in_use_for_order_by);
++ if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
++ order, fields_list, all_fields,
++ &all_order_fields_used)))
++ {
++ bool skip_group= (skip_sort_order &&
++ test_if_skip_sort_order(tab, group_list, select_limit, 1,
++ &tab->table->keys_in_use_for_group_by) != 0);
++ count_field_types(select_lex, &tmp_table_param, all_fields, 0);
++ if ((skip_group && all_order_fields_used) ||
++ select_limit == HA_POS_ERROR ||
++ (order && !skip_sort_order))
++ {
++ /* Change DISTINCT to GROUP BY */
++ select_distinct= 0;
++ no_order= !order;
++ if (all_order_fields_used)
++ {
++ if (order && skip_sort_order)
++ {
++ /*
++ Force MySQL to read the table in sorted order to get result in
++ ORDER BY order.
++ */
++ tmp_table_param.quick_group=0;
++ }
++ order=0;
++ }
++ group=1; // For end_write_group
++ }
++ else
++ group_list= 0;
++ }
++ else if (thd->is_fatal_error) // End of memory
++ DBUG_RETURN(1);
++ }
++ simple_group= 0;
++ {
++ ORDER *old_group_list;
++ group_list= remove_const(this, (old_group_list= group_list), conds,
++ rollup.state == ROLLUP::STATE_NONE,
++ &simple_group);
++ if (thd->is_error())
++ {
++ error= 1;
++ DBUG_PRINT("error",("Error from remove_const"));
++ DBUG_RETURN(1);
++ }
++ if (old_group_list && !group_list)
++ select_distinct= 0;
++ }
++ if (!group_list && group)
++ {
++ order=0; // The output has only one row
++ simple_order=1;
++ select_distinct= 0; // No need in distinct for 1 row
++ group_optimized_away= 1;
++ }
++
++ calc_group_buffer(this, group_list);
++ send_group_parts= tmp_table_param.group_parts; /* Save org parts */
++ if (procedure && procedure->group)
++ {
++ group_list= procedure->group= remove_const(this, procedure->group, conds,
++ 1, &simple_group);
++ if (thd->is_error())
++ {
++ error= 1;
++ DBUG_PRINT("error",("Error from remove_const"));
++ DBUG_RETURN(1);
++ }
++ calc_group_buffer(this, group_list);
++ }
++
++ if (test_if_subpart(group_list, order) ||
++ (!group_list && tmp_table_param.sum_func_count))
++ order=0;
++
++ // Can't use sort on head table if using join buffering
++ if (full_join)
++ {
++ TABLE *stable= (sort_by_table == (TABLE *) 1 ?
++ join_tab[const_tables].table : sort_by_table);
++ /*
++ FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
++ sorting on the first table.
++ */
++ if (!stable || !stable->force_index_order)
++ {
++ if (group_list)
++ simple_group= 0;
++ if (order)
++ simple_order= 0;
++ }
++ }
++
++ /*
++ Check if we need to create a temporary table.
++ This has to be done if all tables are not already read (const tables)
++ and one of the following conditions holds:
++ - We are using DISTINCT (simple distinct's are already optimized away)
++ - We are using an ORDER BY or GROUP BY on fields not in the first table
++ - We are using different ORDER BY and GROUP BY orders
++ - The user wants us to buffer the result.
++ When the WITH ROLLUP modifier is present, we cannot skip temporary table
++ creation for the DISTINCT clause just because there are only const tables.
++ */
++ need_tmp= ((const_tables != tables &&
++ ((select_distinct || !simple_order || !simple_group) ||
++ (group_list && order) ||
++ test(select_options & OPTION_BUFFER_RESULT))) ||
++ (rollup.state != ROLLUP::STATE_NONE && select_distinct));
++
++ // No cache for MATCH
++ make_join_readinfo(this,
++ (select_options & (SELECT_DESCRIBE |
++ SELECT_NO_JOIN_CACHE)) |
++ (select_lex->ftfunc_list->elements ?
++ SELECT_NO_JOIN_CACHE : 0));
++
++ /* Perform FULLTEXT search before all regular searches */
++ if (!(select_options & SELECT_DESCRIBE))
++ init_ftfuncs(thd, select_lex, test(order));
++
++ /*
++ is this simple IN subquery?
++ */
++ if (!group_list && !order &&
++ unit->item && unit->item->substype() == Item_subselect::IN_SUBS &&
++ tables == 1 && conds &&
++ !unit->is_union())
++ {
++ if (!having)
++ {
++ Item *where= conds;
++ if (join_tab[0].type == JT_EQ_REF &&
++ join_tab[0].ref.items[0]->name == in_left_expr_name)
++ {
++ remove_subq_pushed_predicates(&where);
++ save_index_subquery_explain_info(join_tab, where);
++ join_tab[0].type= JT_UNIQUE_SUBQUERY;
++ error= 0;
++ DBUG_RETURN(unit->item->
++ change_engine(new
++ subselect_uniquesubquery_engine(thd,
++ join_tab,
++ unit->item,
++ where)));
++ }
++ else if (join_tab[0].type == JT_REF &&
++ join_tab[0].ref.items[0]->name == in_left_expr_name)
++ {
++ remove_subq_pushed_predicates(&where);
++ save_index_subquery_explain_info(join_tab, where);
++ join_tab[0].type= JT_INDEX_SUBQUERY;
++ error= 0;
++ DBUG_RETURN(unit->item->
++ change_engine(new
++ subselect_indexsubquery_engine(thd,
++ join_tab,
++ unit->item,
++ where,
++ NULL,
++ 0)));
++ }
++ } else if (join_tab[0].type == JT_REF_OR_NULL &&
++ join_tab[0].ref.items[0]->name == in_left_expr_name &&
++ having->name == in_having_cond)
++ {
++ join_tab[0].type= JT_INDEX_SUBQUERY;
++ error= 0;
++ conds= remove_additional_cond(conds);
++ save_index_subquery_explain_info(join_tab, conds);
++ DBUG_RETURN(unit->item->
++ change_engine(new subselect_indexsubquery_engine(thd,
++ join_tab,
++ unit->item,
++ conds,
++ having,
++ 1)));
++ }
++
++ }
++ /*
++ Need to tell handlers that to play it safe, it should fetch all
++ columns of the primary key of the tables: this is because MySQL may
++ build row pointers for the rows, and for all columns of the primary key
++ the read set has not necessarily been set by the server code.
++ */
++ if (need_tmp || select_distinct || group_list || order)
++ {
++ for (uint i = const_tables; i < tables; i++)
++ join_tab[i].table->prepare_for_position();
++ }
++
++ DBUG_EXECUTE("info",TEST_join(this););
++
++ if (const_tables != tables)
++ {
++ /*
++ Because filesort always does a full table scan or a quick range scan
++ we must add the removed reference to the select for the table.
++ We only need to do this when we have a simple_order or simple_group
++ as in other cases the join is done before the sort.
++ */
++ if ((order || group_list) &&
++ join_tab[const_tables].type != JT_ALL &&
++ join_tab[const_tables].type != JT_FT &&
++ join_tab[const_tables].type != JT_REF_OR_NULL &&
++ ((order && simple_order) || (group_list && simple_group)))
++ {
++ if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
++ DBUG_RETURN(1);
++ }
++ }
++
++ if (!(select_options & SELECT_BIG_RESULT) &&
++ ((group_list &&
++ (!simple_group ||
++ !test_if_skip_sort_order(&join_tab[const_tables], group_list,
++ unit->select_limit_cnt, 0,
++ &join_tab[const_tables].table->
++ keys_in_use_for_group_by))) ||
++ select_distinct) &&
++ tmp_table_param.quick_group && !procedure)
++ {
++ need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
++ }
++ if (order)
++ {
++ /*
++ Do we need a temporary table due to the ORDER BY not being equal to
++ the GROUP BY? The call to test_if_skip_sort_order above tests for the
++ GROUP BY clause only and hence is not valid in this case. So the
++ estimated number of rows to be read from the first table is not valid.
++ We clear it here so that it doesn't show up in EXPLAIN.
++ */
++ if (need_tmp && (select_options & SELECT_DESCRIBE) != 0)
++ join_tab[const_tables].limit= 0;
++ /*
++ Force using of tmp table if sorting by a SP or UDF function due to
++ their expensive and probably non-deterministic nature.
++ */
++ for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
++ {
++ Item *item= *tmp_order->item;
++ if (item->walk(&Item::is_expensive_processor, 0, (uchar*)0))
++ {
++ /* Force tmp table without sort */
++ need_tmp=1; simple_order=simple_group=0;
++ break;
++ }
++ }
++ }
++ }
++
++ tmp_having= having;
++ if (select_options & SELECT_DESCRIBE)
++ {
++ error= 0;
++ DBUG_RETURN(0);
++ }
++ having= 0;
++
++ /*
++ The loose index scan access method guarantees that all grouping or
++ duplicate row elimination (for distinct) is already performed
++ during data retrieval, and that all MIN/MAX functions are already
++ computed for each group. Thus all MIN/MAX functions should be
++ treated as regular functions, and there is no need to perform
++ grouping in the main execution loop.
++ Notice that currently loose index scan is applicable only for
++ single table queries, thus it is sufficient to test only the first
++ join_tab element of the plan for its access method.
++ */
++ if (join_tab->is_using_loose_index_scan())
++ tmp_table_param.precomputed_group_by= TRUE;
++
++ /* Create a tmp table if distinct or if the sort is too complicated */
++ if (need_tmp)
++ {
++ DBUG_PRINT("info",("Creating tmp table"));
++ thd_proc_info(thd, "Creating tmp table");
++
++ init_items_ref_array();
++
++ tmp_table_param.hidden_field_count= (all_fields.elements -
++ fields_list.elements);
++ ORDER *tmp_group= ((!simple_group && !procedure &&
++ !(test_flags & TEST_NO_KEY_GROUP)) ? group_list :
++ (ORDER*) 0);
++ /*
++ Pushing LIMIT to the temporary table creation is not applicable
++ when there is ORDER BY or GROUP BY or there is no GROUP BY, but
++ there are aggregate functions, because in all these cases we need
++ all result rows.
++ */
++ ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
++ !tmp_group &&
++ !thd->lex->current_select->with_sum_func) ?
++ select_limit : HA_POS_ERROR;
++
++ if (!(exec_tmp_table1=
++ create_tmp_table(thd, &tmp_table_param, all_fields,
++ tmp_group,
++ group_list ? 0 : select_distinct,
++ group_list && simple_group,
++ select_options,
++ tmp_rows_limit,
++ (char *) "")))
++ {
++ DBUG_RETURN(1);
++ }
++
++ /*
++ We don't have to store rows in temp table that doesn't match HAVING if:
++ - we are sorting the table and writing complete group rows to the
++ temp table.
++ - We are using DISTINCT without resolving the distinct as a GROUP BY
++ on all columns.
++
++ If having is not handled here, it will be checked before the row
++ is sent to the client.
++ */
++ if (tmp_having &&
++ (sort_and_group || (exec_tmp_table1->distinct && !group_list)))
++ having= tmp_having;
++
++ /* if group or order on first table, sort first */
++ if (group_list && simple_group)
++ {
++ DBUG_PRINT("info",("Sorting for group"));
++ thd_proc_info(thd, "Sorting for group");
++ if (create_sort_index(thd, this, group_list,
++ HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
++ alloc_group_fields(this, group_list) ||
++ make_sum_func_list(all_fields, fields_list, 1) ||
++ setup_sum_funcs(thd, sum_funcs))
++ {
++ DBUG_RETURN(1);
++ }
++ group_list=0;
++ }
++ else
++ {
++ if (make_sum_func_list(all_fields, fields_list, 0) ||
++ setup_sum_funcs(thd, sum_funcs))
++ {
++ DBUG_RETURN(1);
++ }
++
++ if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
++ {
++ thd_proc_info(thd, "Sorting for order");
++ if (create_sort_index(thd, this, order,
++ HA_POS_ERROR, HA_POS_ERROR, TRUE))
++ {
++ DBUG_RETURN(1);
++ }
++ order=0;
++ }
++ }
++
++ /*
++ Optimize distinct when used on some of the tables
++ SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
++ In this case we can stop scanning t2 when we have found one t1.a
++ */
++
++ if (exec_tmp_table1->distinct)
++ {
++ table_map used_tables= thd->used_tables;
++ JOIN_TAB *last_join_tab= join_tab+tables-1;
++ do
++ {
++ if (used_tables & last_join_tab->table->map)
++ break;
++ last_join_tab->not_used_in_distinct=1;
++ } while (last_join_tab-- != join_tab);
++ /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
++ if (order && skip_sort_order)
++ {
++ /* Should always succeed */
++ if (test_if_skip_sort_order(&join_tab[const_tables],
++ order, unit->select_limit_cnt, 0,
++ &join_tab[const_tables].table->
++ keys_in_use_for_order_by))
++ order=0;
++ }
++ }
++
++ /* If this join belongs to an uncacheable query save the original join */
++ if (select_lex->uncacheable && init_save_join_tab())
++ DBUG_RETURN(-1); /* purecov: inspected */
++ }
++
++ error= 0;
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Restore values in temporary join.
++*/
++void JOIN::restore_tmp()
++{
++ memcpy(tmp_join, this, (size_t) sizeof(JOIN));
++}
++
++
++int
++JOIN::reinit()
++{
++ DBUG_ENTER("JOIN::reinit");
++
++ unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
++ select_lex->offset_limit->val_uint() :
++ ULL(0));
++
++ first_record= 0;
++
++ if (exec_tmp_table1)
++ {
++ exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
++ exec_tmp_table1->file->ha_delete_all_rows();
++ free_io_cache(exec_tmp_table1);
++ filesort_free_buffers(exec_tmp_table1,0);
++ }
++ if (exec_tmp_table2)
++ {
++ exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
++ exec_tmp_table2->file->ha_delete_all_rows();
++ free_io_cache(exec_tmp_table2);
++ filesort_free_buffers(exec_tmp_table2,0);
++ }
++ if (items0)
++ set_items_ref_array(items0);
++
++ if (join_tab_save)
++ memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables);
++
++ /* need to reset ref access state (see join_read_key) */
++ if (join_tab)
++ for (uint i= 0; i < tables; i++)
++ join_tab[i].ref.key_err= TRUE;
++
++ if (tmp_join)
++ restore_tmp();
++
++ /* Reset of sum functions */
++ if (sum_funcs)
++ {
++ Item_sum *func, **func_ptr= sum_funcs;
++ while ((func= *(func_ptr++)))
++ func->clear();
++ }
++
++ if (!(select_options & SELECT_DESCRIBE))
++ init_ftfuncs(thd, select_lex, test(order));
++
++ DBUG_RETURN(0);
++}
++
++/**
++ @brief Save the original join layout
++
++ @details Saves the original join layout so it can be reused in
++ re-execution and for EXPLAIN.
++
++ @return Operation status
++ @retval 0 success.
++ @retval 1 error occurred.
++*/
++
++bool
++JOIN::init_save_join_tab()
++{
++ if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
++ return 1; /* purecov: inspected */
++ error= 0; // Ensure that tmp_join.error= 0
++ restore_tmp();
++ return 0;
++}
++
++
++bool
++JOIN::save_join_tab()
++{
++ if (!join_tab_save && select_lex->master_unit()->uncacheable)
++ {
++ if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab,
++ sizeof(JOIN_TAB) * tables)))
++ return 1;
++ }
++ return 0;
++}
++
++
++/**
++ Exec select.
++
++ @todo
++ Note, that create_sort_index calls test_if_skip_sort_order and may
++ finally replace sorting with index scan if there is a LIMIT clause in
++ the query. It's never shown in EXPLAIN!
++
++ @todo
++ When can we have here thd->net.report_error not zero?
++*/
++void
++JOIN::exec()
++{
++ List<Item> *columns_list= &fields_list;
++ int tmp_error;
++ DBUG_ENTER("JOIN::exec");
++
++ thd_proc_info(thd, "executing");
++ error= 0;
++ if (procedure)
++ {
++ procedure_fields_list= fields_list;
++ if (procedure->change_columns(procedure_fields_list) ||
++ result->prepare(procedure_fields_list, unit))
++ {
++ thd->limit_found_rows= thd->examined_row_count= 0;
++ DBUG_VOID_RETURN;
++ }
++ columns_list= &procedure_fields_list;
++ }
++ (void) result->prepare2(); // Currently, this cannot fail.
++
++ if (!tables_list && (tables || !select_lex->with_sum_func))
++ { // Only test of functions
++ if (select_options & SELECT_DESCRIBE)
++ select_describe(this, FALSE, FALSE, FALSE,
++ (zero_result_cause?zero_result_cause:"No tables used"));
++ else
++ {
++ if (result->send_fields(*columns_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ {
++ DBUG_VOID_RETURN;
++ }
++ /*
++ We have to test for 'conds' here as the WHERE may not be constant
++ even if we don't have any tables for prepared statements or if
++ conds uses something like 'rand()'.
++ If the HAVING clause is either impossible or always true, then
++ JOIN::having is set to NULL by optimize_cond.
++ In this case JOIN::exec must check for JOIN::having_value, in the
++ same way it checks for JOIN::cond_value.
++ */
++ if (cond_value != Item::COND_FALSE &&
++ having_value != Item::COND_FALSE &&
++ (!conds || conds->val_int()) &&
++ (!having || having->val_int()))
++ {
++ if (do_send_rows &&
++ (procedure ? (procedure->send_row(procedure_fields_list) ||
++ procedure->end_of_records()) : result->send_data(fields_list)))
++ error= 1;
++ else
++ {
++ error= (int) result->send_eof();
++ send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
++ thd->sent_row_count);
++ }
++ }
++ else
++ {
++ error=(int) result->send_eof();
++ send_records= 0;
++ }
++ }
++ /* Single select (without union) always returns 0 or 1 row */
++ thd->limit_found_rows= send_records;
++ thd->examined_row_count= 0;
++ DBUG_VOID_RETURN;
++ }
++ /*
++ Don't reset the found rows count if there're no tables as
++ FOUND_ROWS() may be called. Never reset the examined row count here.
++ It must be accumulated from all join iterations of all join parts.
++ */
++ if (tables)
++ thd->limit_found_rows= 0;
++
++ if (zero_result_cause)
++ {
++ (void) return_zero_rows(this, result, select_lex->leaf_tables,
++ *columns_list,
++ send_row_on_empty_set(),
++ select_options,
++ zero_result_cause,
++ having);
++ DBUG_VOID_RETURN;
++ }
++
++ if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
++ get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
++ DBUG_VOID_RETURN;
++
++ if (select_options & SELECT_DESCRIBE)
++ {
++ /*
++ Check if we managed to optimize ORDER BY away and don't use temporary
++ table to resolve ORDER BY: in that case, we only may need to do
++ filesort for GROUP BY.
++ */
++ if (!order && !no_order && (!skip_sort_order || !need_tmp))
++ {
++ /*
++ Reset 'order' to 'group_list' and reinit variables describing
++ 'order'
++ */
++ order= group_list;
++ simple_order= simple_group;
++ skip_sort_order= 0;
++ }
++ if (order &&
++ (order != group_list || !(select_options & SELECT_BIG_RESULT)) &&
++ (const_tables == tables ||
++ ((simple_order || skip_sort_order) &&
++ test_if_skip_sort_order(&join_tab[const_tables], order,
++ select_limit, 0,
++ &join_tab[const_tables].table->
++ keys_in_use_for_query))))
++ order=0;
++ having= tmp_having;
++ select_describe(this, need_tmp,
++ order != 0 && !skip_sort_order,
++ select_distinct,
++ !tables ? "No tables used" : NullS);
++ DBUG_VOID_RETURN;
++ }
++
++ JOIN *curr_join= this;
++ List<Item> *curr_all_fields= &all_fields;
++ List<Item> *curr_fields_list= &fields_list;
++ TABLE *curr_tmp_table= 0;
++ /*
++ Initialize examined rows here because the values from all join parts
++ must be accumulated in examined_row_count. Hence every join
++ iteration must count from zero.
++ */
++ curr_join->examined_rows= 0;
++
++ /* Create a tmp table if distinct or if the sort is too complicated */
++ if (need_tmp)
++ {
++ if (tmp_join)
++ {
++ /*
++ We are in a non cacheable sub query. Get the saved join structure
++ after optimization.
++ (curr_join may have been modified during last exection and we need
++ to reset it)
++ */
++ curr_join= tmp_join;
++ }
++ curr_tmp_table= exec_tmp_table1;
++
++ /* Copy data to the temporary table */
++ thd_proc_info(thd, "Copying to tmp table");
++ DBUG_PRINT("info", ("%s", thd->proc_info));
++ if (!curr_join->sort_and_group &&
++ curr_join->const_tables != curr_join->tables)
++ curr_join->join_tab[curr_join->const_tables].sorted= 0;
++ if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
++ {
++ error= tmp_error;
++ DBUG_VOID_RETURN;
++ }
++ curr_tmp_table->file->info(HA_STATUS_VARIABLE);
++
++ if (curr_join->having)
++ curr_join->having= curr_join->tmp_having= 0; // Allready done
++
++ /* Change sum_fields reference to calculated fields in tmp_table */
++ if (curr_join != this)
++ curr_join->all_fields= *curr_all_fields;
++ if (!items1)
++ {
++ items1= items0 + all_fields.elements;
++ if (sort_and_group || curr_tmp_table->group ||
++ tmp_table_param.precomputed_group_by)
++ {
++ if (change_to_use_tmp_fields(thd, items1,
++ tmp_fields_list1, tmp_all_fields1,
++ fields_list.elements, all_fields))
++ DBUG_VOID_RETURN;
++ }
++ else
++ {
++ if (change_refs_to_tmp_fields(thd, items1,
++ tmp_fields_list1, tmp_all_fields1,
++ fields_list.elements, all_fields))
++ DBUG_VOID_RETURN;
++ }
++ if (curr_join != this)
++ {
++ curr_join->tmp_all_fields1= tmp_all_fields1;
++ curr_join->tmp_fields_list1= tmp_fields_list1;
++ }
++ curr_join->items1= items1;
++ }
++ curr_all_fields= &tmp_all_fields1;
++ curr_fields_list= &tmp_fields_list1;
++ curr_join->set_items_ref_array(items1);
++
++ if (sort_and_group || curr_tmp_table->group)
++ {
++ curr_join->tmp_table_param.field_count+=
++ curr_join->tmp_table_param.sum_func_count+
++ curr_join->tmp_table_param.func_count;
++ curr_join->tmp_table_param.sum_func_count=
++ curr_join->tmp_table_param.func_count= 0;
++ }
++ else
++ {
++ curr_join->tmp_table_param.field_count+=
++ curr_join->tmp_table_param.func_count;
++ curr_join->tmp_table_param.func_count= 0;
++ }
++
++ // procedure can't be used inside subselect => we do nothing special for it
++ if (procedure)
++ procedure->update_refs();
++
++ if (curr_tmp_table->group)
++ { // Already grouped
++ if (!curr_join->order && !curr_join->no_order && !skip_sort_order)
++ curr_join->order= curr_join->group_list; /* order by group */
++ curr_join->group_list= 0;
++ }
++
++ /*
++ If we have different sort & group then we must sort the data by group
++ and copy it to another tmp table
++ This code is also used if we are using distinct something
++ we haven't been able to store in the temporary table yet
++ like SEC_TO_TIME(SUM(...)).
++ */
++
++ if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list,
++ curr_join->order) ||
++ curr_join->select_distinct)) ||
++ (curr_join->select_distinct &&
++ curr_join->tmp_table_param.using_indirect_summary_function))
++ { /* Must copy to another table */
++ DBUG_PRINT("info",("Creating group table"));
++
++ /* Free first data from old join */
++ curr_join->join_free();
++ if (curr_join->make_simple_join(this, curr_tmp_table))
++ DBUG_VOID_RETURN;
++ calc_group_buffer(curr_join, group_list);
++ count_field_types(select_lex, &curr_join->tmp_table_param,
++ curr_join->tmp_all_fields1,
++ curr_join->select_distinct && !curr_join->group_list);
++ curr_join->tmp_table_param.hidden_field_count=
++ (curr_join->tmp_all_fields1.elements-
++ curr_join->tmp_fields_list1.elements);
++
++
++ if (exec_tmp_table2)
++ curr_tmp_table= exec_tmp_table2;
++ else
++ {
++ /* group data to new table */
++
++ /*
++ If the access method is loose index scan then all MIN/MAX
++ functions are precomputed, and should be treated as regular
++ functions. See extended comment in JOIN::exec.
++ */
++ if (curr_join->join_tab->is_using_loose_index_scan())
++ curr_join->tmp_table_param.precomputed_group_by= TRUE;
++
++ if (!(curr_tmp_table=
++ exec_tmp_table2= create_tmp_table(thd,
++ &curr_join->tmp_table_param,
++ *curr_all_fields,
++ (ORDER*) 0,
++ curr_join->select_distinct &&
++ !curr_join->group_list,
++ 1, curr_join->select_options,
++ HA_POS_ERROR,
++ (char *) "")))
++ DBUG_VOID_RETURN;
++ curr_join->exec_tmp_table2= exec_tmp_table2;
++ }
++ if (curr_join->group_list)
++ {
++ thd_proc_info(thd, "Creating sort index");
++ if (curr_join->join_tab == join_tab && save_join_tab())
++ {
++ DBUG_VOID_RETURN;
++ }
++ if (create_sort_index(thd, curr_join, curr_join->group_list,
++ HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
++ make_group_fields(this, curr_join))
++ {
++ DBUG_VOID_RETURN;
++ }
++ sortorder= curr_join->sortorder;
++ }
++
++ thd_proc_info(thd, "Copying to group table");
++ DBUG_PRINT("info", ("%s", thd->proc_info));
++ tmp_error= -1;
++ if (curr_join != this)
++ {
++ if (sum_funcs2)
++ {
++ curr_join->sum_funcs= sum_funcs2;
++ curr_join->sum_funcs_end= sum_funcs_end2;
++ }
++ else
++ {
++ curr_join->alloc_func_list();
++ sum_funcs2= curr_join->sum_funcs;
++ sum_funcs_end2= curr_join->sum_funcs_end;
++ }
++ }
++ if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
++ 1, TRUE))
++ DBUG_VOID_RETURN;
++ curr_join->group_list= 0;
++ if (!curr_join->sort_and_group &&
++ curr_join->const_tables != curr_join->tables)
++ curr_join->join_tab[curr_join->const_tables].sorted= 0;
++ if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
++ (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
++ 0)))
++ {
++ error= tmp_error;
++ DBUG_VOID_RETURN;
++ }
++ end_read_record(&curr_join->join_tab->read_record);
++ curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
++ curr_join->join_tab[0].table= 0; // Table is freed
++
++ // No sum funcs anymore
++ if (!items2)
++ {
++ items2= items1 + all_fields.elements;
++ if (change_to_use_tmp_fields(thd, items2,
++ tmp_fields_list2, tmp_all_fields2,
++ fields_list.elements, tmp_all_fields1))
++ DBUG_VOID_RETURN;
++ if (curr_join != this)
++ {
++ curr_join->tmp_fields_list2= tmp_fields_list2;
++ curr_join->tmp_all_fields2= tmp_all_fields2;
++ }
++ }
++ curr_fields_list= &curr_join->tmp_fields_list2;
++ curr_all_fields= &curr_join->tmp_all_fields2;
++ curr_join->set_items_ref_array(items2);
++ curr_join->tmp_table_param.field_count+=
++ curr_join->tmp_table_param.sum_func_count;
++ curr_join->tmp_table_param.sum_func_count= 0;
++ }
++ if (curr_tmp_table->distinct)
++ curr_join->select_distinct=0; /* Each row is unique */
++
++ curr_join->join_free(); /* Free quick selects */
++ if (curr_join->select_distinct && ! curr_join->group_list)
++ {
++ thd_proc_info(thd, "Removing duplicates");
++ if (curr_join->tmp_having)
++ curr_join->tmp_having->update_used_tables();
++ if (remove_duplicates(curr_join, curr_tmp_table,
++ *curr_fields_list, curr_join->tmp_having))
++ DBUG_VOID_RETURN;
++ curr_join->tmp_having=0;
++ curr_join->select_distinct=0;
++ }
++ curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
++ if (curr_join->make_simple_join(this, curr_tmp_table))
++ DBUG_VOID_RETURN;
++ calc_group_buffer(curr_join, curr_join->group_list);
++ count_field_types(select_lex, &curr_join->tmp_table_param,
++ *curr_all_fields, 0);
++
++ }
++ if (procedure)
++ count_field_types(select_lex, &curr_join->tmp_table_param,
++ *curr_all_fields, 0);
++
++ if (curr_join->group || curr_join->implicit_grouping ||
++ curr_join->tmp_table_param.sum_func_count ||
++ (procedure && (procedure->flags & PROC_GROUP)))
++ {
++ if (make_group_fields(this, curr_join))
++ {
++ DBUG_VOID_RETURN;
++ }
++ if (!items3)
++ {
++ if (!items0)
++ init_items_ref_array();
++ items3= ref_pointer_array + (all_fields.elements*4);
++ setup_copy_fields(thd, &curr_join->tmp_table_param,
++ items3, tmp_fields_list3, tmp_all_fields3,
++ curr_fields_list->elements, *curr_all_fields);
++ tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
++ tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
++ tmp_table_param.save_copy_field_end=
++ curr_join->tmp_table_param.copy_field_end;
++ if (curr_join != this)
++ {
++ curr_join->tmp_all_fields3= tmp_all_fields3;
++ curr_join->tmp_fields_list3= tmp_fields_list3;
++ }
++ }
++ else
++ {
++ curr_join->tmp_table_param.copy_funcs= tmp_table_param.save_copy_funcs;
++ curr_join->tmp_table_param.copy_field= tmp_table_param.save_copy_field;
++ curr_join->tmp_table_param.copy_field_end=
++ tmp_table_param.save_copy_field_end;
++ }
++ curr_fields_list= &tmp_fields_list3;
++ curr_all_fields= &tmp_all_fields3;
++ curr_join->set_items_ref_array(items3);
++
++ if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
++ 1, TRUE) ||
++ setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
++ thd->is_fatal_error)
++ DBUG_VOID_RETURN;
++ }
++ if (curr_join->group_list || curr_join->order)
++ {
++ DBUG_PRINT("info",("Sorting for send_fields"));
++ thd_proc_info(thd, "Sorting result");
++ /* If we have already done the group, add HAVING to sorted table */
++ if (curr_join->tmp_having && ! curr_join->group_list &&
++ ! curr_join->sort_and_group)
++ {
++ // Some tables may have been const
++ curr_join->tmp_having->update_used_tables();
++ JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables];
++ table_map used_tables= (curr_join->const_table_map |
++ curr_table->table->map);
++
++ Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
++ used_tables,
++ used_tables);
++ if (sort_table_cond)
++ {
++ if (!curr_table->select)
++ if (!(curr_table->select= new SQL_SELECT))
++ DBUG_VOID_RETURN;
++ if (!curr_table->select->cond)
++ curr_table->select->cond= sort_table_cond;
++ else
++ {
++ if (!(curr_table->select->cond=
++ new Item_cond_and(curr_table->select->cond,
++ sort_table_cond)))
++ DBUG_VOID_RETURN;
++ curr_table->select->cond->fix_fields(thd, 0);
++ }
++ curr_table->select_cond= curr_table->select->cond;
++ curr_table->select_cond->top_level_item();
++ DBUG_EXECUTE("where",print_where(curr_table->select->cond,
++ "select and having",
++ QT_ORDINARY););
++ curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
++ ~ (table_map) 0,
++ ~used_tables);
++ DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
++ "having after sort",
++ QT_ORDINARY););
++ }
++ }
++ {
++ if (group)
++ curr_join->select_limit= HA_POS_ERROR;
++ else
++ {
++ /*
++ We can abort sorting after thd->select_limit rows if we there is no
++ WHERE clause for any tables after the sorted one.
++ */
++ JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
++ JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
++ for (; curr_table < end_table ; curr_table++)
++ {
++ /*
++ table->keyuse is set in the case there was an original WHERE clause
++ on the table that was optimized away.
++ */
++ if (curr_table->select_cond ||
++ (curr_table->keyuse && !curr_table->first_inner))
++ {
++ /* We have to sort all rows */
++ curr_join->select_limit= HA_POS_ERROR;
++ break;
++ }
++ }
++ }
++ if (curr_join->join_tab == join_tab && save_join_tab())
++ {
++ DBUG_VOID_RETURN;
++ }
++ /*
++ Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
++ chose FILESORT to be faster than INDEX SCAN or there is no
++ suitable index present.
++ Note, that create_sort_index calls test_if_skip_sort_order and may
++ finally replace sorting with index scan if there is a LIMIT clause in
++ the query. XXX: it's never shown in EXPLAIN!
++ OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
++ */
++ if (create_sort_index(thd, curr_join,
++ curr_join->group_list ?
++ curr_join->group_list : curr_join->order,
++ curr_join->select_limit,
++ (select_options & OPTION_FOUND_ROWS ?
++ HA_POS_ERROR : unit->select_limit_cnt),
++ curr_join->group_list ? TRUE : FALSE))
++ DBUG_VOID_RETURN;
++ sortorder= curr_join->sortorder;
++ if (curr_join->const_tables != curr_join->tables &&
++ !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
++ {
++ /*
++ If no IO cache exists for the first table then we are using an
++ INDEX SCAN and no filesort. Thus we should not remove the sorted
++ attribute on the INDEX SCAN.
++ */
++ skip_sort_order= 1;
++ }
++ }
++ }
++ /* XXX: When can we have here thd->is_error() not zero? */
++ if (thd->is_error())
++ {
++ error= thd->is_error();
++ DBUG_VOID_RETURN;
++ }
++ curr_join->having= curr_join->tmp_having;
++ curr_join->fields= curr_fields_list;
++ curr_join->procedure= procedure;
++
++ if (is_top_level_join() && thd->cursor && tables != const_tables)
++ {
++ /*
++ We are here if this is JOIN::exec for the last select of the main unit
++ and the client requested to open a cursor.
++ We check that not all tables are constant because this case is not
++ handled by do_select() separately, and this case is not implemented
++ for cursors yet.
++ */
++ DBUG_ASSERT(error == 0);
++ /*
++ curr_join is used only for reusable joins - that is,
++ to perform SELECT for each outer row (like in subselects).
++ This join is main, so we know for sure that curr_join == join.
++ */
++ DBUG_ASSERT(curr_join == this);
++ /* Open cursor for the last join sweep */
++ error= thd->cursor->open(this);
++ }
++ else
++ {
++ thd_proc_info(thd, "Sending data");
++ DBUG_PRINT("info", ("%s", thd->proc_info));
++ result->send_fields((procedure ? curr_join->procedure_fields_list :
++ *curr_fields_list),
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
++ error= do_select(curr_join, curr_fields_list, NULL, procedure);
++ thd->limit_found_rows= curr_join->send_records;
++ }
++
++ /* Accumulate the counts from all join iterations of all join parts. */
++ thd->examined_row_count+= curr_join->examined_rows;
++ DBUG_PRINT("counts", ("thd->examined_row_count: %lu",
++ (ulong) thd->examined_row_count));
++
++ /*
++ With EXPLAIN EXTENDED we have to restore original ref_array
++ for a derived table which is always materialized.
++ We also need to do this when we have temp table(s).
++ Otherwise we would not be able to print the query correctly.
++ */
++ if (items0 && (thd->lex->describe & DESCRIBE_EXTENDED) &&
++ (select_lex->linkage == DERIVED_TABLE_TYPE ||
++ exec_tmp_table1 || exec_tmp_table2))
++ set_items_ref_array(items0);
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Clean up join.
++
++ @return
++ Return error that hold JOIN.
++*/
++
++int
++JOIN::destroy()
++{
++ DBUG_ENTER("JOIN::destroy");
++ select_lex->join= 0;
++
++ if (tmp_join)
++ {
++ if (join_tab != tmp_join->join_tab)
++ {
++ JOIN_TAB *tab, *end;
++ for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
++ tab->cleanup();
++ }
++ tmp_join->tmp_join= 0;
++ /*
++ We need to clean up tmp_table_param for reusable JOINs (having non-zero
++ and different from self tmp_join) because it's not being cleaned up
++ anywhere else (as we need to keep the join is reusable).
++ */
++ tmp_table_param.cleanup();
++ tmp_table_param.copy_field= tmp_join->tmp_table_param.copy_field= 0;
++ DBUG_RETURN(tmp_join->destroy());
++ }
++ cond_equal= 0;
++
++ cleanup(1);
++ /* Cleanup items referencing temporary table columns */
++ cleanup_item_list(tmp_all_fields1);
++ cleanup_item_list(tmp_all_fields3);
++ if (exec_tmp_table1)
++ free_tmp_table(thd, exec_tmp_table1);
++ if (exec_tmp_table2)
++ free_tmp_table(thd, exec_tmp_table2);
++ delete select;
++ delete_dynamic(&keyuse);
++ delete procedure;
++ DBUG_RETURN(error);
++}
++
++
++void JOIN::cleanup_item_list(List<Item> &items) const
++{
++ if (!items.is_empty())
++ {
++ List_iterator_fast<Item> it(items);
++ Item *item;
++ while ((item= it++))
++ item->cleanup();
++ }
++}
++
++
++/**
++ An entry point to single-unit select (a select without UNION).
++
++ @param thd thread handler
++ @param rref_pointer_array a reference to ref_pointer_array of
++ the top-level select_lex for this query
++ @param tables list of all tables used in this query.
++ The tables have been pre-opened.
++ @param wild_num number of wildcards used in the top level
++ select of this query.
++ For example statement
++ SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
++ has 3 wildcards.
++ @param fields list of items in SELECT list of the top-level
++ select
++ e.g. SELECT a, b, c FROM t1 will have Item_field
++ for a, b and c in this list.
++ @param conds top level item of an expression representing
++ WHERE clause of the top level select
++ @param og_num total number of ORDER BY and GROUP BY clauses
++ arguments
++ @param order linked list of ORDER BY agruments
++ @param group linked list of GROUP BY arguments
++ @param having top level item of HAVING expression
++ @param proc_param list of PROCEDUREs
++ @param select_options select options (BIG_RESULT, etc)
++ @param result an instance of result set handling class.
++ This object is responsible for send result
++ set rows to the client or inserting them
++ into a table.
++ @param select_lex the only SELECT_LEX of this query
++ @param unit top-level UNIT of this query
++ UNIT is an artificial object created by the
++ parser for every SELECT clause.
++ e.g.
++ SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2)
++ has 2 unions.
++
++ @retval
++ FALSE success
++ @retval
++ TRUE an error
++*/
++
++bool
++mysql_select(THD *thd, Item ***rref_pointer_array,
++ TABLE_LIST *tables, uint wild_num, List<Item> &fields,
++ COND *conds, uint og_num, ORDER *order, ORDER *group,
++ Item *having, ORDER *proc_param, ulonglong select_options,
++ select_result *result, SELECT_LEX_UNIT *unit,
++ SELECT_LEX *select_lex)
++{
++ bool err;
++ bool free_join= 1;
++ DBUG_ENTER("mysql_select");
++
++ select_lex->context.resolve_in_select_list= TRUE;
++ JOIN *join;
++ if (select_lex->join != 0)
++ {
++ join= select_lex->join;
++ /*
++ is it single SELECT in derived table, called in derived table
++ creation
++ */
++ if (select_lex->linkage != DERIVED_TABLE_TYPE ||
++ (select_options & SELECT_DESCRIBE))
++ {
++ if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
++ {
++ //here is EXPLAIN of subselect or derived table
++ if (join->change_result(result))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ /*
++ Original join tabs might be overwritten at first
++ subselect execution. So we need to restore them.
++ */
++ Item_subselect *subselect= select_lex->master_unit()->item;
++ if (subselect && subselect->is_uncacheable() && join->reinit())
++ DBUG_RETURN(TRUE);
++ }
++ else
++ {
++ err= join->prepare(rref_pointer_array, tables, wild_num,
++ conds, og_num, order, group, having, proc_param,
++ select_lex, unit);
++ if (err)
++ {
++ goto err;
++ }
++ }
++ }
++ free_join= 0;
++ join->select_options= select_options;
++ }
++ else
++ {
++ if (!(join= new JOIN(thd, fields, select_options, result)))
++ DBUG_RETURN(TRUE);
++ thd_proc_info(thd, "init");
++ thd->used_tables=0; // Updated by setup_fields
++ err= join->prepare(rref_pointer_array, tables, wild_num,
++ conds, og_num, order, group, having, proc_param,
++ select_lex, unit);
++ if (err)
++ {
++ goto err;
++ }
++ }
++
++ if ((err= join->optimize()))
++ {
++ goto err; // 1
++ }
++
++ if (thd->lex->describe & DESCRIBE_EXTENDED)
++ {
++ join->conds_history= join->conds;
++ join->having_history= (join->having?join->having:join->tmp_having);
++ }
++
++ if (thd->is_error())
++ goto err;
++
++ join->exec();
++
++ if (thd->cursor && thd->cursor->is_open())
++ {
++ /*
++ A cursor was opened for the last sweep in exec().
++ We are here only if this is mysql_select for top-level SELECT_LEX_UNIT
++ and there were no error.
++ */
++ free_join= 0;
++ }
++
++ if (thd->lex->describe & DESCRIBE_EXTENDED)
++ {
++ select_lex->where= join->conds_history;
++ select_lex->having= join->having_history;
++ }
++
++err:
++ if (free_join)
++ {
++ thd_proc_info(thd, "end");
++ err|= select_lex->cleanup();
++ DBUG_RETURN(err || thd->is_error());
++ }
++ DBUG_RETURN(join->error);
++}
++
++/*****************************************************************************
++ Create JOIN_TABS, make a guess about the table types,
++ Approximate how many records will be used in each table
++*****************************************************************************/
++
++static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
++ TABLE *table,
++ const key_map *keys,ha_rows limit)
++{
++ int error;
++ DBUG_ENTER("get_quick_record_count");
++#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
++ uchar buff[STACK_BUFF_ALLOC];
++#endif
++ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
++ DBUG_RETURN(0); // Fatal error flag is set
++ if (select)
++ {
++ select->head=table;
++ if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
++ limit, 0)) == 1)
++ DBUG_RETURN(select->quick->records);
++ if (error == -1)
++ {
++ table->reginfo.impossible_range=1;
++ DBUG_RETURN(0);
++ }
++ DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
++ }
++ DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
++}
++
++/*
++ This structure is used to collect info on potentially sargable
++ predicates in order to check whether they become sargable after
++ reading const tables.
++ We form a bitmap of indexes that can be used for sargable predicates.
++ Only such indexes are involved in range analysis.
++*/
++typedef struct st_sargable_param
++{
++ Field *field; /* field against which to check sargability */
++ Item **arg_value; /* values of potential keys for lookups */
++ uint num_values; /* number of values in the above array */
++} SARGABLE_PARAM;
++
++/**
++ Calculate the best possible join and initialize the join structure.
++
++ @retval
++ 0 ok
++ @retval
++ 1 Fatal error
++*/
++
++static bool
++make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
++ DYNAMIC_ARRAY *keyuse_array)
++{
++ int error;
++ TABLE *table;
++ TABLE_LIST *tables= tables_arg;
++ uint i,table_count,const_count,key;
++ table_map found_const_table_map, all_table_map, found_ref, refs;
++ key_map const_ref, eq_part;
++ TABLE **table_vector;
++ JOIN_TAB *stat,*stat_end,*s,**stat_ref;
++ KEYUSE *keyuse,*start_keyuse;
++ table_map outer_join=0;
++ SARGABLE_PARAM *sargables= 0;
++ JOIN_TAB *stat_vector[MAX_TABLES+1];
++ DBUG_ENTER("make_join_statistics");
++
++ table_count=join->tables;
++ stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
++ stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
++ table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
++ if (!stat || !stat_ref || !table_vector)
++ DBUG_RETURN(1); // Eom /* purecov: inspected */
++
++ join->best_ref=stat_vector;
++
++ stat_end=stat+table_count;
++ found_const_table_map= all_table_map=0;
++ const_count=0;
++
++ for (s= stat, i= 0;
++ tables;
++ s++, tables= tables->next_leaf, i++)
++ {
++ TABLE_LIST *embedding= tables->embedding;
++ stat_vector[i]=s;
++ s->keys.init();
++ s->const_keys.init();
++ s->checked_keys.init();
++ s->needed_reg.init();
++ table_vector[i]=s->table=table=tables->table;
++ table->pos_in_table_list= tables;
++ error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
++ if (error)
++ {
++ table->file->print_error(error, MYF(0));
++ goto error;
++ }
++ table->quick_keys.clear_all();
++ table->reginfo.join_tab=s;
++ table->reginfo.not_exists_optimize=0;
++ bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
++ all_table_map|= table->map;
++ s->join=join;
++ s->info=0; // For describe
++
++ s->dependent= tables->dep_tables;
++ s->key_dependent= 0;
++ if (tables->schema_table)
++ table->file->stats.records= 2;
++ table->quick_condition_rows= table->file->stats.records;
++
++ s->on_expr_ref= &tables->on_expr;
++ if (*s->on_expr_ref)
++ {
++ /* s is the only inner table of an outer join */
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if ((!table->file->stats.records || table->no_partitions_used) && !embedding)
++#else
++ if (!table->file->stats.records && !embedding)
++#endif
++ { // Empty table
++ s->dependent= 0; // Ignore LEFT JOIN depend.
++ set_position(join,const_count++,s,(KEYUSE*) 0);
++ continue;
++ }
++ outer_join|= table->map;
++ s->embedding_map= 0;
++ for (;embedding; embedding= embedding->embedding)
++ s->embedding_map|= embedding->nested_join->nj_map;
++ continue;
++ }
++ if (embedding)
++ {
++ /* s belongs to a nested join, maybe to several embedded joins */
++ s->embedding_map= 0;
++ do
++ {
++ NESTED_JOIN *nested_join= embedding->nested_join;
++ s->embedding_map|=nested_join->nj_map;
++ s->dependent|= embedding->dep_tables;
++ embedding= embedding->embedding;
++ outer_join|= nested_join->used_tables;
++ }
++ while (embedding);
++ continue;
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ const bool no_partitions_used= table->no_partitions_used;
++#else
++ const bool no_partitions_used= FALSE;
++#endif
++ if ((table->s->system || table->file->stats.records <= 1 ||
++ no_partitions_used) &&
++ !s->dependent &&
++ (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
++ !table->fulltext_searched && !join->no_const_tables)
++ {
++ set_position(join,const_count++,s,(KEYUSE*) 0);
++ }
++ }
++ stat_vector[i]=0;
++ join->outer_join=outer_join;
++
++ if (join->outer_join)
++ {
++ /*
++ Build transitive closure for relation 'to be dependent on'.
++ This will speed up the plan search for many cases with outer joins,
++ as well as allow us to catch illegal cross references.
++ Warshall's algorithm is used to build the transitive closure.
++ As we may restart the outer loop upto 'table_count' times, the
++ complexity of the algorithm is O((number of tables)^3).
++ However, most of the iterations will be shortcircuited when
++ there are no pedendencies to propogate.
++ */
++ for (i= 0 ; i < table_count ; i++)
++ {
++ uint j;
++ table= stat[i].table;
++
++ if (!table->reginfo.join_tab->dependent)
++ continue;
++
++ /* Add my dependencies to other tables depending on me */
++ for (j= 0, s= stat ; j < table_count ; j++, s++)
++ {
++ if (s->dependent & table->map)
++ {
++ table_map was_dependent= s->dependent;
++ s->dependent |= table->reginfo.join_tab->dependent;
++ /*
++ If we change dependencies for a table we already have
++ processed: Redo dependency propagation from this table.
++ */
++ if (i > j && s->dependent != was_dependent)
++ {
++ i = j-1;
++ break;
++ }
++ }
++ }
++ }
++
++ for (i= 0, s= stat ; i < table_count ; i++, s++)
++ {
++ /* Catch illegal cross references for outer joins */
++ if (s->dependent & s->table->map)
++ {
++ join->tables=0; // Don't use join->table
++ my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
++ goto error;
++ }
++
++ if (outer_join & s->table->map)
++ s->table->maybe_null= 1;
++ s->key_dependent= s->dependent;
++ }
++ }
++
++ if (conds || outer_join)
++ if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
++ conds, join->cond_equal,
++ ~outer_join, join->select_lex, &sargables))
++ goto error;
++
++ /* Read tables with 0 or 1 rows (system tables) */
++ join->const_table_map= 0;
++
++ for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
++ p_pos < p_end ;
++ p_pos++)
++ {
++ int tmp;
++ s= p_pos->table;
++ s->type=JT_SYSTEM;
++ join->const_table_map|=s->table->map;
++ if ((tmp=join_read_const_table(s, p_pos)))
++ {
++ if (tmp > 0)
++ goto error; // Fatal error
++ }
++ else
++ found_const_table_map|= s->table->map;
++ }
++
++ /* loop until no more const tables are found */
++ int ref_changed;
++ do
++ {
++ more_const_tables_found:
++ ref_changed = 0;
++ found_ref=0;
++
++ /*
++ We only have to loop from stat_vector + const_count as
++ set_position() will move all const_tables first in stat_vector
++ */
++
++ for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
++ {
++ table=s->table;
++
++ /*
++ If equi-join condition by a key is null rejecting and after a
++ substitution of a const table the key value happens to be null
++ then we can state that there are no matches for this equi-join.
++ */
++ if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map)
++ {
++ /*
++ When performing an outer join operation if there are no matching rows
++ for the single row of the outer table all the inner tables are to be
++ null complemented and thus considered as constant tables.
++ Here we apply this consideration to the case of outer join operations
++ with a single inner table only because the case with nested tables
++ would require a more thorough analysis.
++ TODO. Apply single row substitution to null complemented inner tables
++ for nested outer join operations.
++ */
++ while (keyuse->table == table)
++ {
++ if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
++ keyuse->val->is_null() && keyuse->null_rejecting)
++ {
++ s->type= JT_CONST;
++ mark_as_null_row(table);
++ found_const_table_map|= table->map;
++ join->const_table_map|= table->map;
++ set_position(join,const_count++,s,(KEYUSE*) 0);
++ goto more_const_tables_found;
++ }
++ keyuse++;
++ }
++ }
++
++ if (s->dependent) // If dependent on some table
++ {
++ // All dep. must be constants
++ if (s->dependent & ~(found_const_table_map))
++ continue;
++ if (table->file->stats.records <= 1L &&
++ (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
++ !table->pos_in_table_list->embedding)
++ { // system table
++ int tmp= 0;
++ s->type=JT_SYSTEM;
++ join->const_table_map|=table->map;
++ set_position(join,const_count++,s,(KEYUSE*) 0);
++ if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
++ {
++ if (tmp > 0)
++ goto error; // Fatal error
++ }
++ else
++ found_const_table_map|= table->map;
++ continue;
++ }
++ }
++ /* check if table can be read by key or table only uses const refs */
++ if ((keyuse=s->keyuse))
++ {
++ s->type= JT_REF;
++ while (keyuse->table == table)
++ {
++ start_keyuse=keyuse;
++ key=keyuse->key;
++ s->keys.set_bit(key); // QQ: remove this ?
++
++ refs=0;
++ const_ref.clear_all();
++ eq_part.clear_all();
++ do
++ {
++ if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
++ {
++ if (!((~found_const_table_map) & keyuse->used_tables))
++ const_ref.set_bit(keyuse->keypart);
++ else
++ refs|=keyuse->used_tables;
++ eq_part.set_bit(keyuse->keypart);
++ }
++ keyuse++;
++ } while (keyuse->table == table && keyuse->key == key);
++
++ if (eq_part.is_prefix(table->key_info[key].key_parts) &&
++ !table->fulltext_searched &&
++ !table->pos_in_table_list->embedding)
++ {
++ if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
++ == HA_NOSAME)
++ {
++ if (const_ref == eq_part)
++ { // Found everything for ref.
++ int tmp;
++ ref_changed = 1;
++ s->type= JT_CONST;
++ join->const_table_map|=table->map;
++ set_position(join,const_count++,s,start_keyuse);
++ if (create_ref_for_key(join, s, start_keyuse,
++ found_const_table_map))
++ goto error;
++ if ((tmp=join_read_const_table(s,
++ join->positions+const_count-1)))
++ {
++ if (tmp > 0)
++ goto error; // Fatal error
++ }
++ else
++ found_const_table_map|= table->map;
++ break;
++ }
++ else
++ found_ref|= refs; // Table is const if all refs are const
++ }
++ else if (const_ref == eq_part)
++ s->const_keys.set_bit(key);
++ }
++ }
++ }
++ }
++ } while (join->const_table_map & found_ref && ref_changed);
++
++ /*
++ Update info on indexes that can be used for search lookups as
++ reading const tables may has added new sargable predicates.
++ */
++ if (const_count && sargables)
++ {
++ for( ; sargables->field ; sargables++)
++ {
++ Field *field= sargables->field;
++ JOIN_TAB *join_tab= field->table->reginfo.join_tab;
++ key_map possible_keys= field->key_start;
++ possible_keys.intersect(field->table->keys_in_use_for_query);
++ bool is_const= 1;
++ for (uint j=0; j < sargables->num_values; j++)
++ is_const&= sargables->arg_value[j]->const_item();
++ if (is_const)
++ join_tab[0].const_keys.merge(possible_keys);
++ }
++ }
++
++ /* Calc how many (possible) matched records in each table */
++
++ for (s=stat ; s < stat_end ; s++)
++ {
++ if (s->type == JT_SYSTEM || s->type == JT_CONST)
++ {
++ /* Only one matching row */
++ s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
++ continue;
++ }
++ /* Approximate found rows and time to read them */
++ s->found_records=s->records=s->table->file->stats.records;
++ s->read_time=(ha_rows) s->table->file->scan_time();
++
++ /*
++ Set a max range of how many seeks we can expect when using keys
++ This is can't be to high as otherwise we are likely to use
++ table scan.
++ */
++ s->worst_seeks= min((double) s->found_records / 10,
++ (double) s->read_time*3);
++ if (s->worst_seeks < 2.0) // Fix for small tables
++ s->worst_seeks=2.0;
++
++ /*
++ Add to stat->const_keys those indexes for which all group fields or
++ all select distinct fields participate in one index.
++ */
++ add_group_and_distinct_keys(join, s);
++
++ if (!s->const_keys.is_clear_all() &&
++ !s->table->pos_in_table_list->embedding)
++ {
++ ha_rows records;
++ SQL_SELECT *select;
++ select= make_select(s->table, found_const_table_map,
++ found_const_table_map,
++ *s->on_expr_ref ? *s->on_expr_ref : conds,
++ 1, &error);
++ if (!select)
++ goto error;
++ records= get_quick_record_count(join->thd, select, s->table,
++ &s->const_keys, join->row_limit);
++ s->quick=select->quick;
++ s->needed_reg=select->needed_reg;
++ select->quick=0;
++ if (records == 0 && s->table->reginfo.impossible_range)
++ {
++ /*
++ Impossible WHERE or ON expression
++ In case of ON, we mark that the we match one empty NULL row.
++ In case of WHERE, don't set found_const_table_map to get the
++ caller to abort with a zero row result.
++ */
++ join->const_table_map|= s->table->map;
++ set_position(join,const_count++,s,(KEYUSE*) 0);
++ s->type= JT_CONST;
++ if (*s->on_expr_ref)
++ {
++ /* Generate empty row */
++ s->info= "Impossible ON condition";
++ found_const_table_map|= s->table->map;
++ s->type= JT_CONST;
++ mark_as_null_row(s->table); // All fields are NULL
++ }
++ }
++ if (records != HA_POS_ERROR)
++ {
++ s->found_records=records;
++ s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
++ }
++ delete select;
++ }
++ }
++
++ join->join_tab=stat;
++ join->map2table=stat_ref;
++ join->table= join->all_tables=table_vector;
++ join->const_tables=const_count;
++ join->found_const_table_map=found_const_table_map;
++
++ /* Find an optimal join order of the non-constant tables. */
++ if (join->const_tables != join->tables)
++ {
++ optimize_keyuse(join, keyuse_array);
++ if (choose_plan(join, all_table_map & ~join->const_table_map))
++ goto error;
++ }
++ else
++ {
++ memcpy((uchar*) join->best_positions,(uchar*) join->positions,
++ sizeof(POSITION)*join->const_tables);
++ join->best_read=1.0;
++ }
++ /* Generate an execution plan from the found optimal join order. */
++ DBUG_RETURN(join->thd->killed || get_best_combination(join));
++
++error:
++ /*
++ Need to clean up join_tab from TABLEs in case of error.
++ They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
++ may not be assigned yet by this function (which is building join_tab).
++ Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
++ */
++ for (tables= tables_arg; tables; tables= tables->next_leaf)
++ tables->table->reginfo.join_tab= NULL;
++ DBUG_RETURN (1);
++}
++
++
++/*****************************************************************************
++ Check with keys are used and with tables references with tables
++ Updates in stat:
++ keys Bitmap of all used keys
++ const_keys Bitmap of all keys with may be used with quick_select
++ keyuse Pointer to possible keys
++*****************************************************************************/
++
++/// Used when finding key fields
++typedef struct key_field_t {
++ Field *field;
++ Item *val; ///< May be empty if diff constant
++ uint level;
++ uint optimize;
++ bool eq_func;
++ /**
++ If true, the condition this struct represents will not be satisfied
++ when val IS NULL.
++ */
++ bool null_rejecting;
++ bool *cond_guard; /* See KEYUSE::cond_guard */
++} KEY_FIELD;
++
++/* Values in optimize */
++#define KEY_OPTIMIZE_EXISTS 1
++#define KEY_OPTIMIZE_REF_OR_NULL 2
++
++/**
++ Merge new key definitions to old ones, remove those not used in both.
++
++ This is called for OR between different levels.
++
++ To be able to do 'ref_or_null' we merge a comparison of a column
++ and 'column IS NULL' to one test. This is useful for sub select queries
++ that are internally transformed to something like:.
++
++ @code
++ SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
++ @endcode
++
++ KEY_FIELD::null_rejecting is processed as follows: @n
++ result has null_rejecting=true if it is set for both ORed references.
++ for example:
++ - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
++ - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
++
++ @todo
++ The result of this is that we're missing some 'ref' accesses.
++ OptimizerTeam: Fix this
++*/
++
++static KEY_FIELD *
++merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
++ uint and_level)
++{
++ if (start == new_fields)
++ return start; // Impossible or
++ if (new_fields == end)
++ return start; // No new fields, skip all
++
++ KEY_FIELD *first_free=new_fields;
++
++ /* Mark all found fields in old array */
++ for (; new_fields != end ; new_fields++)
++ {
++ for (KEY_FIELD *old=start ; old != first_free ; old++)
++ {
++ if (old->field == new_fields->field)
++ {
++ /*
++ NOTE: below const_item() call really works as "!used_tables()", i.e.
++ it can return FALSE where it is feasible to make it return TRUE.
++
++ The cause is as follows: Some of the tables are already known to be
++ const tables (the detection code is in make_join_statistics(),
++ above the update_ref_and_keys() call), but we didn't propagate
++ information about this: TABLE::const_table is not set to TRUE, and
++ Item::update_used_tables() hasn't been called for each item.
++ The result of this is that we're missing some 'ref' accesses.
++ TODO: OptimizerTeam: Fix this
++ */
++ if (!new_fields->val->const_item())
++ {
++ /*
++ If the value matches, we can use the key reference.
++ If not, we keep it until we have examined all new values
++ */
++ if (old->val->eq(new_fields->val, old->field->binary()))
++ {
++ old->level= and_level;
++ old->optimize= ((old->optimize & new_fields->optimize &
++ KEY_OPTIMIZE_EXISTS) |
++ ((old->optimize | new_fields->optimize) &
++ KEY_OPTIMIZE_REF_OR_NULL));
++ old->null_rejecting= (old->null_rejecting &&
++ new_fields->null_rejecting);
++ }
++ }
++ else if (old->eq_func && new_fields->eq_func &&
++ old->val->eq_by_collation(new_fields->val,
++ old->field->binary(),
++ old->field->charset()))
++
++ {
++ old->level= and_level;
++ old->optimize= ((old->optimize & new_fields->optimize &
++ KEY_OPTIMIZE_EXISTS) |
++ ((old->optimize | new_fields->optimize) &
++ KEY_OPTIMIZE_REF_OR_NULL));
++ old->null_rejecting= (old->null_rejecting &&
++ new_fields->null_rejecting);
++ }
++ else if (old->eq_func && new_fields->eq_func &&
++ ((old->val->const_item() && old->val->is_null()) ||
++ new_fields->val->is_null()))
++ {
++ /* field = expression OR field IS NULL */
++ old->level= and_level;
++ old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
++ /*
++ Remember the NOT NULL value unless the value does not depend
++ on other tables.
++ */
++ if (!old->val->used_tables() && old->val->is_null())
++ old->val= new_fields->val;
++ /* The referred expression can be NULL: */
++ old->null_rejecting= 0;
++ }
++ else
++ {
++ /*
++ We are comparing two different const. In this case we can't
++ use a key-lookup on this so it's better to remove the value
++ and let the range optimzier handle it
++ */
++ if (old == --first_free) // If last item
++ break;
++ *old= *first_free; // Remove old value
++ old--; // Retry this value
++ }
++ }
++ }
++ }
++ /* Remove all not used items */
++ for (KEY_FIELD *old=start ; old != first_free ;)
++ {
++ if (old->level != and_level)
++ { // Not used in all levels
++ if (old == --first_free)
++ break;
++ *old= *first_free; // Remove old value
++ continue;
++ }
++ old++;
++ }
++ return first_free;
++}
++
++
++/**
++ Add a possible key to array of possible keys if it's usable as a key
++
++ @param key_fields Pointer to add key, if usable
++ @param and_level And level, to be stored in KEY_FIELD
++ @param cond Condition predicate
++ @param field Field used in comparision
++ @param eq_func True if we used =, <=> or IS NULL
++ @param value Value used for comparison with field
++ @param usable_tables Tables which can be used for key optimization
++ @param sargables IN/OUT Array of found sargable candidates
++
++ @note
++ If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
++ table, we store this to be able to do not exists optimization later.
++
++ @returns
++ *key_fields is incremented if we stored a key in the array
++*/
++
++static void
++add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
++ Field *field, bool eq_func, Item **value, uint num_values,
++ table_map usable_tables, SARGABLE_PARAM **sargables)
++{
++ uint exists_optimize= 0;
++ if (!(field->flags & PART_KEY_FLAG))
++ {
++ // Don't remove column IS NULL on a LEFT JOIN table
++ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
++ !field->table->maybe_null || field->null_ptr)
++ return; // Not a key. Skip it
++ exists_optimize= KEY_OPTIMIZE_EXISTS;
++ DBUG_ASSERT(num_values == 1);
++ }
++ else
++ {
++ table_map used_tables=0;
++ bool optimizable=0;
++ for (uint i=0; i<num_values; i++)
++ {
++ used_tables|=(value[i])->used_tables();
++ if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
++ optimizable=1;
++ }
++ if (!optimizable)
++ return;
++ if (!(usable_tables & field->table->map))
++ {
++ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
++ !field->table->maybe_null || field->null_ptr)
++ return; // Can't use left join optimize
++ exists_optimize= KEY_OPTIMIZE_EXISTS;
++ }
++ else
++ {
++ JOIN_TAB *stat=field->table->reginfo.join_tab;
++ key_map possible_keys=field->key_start;
++ possible_keys.intersect(field->table->keys_in_use_for_query);
++ stat[0].keys.merge(possible_keys); // Add possible keys
++
++ /*
++ Save the following cases:
++ Field op constant
++ Field LIKE constant where constant doesn't start with a wildcard
++ Field = field2 where field2 is in a different table
++ Field op formula
++ Field IS NULL
++ Field IS NOT NULL
++ Field BETWEEN ...
++ Field IN ...
++ */
++ stat[0].key_dependent|=used_tables;
++
++ bool is_const=1;
++ for (uint i=0; i<num_values; i++)
++ {
++ if (!(is_const&= value[i]->const_item()))
++ break;
++ }
++ if (is_const)
++ stat[0].const_keys.merge(possible_keys);
++ else if (!eq_func)
++ {
++ /*
++ Save info to be able check whether this predicate can be
++ considered as sargable for range analisis after reading const tables.
++ We do not save info about equalities as update_const_equal_items
++ will take care of updating info on keys from sargable equalities.
++ */
++ (*sargables)--;
++ (*sargables)->field= field;
++ (*sargables)->arg_value= value;
++ (*sargables)->num_values= num_values;
++ }
++ /*
++ We can't always use indexes when comparing a string index to a
++ number. cmp_type() is checked to allow compare of dates to numbers.
++ eq_func is NEVER true when num_values > 1
++ */
++ if (!eq_func)
++ return;
++ if (field->result_type() == STRING_RESULT)
++ {
++ if ((*value)->result_type() != STRING_RESULT)
++ {
++ if (field->cmp_type() != (*value)->result_type())
++ return;
++ }
++ else
++ {
++ /*
++ We can't use indexes if the effective collation
++ of the operation differ from the field collation.
++ */
++ if (field->cmp_type() == STRING_RESULT &&
++ ((Field_str*)field)->charset() != cond->compare_collation())
++ return;
++ }
++ }
++ }
++ }
++ /*
++ For the moment eq_func is always true. This slot is reserved for future
++ extensions where we want to remembers other things than just eq comparisons
++ */
++ DBUG_ASSERT(eq_func);
++ /* Store possible eq field */
++ (*key_fields)->field= field;
++ (*key_fields)->eq_func= eq_func;
++ (*key_fields)->val= *value;
++ (*key_fields)->level= and_level;
++ (*key_fields)->optimize= exists_optimize;
++ /*
++ If the condition has form "tbl.keypart = othertbl.field" and
++ othertbl.field can be NULL, there will be no matches if othertbl.field
++ has NULL value.
++ We use null_rejecting in add_not_null_conds() to add
++ 'othertbl.field IS NOT NULL' to tab->select_cond.
++ */
++ (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
++ cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
++ ((*value)->type() == Item::FIELD_ITEM) &&
++ ((Item_field*)*value)->field->maybe_null());
++ (*key_fields)->cond_guard= NULL;
++ (*key_fields)++;
++}
++
++/**
++ Add possible keys to array of possible keys originated from a simple
++ predicate.
++
++ @param key_fields Pointer to add key, if usable
++ @param and_level And level, to be stored in KEY_FIELD
++ @param cond Condition predicate
++ @param field Field used in comparision
++ @param eq_func True if we used =, <=> or IS NULL
++ @param value Value used for comparison with field
++ Is NULL for BETWEEN and IN
++ @param usable_tables Tables which can be used for key optimization
++ @param sargables IN/OUT Array of found sargable candidates
++
++ @note
++ If field items f1 and f2 belong to the same multiple equality and
++ a key is added for f1, the the same key is added for f2.
++
++ @returns
++ *key_fields is incremented if we stored a key in the array
++*/
++
++static void
++add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
++ Item_func *cond, Item_field *field_item,
++ bool eq_func, Item **val,
++ uint num_values, table_map usable_tables,
++ SARGABLE_PARAM **sargables)
++{
++ Field *field= field_item->field;
++ add_key_field(key_fields, and_level, cond, field,
++ eq_func, val, num_values, usable_tables, sargables);
++ Item_equal *item_equal= field_item->item_equal;
++ if (item_equal)
++ {
++ /*
++ Add to the set of possible key values every substitution of
++ the field for an equal field included into item_equal
++ */
++ Item_equal_iterator it(*item_equal);
++ Item_field *item;
++ while ((item= it++))
++ {
++ if (!field->eq(item->field))
++ {
++ add_key_field(key_fields, and_level, cond, item->field,
++ eq_func, val, num_values, usable_tables,
++ sargables);
++ }
++ }
++ }
++}
++
++
++/**
++ Check if an expression is a non-outer field.
++
++ Checks if an expression is a field and belongs to the current select.
++
++ @param field Item expression to check
++
++ @return boolean
++ @retval TRUE the expression is a local field
++ @retval FALSE it's something else
++*/
++
++static bool
++is_local_field (Item *field)
++{
++ return field->real_item()->type() == Item::FIELD_ITEM
++ && !(field->used_tables() & OUTER_REF_TABLE_BIT)
++ && !((Item_field *)field->real_item())->depended_from;
++}
++
++
++static void
++add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
++ COND *cond, table_map usable_tables,
++ SARGABLE_PARAM **sargables)
++{
++ if (cond->type() == Item_func::COND_ITEM)
++ {
++ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
++ KEY_FIELD *org_key_fields= *key_fields;
++
++ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ {
++ Item *item;
++ while ((item=li++))
++ add_key_fields(join, key_fields, and_level, item, usable_tables,
++ sargables);
++ for (; org_key_fields != *key_fields ; org_key_fields++)
++ org_key_fields->level= *and_level;
++ }
++ else
++ {
++ (*and_level)++;
++ add_key_fields(join, key_fields, and_level, li++, usable_tables,
++ sargables);
++ Item *item;
++ while ((item=li++))
++ {
++ KEY_FIELD *start_key_fields= *key_fields;
++ (*and_level)++;
++ add_key_fields(join, key_fields, and_level, item, usable_tables,
++ sargables);
++ *key_fields=merge_key_fields(org_key_fields,start_key_fields,
++ *key_fields,++(*and_level));
++ }
++ }
++ return;
++ }
++
++ /*
++ Subquery optimization: Conditions that are pushed down into subqueries
++ are wrapped into Item_func_trig_cond. We process the wrapped condition
++ but need to set cond_guard for KEYUSE elements generated from it.
++ */
++ {
++ if (cond->type() == Item::FUNC_ITEM &&
++ ((Item_func*)cond)->functype() == Item_func::TRIG_COND_FUNC)
++ {
++ Item *cond_arg= ((Item_func*)cond)->arguments()[0];
++ if (!join->group_list && !join->order &&
++ join->unit->item &&
++ join->unit->item->substype() == Item_subselect::IN_SUBS &&
++ !join->unit->is_union())
++ {
++ KEY_FIELD *save= *key_fields;
++ add_key_fields(join, key_fields, and_level, cond_arg, usable_tables,
++ sargables);
++ // Indicate that this ref access candidate is for subquery lookup:
++ for (; save != *key_fields; save++)
++ save->cond_guard= ((Item_func_trig_cond*)cond)->get_trig_var();
++ }
++ return;
++ }
++ }
++
++ /* If item is of type 'field op field/constant' add it to key_fields */
++ if (cond->type() != Item::FUNC_ITEM)
++ return;
++ Item_func *cond_func= (Item_func*) cond;
++ switch (cond_func->select_optimize()) {
++ case Item_func::OPTIMIZE_NONE:
++ break;
++ case Item_func::OPTIMIZE_KEY:
++ {
++ Item **values;
++ /*
++ Build list of possible keys for 'a BETWEEN low AND high'.
++ It is handled similar to the equivalent condition
++ 'a >= low AND a <= high':
++ */
++ if (cond_func->functype() == Item_func::BETWEEN)
++ {
++ Item_field *field_item;
++ bool equal_func= FALSE;
++ uint num_values= 2;
++ values= cond_func->arguments();
++
++ bool binary_cmp= (values[0]->real_item()->type() == Item::FIELD_ITEM)
++ ? ((Item_field*)values[0]->real_item())->field->binary()
++ : TRUE;
++
++ /*
++ Additional optimization: If 'low = high':
++ Handle as if the condition was "t.key = low".
++ */
++ if (!((Item_func_between*)cond_func)->negated &&
++ values[1]->eq(values[2], binary_cmp))
++ {
++ equal_func= TRUE;
++ num_values= 1;
++ }
++
++ /*
++ Append keys for 'field <cmp> value[]' if the
++ condition is of the form::
++ '<field> BETWEEN value[1] AND value[2]'
++ */
++ if (is_local_field (values[0]))
++ {
++ field_item= (Item_field *) (values[0]->real_item());
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ field_item, equal_func, &values[1],
++ num_values, usable_tables, sargables);
++ }
++ /*
++ Append keys for 'value[0] <cmp> field' if the
++ condition is of the form:
++ 'value[0] BETWEEN field1 AND field2'
++ */
++ for (uint i= 1; i <= num_values; i++)
++ {
++ if (is_local_field (values[i]))
++ {
++ field_item= (Item_field *) (values[i]->real_item());
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ field_item, equal_func, values,
++ 1, usable_tables, sargables);
++ }
++ }
++ } // if ( ... Item_func::BETWEEN)
++
++ // IN, NE
++ else if (is_local_field (cond_func->key_item()) &&
++ !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
++ {
++ values= cond_func->arguments()+1;
++ if (cond_func->functype() == Item_func::NE_FUNC &&
++ is_local_field (cond_func->arguments()[1]))
++ values--;
++ DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
++ cond_func->argument_count() != 2);
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ (Item_field*) (cond_func->key_item()->real_item()),
++ 0, values,
++ cond_func->argument_count()-1,
++ usable_tables, sargables);
++ }
++ break;
++ }
++ case Item_func::OPTIMIZE_OP:
++ {
++ bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
++ cond_func->functype() == Item_func::EQUAL_FUNC);
++
++ if (is_local_field (cond_func->arguments()[0]))
++ {
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ (Item_field*) (cond_func->arguments()[0])->real_item(),
++ equal_func,
++ cond_func->arguments()+1, 1, usable_tables,
++ sargables);
++ }
++ if (is_local_field (cond_func->arguments()[1]) &&
++ cond_func->functype() != Item_func::LIKE_FUNC)
++ {
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ (Item_field*) (cond_func->arguments()[1])->real_item(),
++ equal_func,
++ cond_func->arguments(),1,usable_tables,
++ sargables);
++ }
++ break;
++ }
++ case Item_func::OPTIMIZE_NULL:
++ /* column_name IS [NOT] NULL */
++ if (is_local_field (cond_func->arguments()[0]) &&
++ !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
++ {
++ Item *tmp=new Item_null;
++ if (unlikely(!tmp)) // Should never be true
++ return;
++ add_key_equal_fields(key_fields, *and_level, cond_func,
++ (Item_field*) (cond_func->arguments()[0])->real_item(),
++ cond_func->functype() == Item_func::ISNULL_FUNC,
++ &tmp, 1, usable_tables, sargables);
++ }
++ break;
++ case Item_func::OPTIMIZE_EQUAL:
++ Item_equal *item_equal= (Item_equal *) cond;
++ Item *const_item= item_equal->get_const();
++ Item_equal_iterator it(*item_equal);
++ Item_field *item;
++ if (const_item)
++ {
++ /*
++ For each field field1 from item_equal consider the equality
++ field1=const_item as a condition allowing an index access of the table
++ with field1 by the keys value of field1.
++ */
++ while ((item= it++))
++ {
++ add_key_field(key_fields, *and_level, cond_func, item->field,
++ TRUE, &const_item, 1, usable_tables, sargables);
++ }
++ }
++ else
++ {
++ /*
++ Consider all pairs of different fields included into item_equal.
++ For each of them (field1, field1) consider the equality
++ field1=field2 as a condition allowing an index access of the table
++ with field1 by the keys value of field2.
++ */
++ Item_equal_iterator fi(*item_equal);
++ while ((item= fi++))
++ {
++ Field *field= item->field;
++ while ((item= it++))
++ {
++ if (!field->eq(item->field))
++ {
++ add_key_field(key_fields, *and_level, cond_func, field,
++ TRUE, (Item **) &item, 1, usable_tables,
++ sargables);
++ }
++ }
++ it.rewind();
++ }
++ }
++ break;
++ }
++}
++
++
++static uint
++max_part_bit(key_part_map bits)
++{
++ uint found;
++ for (found=0; bits & 1 ; found++,bits>>=1) ;
++ return found;
++}
++
++/*
++ Add all keys with uses 'field' for some keypart
++ If field->and_level != and_level then only mark key_part as const_part
++
++ RETURN
++ 0 - OK
++ 1 - Out of memory.
++*/
++
++static bool
++add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
++{
++ Field *field=key_field->field;
++ TABLE *form= field->table;
++ KEYUSE keyuse;
++
++ if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
++ {
++ for (uint key=0 ; key < form->s->keys ; key++)
++ {
++ if (!(form->keys_in_use_for_query.is_set(key)))
++ continue;
++ if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
++ continue; // ToDo: ft-keys in non-ft queries. SerG
++
++ uint key_parts= (uint) form->key_info[key].key_parts;
++ for (uint part=0 ; part < key_parts ; part++)
++ {
++ if (field->eq(form->key_info[key].key_part[part].field))
++ {
++ keyuse.table= field->table;
++ keyuse.val = key_field->val;
++ keyuse.key = key;
++ keyuse.keypart=part;
++ keyuse.keypart_map= (key_part_map) 1 << part;
++ keyuse.used_tables=key_field->val->used_tables();
++ keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
++ keyuse.null_rejecting= key_field->null_rejecting;
++ keyuse.cond_guard= key_field->cond_guard;
++ if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
++ return TRUE;
++ }
++ }
++ }
++ }
++ return FALSE;
++}
++
++
++#define FT_KEYPART (MAX_REF_PARTS+10)
++
++static bool
++add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
++ JOIN_TAB *stat,COND *cond,table_map usable_tables)
++{
++ Item_func_match *cond_func=NULL;
++
++ if (!cond)
++ return FALSE;
++
++ if (cond->type() == Item::FUNC_ITEM)
++ {
++ Item_func *func=(Item_func *)cond;
++ Item_func::Functype functype= func->functype();
++ if (functype == Item_func::FT_FUNC)
++ cond_func=(Item_func_match *)cond;
++ else if (func->arg_count == 2)
++ {
++ Item *arg0= func->arguments()[0],
++ *arg1= func->arguments()[1];
++ if (arg1->const_item() && arg1->cols() == 1 &&
++ ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
++ (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)) &&
++ arg0->type() == Item::FUNC_ITEM &&
++ ((Item_func *) arg0)->functype() == Item_func::FT_FUNC)
++ cond_func= (Item_func_match *) arg0;
++ else if (arg0->const_item() && arg0->cols() == 1 &&
++ ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
++ (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)) &&
++ arg1->type() == Item::FUNC_ITEM &&
++ ((Item_func *) arg1)->functype() == Item_func::FT_FUNC)
++ cond_func= (Item_func_match *) arg1;
++ }
++ }
++ else if (cond->type() == Item::COND_ITEM)
++ {
++ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
++
++ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ {
++ Item *item;
++ while ((item=li++))
++ {
++ if (add_ft_keys(keyuse_array,stat,item,usable_tables))
++ return TRUE;
++ }
++ }
++ }
++
++ if (!cond_func || cond_func->key == NO_SUCH_KEY ||
++ !(usable_tables & cond_func->table->map))
++ return FALSE;
++
++ KEYUSE keyuse;
++ keyuse.table= cond_func->table;
++ keyuse.val = cond_func;
++ keyuse.key = cond_func->key;
++ keyuse.keypart= FT_KEYPART;
++ keyuse.used_tables=cond_func->key_item()->used_tables();
++ keyuse.optimize= 0;
++ keyuse.keypart_map= 0;
++ return insert_dynamic(keyuse_array,(uchar*) &keyuse);
++}
++
++
++static int
++sort_keyuse(KEYUSE *a,KEYUSE *b)
++{
++ int res;
++ if (a->table->tablenr != b->table->tablenr)
++ return (int) (a->table->tablenr - b->table->tablenr);
++ if (a->key != b->key)
++ return (int) (a->key - b->key);
++ if (a->keypart != b->keypart)
++ return (int) (a->keypart - b->keypart);
++ // Place const values before other ones
++ if ((res= test((a->used_tables & ~OUTER_REF_TABLE_BIT)) -
++ test((b->used_tables & ~OUTER_REF_TABLE_BIT))))
++ return res;
++ /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
++ return (int) ((a->optimize & KEY_OPTIMIZE_REF_OR_NULL) -
++ (b->optimize & KEY_OPTIMIZE_REF_OR_NULL));
++}
++
++
++/*
++ Add to KEY_FIELD array all 'ref' access candidates within nested join.
++
++ This function populates KEY_FIELD array with entries generated from the
++ ON condition of the given nested join, and does the same for nested joins
++ contained within this nested join.
++
++ @param[in] nested_join_table Nested join pseudo-table to process
++ @param[in,out] end End of the key field array
++ @param[in,out] and_level And-level
++ @param[in,out] sargables Array of found sargable candidates
++
++
++ @note
++ We can add accesses to the tables that are direct children of this nested
++ join (1), and are not inner tables w.r.t their neighbours (2).
++
++ Example for #1 (outer brackets pair denotes nested join this function is
++ invoked for):
++ @code
++ ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
++ @endcode
++ Example for #2:
++ @code
++ ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
++ @endcode
++ In examples 1-2 for condition cond, we can add 'ref' access candidates to
++ t1 only.
++ Example #3:
++ @code
++ ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
++ @endcode
++ Here we can add 'ref' access candidates for t1 and t2, but not for t3.
++*/
++
++static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
++ KEY_FIELD **end, uint *and_level,
++ SARGABLE_PARAM **sargables)
++{
++ List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
++ table_map tables= 0;
++ TABLE_LIST *table;
++ DBUG_ASSERT(nested_join_table->nested_join);
++
++ while ((table= li++))
++ {
++ if (table->nested_join)
++ add_key_fields_for_nj(join, table, end, and_level, sargables);
++ else
++ if (!table->on_expr)
++ tables |= table->table->map;
++ }
++ add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
++ sargables);
++}
++
++
++/**
++ Update keyuse array with all possible keys we can use to fetch rows.
++
++ @param thd
++ @param[out] keyuse Put here ordered array of KEYUSE structures
++ @param join_tab Array in tablenr_order
++ @param tables Number of tables in join
++ @param cond WHERE condition (note that the function analyzes
++ join_tab[i]->on_expr too)
++ @param normal_tables Tables not inner w.r.t some outer join (ones
++ for which we can make ref access based the WHERE
++ clause)
++ @param select_lex current SELECT
++ @param[out] sargables Array of found sargable candidates
++
++ @retval
++ 0 OK
++ @retval
++ 1 Out of memory.
++*/
++
++static bool
++update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
++ uint tables, COND *cond, COND_EQUAL *cond_equal,
++ table_map normal_tables, SELECT_LEX *select_lex,
++ SARGABLE_PARAM **sargables)
++{
++ uint and_level,i,found_eq_constant;
++ KEY_FIELD *key_fields, *end, *field;
++ uint sz;
++ uint m= max(select_lex->max_equal_elems,1);
++
++ /*
++ We use the same piece of memory to store both KEY_FIELD
++ and SARGABLE_PARAM structure.
++ KEY_FIELD values are placed at the beginning this memory
++ while SARGABLE_PARAM values are put at the end.
++ All predicates that are used to fill arrays of KEY_FIELD
++ and SARGABLE_PARAM structures have at most 2 arguments
++ except BETWEEN predicates that have 3 arguments and
++ IN predicates.
++ This any predicate if it's not BETWEEN/IN can be used
++ directly to fill at most 2 array elements, either of KEY_FIELD
++ or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements
++ can be filled as this predicate is considered as
++ saragable with respect to each of its argument.
++ An IN predicate can require at most 1 element as currently
++ it is considered as sargable only for its first argument.
++ Multiple equality can add elements that are filled after
++ substitution of field arguments by equal fields. There
++ can be not more than select_lex->max_equal_elems such
++ substitutions.
++ */
++ sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ (((thd->lex->current_select->cond_count+1)*2 +
++ thd->lex->current_select->between_count)*m+1);
++ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
++ return TRUE; /* purecov: inspected */
++ and_level= 0;
++ field= end= key_fields;
++ *sargables= (SARGABLE_PARAM *) key_fields +
++ (sz - sizeof((*sargables)[0].field))/sizeof(SARGABLE_PARAM);
++ /* set a barrier for the array of SARGABLE_PARAM */
++ (*sargables)[0].field= 0;
++
++ if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
++ return TRUE;
++ if (cond)
++ {
++ add_key_fields(join_tab->join, &end, &and_level, cond, normal_tables,
++ sargables);
++ for (; field != end ; field++)
++ {
++ if (add_key_part(keyuse,field))
++ return TRUE;
++ /* Mark that we can optimize LEFT JOIN */
++ if (field->val->type() == Item::NULL_ITEM &&
++ !field->field->real_maybe_null())
++ field->field->table->reginfo.not_exists_optimize=1;
++ }
++ }
++ for (i=0 ; i < tables ; i++)
++ {
++ /*
++ Block the creation of keys for inner tables of outer joins.
++ Here only the outer joins that can not be converted to
++ inner joins are left and all nests that can be eliminated
++ are flattened.
++ In the future when we introduce conditional accesses
++ for inner tables in outer joins these keys will be taken
++ into account as well.
++ */
++ if (*join_tab[i].on_expr_ref)
++ add_key_fields(join_tab->join, &end, &and_level,
++ *join_tab[i].on_expr_ref,
++ join_tab[i].table->map, sargables);
++ }
++
++ /* Process ON conditions for the nested joins */
++ {
++ List_iterator<TABLE_LIST> li(*join_tab->join->join_list);
++ TABLE_LIST *table;
++ while ((table= li++))
++ {
++ if (table->nested_join)
++ add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
++ sargables);
++ }
++ }
++
++ /* fill keyuse with found key parts */
++ for ( ; field != end ; field++)
++ {
++ if (add_key_part(keyuse,field))
++ return TRUE;
++ }
++
++ if (select_lex->ftfunc_list->elements)
++ {
++ if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
++ return TRUE;
++ }
++
++ /*
++ Sort the array of possible keys and remove the following key parts:
++ - ref if there is a keypart which is a ref and a const.
++ (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
++ then we skip the key part corresponding to b=t2.d)
++ - keyparts without previous keyparts
++ (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
++ used in the query, we drop the partial key parts from consideration).
++ Special treatment for ft-keys.
++ */
++ if (keyuse->elements)
++ {
++ KEYUSE key_end,*prev,*save_pos,*use;
++
++ my_qsort(keyuse->buffer,keyuse->elements,sizeof(KEYUSE),
++ (qsort_cmp) sort_keyuse);
++
++ bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */
++ if (insert_dynamic(keyuse,(uchar*) &key_end))
++ return TRUE;
++
++ use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
++ prev= &key_end;
++ found_eq_constant=0;
++ for (i=0 ; i < keyuse->elements-1 ; i++,use++)
++ {
++ if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
++ use->table->const_key_parts[use->key]|= use->keypart_map;
++ if (use->keypart != FT_KEYPART)
++ {
++ if (use->key == prev->key && use->table == prev->table)
++ {
++ if (prev->keypart+1 < use->keypart ||
++ (prev->keypart == use->keypart && found_eq_constant))
++ continue; /* remove */
++ }
++ else if (use->keypart != 0) // First found must be 0
++ continue;
++ }
++
++#if defined(__GNUC__) && !MY_GNUC_PREREQ(4,4)
++ /*
++ Old gcc used a memcpy(), which is undefined if save_pos==use:
++ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
++ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
++ */
++ if (save_pos != use)
++#endif
++ *save_pos= *use;
++ prev=use;
++ found_eq_constant= !use->used_tables;
++ /* Save ptr to first use */
++ if (!use->table->reginfo.join_tab->keyuse)
++ use->table->reginfo.join_tab->keyuse=save_pos;
++ use->table->reginfo.join_tab->checked_keys.set_bit(use->key);
++ save_pos++;
++ }
++ i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
++ VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
++ keyuse->elements=i;
++ }
++ return FALSE;
++}
++
++/**
++ Update some values in keyuse for faster choose_plan() loop.
++*/
++
++static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
++{
++ KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
++
++ for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
++ {
++ table_map map;
++ /*
++ If we find a ref, assume this table matches a proportional
++ part of this table.
++ For example 100 records matching a table with 5000 records
++ gives 5000/100 = 50 records per key
++ Constant tables are ignored.
++ To avoid bad matches, we don't make ref_table_rows less than 100.
++ */
++ keyuse->ref_table_rows= ~(ha_rows) 0; // If no ref
++ if (keyuse->used_tables &
++ (map= (keyuse->used_tables & ~join->const_table_map &
++ ~OUTER_REF_TABLE_BIT)))
++ {
++ uint tablenr;
++ for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
++ if (map == 1) // Only one table
++ {
++ TABLE *tmp_table=join->all_tables[tablenr];
++ keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ }
++ }
++ /*
++ Outer reference (external field) is constant for single executing
++ of subquery
++ */
++ if (keyuse->used_tables == OUTER_REF_TABLE_BIT)
++ keyuse->ref_table_rows= 1;
++ }
++}
++
++
++/**
++ Discover the indexes that can be used for GROUP BY or DISTINCT queries.
++
++ If the query has a GROUP BY clause, find all indexes that contain all
++ GROUP BY fields, and add those indexes to join->const_keys.
++
++ If the query has a DISTINCT clause, find all indexes that contain all
++ SELECT fields, and add those indexes to join->const_keys.
++ This allows later on such queries to be processed by a
++ QUICK_GROUP_MIN_MAX_SELECT.
++
++ @param join
++ @param join_tab
++
++ @return
++ None
++*/
++
++static void
++add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
++{
++ List<Item_field> indexed_fields;
++ List_iterator<Item_field> indexed_fields_it(indexed_fields);
++ ORDER *cur_group;
++ Item_field *cur_item;
++ key_map possible_keys(0);
++
++ if (join->group_list)
++ { /* Collect all query fields referenced in the GROUP clause. */
++ for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
++ (*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
++ (uchar*) &indexed_fields);
++ }
++ else if (join->select_distinct)
++ { /* Collect all query fields referenced in the SELECT clause. */
++ List<Item> &select_items= join->fields_list;
++ List_iterator<Item> select_items_it(select_items);
++ Item *item;
++ while ((item= select_items_it++))
++ item->walk(&Item::collect_item_field_processor, 0,
++ (uchar*) &indexed_fields);
++ }
++ else
++ return;
++
++ if (indexed_fields.elements == 0)
++ return;
++
++ /* Intersect the keys of all group fields. */
++ cur_item= indexed_fields_it++;
++ possible_keys.merge(cur_item->field->part_of_key);
++ while ((cur_item= indexed_fields_it++))
++ {
++ possible_keys.intersect(cur_item->field->part_of_key);
++ }
++
++ if (!possible_keys.is_clear_all())
++ join_tab->const_keys.merge(possible_keys);
++}
++
++
++/*****************************************************************************
++ Go through all combinations of not marked tables and find the one
++ which uses least records
++*****************************************************************************/
++
++/** Save const tables first as used tables. */
++
++static void
++set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
++{
++ join->positions[idx].table= table;
++ join->positions[idx].key=key;
++ join->positions[idx].records_read=1.0; /* This is a const table */
++ join->positions[idx].ref_depend_map= 0;
++
++ /* Move the const table as down as possible in best_ref */
++ JOIN_TAB **pos=join->best_ref+idx+1;
++ JOIN_TAB *next=join->best_ref[idx];
++ for (;next != table ; pos++)
++ {
++ JOIN_TAB *tmp=pos[0];
++ pos[0]=next;
++ next=tmp;
++ }
++ join->best_ref[idx]=table;
++}
++
++
++/**
++ Find the best access path for an extension of a partial execution
++ plan and add this path to the plan.
++
++ The function finds the best access path to table 's' from the passed
++ partial plan where an access path is the general term for any means to
++ access the data in 's'. An access path may use either an index or a scan,
++ whichever is cheaper. The input partial plan is passed via the array
++ 'join->positions' of length 'idx'. The chosen access method for 's' and its
++ cost are stored in 'join->positions[idx]'.
++
++ @param join pointer to the structure providing all context info
++ for the query
++ @param s the table to be joined by the function
++ @param thd thread for the connection that submitted the query
++ @param remaining_tables set of tables not included into the partial plan yet
++ @param idx the length of the partial plan
++ @param record_count estimate for the number of records returned by the
++ partial plan
++ @param read_time the cost of the partial plan
++
++ @return
++ None
++*/
++
++static void
++best_access_path(JOIN *join,
++ JOIN_TAB *s,
++ THD *thd,
++ table_map remaining_tables,
++ uint idx,
++ double record_count,
++ double read_time)
++{
++ KEYUSE *best_key= 0;
++ uint best_max_key_part= 0;
++ my_bool found_constraint= 0;
++ double best= DBL_MAX;
++ double best_time= DBL_MAX;
++ double records= DBL_MAX;
++ table_map best_ref_depends_map= 0;
++ double tmp;
++ ha_rows rec;
++ DBUG_ENTER("best_access_path");
++
++ if (s->keyuse)
++ { /* Use key if possible */
++ TABLE *table= s->table;
++ KEYUSE *keyuse,*start_key=0;
++ double best_records= DBL_MAX;
++ uint max_key_part=0;
++
++ /* Test how we can use keys */
++ rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
++ for (keyuse=s->keyuse ; keyuse->table == table ;)
++ {
++ key_part_map found_part= 0;
++ table_map found_ref= 0;
++ uint key= keyuse->key;
++ KEY *keyinfo= table->key_info+key;
++ bool ft_key= (keyuse->keypart == FT_KEYPART);
++ /* Bitmap of keyparts where the ref access is over 'keypart=const': */
++ key_part_map const_part= 0;
++ /* The or-null keypart in ref-or-null access: */
++ key_part_map ref_or_null_part= 0;
++
++ /* Calculate how many key segments of the current key we can use */
++ start_key= keyuse;
++
++ do /* For each keypart */
++ {
++ uint keypart= keyuse->keypart;
++ table_map best_part_found_ref= 0;
++ double best_prev_record_reads= DBL_MAX;
++
++ do /* For each way to access the keypart */
++ {
++
++ /*
++ if 1. expression doesn't refer to forward tables
++ 2. we won't get two ref-or-null's
++ */
++ if (!(remaining_tables & keyuse->used_tables) &&
++ !(ref_or_null_part && (keyuse->optimize &
++ KEY_OPTIMIZE_REF_OR_NULL)))
++ {
++ found_part|= keyuse->keypart_map;
++ if (!(keyuse->used_tables & ~join->const_table_map))
++ const_part|= keyuse->keypart_map;
++
++ double tmp2= prev_record_reads(join, idx, (found_ref |
++ keyuse->used_tables));
++ if (tmp2 < best_prev_record_reads)
++ {
++ best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
++ best_prev_record_reads= tmp2;
++ }
++ if (rec > keyuse->ref_table_rows)
++ rec= keyuse->ref_table_rows;
++ /*
++ If there is one 'key_column IS NULL' expression, we can
++ use this ref_or_null optimisation of this field
++ */
++ if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
++ ref_or_null_part |= keyuse->keypart_map;
++ }
++ keyuse++;
++ } while (keyuse->table == table && keyuse->key == key &&
++ keyuse->keypart == keypart);
++ found_ref|= best_part_found_ref;
++ } while (keyuse->table == table && keyuse->key == key);
++
++ /*
++ Assume that that each key matches a proportional part of table.
++ */
++ if (!found_part && !ft_key)
++ continue; // Nothing usable found
++
++ if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
++ rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
++
++ /*
++ ft-keys require special treatment
++ */
++ if (ft_key)
++ {
++ /*
++ Really, there should be records=0.0 (yes!)
++ but 1.0 would be probably safer
++ */
++ tmp= prev_record_reads(join, idx, found_ref);
++ records= 1.0;
++ }
++ else
++ {
++ found_constraint= 1;
++ /*
++ Check if we found full key
++ */
++ if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
++ !ref_or_null_part)
++ { /* use eq key */
++ max_key_part= (uint) ~0;
++ if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
++ {
++ tmp = prev_record_reads(join, idx, found_ref);
++ records=1.0;
++ }
++ else
++ {
++ if (!found_ref)
++ { /* We found a const key */
++ /*
++ ReuseRangeEstimateForRef-1:
++ We get here if we've found a ref(const) (c_i are constants):
++ "(keypart1=c1) AND ... AND (keypartN=cN)" [ref_const_cond]
++
++ If range optimizer was able to construct a "range"
++ access on this index, then its condition "quick_cond" was
++ eqivalent to ref_const_cond (*), and we can re-use E(#rows)
++ from the range optimizer.
++
++ Proof of (*): By properties of range and ref optimizers
++ quick_cond will be equal or tighther than ref_const_cond.
++ ref_const_cond already covers "smallest" possible interval -
++ a singlepoint interval over all keyparts. Therefore,
++ quick_cond is equivalent to ref_const_cond (if it was an
++ empty interval we wouldn't have got here).
++ */
++ if (table->quick_keys.is_set(key))
++ records= (double) table->quick_rows[key];
++ else
++ {
++ /* quick_range couldn't use key! */
++ records= (double) s->records/rec;
++ }
++ }
++ else
++ {
++ if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
++ { /* Prefer longer keys */
++ records=
++ ((double) s->records / (double) rec *
++ (1.0 +
++ ((double) (table->s->max_key_length-keyinfo->key_length) /
++ (double) table->s->max_key_length)));
++ if (records < 2.0)
++ records=2.0; /* Can't be as good as a unique */
++ }
++ /*
++ ReuseRangeEstimateForRef-2: We get here if we could not reuse
++ E(#rows) from range optimizer. Make another try:
++
++ If range optimizer produced E(#rows) for a prefix of the ref
++ access we're considering, and that E(#rows) is lower then our
++ current estimate, make an adjustment. The criteria of when we
++ can make an adjustment is a special case of the criteria used
++ in ReuseRangeEstimateForRef-3.
++ */
++ if (table->quick_keys.is_set(key) &&
++ const_part & (1 << table->quick_key_parts[key]) &&
++ table->quick_n_ranges[key] == 1 &&
++ records > (double) table->quick_rows[key])
++ {
++ records= (double) table->quick_rows[key];
++ }
++ }
++ /* Limit the number of matched rows */
++ tmp= records;
++ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
++ if (table->covering_keys.is_set(key))
++ {
++ /* we can use only index tree */
++ uint keys_per_block= table->file->stats.block_size/2/
++ (keyinfo->key_length+table->file->ref_length)+1;
++ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
++ }
++ else
++ tmp= record_count*min(tmp,s->worst_seeks);
++ }
++ }
++ else
++ {
++ /*
++ Use as much key-parts as possible and a uniq key is better
++ than a not unique key
++ Set tmp to (previous record count) * (records / combination)
++ */
++ if ((found_part & 1) &&
++ (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
++ found_part == PREV_BITS(uint,keyinfo->key_parts)))
++ {
++ max_key_part= max_part_bit(found_part);
++ /*
++ ReuseRangeEstimateForRef-3:
++ We're now considering a ref[or_null] access via
++ (t.keypart1=e1 AND ... AND t.keypartK=eK) [ OR
++ (same-as-above but with one cond replaced
++ with "t.keypart_i IS NULL")] (**)
++
++ Try re-using E(#rows) from "range" optimizer:
++ We can do so if "range" optimizer used the same intervals as
++ in (**). The intervals used by range optimizer may be not
++ available at this point (as "range" access might have choosen to
++ create quick select over another index), so we can't compare
++ them to (**). We'll make indirect judgements instead.
++ The sufficient conditions for re-use are:
++ (C1) All e_i in (**) are constants, i.e. found_ref==FALSE. (if
++ this is not satisfied we have no way to know which ranges
++ will be actually scanned by 'ref' until we execute the
++ join)
++ (C2) max #key parts in 'range' access == K == max_key_part (this
++ is apparently a necessary requirement)
++
++ We also have a property that "range optimizer produces equal or
++ tighter set of scan intervals than ref(const) optimizer". Each
++ of the intervals in (**) are "tightest possible" intervals when
++ one limits itself to using keyparts 1..K (which we do in #2).
++ From here it follows that range access used either one, or
++ both of the (I1) and (I2) intervals:
++
++ (t.keypart1=c1 AND ... AND t.keypartK=eK) (I1)
++ (same-as-above but with one cond replaced
++ with "t.keypart_i IS NULL") (I2)
++
++ The remaining part is to exclude the situation where range
++ optimizer used one interval while we're considering
++ ref-or-null and looking for estimate for two intervals. This
++ is done by last limitation:
++
++ (C3) "range optimizer used (have ref_or_null?2:1) intervals"
++ */
++ if (table->quick_keys.is_set(key) && !found_ref && //(C1)
++ table->quick_key_parts[key] == max_key_part && //(C2)
++ table->quick_n_ranges[key] == 1+test(ref_or_null_part)) //(C3)
++ {
++ tmp= records= (double) table->quick_rows[key];
++ }
++ else
++ {
++ /* Check if we have statistic about the distribution */
++ if ((records= keyinfo->rec_per_key[max_key_part-1]))
++ {
++ /*
++ Fix for the case where the index statistics is too
++ optimistic: If
++ (1) We're considering ref(const) and there is quick select
++ on the same index,
++ (2) and that quick select uses more keyparts (i.e. it will
++ scan equal/smaller interval then this ref(const))
++ (3) and E(#rows) for quick select is higher then our
++ estimate,
++ Then
++ We'll use E(#rows) from quick select.
++
++ Q: Why do we choose to use 'ref'? Won't quick select be
++ cheaper in some cases ?
++ TODO: figure this out and adjust the plan choice if needed.
++ */
++ if (!found_ref && table->quick_keys.is_set(key) && // (1)
++ table->quick_key_parts[key] > max_key_part && // (2)
++ records < (double)table->quick_rows[key]) // (3)
++ records= (double)table->quick_rows[key];
++
++ tmp= records;
++ }
++ else
++ {
++ /*
++ Assume that the first key part matches 1% of the file
++ and that the whole key matches 10 (duplicates) or 1
++ (unique) records.
++ Assume also that more key matches proportionally more
++ records
++ This gives the formula:
++ records = (x * (b-a) + a*c-b)/(c-1)
++
++ b = records matched by whole key
++ a = records matched by first key part (1% of all records?)
++ c = number of key parts in key
++ x = used key parts (1 <= x <= c)
++ */
++ double rec_per_key;
++ if (!(rec_per_key=(double)
++ keyinfo->rec_per_key[keyinfo->key_parts-1]))
++ rec_per_key=(double) s->records/rec+1;
++
++ if (!s->records)
++ tmp = 0;
++ else if (rec_per_key/(double) s->records >= 0.01)
++ tmp = rec_per_key;
++ else
++ {
++ double a=s->records*0.01;
++ if (keyinfo->key_parts > 1)
++ tmp= (max_key_part * (rec_per_key - a) +
++ a*keyinfo->key_parts - rec_per_key)/
++ (keyinfo->key_parts-1);
++ else
++ tmp= a;
++ set_if_bigger(tmp,1.0);
++ }
++ records = (ulong) tmp;
++ }
++
++ if (ref_or_null_part)
++ {
++ /* We need to do two key searches to find key */
++ tmp *= 2.0;
++ records *= 2.0;
++ }
++
++ /*
++ ReuseRangeEstimateForRef-4: We get here if we could not reuse
++ E(#rows) from range optimizer. Make another try:
++
++ If range optimizer produced E(#rows) for a prefix of the ref
++ access we're considering, and that E(#rows) is lower then our
++ current estimate, make the adjustment.
++
++ The decision whether we can re-use the estimate from the range
++ optimizer is the same as in ReuseRangeEstimateForRef-3,
++ applied to first table->quick_key_parts[key] key parts.
++ */
++ if (table->quick_keys.is_set(key) &&
++ table->quick_key_parts[key] <= max_key_part &&
++ const_part & (1 << table->quick_key_parts[key]) &&
++ table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
++ const_part) &&
++ records > (double) table->quick_rows[key])
++ {
++ tmp= records= (double) table->quick_rows[key];
++ }
++ }
++
++ /* Limit the number of matched rows */
++ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
++ if (table->covering_keys.is_set(key))
++ {
++ /* we can use only index tree */
++ uint keys_per_block= table->file->stats.block_size/2/
++ (keyinfo->key_length+table->file->ref_length)+1;
++ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
++ }
++ else
++ tmp= record_count*min(tmp,s->worst_seeks);
++ }
++ else
++ tmp= best_time; // Do nothing
++ }
++ } /* not ft_key */
++ if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
++ {
++ best_time= tmp + records/(double) TIME_FOR_COMPARE;
++ best= tmp;
++ best_records= records;
++ best_key= start_key;
++ best_max_key_part= max_key_part;
++ best_ref_depends_map= found_ref;
++ }
++ }
++ records= best_records;
++ }
++
++ /*
++ Don't test table scan if it can't be better.
++ Prefer key lookup if we would use the same key for scanning.
++
++ Don't do a table scan on InnoDB tables, if we can read the used
++ parts of the row from any of the used index.
++ This is because table scans uses index and we would not win
++ anything by using a table scan.
++
++ A word for word translation of the below if-statement in psergey's
++ understanding: we check if we should use table scan if:
++ (1) The found 'ref' access produces more records than a table scan
++ (or index scan, or quick select), or 'ref' is more expensive than
++ any of them.
++ (2) This doesn't hold: the best way to perform table scan is to to perform
++ 'range' access using index IDX, and the best way to perform 'ref'
++ access is to use the same index IDX, with the same or more key parts.
++ (note: it is not clear how this rule is/should be extended to
++ index_merge quick selects)
++ (3) See above note about InnoDB.
++ (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access
++ path, but there is no quick select)
++ If the condition in the above brackets holds, then the only possible
++ "table scan" access method is ALL/index (there is no quick select).
++ Since we have a 'ref' access path, and FORCE INDEX instructs us to
++ choose it over ALL/index, there is no need to consider a full table
++ scan.
++ */
++ if ((records >= s->found_records || best > s->read_time) && // (1)
++ !(s->quick && best_key && s->quick->index == best_key->key && // (2)
++ best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
++ !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
++ ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
++ !(s->table->force_index && best_key && !s->quick)) // (4)
++ { // Check full join
++ ha_rows rnd_records= s->found_records;
++ /*
++ If there is a filtering condition on the table (i.e. ref analyzer found
++ at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
++ preceding this table in the join order we're now considering), then
++ assume that 25% of the rows will be filtered out by this condition.
++
++ This heuristic is supposed to force tables used in exprZ to be before
++ this table in join order.
++ */
++ if (found_constraint)
++ rnd_records-= rnd_records/4;
++
++ /*
++ If applicable, get a more accurate estimate. Don't use the two
++ heuristics at once.
++ */
++ if (s->table->quick_condition_rows != s->found_records)
++ rnd_records= s->table->quick_condition_rows;
++
++ /*
++ Range optimizer never proposes a RANGE if it isn't better
++ than FULL: so if RANGE is present, it's always preferred to FULL.
++ Here we estimate its cost.
++ */
++ if (s->quick)
++ {
++ /*
++ For each record we:
++ - read record range through 'quick'
++ - skip rows which does not satisfy WHERE constraints
++ TODO:
++ We take into account possible use of join cache for ALL/index
++ access (see first else-branch below), but we don't take it into
++ account here for range/index_merge access. Find out why this is so.
++ */
++ tmp= record_count *
++ (s->quick->read_time +
++ (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
++ }
++ else
++ {
++ /* Estimate cost of reading table. */
++ tmp= s->table->file->scan_time();
++ if (s->table->map & join->outer_join) // Can't use join cache
++ {
++ /*
++ For each record we have to:
++ - read the whole table record
++ - skip rows which does not satisfy join condition
++ */
++ tmp= record_count *
++ (tmp +
++ (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
++ }
++ else
++ {
++ /* We read the table as many times as join buffer becomes full. */
++ tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
++ record_count /
++ (double) thd->variables.join_buff_size));
++ /*
++ We don't make full cartesian product between rows in the scanned
++ table and existing records because we skip all rows from the
++ scanned table, which does not satisfy join condition when
++ we read the table (see flush_cached_records for details). Here we
++ take into account cost to read and skip these records.
++ */
++ tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
++ }
++ }
++
++ /*
++ We estimate the cost of evaluating WHERE clause for found records
++ as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
++ tmp give us total cost of using TABLE SCAN
++ */
++ if (best == DBL_MAX ||
++ (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
++ best + record_count/(double) TIME_FOR_COMPARE*records))
++ {
++ /*
++ If the table has a range (s->quick is set) make_join_select()
++ will ensure that this will be used
++ */
++ best= tmp;
++ records= rows2double(rnd_records);
++ best_key= 0;
++ /* range/index_merge/ALL/index access method are "independent", so: */
++ best_ref_depends_map= 0;
++ }
++ }
++
++ /* Update the cost information for the current partial plan */
++ join->positions[idx].records_read= records;
++ join->positions[idx].read_time= best;
++ join->positions[idx].key= best_key;
++ join->positions[idx].table= s;
++ join->positions[idx].ref_depend_map= best_ref_depends_map;
++
++ if (!best_key &&
++ idx == join->const_tables &&
++ s->table == join->sort_by_table &&
++ join->unit->select_limit_cnt >= records)
++ join->sort_by_table= (TABLE*) 1; // Must use temporary table
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Selects and invokes a search strategy for an optimal query plan.
++
++ The function checks user-configurable parameters that control the search
++ strategy for an optimal plan, selects the search method and then invokes
++ it. Each specific optimization procedure stores the final optimal plan in
++ the array 'join->best_positions', and the cost of the plan in
++ 'join->best_read'.
++
++ @param join pointer to the structure providing all context info for
++ the query
++ @param join_tables set of the tables in the query
++
++ @todo
++ 'MAX_TABLES+2' denotes the old implementation of find_best before
++ the greedy version. Will be removed when greedy_search is approved.
++
++ @retval
++ FALSE ok
++ @retval
++ TRUE Fatal error
++*/
++
++static bool
++choose_plan(JOIN *join, table_map join_tables)
++{
++ uint search_depth= join->thd->variables.optimizer_search_depth;
++ uint prune_level= join->thd->variables.optimizer_prune_level;
++ bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
++ DBUG_ENTER("choose_plan");
++
++ join->cur_embedding_map= 0;
++ reset_nj_counters(join->join_list);
++ /*
++ if (SELECT_STRAIGHT_JOIN option is set)
++ reorder tables so dependent tables come after tables they depend
++ on, otherwise keep tables in the order they were specified in the query
++ else
++ Apply heuristic: pre-sort all access plans with respect to the number of
++ records accessed.
++ */
++ my_qsort(join->best_ref + join->const_tables,
++ join->tables - join->const_tables, sizeof(JOIN_TAB*),
++ straight_join ? join_tab_cmp_straight : join_tab_cmp);
++
++ if (straight_join)
++ {
++ optimize_straight_join(join, join_tables);
++ }
++ else
++ {
++ if (search_depth == MAX_TABLES+2)
++ { /*
++ TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
++ the greedy version. Will be removed when greedy_search is approved.
++ */
++ join->best_read= DBL_MAX;
++ if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
++ DBUG_RETURN(TRUE);
++ }
++ else
++ {
++ if (search_depth == 0)
++ /* Automatically determine a reasonable value for 'search_depth' */
++ search_depth= determine_search_depth(join);
++ if (greedy_search(join, join_tables, search_depth, prune_level))
++ DBUG_RETURN(TRUE);
++ }
++ }
++
++ /*
++ Store the cost of this query into a user variable
++ Don't update last_query_cost for statements that are not "flat joins" :
++ i.e. they have subqueries, unions or call stored procedures.
++ TODO: calculate a correct cost for a query with subqueries and UNIONs.
++ */
++ if (join->thd->lex->is_single_level_stmt())
++ join->thd->status_var.last_query_cost= join->best_read;
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Compare two JOIN_TAB objects based on the number of accessed records.
++
++ @param ptr1 pointer to first JOIN_TAB object
++ @param ptr2 pointer to second JOIN_TAB object
++
++ NOTES
++ The order relation implemented by join_tab_cmp() is not transitive,
++ i.e. it is possible to choose such a, b and c that (a < b) && (b < c)
++ but (c < a). This implies that result of a sort using the relation
++ implemented by join_tab_cmp() depends on the order in which
++ elements are compared, i.e. the result is implementation-specific.
++ Example:
++ a: dependent = 0x0 table->map = 0x1 found_records = 3 ptr = 0x907e6b0
++ b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838
++ c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0
++
++ @retval
++ 1 if first is bigger
++ @retval
++ -1 if second is bigger
++ @retval
++ 0 if equal
++*/
++
++static int
++join_tab_cmp(const void* ptr1, const void* ptr2)
++{
++ JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
++ JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
++
++ if (jt1->dependent & jt2->table->map)
++ return 1;
++ if (jt2->dependent & jt1->table->map)
++ return -1;
++ if (jt1->found_records > jt2->found_records)
++ return 1;
++ if (jt1->found_records < jt2->found_records)
++ return -1;
++ return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
++}
++
++
++/**
++ Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
++*/
++
++static int
++join_tab_cmp_straight(const void* ptr1, const void* ptr2)
++{
++ JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
++ JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
++
++ if (jt1->dependent & jt2->table->map)
++ return 1;
++ if (jt2->dependent & jt1->table->map)
++ return -1;
++ return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
++}
++
++/**
++ Heuristic procedure to automatically guess a reasonable degree of
++ exhaustiveness for the greedy search procedure.
++
++ The procedure estimates the optimization time and selects a search depth
++ big enough to result in a near-optimal QEP, that doesn't take too long to
++ find. If the number of tables in the query exceeds some constant, then
++ search_depth is set to this constant.
++
++ @param join pointer to the structure providing all context info for
++ the query
++
++ @note
++ This is an extremely simplistic implementation that serves as a stub for a
++ more advanced analysis of the join. Ideally the search depth should be
++ determined by learning from previous query optimizations, because it will
++ depend on the CPU power (and other factors).
++
++ @todo
++ this value should be determined dynamically, based on statistics:
++ uint max_tables_for_exhaustive_opt= 7;
++
++ @todo
++ this value could be determined by some mapping of the form:
++ depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
++
++ @return
++ A positive integer that specifies the search depth (and thus the
++ exhaustiveness) of the depth-first search algorithm used by
++ 'greedy_search'.
++*/
++
++static uint
++determine_search_depth(JOIN *join)
++{
++ uint table_count= join->tables - join->const_tables;
++ uint search_depth;
++ /* TODO: this value should be determined dynamically, based on statistics: */
++ uint max_tables_for_exhaustive_opt= 7;
++
++ if (table_count <= max_tables_for_exhaustive_opt)
++ search_depth= table_count+1; // use exhaustive for small number of tables
++ else
++ /*
++ TODO: this value could be determined by some mapping of the form:
++ depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
++ */
++ search_depth= max_tables_for_exhaustive_opt; // use greedy search
++
++ return search_depth;
++}
++
++
++/**
++ Select the best ways to access the tables in a query without reordering them.
++
++ Find the best access paths for each query table and compute their costs
++ according to their order in the array 'join->best_ref' (thus without
++ reordering the join tables). The function calls sequentially
++ 'best_access_path' for each table in the query to select the best table
++ access method. The final optimal plan is stored in the array
++ 'join->best_positions', and the corresponding cost in 'join->best_read'.
++
++ @param join pointer to the structure providing all context info for
++ the query
++ @param join_tables set of the tables in the query
++
++ @note
++ This function can be applied to:
++ - queries with STRAIGHT_JOIN
++ - internally to compute the cost of an arbitrary QEP
++ @par
++ Thus 'optimize_straight_join' can be used at any stage of the query
++ optimization process to finalize a QEP as it is.
++*/
++
++static void
++optimize_straight_join(JOIN *join, table_map join_tables)
++{
++ JOIN_TAB *s;
++ uint idx= join->const_tables;
++ double record_count= 1.0;
++ double read_time= 0.0;
++
++ for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
++ {
++ /* Find the best access method from 's' to the current partial plan */
++ best_access_path(join, s, join->thd, join_tables, idx,
++ record_count, read_time);
++ /* compute the cost of the new plan extended with 's' */
++ record_count*= join->positions[idx].records_read;
++ read_time+= join->positions[idx].read_time;
++ join_tables&= ~(s->table->map);
++ ++idx;
++ }
++
++ read_time+= record_count / (double) TIME_FOR_COMPARE;
++ if (join->sort_by_table &&
++ join->sort_by_table != join->positions[join->const_tables].table->table)
++ read_time+= record_count; // We have to make a temp table
++ memcpy((uchar*) join->best_positions, (uchar*) join->positions,
++ sizeof(POSITION)*idx);
++ join->best_read= read_time;
++}
++
++
++/**
++ Find a good, possibly optimal, query execution plan (QEP) by a greedy search.
++
++ The search procedure uses a hybrid greedy/exhaustive search with controlled
++ exhaustiveness. The search is performed in N = card(remaining_tables)
++ steps. Each step evaluates how promising is each of the unoptimized tables,
++ selects the most promising table, and extends the current partial QEP with
++ that table. Currenly the most 'promising' table is the one with least
++ expensive extension.\
++
++ There are two extreme cases:
++ -# When (card(remaining_tables) < search_depth), the estimate finds the
++ best complete continuation of the partial QEP. This continuation can be
++ used directly as a result of the search.
++ -# When (search_depth == 1) the 'best_extension_by_limited_search'
++ consideres the extension of the current QEP with each of the remaining
++ unoptimized tables.
++
++ All other cases are in-between these two extremes. Thus the parameter
++ 'search_depth' controlls the exhaustiveness of the search. The higher the
++ value, the longer the optimizaton time and possibly the better the
++ resulting plan. The lower the value, the fewer alternative plans are
++ estimated, but the more likely to get a bad QEP.
++
++ All intermediate and final results of the procedure are stored in 'join':
++ - join->positions : modified for every partial QEP that is explored
++ - join->best_positions: modified for the current best complete QEP
++ - join->best_read : modified for the current best complete QEP
++ - join->best_ref : might be partially reordered
++
++ The final optimal plan is stored in 'join->best_positions', and its
++ corresponding cost in 'join->best_read'.
++
++ @note
++ The following pseudocode describes the algorithm of 'greedy_search':
++
++ @code
++ procedure greedy_search
++ input: remaining_tables
++ output: pplan;
++ {
++ pplan = <>;
++ do {
++ (t, a) = best_extension(pplan, remaining_tables);
++ pplan = concat(pplan, (t, a));
++ remaining_tables = remaining_tables - t;
++ } while (remaining_tables != {})
++ return pplan;
++ }
++
++ @endcode
++ where 'best_extension' is a placeholder for a procedure that selects the
++ most "promising" of all tables in 'remaining_tables'.
++ Currently this estimate is performed by calling
++ 'best_extension_by_limited_search' to evaluate all extensions of the
++ current QEP of size 'search_depth', thus the complexity of 'greedy_search'
++ mainly depends on that of 'best_extension_by_limited_search'.
++
++ @par
++ If 'best_extension()' == 'best_extension_by_limited_search()', then the
++ worst-case complexity of this algorithm is <=
++ O(N*N^search_depth/search_depth). When serch_depth >= N, then the
++ complexity of greedy_search is O(N!).
++
++ @par
++ In the future, 'greedy_search' might be extended to support other
++ implementations of 'best_extension', e.g. some simpler quadratic procedure.
++
++ @param join pointer to the structure providing all context info
++ for the query
++ @param remaining_tables set of tables not included into the partial plan yet
++ @param search_depth controlls the exhaustiveness of the search
++ @param prune_level the pruning heuristics that should be applied during
++ search
++
++ @retval
++ FALSE ok
++ @retval
++ TRUE Fatal error
++*/
++
++static bool
++greedy_search(JOIN *join,
++ table_map remaining_tables,
++ uint search_depth,
++ uint prune_level)
++{
++ double record_count= 1.0;
++ double read_time= 0.0;
++ uint idx= join->const_tables; // index into 'join->best_ref'
++ uint best_idx;
++ uint size_remain; // cardinality of remaining_tables
++ POSITION best_pos;
++ JOIN_TAB *best_table; // the next plan node to be added to the curr QEP
++
++ DBUG_ENTER("greedy_search");
++
++ /* number of tables that remain to be optimized */
++ size_remain= my_count_bits(remaining_tables);
++
++ do {
++ /* Find the extension of the current QEP with the lowest cost */
++ join->best_read= DBL_MAX;
++ if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
++ read_time, search_depth, prune_level))
++ DBUG_RETURN(TRUE);
++ /*
++ 'best_read < DBL_MAX' means that optimizer managed to find
++ some plan and updated 'best_positions' array accordingly.
++ */
++ DBUG_ASSERT(join->best_read < DBL_MAX);
++
++ if (size_remain <= search_depth)
++ {
++ /*
++ 'join->best_positions' contains a complete optimal extension of the
++ current partial QEP.
++ */
++ DBUG_EXECUTE("opt", print_plan(join, join->tables,
++ record_count, read_time, read_time,
++ "optimal"););
++ DBUG_RETURN(FALSE);
++ }
++
++ /* select the first table in the optimal extension as most promising */
++ best_pos= join->best_positions[idx];
++ best_table= best_pos.table;
++ /*
++ Each subsequent loop of 'best_extension_by_limited_search' uses
++ 'join->positions' for cost estimates, therefore we have to update its
++ value.
++ */
++ join->positions[idx]= best_pos;
++
++ /*
++ Update the interleaving state after extending the current partial plan
++ with a new table.
++ We are doing this here because best_extension_by_limited_search reverts
++ the interleaving state to the one of the non-extended partial plan
++ on exit.
++ */
++ IF_DBUG(bool is_interleave_error= )
++ check_interleaving_with_nj (best_table);
++ /* This has been already checked by best_extension_by_limited_search */
++ DBUG_ASSERT(!is_interleave_error);
++
++ /* find the position of 'best_table' in 'join->best_ref' */
++ best_idx= idx;
++ JOIN_TAB *pos= join->best_ref[best_idx];
++ while (pos && best_table != pos)
++ pos= join->best_ref[++best_idx];
++ DBUG_ASSERT((pos != NULL)); // should always find 'best_table'
++ /* move 'best_table' at the first free position in the array of joins */
++ swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]);
++
++ /* compute the cost of the new plan extended with 'best_table' */
++ record_count*= join->positions[idx].records_read;
++ read_time+= join->positions[idx].read_time;
++
++ remaining_tables&= ~(best_table->table->map);
++ --size_remain;
++ ++idx;
++
++ DBUG_EXECUTE("opt", print_plan(join, idx,
++ record_count, read_time, read_time,
++ "extended"););
++ } while (TRUE);
++}
++
++
++/**
++ Find a good, possibly optimal, query execution plan (QEP) by a possibly
++ exhaustive search.
++
++ The procedure searches for the optimal ordering of the query tables in set
++ 'remaining_tables' of size N, and the corresponding optimal access paths to
++ each table. The choice of a table order and an access path for each table
++ constitutes a query execution plan (QEP) that fully specifies how to
++ execute the query.
++
++ The maximal size of the found plan is controlled by the parameter
++ 'search_depth'. When search_depth == N, the resulting plan is complete and
++ can be used directly as a QEP. If search_depth < N, the found plan consists
++ of only some of the query tables. Such "partial" optimal plans are useful
++ only as input to query optimization procedures, and cannot be used directly
++ to execute a query.
++
++ The algorithm begins with an empty partial plan stored in 'join->positions'
++ and a set of N tables - 'remaining_tables'. Each step of the algorithm
++ evaluates the cost of the partial plan extended by all access plans for
++ each of the relations in 'remaining_tables', expands the current partial
++ plan with the access plan that results in lowest cost of the expanded
++ partial plan, and removes the corresponding relation from
++ 'remaining_tables'. The algorithm continues until it either constructs a
++ complete optimal plan, or constructs an optimal plartial plan with size =
++ search_depth.
++
++ The final optimal plan is stored in 'join->best_positions'. The
++ corresponding cost of the optimal plan is in 'join->best_read'.
++
++ @note
++ The procedure uses a recursive depth-first search where the depth of the
++ recursion (and thus the exhaustiveness of the search) is controlled by the
++ parameter 'search_depth'.
++
++ @note
++ The pseudocode below describes the algorithm of
++ 'best_extension_by_limited_search'. The worst-case complexity of this
++ algorithm is O(N*N^search_depth/search_depth). When serch_depth >= N, then
++ the complexity of greedy_search is O(N!).
++
++ @code
++ procedure best_extension_by_limited_search(
++ pplan in, // in, partial plan of tables-joined-so-far
++ pplan_cost, // in, cost of pplan
++ remaining_tables, // in, set of tables not referenced in pplan
++ best_plan_so_far, // in/out, best plan found so far
++ best_plan_so_far_cost,// in/out, cost of best_plan_so_far
++ search_depth) // in, maximum size of the plans being considered
++ {
++ for each table T from remaining_tables
++ {
++ // Calculate the cost of using table T as above
++ cost = complex-series-of-calculations;
++
++ // Add the cost to the cost so far.
++ pplan_cost+= cost;
++
++ if (pplan_cost >= best_plan_so_far_cost)
++ // pplan_cost already too great, stop search
++ continue;
++
++ pplan= expand pplan by best_access_method;
++ remaining_tables= remaining_tables - table T;
++ if (remaining_tables is not an empty set
++ and
++ search_depth > 1)
++ {
++ best_extension_by_limited_search(pplan, pplan_cost,
++ remaining_tables,
++ best_plan_so_far,
++ best_plan_so_far_cost,
++ search_depth - 1);
++ }
++ else
++ {
++ best_plan_so_far_cost= pplan_cost;
++ best_plan_so_far= pplan;
++ }
++ }
++ }
++ @endcode
++
++ @note
++ When 'best_extension_by_limited_search' is called for the first time,
++ 'join->best_read' must be set to the largest possible value (e.g. DBL_MAX).
++ The actual implementation provides a way to optionally use pruning
++ heuristic (controlled by the parameter 'prune_level') to reduce the search
++ space by skipping some partial plans.
++
++ @note
++ The parameter 'search_depth' provides control over the recursion
++ depth, and thus the size of the resulting optimal plan.
++
++ @param join pointer to the structure providing all context info
++ for the query
++ @param remaining_tables set of tables not included into the partial plan yet
++ @param idx length of the partial QEP in 'join->positions';
++ since a depth-first search is used, also corresponds
++ to the current depth of the search tree;
++ also an index in the array 'join->best_ref';
++ @param record_count estimate for the number of records returned by the
++ best partial plan
++ @param read_time the cost of the best partial plan
++ @param search_depth maximum depth of the recursion and thus size of the
++ found optimal plan
++ (0 < search_depth <= join->tables+1).
++ @param prune_level pruning heuristics that should be applied during
++ optimization
++ (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)
++
++ @retval
++ FALSE ok
++ @retval
++ TRUE Fatal error
++*/
++
++static bool
++best_extension_by_limited_search(JOIN *join,
++ table_map remaining_tables,
++ uint idx,
++ double record_count,
++ double read_time,
++ uint search_depth,
++ uint prune_level)
++{
++ DBUG_ENTER("best_extension_by_limited_search");
++
++ THD *thd= join->thd;
++ if (thd->killed) // Abort
++ DBUG_RETURN(TRUE);
++
++ DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx,
++ "SOFAR:"););
++
++ /*
++ 'join' is a partial plan with lower cost than the best plan so far,
++ so continue expanding it further with the tables in 'remaining_tables'.
++ */
++ JOIN_TAB *s;
++ double best_record_count= DBL_MAX;
++ double best_read_time= DBL_MAX;
++
++ DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
++ "part_plan"););
++
++ for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
++ {
++ table_map real_table_bit= s->table->map;
++ if ((remaining_tables & real_table_bit) &&
++ !(remaining_tables & s->dependent) &&
++ (!idx || !check_interleaving_with_nj(s)))
++ {
++ double current_record_count, current_read_time;
++
++ /* Find the best access method from 's' to the current partial plan */
++ best_access_path(join, s, thd, remaining_tables, idx,
++ record_count, read_time);
++ /* Compute the cost of extending the plan with 's' */
++ current_record_count= record_count * join->positions[idx].records_read;
++ current_read_time= read_time + join->positions[idx].read_time;
++
++ /* Expand only partial plans with lower cost than the best QEP so far */
++ if ((current_read_time +
++ current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
++ {
++ DBUG_EXECUTE("opt", print_plan(join, idx+1,
++ current_record_count,
++ read_time,
++ (current_read_time +
++ current_record_count /
++ (double) TIME_FOR_COMPARE),
++ "prune_by_cost"););
++ restore_prev_nj_state(s);
++ continue;
++ }
++
++ /*
++ Prune some less promising partial plans. This heuristic may miss
++ the optimal QEPs, thus it results in a non-exhaustive search.
++ */
++ if (prune_level == 1)
++ {
++ if (best_record_count > current_record_count ||
++ best_read_time > current_read_time ||
++ (idx == join->const_tables && // 's' is the first table in the QEP
++ s->table == join->sort_by_table))
++ {
++ if (best_record_count >= current_record_count &&
++ best_read_time >= current_read_time &&
++ /* TODO: What is the reasoning behind this condition? */
++ (!(s->key_dependent & remaining_tables) ||
++ join->positions[idx].records_read < 2.0))
++ {
++ best_record_count= current_record_count;
++ best_read_time= current_read_time;
++ }
++ }
++ else
++ {
++ DBUG_EXECUTE("opt", print_plan(join, idx+1,
++ current_record_count,
++ read_time,
++ current_read_time,
++ "pruned_by_heuristic"););
++ restore_prev_nj_state(s);
++ continue;
++ }
++ }
++
++ if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
++ { /* Recursively expand the current partial plan */
++ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
++ if (best_extension_by_limited_search(join,
++ remaining_tables & ~real_table_bit,
++ idx + 1,
++ current_record_count,
++ current_read_time,
++ search_depth - 1,
++ prune_level))
++ DBUG_RETURN(TRUE);
++ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
++ }
++ else
++ { /*
++ 'join' is either the best partial QEP with 'search_depth' relations,
++ or the best complete QEP so far, whichever is smaller.
++ */
++ current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
++ if (join->sort_by_table &&
++ join->sort_by_table !=
++ join->positions[join->const_tables].table->table)
++ /* We have to make a temp table */
++ current_read_time+= current_record_count;
++ if ((search_depth == 1) || (current_read_time < join->best_read))
++ {
++ memcpy((uchar*) join->best_positions, (uchar*) join->positions,
++ sizeof(POSITION) * (idx + 1));
++ join->best_read= current_read_time - 0.001;
++ }
++ DBUG_EXECUTE("opt", print_plan(join, idx+1,
++ current_record_count,
++ read_time,
++ current_read_time,
++ "full_plan"););
++ }
++ restore_prev_nj_state(s);
++ }
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ @todo
++ - TODO: this function is here only temporarily until 'greedy_search' is
++ tested and accepted.
++
++ RETURN VALUES
++ FALSE ok
++ TRUE Fatal error
++*/
++static bool
++find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
++ double read_time)
++{
++ DBUG_ENTER("find_best");
++ THD *thd= join->thd;
++ if (thd->killed)
++ DBUG_RETURN(TRUE);
++ if (!rest_tables)
++ {
++ DBUG_PRINT("best",("read_time: %g record_count: %g",read_time,
++ record_count));
++
++ read_time+=record_count/(double) TIME_FOR_COMPARE;
++ if (join->sort_by_table &&
++ join->sort_by_table !=
++ join->positions[join->const_tables].table->table)
++ read_time+=record_count; // We have to make a temp table
++ if (read_time < join->best_read)
++ {
++ memcpy((uchar*) join->best_positions,(uchar*) join->positions,
++ sizeof(POSITION)*idx);
++ join->best_read= read_time - 0.001;
++ }
++ DBUG_RETURN(FALSE);
++ }
++ if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
++ DBUG_RETURN(FALSE); /* Found better before */
++
++ JOIN_TAB *s;
++ double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
++ for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
++ {
++ table_map real_table_bit=s->table->map;
++ if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
++ (!idx|| !check_interleaving_with_nj(s)))
++ {
++ double records, best;
++ best_access_path(join, s, thd, rest_tables, idx, record_count,
++ read_time);
++ records= join->positions[idx].records_read;
++ best= join->positions[idx].read_time;
++ /*
++ Go to the next level only if there hasn't been a better key on
++ this level! This will cut down the search for a lot simple cases!
++ */
++ double current_record_count=record_count*records;
++ double current_read_time=read_time+best;
++ if (best_record_count > current_record_count ||
++ best_read_time > current_read_time ||
++ (idx == join->const_tables && s->table == join->sort_by_table))
++ {
++ if (best_record_count >= current_record_count &&
++ best_read_time >= current_read_time &&
++ (!(s->key_dependent & rest_tables) || records < 2.0))
++ {
++ best_record_count=current_record_count;
++ best_read_time=current_read_time;
++ }
++ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
++ if (find_best(join,rest_tables & ~real_table_bit,idx+1,
++ current_record_count,current_read_time))
++ DBUG_RETURN(TRUE);
++ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
++ }
++ restore_prev_nj_state(s);
++ if (join->select_options & SELECT_STRAIGHT_JOIN)
++ break; // Don't test all combinations
++ }
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Find how much space the prevous read not const tables takes in cache.
++*/
++
++static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
++{
++ uint null_fields,blobs,fields,rec_length;
++ Field **f_ptr,*field;
++ MY_BITMAP *read_set= join_tab->table->read_set;;
++
++ null_fields= blobs= fields= rec_length=0;
++ for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
++ {
++ if (bitmap_is_set(read_set, field->field_index))
++ {
++ uint flags=field->flags;
++ fields++;
++ rec_length+=field->pack_length();
++ if (flags & BLOB_FLAG)
++ blobs++;
++ if (!(flags & NOT_NULL_FLAG))
++ null_fields++;
++ }
++ }
++ if (null_fields)
++ rec_length+=(join_tab->table->s->null_fields+7)/8;
++ if (join_tab->table->maybe_null)
++ rec_length+=sizeof(my_bool);
++ if (blobs)
++ {
++ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
++ (join_tab->table->s->reclength- rec_length));
++ rec_length+=(uint) max(4,blob_length);
++ }
++ join_tab->used_fields=fields;
++ join_tab->used_fieldlength=rec_length;
++ join_tab->used_blobs=blobs;
++}
++
++
++static uint
++cache_record_length(JOIN *join,uint idx)
++{
++ uint length=0;
++ JOIN_TAB **pos,**end;
++ THD *thd=join->thd;
++
++ for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
++ pos != end ;
++ pos++)
++ {
++ JOIN_TAB *join_tab= *pos;
++ if (!join_tab->used_fieldlength) /* Not calced yet */
++ calc_used_field_length(thd, join_tab);
++ length+=join_tab->used_fieldlength;
++ }
++ return length;
++}
++
++
++/*
++ Get the number of different row combinations for subset of partial join
++
++ SYNOPSIS
++ prev_record_reads()
++ join The join structure
++ idx Number of tables in the partial join order (i.e. the
++ partial join order is in join->positions[0..idx-1])
++ found_ref Bitmap of tables for which we need to find # of distinct
++ row combinations.
++
++ DESCRIPTION
++ Given a partial join order (in join->positions[0..idx-1]) and a subset of
++ tables within that join order (specified in found_ref), find out how many
++ distinct row combinations of subset tables will be in the result of the
++ partial join order.
++
++ This is used as follows: Suppose we have a table accessed with a ref-based
++ method. The ref access depends on current rows of tables in found_ref.
++ We want to count # of different ref accesses. We assume two ref accesses
++ will be different if at least one of access parameters is different.
++ Example: consider a query
++
++ SELECT * FROM t1, t2, t3 WHERE t1.key=c1 AND t2.key=c2 AND t3.key=t1.field
++
++ and a join order:
++ t1, ref access on t1.key=c1
++ t2, ref access on t2.key=c2
++ t3, ref access on t3.key=t1.field
++
++ For t1: n_ref_scans = 1, n_distinct_ref_scans = 1
++ For t2: n_ref_scans = records_read(t1), n_distinct_ref_scans=1
++ For t3: n_ref_scans = records_read(t1)*records_read(t2)
++ n_distinct_ref_scans = #records_read(t1)
++
++ The reason for having this function (at least the latest version of it)
++ is that we need to account for buffering in join execution.
++
++ An edge-case example: if we have a non-first table in join accessed via
++ ref(const) or ref(param) where there is a small number of different
++ values of param, then the access will likely hit the disk cache and will
++ not require any disk seeks.
++
++ The proper solution would be to assume an LRU disk cache of some size,
++ calculate probability of cache hits, etc. For now we just count
++ identical ref accesses as one.
++
++ RETURN
++ Expected number of row combinations
++*/
++
++static double
++prev_record_reads(JOIN *join, uint idx, table_map found_ref)
++{
++ double found=1.0;
++ POSITION *pos_end= join->positions - 1;
++ for (POSITION *pos= join->positions + idx - 1; pos != pos_end; pos--)
++ {
++ if (pos->table->table->map & found_ref)
++ {
++ found_ref|= pos->ref_depend_map;
++ /*
++ For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
++ with no matching row we will get position[t2].records_read==0.
++ Actually the size of output is one null-complemented row, therefore
++ we will use value of 1 whenever we get records_read==0.
++
++ Note
++ - the above case can't occur if inner part of outer join has more
++ than one table: table with no matches will not be marked as const.
++
++ - Ideally we should add 1 to records_read for every possible null-
++ complemented row. We're not doing it because: 1. it will require
++ non-trivial code and add overhead. 2. The value of records_read
++ is an inprecise estimate and adding 1 (or, in the worst case,
++ #max_nested_outer_joins=64-1) will not make it any more precise.
++ */
++ if (pos->records_read)
++ found*= pos->records_read;
++ }
++ }
++ return found;
++}
++
++
++/**
++ Set up join struct according to best position.
++*/
++
++static bool
++get_best_combination(JOIN *join)
++{
++ uint i,tablenr;
++ table_map used_tables;
++ JOIN_TAB *join_tab,*j;
++ KEYUSE *keyuse;
++ uint table_count;
++ THD *thd=join->thd;
++ DBUG_ENTER("get_best_combination");
++
++ table_count=join->tables;
++ if (!(join->join_tab=join_tab=
++ (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
++ DBUG_RETURN(TRUE);
++
++ join->full_join=0;
++
++ used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
++ for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
++ {
++ TABLE *form;
++ *j= *join->best_positions[tablenr].table;
++ form=join->table[tablenr]=j->table;
++ used_tables|= form->map;
++ form->reginfo.join_tab=j;
++ if (!*j->on_expr_ref)
++ form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
++ DBUG_PRINT("info",("type: %d", j->type));
++ if (j->type == JT_CONST)
++ continue; // Handled in make_join_stat..
++
++ j->ref.key = -1;
++ j->ref.key_parts=0;
++
++ if (j->type == JT_SYSTEM)
++ continue;
++ if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
++ {
++ j->type=JT_ALL;
++ if (tablenr != join->const_tables)
++ join->full_join=1;
++ }
++ else if (create_ref_for_key(join, j, keyuse, used_tables))
++ DBUG_RETURN(TRUE); // Something went wrong
++ }
++
++ for (i=0 ; i < table_count ; i++)
++ join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
++ update_depend_map(join);
++ DBUG_RETURN(0);
++}
++
++
++static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
++ table_map used_tables)
++{
++ KEYUSE *keyuse=org_keyuse;
++ bool ftkey=(keyuse->keypart == FT_KEYPART);
++ THD *thd= join->thd;
++ uint keyparts,length,key;
++ TABLE *table;
++ KEY *keyinfo;
++ DBUG_ENTER("create_ref_for_key");
++
++ /* Use best key from find_best */
++ table=j->table;
++ key=keyuse->key;
++ keyinfo=table->key_info+key;
++
++ if (ftkey)
++ {
++ Item_func_match *ifm=(Item_func_match *)keyuse->val;
++
++ length=0;
++ keyparts=1;
++ ifm->join_key=1;
++ }
++ else
++ {
++ keyparts=length=0;
++ uint found_part_ref_or_null= 0;
++ /*
++ Calculate length for the used key
++ Stop if there is a missing key part or when we find second key_part
++ with KEY_OPTIMIZE_REF_OR_NULL
++ */
++ do
++ {
++ if (!(~used_tables & keyuse->used_tables))
++ {
++ if (keyparts == keyuse->keypart &&
++ !(found_part_ref_or_null & keyuse->optimize))
++ {
++ keyparts++;
++ length+= keyinfo->key_part[keyuse->keypart].store_length;
++ found_part_ref_or_null|= keyuse->optimize;
++ }
++ }
++ keyuse++;
++ } while (keyuse->table == table && keyuse->key == key);
++ } /* not ftkey */
++
++ /* set up fieldref */
++ keyinfo=table->key_info+key;
++ j->ref.key_parts=keyparts;
++ j->ref.key_length=length;
++ j->ref.key=(int) key;
++ if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) ||
++ !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
++ (keyparts+1)))) ||
++ !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
++ !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
++ j->ref.key_err=1;
++ j->ref.has_record= FALSE;
++ j->ref.null_rejecting= 0;
++ j->ref.use_count= 0;
++ keyuse=org_keyuse;
++
++ store_key **ref_key= j->ref.key_copy;
++ uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
++ bool keyuse_uses_no_tables= TRUE;
++ if (ftkey)
++ {
++ j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
++ /* Predicates pushed down into subquery can't be used FT access */
++ j->ref.cond_guards[0]= NULL;
++ if (keyuse->used_tables)
++ DBUG_RETURN(TRUE); // not supported yet. SerG
++
++ j->type=JT_FT;
++ }
++ else
++ {
++ uint i;
++ for (i=0 ; i < keyparts ; keyuse++,i++)
++ {
++ while (keyuse->keypart != i ||
++ ((~used_tables) & keyuse->used_tables))
++ keyuse++; /* Skip other parts */
++
++ uint maybe_null= test(keyinfo->key_part[i].null_bit);
++ j->ref.items[i]=keyuse->val; // Save for cond removal
++ j->ref.cond_guards[i]= keyuse->cond_guard;
++ if (keyuse->null_rejecting)
++ j->ref.null_rejecting |= 1 << i;
++ keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
++ if (!keyuse->used_tables &&
++ !(join->select_options & SELECT_DESCRIBE))
++ { // Compare against constant
++ store_key_item tmp(thd, keyinfo->key_part[i].field,
++ key_buff + maybe_null,
++ maybe_null ? key_buff : 0,
++ keyinfo->key_part[i].length, keyuse->val);
++ if (thd->is_fatal_error)
++ DBUG_RETURN(TRUE);
++ tmp.copy();
++ }
++ else
++ *ref_key++= get_store_key(thd,
++ keyuse,join->const_table_map,
++ &keyinfo->key_part[i],
++ key_buff, maybe_null);
++ /*
++ Remember if we are going to use REF_OR_NULL
++ But only if field _really_ can be null i.e. we force JT_REF
++ instead of JT_REF_OR_NULL in case if field can't be null
++ */
++ if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
++ null_ref_key= key_buff;
++ key_buff+=keyinfo->key_part[i].store_length;
++ }
++ } /* not ftkey */
++ *ref_key=0; // end_marker
++ if (j->type == JT_FT)
++ DBUG_RETURN(0);
++ if (j->type == JT_CONST)
++ j->table->const_table= 1;
++ else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
++ HA_END_SPACE_KEY)) != HA_NOSAME) ||
++ keyparts != keyinfo->key_parts || null_ref_key)
++ {
++ /* Must read with repeat */
++ j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
++ j->ref.null_ref_key= null_ref_key;
++ }
++ else if (keyuse_uses_no_tables)
++ {
++ /*
++ This happen if we are using a constant expression in the ON part
++ of an LEFT JOIN.
++ SELECT * FROM a LEFT JOIN b ON b.key=30
++ Here we should not mark the table as a 'const' as a field may
++ have a 'normal' value or a NULL value.
++ */
++ j->type=JT_CONST;
++ }
++ else
++ j->type=JT_EQ_REF;
++ DBUG_RETURN(0);
++}
++
++
++
++static store_key *
++get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
++ KEY_PART_INFO *key_part, uchar *key_buff, uint maybe_null)
++{
++ if (!((~used_tables) & keyuse->used_tables)) // if const item
++ {
++ return new store_key_const_item(thd,
++ key_part->field,
++ key_buff + maybe_null,
++ maybe_null ? key_buff : 0,
++ key_part->length,
++ keyuse->val);
++ }
++ else if (keyuse->val->type() == Item::FIELD_ITEM ||
++ (keyuse->val->type() == Item::REF_ITEM &&
++ ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
++ (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
++ Item_ref::DIRECT_REF &&
++ keyuse->val->real_item()->type() == Item::FIELD_ITEM))
++ return new store_key_field(thd,
++ key_part->field,
++ key_buff + maybe_null,
++ maybe_null ? key_buff : 0,
++ key_part->length,
++ ((Item_field*) keyuse->val->real_item())->field,
++ keyuse->val->full_name());
++ return new store_key_item(thd,
++ key_part->field,
++ key_buff + maybe_null,
++ maybe_null ? key_buff : 0,
++ key_part->length,
++ keyuse->val);
++}
++
++/**
++ This function is only called for const items on fields which are keys.
++
++ @return
++ returns 1 if there was some conversion made when the field was stored.
++*/
++
++bool
++store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
++{
++ bool error;
++ TABLE *table= field->table;
++ THD *thd= table->in_use;
++ ha_rows cuted_fields=thd->cuted_fields;
++ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
++ table->write_set);
++
++ /*
++ we should restore old value of count_cuted_fields because
++ store_val_in_field can be called from mysql_insert
++ with select_insert, which make count_cuted_fields= 1
++ */
++ enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
++ thd->count_cuted_fields= check_flag;
++ error= item->save_in_field(field, 1);
++ thd->count_cuted_fields= old_count_cuted_fields;
++ dbug_tmp_restore_column_map(table->write_set, old_map);
++ return error || cuted_fields != thd->cuted_fields;
++}
++
++
++/**
++ @details Initialize a JOIN as a query execution plan
++ that accesses a single table via a table scan.
++
++ @param parent contains JOIN_TAB and TABLE object buffers for this join
++ @param tmp_table temporary table
++
++ @retval FALSE success
++ @retval TRUE error occurred
++*/
++bool
++JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
++{
++ DBUG_ENTER("JOIN::make_simple_join");
++
++ /*
++ Reuse TABLE * and JOIN_TAB if already allocated by a previous call
++ to this function through JOIN::exec (may happen for sub-queries).
++ */
++ if (!parent->join_tab_reexec &&
++ !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
++ DBUG_RETURN(TRUE); /* purecov: inspected */
++
++ join_tab= parent->join_tab_reexec;
++ table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table;
++ tables= 1;
++ const_tables= 0;
++ const_table_map= 0;
++ tmp_table_param.field_count= tmp_table_param.sum_func_count=
++ tmp_table_param.func_count= 0;
++ /*
++ We need to destruct the copy_field (allocated in create_tmp_table())
++ before setting it to 0 if the join is not "reusable".
++ */
++ if (!tmp_join || tmp_join != this)
++ tmp_table_param.cleanup();
++ tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
++ first_record= sort_and_group=0;
++ send_records= (ha_rows) 0;
++ group= 0;
++ row_limit= unit->select_limit_cnt;
++ do_send_rows= row_limit ? 1 : 0;
++
++ join_tab->cache.buff=0; /* No caching */
++ join_tab->table=temp_table;
++ join_tab->select=0;
++ join_tab->select_cond=0;
++ join_tab->quick=0;
++ join_tab->type= JT_ALL; /* Map through all records */
++ join_tab->keys.init();
++ join_tab->keys.set_all(); /* test everything in quick */
++ join_tab->info=0;
++ join_tab->on_expr_ref=0;
++ join_tab->last_inner= 0;
++ join_tab->first_unmatched= 0;
++ join_tab->ref.key = -1;
++ join_tab->not_used_in_distinct=0;
++ join_tab->read_first_record= join_init_read_record;
++ join_tab->join= this;
++ join_tab->ref.key_parts= 0;
++ bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
++ temp_table->status=0;
++ temp_table->null_row=0;
++ DBUG_RETURN(FALSE);
++}
++
++
++inline void add_cond_and_fix(Item **e1, Item *e2)
++{
++ if (*e1)
++ {
++ Item *res;
++ if ((res= new Item_cond_and(*e1, e2)))
++ {
++ *e1= res;
++ res->quick_fix_field();
++ res->update_used_tables();
++ }
++ }
++ else
++ *e1= e2;
++}
++
++
++/**
++ Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions
++ we've inferred from ref/eq_ref access performed.
++
++ This function is a part of "Early NULL-values filtering for ref access"
++ optimization.
++
++ Example of this optimization:
++ For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n
++ and plan " any-access(t1), ref(t2.key=t1.field) " @n
++ add "t1.field IS NOT NULL" to t1's table condition. @n
++
++ Description of the optimization:
++
++ We look through equalities choosen to perform ref/eq_ref access,
++ pick equalities that have form "tbl.part_of_key = othertbl.field"
++ (where othertbl is a non-const table and othertbl.field may be NULL)
++ and add them to conditions on correspoding tables (othertbl in this
++ example).
++
++ Exception from that is the case when referred_tab->join != join.
++ I.e. don't add NOT NULL constraints from any embedded subquery.
++ Consider this query:
++ @code
++ SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1
++ WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL;
++ @endocde
++ Here condition A.f3 IS NOT NULL is going to be added to the WHERE
++ condition of the embedding query.
++ Another example:
++ SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL)
++ AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12
++ WHERE t12.b = t10.a ));
++ Here condition t10.a IS NOT NULL is going to be added.
++ In both cases addition of NOT NULL condition will erroneously reject
++ some rows of the result set.
++ referred_tab->join != join constraint would disallow such additions.
++
++ This optimization doesn't affect the choices that ref, range, or join
++ optimizer make. This was intentional because this was added after 4.1
++ was GA.
++
++ Implementation overview
++ 1. update_ref_and_keys() accumulates info about null-rejecting
++ predicates in in KEY_FIELD::null_rejecting
++ 1.1 add_key_part saves these to KEYUSE.
++ 2. create_ref_for_key copies them to TABLE_REF.
++ 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
++ appropiate JOIN_TAB members.
++*/
++
++static void add_not_null_conds(JOIN *join)
++{
++ DBUG_ENTER("add_not_null_conds");
++ for (uint i=join->const_tables ; i < join->tables ; i++)
++ {
++ JOIN_TAB *tab=join->join_tab+i;
++ if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
++ tab->type == JT_REF_OR_NULL) &&
++ !tab->table->maybe_null)
++ {
++ for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
++ {
++ if (tab->ref.null_rejecting & (1 << keypart))
++ {
++ Item *item= tab->ref.items[keypart];
++ Item *notnull;
++ DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
++ Item_field *not_null_item= (Item_field*)item;
++ JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
++ /*
++ For UPDATE queries such as:
++ UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
++ not_null_item is the t1.f1, but it's referred_tab is 0.
++ */
++ if (!referred_tab || referred_tab->join != join)
++ continue;
++ if (!(notnull= new Item_func_isnotnull(not_null_item)))
++ DBUG_VOID_RETURN;
++ /*
++ We need to do full fix_fields() call here in order to have correct
++ notnull->const_item(). This is needed e.g. by test_quick_select
++ when it is called from make_join_select after this function is
++ called.
++ */
++ if (notnull->fix_fields(join->thd, ¬null))
++ DBUG_VOID_RETURN;
++ DBUG_EXECUTE("where",print_where(notnull,
++ referred_tab->table->alias,
++ QT_ORDINARY););
++ add_cond_and_fix(&referred_tab->select_cond, notnull);
++ }
++ }
++ }
++ }
++ DBUG_VOID_RETURN;
++}
++
++/**
++ Build a predicate guarded by match variables for embedding outer joins.
++ The function recursively adds guards for predicate cond
++ assending from tab to the first inner table next embedding
++ nested outer join and so on until it reaches root_tab
++ (root_tab can be 0).
++
++ @param tab the first inner table for most nested outer join
++ @param cond the predicate to be guarded (must be set)
++ @param root_tab the first inner table to stop
++
++ @return
++ - pointer to the guarded predicate, if success
++ - 0, otherwise
++*/
++
++static COND*
++add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
++{
++ COND *tmp;
++ DBUG_ASSERT(cond != 0);
++ if (tab == root_tab)
++ return cond;
++ if ((tmp= add_found_match_trig_cond(tab->first_upper, cond, root_tab)))
++ tmp= new Item_func_trig_cond(tmp, &tab->found);
++ if (tmp)
++ {
++ tmp->quick_fix_field();
++ tmp->update_used_tables();
++ }
++ return tmp;
++}
++
++
++/**
++ Fill in outer join related info for the execution plan structure.
++
++ For each outer join operation left after simplification of the
++ original query the function set up the following pointers in the linear
++ structure join->join_tab representing the selected execution plan.
++ The first inner table t0 for the operation is set to refer to the last
++ inner table tk through the field t0->last_inner.
++ Any inner table ti for the operation are set to refer to the first
++ inner table ti->first_inner.
++ The first inner table t0 for the operation is set to refer to the
++ first inner table of the embedding outer join operation, if there is any,
++ through the field t0->first_upper.
++ The on expression for the outer join operation is attached to the
++ corresponding first inner table through the field t0->on_expr_ref.
++ Here ti are structures of the JOIN_TAB type.
++
++ EXAMPLE. For the query:
++ @code
++ SELECT * FROM t1
++ LEFT JOIN
++ (t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
++ ON (t1.a=t2.a AND t1.b=t3.b)
++ WHERE t1.c > 5,
++ @endcode
++
++ given the execution plan with the table order t1,t2,t3,t4
++ is selected, the following references will be set;
++ t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2]
++ t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2],
++ on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to
++ *t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref.
++
++ @param join reference to the info fully describing the query
++
++ @note
++ The function assumes that the simplification procedure has been
++ already applied to the join query (see simplify_joins).
++ This function can be called only after the execution plan
++ has been chosen.
++*/
++
++static void
++make_outerjoin_info(JOIN *join)
++{
++ DBUG_ENTER("make_outerjoin_info");
++ for (uint i=join->const_tables ; i < join->tables ; i++)
++ {
++ JOIN_TAB *tab=join->join_tab+i;
++ TABLE *table=tab->table;
++ TABLE_LIST *tbl= table->pos_in_table_list;
++ TABLE_LIST *embedding= tbl->embedding;
++
++ if (tbl->outer_join)
++ {
++ /*
++ Table tab is the only one inner table for outer join.
++ (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
++ is in the query above.)
++ */
++ tab->last_inner= tab->first_inner= tab;
++ tab->on_expr_ref= &tbl->on_expr;
++ tab->cond_equal= tbl->cond_equal;
++ if (embedding)
++ tab->first_upper= embedding->nested_join->first_nested;
++ }
++ for ( ; embedding ; embedding= embedding->embedding)
++ {
++ NESTED_JOIN *nested_join= embedding->nested_join;
++ if (!nested_join->counter)
++ {
++ /*
++ Table tab is the first inner table for nested_join.
++ Save reference to it in the nested join structure.
++ */
++ nested_join->first_nested= tab;
++ tab->on_expr_ref= &embedding->on_expr;
++ tab->cond_equal= tbl->cond_equal;
++ if (embedding->embedding)
++ tab->first_upper= embedding->embedding->nested_join->first_nested;
++ }
++ if (!tab->first_inner)
++ tab->first_inner= nested_join->first_nested;
++ if (++nested_join->counter < nested_join->join_list.elements)
++ break;
++ /* Table tab is the last inner table for nested join. */
++ nested_join->first_nested->last_inner= tab;
++ }
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++static bool
++make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
++{
++ THD *thd= join->thd;
++ DBUG_ENTER("make_join_select");
++ if (select)
++ {
++ add_not_null_conds(join);
++ table_map used_tables;
++ if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */
++ { /* there may be a select without a cond. */
++ if (join->tables > 1)
++ cond->update_used_tables(); // Tablenr may have changed
++ if (join->const_tables == join->tables &&
++ thd->lex->current_select->master_unit() ==
++ &thd->lex->unit) // not upper level SELECT
++ join->const_table_map|=RAND_TABLE_BIT;
++ { // Check const tables
++ COND *const_cond=
++ make_cond_for_table(cond,
++ join->const_table_map,
++ (table_map) 0);
++ DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
++ for (JOIN_TAB *tab= join->join_tab+join->const_tables;
++ tab < join->join_tab+join->tables ; tab++)
++ {
++ if (*tab->on_expr_ref)
++ {
++ JOIN_TAB *cond_tab= tab->first_inner;
++ COND *tmp= make_cond_for_table(*tab->on_expr_ref,
++ join->const_table_map,
++ ( table_map) 0);
++ if (!tmp)
++ continue;
++ tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
++ if (!tmp)
++ DBUG_RETURN(1);
++ tmp->quick_fix_field();
++ cond_tab->select_cond= !cond_tab->select_cond ? tmp :
++ new Item_cond_and(cond_tab->select_cond,
++ tmp);
++ if (!cond_tab->select_cond)
++ DBUG_RETURN(1);
++ cond_tab->select_cond->quick_fix_field();
++ }
++ }
++ if (const_cond && !const_cond->val_int())
++ {
++ DBUG_PRINT("info",("Found impossible WHERE condition"));
++ DBUG_RETURN(1); // Impossible const condition
++ }
++ }
++ }
++ used_tables=((select->const_tables=join->const_table_map) |
++ OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
++ for (uint i=join->const_tables ; i < join->tables ; i++)
++ {
++ JOIN_TAB *tab=join->join_tab+i;
++ /*
++ first_inner is the X in queries like:
++ SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
++ */
++ JOIN_TAB *first_inner_tab= tab->first_inner;
++ table_map current_map= tab->table->map;
++ bool use_quick_range=0;
++ COND *tmp;
++
++ /*
++ Following force including random expression in last table condition.
++ It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
++ */
++ if (i == join->tables-1)
++ current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
++ used_tables|=current_map;
++
++ if (tab->type == JT_REF && tab->quick &&
++ (uint) tab->ref.key == tab->quick->index &&
++ tab->ref.key_length < tab->quick->max_used_key_length)
++ {
++ /* Range uses longer key; Use this instead of ref on key */
++ tab->type=JT_ALL;
++ use_quick_range=1;
++ tab->use_quick=1;
++ tab->ref.key= -1;
++ tab->ref.key_parts=0; // Don't use ref key.
++ join->best_positions[i].records_read= rows2double(tab->quick->records);
++ /*
++ We will use join cache here : prevent sorting of the first
++ table only and sort at the end.
++ */
++ if (i != join->const_tables && join->tables > join->const_tables + 1)
++ join->full_join= 1;
++ }
++
++ tmp= NULL;
++ if (cond)
++ tmp= make_cond_for_table(cond,used_tables,current_map);
++ if (cond && !tmp && tab->quick)
++ { // Outer join
++ if (tab->type != JT_ALL)
++ {
++ /*
++ Don't use the quick method
++ We come here in the case where we have 'key=constant' and
++ the test is removed by make_cond_for_table()
++ */
++ delete tab->quick;
++ tab->quick= 0;
++ }
++ else
++ {
++ /*
++ Hack to handle the case where we only refer to a table
++ in the ON part of an OUTER JOIN. In this case we want the code
++ below to check if we should use 'quick' instead.
++ */
++ DBUG_PRINT("info", ("Item_int"));
++ tmp= new Item_int((longlong) 1,1); // Always true
++ }
++
++ }
++ if (tmp || !cond || tab->type == JT_REF)
++ {
++ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
++ SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
++ thd->memdup((uchar*) select,
++ sizeof(*select)));
++ if (!sel)
++ DBUG_RETURN(1); // End of memory
++ /*
++ If tab is an inner table of an outer join operation,
++ add a match guard to the pushed down predicate.
++ The guard will turn the predicate on only after
++ the first match for outer tables is encountered.
++ */
++ if (cond && tmp)
++ {
++ /*
++ Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
++ a cond, so neutralize the hack above.
++ */
++ 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 */
++ if (thd->variables.engine_condition_pushdown)
++ {
++ COND *push_cond=
++ make_cond_for_table(tmp, current_map, current_map);
++ if (push_cond)
++ {
++ /* Push condition to handler */
++ if (!tab->table->file->cond_push(push_cond))
++ tab->table->file->pushed_cond= push_cond;
++ }
++ }
++ }
++ else
++ tab->select_cond= sel->cond= NULL;
++
++ sel->head=tab->table;
++ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
++ if (tab->quick)
++ {
++ /* Use quick key read if it's a constant and it's not used
++ with key reading */
++ if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
++ && tab->type != JT_FT && (tab->type != JT_REF ||
++ (uint) tab->ref.key == tab->quick->index))
++ {
++ sel->quick=tab->quick; // Use value from get_quick_...
++ sel->quick_keys.clear_all();
++ sel->needed_reg.clear_all();
++ }
++ else
++ {
++ delete tab->quick;
++ }
++ tab->quick=0;
++ }
++ uint ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
++ if (i == join->const_tables && ref_key)
++ {
++ if (!tab->const_keys.is_clear_all() &&
++ tab->table->reginfo.impossible_range)
++ DBUG_RETURN(1);
++ }
++ else if (tab->type == JT_ALL && ! use_quick_range)
++ {
++ if (!tab->const_keys.is_clear_all() &&
++ tab->table->reginfo.impossible_range)
++ DBUG_RETURN(1); // Impossible range
++ /*
++ We plan to scan all rows.
++ Check again if we should use an index.
++ We could have used an column from a previous table in
++ the index if we are using limit and this is the first table
++ */
++
++ if ((cond &&
++ !tab->keys.is_subset(tab->const_keys) && i > 0) ||
++ (!tab->const_keys.is_clear_all() && i == join->const_tables &&
++ join->unit->select_limit_cnt <
++ join->best_positions[i].records_read &&
++ !(join->select_options & OPTION_FOUND_ROWS)))
++ {
++ /* Join with outer join condition */
++ COND *orig_cond=sel->cond;
++ sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
++
++ /*
++ We can't call sel->cond->fix_fields,
++ as it will break tab->on_expr if it's AND condition
++ (fix_fields currently removes extra AND/OR levels).
++ Yet attributes of the just built condition are not needed.
++ Thus we call sel->cond->quick_fix_field for safety.
++ */
++ if (sel->cond && !sel->cond->fixed)
++ sel->cond->quick_fix_field();
++
++ if (sel->test_quick_select(thd, tab->keys,
++ used_tables & ~ current_map,
++ (join->select_options &
++ OPTION_FOUND_ROWS ?
++ HA_POS_ERROR :
++ join->unit->select_limit_cnt), 0) < 0)
++ {
++ /*
++ Before reporting "Impossible WHERE" for the whole query
++ we have to check isn't it only "impossible ON" instead
++ */
++ sel->cond=orig_cond;
++ if (!*tab->on_expr_ref ||
++ sel->test_quick_select(thd, tab->keys,
++ used_tables & ~ current_map,
++ (join->select_options &
++ OPTION_FOUND_ROWS ?
++ HA_POS_ERROR :
++ join->unit->select_limit_cnt),0) < 0)
++ DBUG_RETURN(1); // Impossible WHERE
++ }
++ else
++ sel->cond=orig_cond;
++
++ /* Fix for EXPLAIN */
++ if (sel->quick)
++ join->best_positions[i].records_read= (double)sel->quick->records;
++ }
++ else
++ {
++ sel->needed_reg=tab->needed_reg;
++ sel->quick_keys.clear_all();
++ }
++ if (!sel->quick_keys.is_subset(tab->checked_keys) ||
++ !sel->needed_reg.is_subset(tab->checked_keys))
++ {
++ tab->keys=sel->quick_keys;
++ tab->keys.merge(sel->needed_reg);
++ tab->use_quick= (!sel->needed_reg.is_clear_all() &&
++ (select->quick_keys.is_clear_all() ||
++ (select->quick &&
++ (select->quick->records >= 100L)))) ?
++ 2 : 1;
++ sel->read_tables= used_tables & ~current_map;
++ }
++ if (i != join->const_tables && tab->use_quick != 2)
++ { /* Read with cache */
++ if (cond &&
++ (tmp=make_cond_for_table(cond,
++ join->const_table_map |
++ current_map,
++ current_map)))
++ {
++ DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
++ tab->cache.select=(SQL_SELECT*)
++ thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
++ tab->cache.select->cond=tmp;
++ tab->cache.select->read_tables=join->const_table_map;
++ }
++ }
++ }
++ }
++
++ /*
++ Push down conditions from all on expressions.
++ Each of these conditions are guarded by a variable
++ that turns if off just before null complemented row for
++ outer joins is formed. Thus, the condition from an
++ 'on expression' are guaranteed not to be checked for
++ the null complemented row.
++ */
++
++ /* First push down constant conditions from on expressions */
++ for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
++ join_tab < join->join_tab+join->tables ; join_tab++)
++ {
++ if (*join_tab->on_expr_ref)
++ {
++ JOIN_TAB *cond_tab= join_tab->first_inner;
++ COND *tmp= make_cond_for_table(*join_tab->on_expr_ref,
++ join->const_table_map,
++ (table_map) 0);
++ if (!tmp)
++ continue;
++ tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
++ if (!tmp)
++ DBUG_RETURN(1);
++ tmp->quick_fix_field();
++ cond_tab->select_cond= !cond_tab->select_cond ? tmp :
++ new Item_cond_and(cond_tab->select_cond,tmp);
++ if (!cond_tab->select_cond)
++ DBUG_RETURN(1);
++ cond_tab->select_cond->quick_fix_field();
++ }
++ }
++
++ /* Push down non-constant conditions from on expressions */
++ JOIN_TAB *last_tab= tab;
++ while (first_inner_tab && first_inner_tab->last_inner == last_tab)
++ {
++ /*
++ Table tab is the last inner table of an outer join.
++ An on expression is always attached to it.
++ */
++ COND *on_expr= *first_inner_tab->on_expr_ref;
++
++ table_map used_tables2= (join->const_table_map |
++ OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
++ for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
++ {
++ current_map= tab->table->map;
++ used_tables2|= current_map;
++ COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
++ current_map);
++ if (tmp_cond)
++ {
++ JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
++ /*
++ First add the guards for match variables of
++ all embedding outer join operations.
++ */
++ if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
++ tmp_cond,
++ first_inner_tab)))
++ DBUG_RETURN(1);
++ /*
++ Now add the guard turning the predicate off for
++ the null complemented row.
++ */
++ DBUG_PRINT("info", ("Item_func_trig_cond"));
++ tmp_cond= new Item_func_trig_cond(tmp_cond,
++ &first_inner_tab->
++ not_null_compl);
++ DBUG_PRINT("info", ("Item_func_trig_cond 0x%lx",
++ (ulong) tmp_cond));
++ if (tmp_cond)
++ tmp_cond->quick_fix_field();
++ /* Add the predicate to other pushed down predicates */
++ DBUG_PRINT("info", ("Item_cond_and"));
++ cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
++ new Item_cond_and(cond_tab->select_cond,
++ tmp_cond);
++ DBUG_PRINT("info", ("Item_cond_and 0x%lx",
++ (ulong)cond_tab->select_cond));
++ if (!cond_tab->select_cond)
++ DBUG_RETURN(1);
++ cond_tab->select_cond->quick_fix_field();
++ }
++ }
++ first_inner_tab= first_inner_tab->first_upper;
++ }
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++
++/**
++ The default implementation of unlock-row method of READ_RECORD,
++ used in all access methods.
++*/
++
++void rr_unlock_row(st_join_table *tab)
++{
++ READ_RECORD *info= &tab->read_record;
++ info->file->unlock_row();
++}
++
++
++
++/**
++ Pick the appropriate access method functions
++
++ Sets the functions for the selected table access method
++
++ @param tab Table reference to put access method
++*/
++
++static void
++pick_table_access_method(JOIN_TAB *tab)
++{
++ switch (tab->type)
++ {
++ case JT_REF:
++ tab->read_first_record= join_read_always_key;
++ tab->read_record.read_record= join_read_next_same;
++ break;
++
++ case JT_REF_OR_NULL:
++ tab->read_first_record= join_read_always_key_or_null;
++ tab->read_record.read_record= join_read_next_same_or_null;
++ break;
++
++ case JT_CONST:
++ tab->read_first_record= join_read_const;
++ tab->read_record.read_record= join_no_more_records;
++ break;
++
++ case JT_EQ_REF:
++ tab->read_first_record= join_read_key;
++ tab->read_record.read_record= join_no_more_records;
++ break;
++
++ case JT_FT:
++ tab->read_first_record= join_ft_read_first;
++ tab->read_record.read_record= join_ft_read_next;
++ break;
++
++ case JT_SYSTEM:
++ tab->read_first_record= join_read_system;
++ tab->read_record.read_record= join_no_more_records;
++ break;
++
++ /* keep gcc happy */
++ default:
++ break;
++ }
++}
++
++
++static void
++make_join_readinfo(JOIN *join, ulonglong options)
++{
++ uint i;
++ bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
++ bool ordered_set= 0;
++ bool sorted= 1;
++ DBUG_ENTER("make_join_readinfo");
++
++ for (i=join->const_tables ; i < join->tables ; i++)
++ {
++ JOIN_TAB *tab=join->join_tab+i;
++ TABLE *table=tab->table;
++ tab->read_record.table= table;
++ tab->read_record.file=table->file;
++ tab->read_record.unlock_row= rr_unlock_row;
++ tab->next_select=sub_select; /* normal select */
++
++ /*
++ Determine if the set is already ordered for ORDER BY, so it can
++ disable join cache because it will change the ordering of the results.
++ Code handles sort table that is at any location (not only first after
++ the const tables) despite the fact that it's currently prohibited.
++ We must disable join cache if the first non-const table alone is
++ ordered. If there is a temp table the ordering is done as a last
++ operation and doesn't prevent join cache usage.
++ */
++ if (!ordered_set && !join->need_tmp &&
++ (table == join->sort_by_table ||
++ (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
++ ordered_set= 1;
++
++ tab->sorted= sorted;
++ sorted= 0; // only first must be sorted
++ table->status=STATUS_NO_RECORD;
++ pick_table_access_method (tab);
++
++ switch (tab->type) {
++ case JT_EQ_REF:
++ tab->read_record.unlock_row= join_read_key_unlock_row;
++ /* fall through */
++ case JT_REF_OR_NULL:
++ case JT_REF:
++ if (tab->select)
++ {
++ delete tab->select->quick;
++ tab->select->quick=0;
++ }
++ delete tab->quick;
++ tab->quick=0;
++ /* fall through */
++ case JT_CONST: // Only happens with left join
++ if (table->covering_keys.is_set(tab->ref.key) &&
++ !table->no_keyread)
++ table->set_keyread(TRUE);
++ break;
++ case JT_ALL:
++ /*
++ If previous table use cache
++ If the incoming data set is already sorted don't use cache.
++ */
++ if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
++ tab->use_quick != 2 && !tab->first_inner && !ordered_set)
++ {
++ if ((options & SELECT_DESCRIBE) ||
++ !join_init_cache(join->thd,join->join_tab+join->const_tables,
++ i-join->const_tables))
++ {
++ tab[-1].next_select=sub_select_cache; /* Patch previous */
++ }
++ }
++ /* These init changes read_record */
++ if (tab->use_quick == 2)
++ {
++ join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
++ tab->read_first_record= join_init_quick_read_record;
++ if (statistics)
++ status_var_increment(join->thd->status_var.select_range_check_count);
++ }
++ else
++ {
++ tab->read_first_record= join_init_read_record;
++ if (i == join->const_tables)
++ {
++ if (tab->select && tab->select->quick)
++ {
++ if (statistics)
++ status_var_increment(join->thd->status_var.select_range_count);
++ }
++ else
++ {
++ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
++ if (statistics)
++ status_var_increment(join->thd->status_var.select_scan_count);
++ }
++ }
++ else
++ {
++ if (tab->select && tab->select->quick)
++ {
++ if (statistics)
++ status_var_increment(join->thd->status_var.select_full_range_join_count);
++ }
++ else
++ {
++ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
++ if (statistics)
++ status_var_increment(join->thd->status_var.select_full_join_count);
++ }
++ }
++ if (!table->no_keyread)
++ {
++ if (tab->select && tab->select->quick &&
++ tab->select->quick->index != MAX_KEY && //not index_merge
++ table->covering_keys.is_set(tab->select->quick->index))
++ table->set_keyread(TRUE);
++ else if (!table->covering_keys.is_clear_all() &&
++ !(tab->select && tab->select->quick))
++ { // Only read index tree
++ /*
++ It has turned out that the below change, while speeding things
++ up for disk-bound loads, slows them down for cases when the data
++ is in disk cache (see BUG#35850):
++ // See bug #26447: "Using the clustered index for a table scan
++ // is always faster than using a secondary index".
++ if (table->s->primary_key != MAX_KEY &&
++ table->file->primary_key_is_clustered())
++ tab->index= table->s->primary_key;
++ else
++ */
++ tab->index=find_shortest_key(table, & table->covering_keys);
++ tab->read_first_record= join_read_first;
++ tab->type=JT_NEXT; // Read with index_first / index_next
++ }
++ }
++ }
++ break;
++ case JT_FT:
++ case JT_SYSTEM:
++ break;
++ default:
++ DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
++ break; /* purecov: deadcode */
++ case JT_UNKNOWN:
++ case JT_MAYBE_REF:
++ abort(); /* purecov: deadcode */
++ }
++ }
++ join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Give error if we some tables are done with a full join.
++
++ This is used by multi_table_update and multi_table_delete when running
++ in safe mode.
++
++ @param join Join condition
++
++ @retval
++ 0 ok
++ @retval
++ 1 Error (full join used)
++*/
++
++bool error_if_full_join(JOIN *join)
++{
++ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
++ tab < end;
++ tab++)
++ {
++ if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
++ {
++ /* This error should not be ignored. */
++ join->select_lex->no_error= FALSE;
++ my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
++ ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
++ return(1);
++ }
++ }
++ return(0);
++}
++
++
++/**
++ cleanup JOIN_TAB.
++*/
++
++void JOIN_TAB::cleanup()
++{
++ delete select;
++ select= 0;
++ delete quick;
++ quick= 0;
++ x_free(cache.buff);
++ cache.buff= 0;
++ limit= 0;
++ if (table)
++ {
++ table->set_keyread(FALSE);
++ table->file->ha_index_or_rnd_end();
++ /*
++ We need to reset this for next select
++ (Tested in part_of_refkey)
++ */
++ table->reginfo.join_tab= 0;
++ }
++ end_read_record(&read_record);
++}
++
++
++/**
++ Partially cleanup JOIN after it has executed: close index or rnd read
++ (table cursors), free quick selects.
++
++ This function is called in the end of execution of a JOIN, before the used
++ tables are unlocked and closed.
++
++ For a join that is resolved using a temporary table, the first sweep is
++ performed against actual tables and an intermediate result is inserted
++ into the temprorary table.
++ The last sweep is performed against the temporary table. Therefore,
++ the base tables and associated buffers used to fill the temporary table
++ are no longer needed, and this function is called to free them.
++
++ For a join that is performed without a temporary table, this function
++ is called after all rows are sent, but before EOF packet is sent.
++
++ For a simple SELECT with no subqueries this function performs a full
++ cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
++ tables.
++
++ If a JOIN is executed for a subquery or if it has a subquery, we can't
++ do the full cleanup and need to do a partial cleanup only.
++ - If a JOIN is not the top level join, we must not unlock the tables
++ because the outer select may not have been evaluated yet, and we
++ can't unlock only selected tables of a query.
++ - Additionally, if this JOIN corresponds to a correlated subquery, we
++ should not free quick selects and join buffers because they will be
++ needed for the next execution of the correlated subquery.
++ - However, if this is a JOIN for a [sub]select, which is not
++ a correlated subquery itself, but has subqueries, we can free it
++ fully and also free JOINs of all its subqueries. The exception
++ is a subquery in SELECT list, e.g: @n
++ SELECT a, (select max(b) from t1) group by c @n
++ This subquery will not be evaluated at first sweep and its value will
++ not be inserted into the temporary table. Instead, it's evaluated
++ when selecting from the temporary table. Therefore, it can't be freed
++ here even though it's not correlated.
++
++ @todo
++ Unlock tables even if the join isn't top level select in the tree
++*/
++
++void JOIN::join_free()
++{
++ SELECT_LEX_UNIT *tmp_unit;
++ SELECT_LEX *sl;
++ /*
++ Optimization: if not EXPLAIN and we are done with the JOIN,
++ free all tables.
++ */
++ bool full= (!select_lex->uncacheable && !thd->lex->describe);
++ bool can_unlock= full;
++ DBUG_ENTER("JOIN::join_free");
++
++ cleanup(full);
++
++ for (tmp_unit= select_lex->first_inner_unit();
++ tmp_unit;
++ tmp_unit= tmp_unit->next_unit())
++ for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
++ {
++ Item_subselect *subselect= sl->master_unit()->item;
++ bool full_local= full && (!subselect || subselect->is_evaluated());
++ /*
++ If this join is evaluated, we can fully clean it up and clean up all
++ its underlying joins even if they are correlated -- they will not be
++ used any more anyway.
++ If this join is not yet evaluated, we still must clean it up to
++ close its table cursors -- it may never get evaluated, as in case of
++ ... HAVING FALSE OR a IN (SELECT ...))
++ but all table cursors must be closed before the unlock.
++ */
++ sl->cleanup_all_joins(full_local);
++ /* Can't unlock if at least one JOIN is still needed */
++ can_unlock= can_unlock && full_local;
++ }
++
++ /*
++ We are not using tables anymore
++ Unlock all tables. We may be in an INSERT .... SELECT statement.
++ */
++ if (can_unlock && lock && thd->lock &&
++ !(select_options & SELECT_NO_UNLOCK) &&
++ !select_lex->subquery_in_having &&
++ (select_lex == (thd->lex->unit.fake_select_lex ?
++ thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
++ {
++ /*
++ TODO: unlock tables even if the join isn't top level select in the
++ tree.
++ */
++ mysql_unlock_read_tables(thd, lock); // Don't free join->lock
++ lock= 0;
++ }
++
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Free resources of given join.
++
++ @param fill true if we should free all resources, call with full==1
++ should be last, before it this function can be called with
++ full==0
++
++ @note
++ With subquery this function definitely will be called several times,
++ but even for simple query it can be called several times.
++*/
++
++void JOIN::cleanup(bool full)
++{
++ DBUG_ENTER("JOIN::cleanup");
++
++ if (table)
++ {
++ JOIN_TAB *tab,*end;
++ /*
++ Only a sorted table may be cached. This sorted table is always the
++ first non const table in join->table
++ */
++ if (tables > const_tables) // Test for not-const tables
++ {
++ free_io_cache(table[const_tables]);
++ filesort_free_buffers(table[const_tables],full);
++ }
++
++ if (full)
++ {
++ for (tab= join_tab, end= tab+tables; tab != end; tab++)
++ tab->cleanup();
++ table= 0;
++ }
++ else
++ {
++ for (tab= join_tab, end= tab+tables; tab != end; tab++)
++ {
++ if (tab->table)
++ tab->table->file->ha_index_or_rnd_end();
++ }
++ }
++ }
++ /*
++ We are not using tables anymore
++ Unlock all tables. We may be in an INSERT .... SELECT statement.
++ */
++ if (full)
++ {
++ if (tmp_join)
++ tmp_table_param.copy_field= 0;
++ group_fields.delete_elements();
++ /*
++ Ensure that the above delete_elements() would not be called
++ twice for the same list.
++ */
++ if (tmp_join && tmp_join != this)
++ tmp_join->group_fields= group_fields;
++ /*
++ We can't call delete_elements() on copy_funcs as this will cause
++ problems in free_elements() as some of the elements are then deleted.
++ */
++ tmp_table_param.copy_funcs.empty();
++ /*
++ If we have tmp_join and 'this' JOIN is not tmp_join and
++ tmp_table_param.copy_field's of them are equal then we have to remove
++ pointer to tmp_table_param.copy_field from tmp_join, because it qill
++ be removed in tmp_table_param.cleanup().
++ */
++ if (tmp_join &&
++ tmp_join != this &&
++ tmp_join->tmp_table_param.copy_field ==
++ tmp_table_param.copy_field)
++ {
++ tmp_join->tmp_table_param.copy_field=
++ tmp_join->tmp_table_param.save_copy_field= 0;
++ }
++ tmp_table_param.cleanup();
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Remove the following expressions from ORDER BY and GROUP BY:
++ Constant expressions @n
++ Expression that only uses tables that are of type EQ_REF and the reference
++ is in the ORDER list or if all refereed tables are of the above type.
++
++ In the following, the X field can be removed:
++ @code
++ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
++ SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
++ @endcode
++
++ These can't be optimized:
++ @code
++ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
++ SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
++ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
++ @endcode
++*/
++
++static bool
++eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
++{
++ if (tab->cached_eq_ref_table) // If cached
++ return tab->eq_ref_table;
++ tab->cached_eq_ref_table=1;
++ /* We can skip const tables only if not an outer table */
++ if (tab->type == JT_CONST && !tab->first_inner)
++ return (tab->eq_ref_table=1); /* purecov: inspected */
++ if (tab->type != JT_EQ_REF || tab->table->maybe_null)
++ return (tab->eq_ref_table=0); // We must use this
++ Item **ref_item=tab->ref.items;
++ Item **end=ref_item+tab->ref.key_parts;
++ uint found=0;
++ table_map map=tab->table->map;
++
++ for (; ref_item != end ; ref_item++)
++ {
++ if (! (*ref_item)->const_item())
++ { // Not a const ref
++ ORDER *order;
++ for (order=start_order ; order ; order=order->next)
++ {
++ if ((*ref_item)->eq(order->item[0],0))
++ break;
++ }
++ if (order)
++ {
++ if (!(order->used & map))
++ {
++ found++;
++ order->used|= map;
++ }
++ continue; // Used in ORDER BY
++ }
++ if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables()))
++ return (tab->eq_ref_table=0);
++ }
++ }
++ /* Check that there was no reference to table before sort order */
++ for (; found && start_order ; start_order=start_order->next)
++ {
++ if (start_order->used & map)
++ {
++ found--;
++ continue;
++ }
++ if (start_order->depend_map & map)
++ return (tab->eq_ref_table=0);
++ }
++ return tab->eq_ref_table=1;
++}
++
++
++static bool
++only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
++{
++ if (specialflag & SPECIAL_SAFE_MODE)
++ return 0; // skip this optimize /* purecov: inspected */
++ tables&= ~PSEUDO_TABLE_BITS;
++ for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
++ {
++ if (tables & 1 && !eq_ref_table(join, order, *tab))
++ return 0;
++ }
++ return 1;
++}
++
++
++/** Update the dependency map for the tables. */
++
++static void update_depend_map(JOIN *join)
++{
++ JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
++
++ for (; join_tab != end ; join_tab++)
++ {
++ TABLE_REF *ref= &join_tab->ref;
++ table_map depend_map=0;
++ Item **item=ref->items;
++ uint i;
++ for (i=0 ; i < ref->key_parts ; i++,item++)
++ depend_map|=(*item)->used_tables();
++ ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
++ depend_map&= ~OUTER_REF_TABLE_BIT;
++ for (JOIN_TAB **tab=join->map2table;
++ depend_map ;
++ tab++,depend_map>>=1 )
++ {
++ if (depend_map & 1)
++ ref->depend_map|=(*tab)->ref.depend_map;
++ }
++ }
++}
++
++
++/** Update the dependency map for the sort order. */
++
++static void update_depend_map(JOIN *join, ORDER *order)
++{
++ for (; order ; order=order->next)
++ {
++ table_map depend_map;
++ order->item[0]->update_used_tables();
++ order->depend_map=depend_map=order->item[0]->used_tables();
++ order->used= 0;
++ // Not item_sum(), RAND() and no reference to table outside of sub select
++ if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
++ && !order->item[0]->with_sum_func)
++ {
++ for (JOIN_TAB **tab=join->map2table;
++ depend_map ;
++ tab++, depend_map>>=1)
++ {
++ if (depend_map & 1)
++ order->depend_map|=(*tab)->ref.depend_map;
++ }
++ }
++ }
++}
++
++
++/**
++ Remove all constants and check if ORDER only contains simple
++ expressions.
++
++ simple_order is set to 1 if sort_order only uses fields from head table
++ and the head table is not a LEFT JOIN table.
++
++ @param join Join handler
++ @param first_order List of SORT or GROUP order
++ @param cond WHERE statement
++ @param change_list Set to 1 if we should remove things from list.
++ If this is not set, then only simple_order is
++ calculated.
++ @param simple_order Set to 1 if we are only using simple expressions
++
++ @return
++ Returns new sort order
++*/
++
++static ORDER *
++remove_const(JOIN *join,ORDER *first_order, COND *cond,
++ bool change_list, bool *simple_order)
++{
++ if (join->tables == join->const_tables)
++ return change_list ? 0 : first_order; // No need to sort
++
++ ORDER *order,**prev_ptr;
++ table_map first_table= join->join_tab[join->const_tables].table->map;
++ table_map not_const_tables= ~join->const_table_map;
++ table_map ref;
++ DBUG_ENTER("remove_const");
++
++ prev_ptr= &first_order;
++ *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
++
++ /* NOTE: A variable of not_const_tables ^ first_table; breaks gcc 2.7 */
++
++ update_depend_map(join, first_order);
++ for (order=first_order; order ; order=order->next)
++ {
++ table_map order_tables=order->item[0]->used_tables();
++ if (order->item[0]->with_sum_func ||
++ /*
++ If the outer table of an outer join is const (either by itself or
++ after applying WHERE condition), grouping on a field from such a
++ table will be optimized away and filesort without temporary table
++ will be used unless we prevent that now. Filesort is not fit to
++ handle joins and the join condition is not applied. We can't detect
++ the case without an expensive test, however, so we force temporary
++ table for all queries containing more than one table, ROLLUP, and an
++ outer join.
++ */
++ (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
++ join->outer_join))
++ *simple_order=0; // Must do a temp table to sort
++ else if (!(order_tables & not_const_tables))
++ {
++ if (order->item[0]->with_subselect &&
++ !(join->select_lex->options & SELECT_DESCRIBE))
++ order->item[0]->val_str(&order->item[0]->str_value);
++ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
++ continue; // skip const item
++ }
++ else
++ {
++ if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))
++ *simple_order=0;
++ else
++ {
++ Item *comp_item=0;
++ if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
++ {
++ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
++ continue;
++ }
++ if ((ref=order_tables & (not_const_tables ^ first_table)))
++ {
++ if (!(order_tables & first_table) &&
++ only_eq_ref_tables(join,first_order, ref))
++ {
++ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
++ continue;
++ }
++ *simple_order=0; // Must do a temp table to sort
++ }
++ }
++ }
++ if (change_list)
++ *prev_ptr= order; // use this entry
++ prev_ptr= &order->next;
++ }
++ if (change_list)
++ *prev_ptr=0;
++ if (prev_ptr == &first_order) // Nothing to sort/group
++ *simple_order=1;
++ DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order));
++ DBUG_RETURN(first_order);
++}
++
++
++static int
++return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
++ List<Item> &fields, bool send_row, ulonglong select_options,
++ const char *info, Item *having)
++{
++ DBUG_ENTER("return_zero_rows");
++
++ if (select_options & SELECT_DESCRIBE)
++ {
++ select_describe(join, FALSE, FALSE, FALSE, info);
++ DBUG_RETURN(0);
++ }
++
++ join->join_free();
++
++ if (send_row)
++ {
++ for (TABLE_LIST *table= tables; table; table= table->next_leaf)
++ mark_as_null_row(table->table); // All fields are NULL
++ if (having && having->val_int() == 0)
++ send_row=0;
++ }
++ if (!(result->send_fields(fields,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
++ {
++ bool send_error= FALSE;
++ if (send_row)
++ {
++ List_iterator_fast<Item> it(fields);
++ Item *item;
++ while ((item= it++))
++ item->no_rows_in_result();
++ send_error= result->send_data(fields);
++ }
++ if (!send_error)
++ result->send_eof(); // Should be safe
++ }
++ /* Update results for FOUND_ROWS */
++ join->thd->limit_found_rows= join->thd->examined_row_count= 0;
++ DBUG_RETURN(0);
++}
++
++/*
++ used only in JOIN::clear
++*/
++static void clear_tables(JOIN *join)
++{
++ /*
++ must clear only the non-const tables, as const tables
++ are not re-calculated.
++ */
++ for (uint i=join->const_tables ; i < join->tables ; i++)
++ mark_as_null_row(join->table[i]); // All fields are NULL
++}
++
++/*****************************************************************************
++ Make som simple condition optimization:
++ If there is a test 'field = const' change all refs to 'field' to 'const'
++ Remove all dummy tests 'item = item', 'const op const'.
++ Remove all 'item is NULL', when item can never be null!
++ item->marker should be 0 for all items on entry
++ Return in cond_value FALSE if condition is impossible (1 = 2)
++*****************************************************************************/
++
++class COND_CMP :public ilink {
++public:
++ static void *operator new(size_t size)
++ {
++ return (void*) sql_alloc((uint) size);
++ }
++ static void operator delete(void *ptr __attribute__((unused)),
++ size_t size __attribute__((unused)))
++ { TRASH(ptr, size); }
++
++ Item *and_level;
++ Item_func *cmp_func;
++ COND_CMP(Item *a,Item_func *b) :and_level(a),cmp_func(b) {}
++};
++
++#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
++template class I_List<COND_CMP>;
++template class I_List_iterator<COND_CMP>;
++template class List<Item_func_match>;
++template class List_iterator<Item_func_match>;
++#endif
++
++
++/**
++ Find the multiple equality predicate containing a field.
++
++ The function retrieves the multiple equalities accessed through
++ the con_equal structure from current level and up looking for
++ an equality containing field. It stops retrieval as soon as the equality
++ is found and set up inherited_fl to TRUE if it's found on upper levels.
++
++ @param cond_equal multiple equalities to search in
++ @param field field to look for
++ @param[out] inherited_fl set up to TRUE if multiple equality is found
++ on upper levels (not on current level of
++ cond_equal)
++
++ @return
++ - Item_equal for the found multiple equality predicate if a success;
++ - NULL otherwise.
++*/
++
++Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
++ bool *inherited_fl)
++{
++ Item_equal *item= 0;
++ bool in_upper_level= FALSE;
++ while (cond_equal)
++ {
++ List_iterator_fast<Item_equal> li(cond_equal->current_level);
++ while ((item= li++))
++ {
++ if (item->contains(field))
++ goto finish;
++ }
++ in_upper_level= TRUE;
++ cond_equal= cond_equal->upper_levels;
++ }
++ in_upper_level= FALSE;
++finish:
++ *inherited_fl= in_upper_level;
++ return item;
++}
++
++
++/**
++ Check whether an equality can be used to build multiple equalities.
++
++ This function first checks whether the equality (left_item=right_item)
++ is a simple equality i.e. the one that equates a field with another field
++ or a constant (field=field_item or field=const_item).
++ If this is the case the function looks for a multiple equality
++ in the lists referenced directly or indirectly by cond_equal inferring
++ the given simple equality. If it doesn't find any, it builds a multiple
++ equality that covers the predicate, i.e. the predicate can be inferred
++ from this multiple equality.
++ The built multiple equality could be obtained in such a way:
++ create a binary multiple equality equivalent to the predicate, then
++ merge it, if possible, with one of old multiple equalities.
++ This guarantees that the set of multiple equalities covering equality
++ predicates will be minimal.
++
++ EXAMPLE:
++ For the where condition
++ @code
++ WHERE a=b AND b=c AND
++ (b=2 OR f=e)
++ @endcode
++ the check_equality will be called for the following equality
++ predicates a=b, b=c, b=2 and f=e.
++ - For a=b it will be called with *cond_equal=(0,[]) and will transform
++ *cond_equal into (0,[Item_equal(a,b)]).
++ - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
++ and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
++ - For b=2 it will be called with *cond_equal=(ptr(CE),[])
++ and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
++ - For f=e it will be called with *cond_equal=(ptr(CE), [])
++ and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
++
++ @note
++ Now only fields that have the same type definitions (verified by
++ the Field::eq_def method) are placed to the same multiple equalities.
++ Because of this some equality predicates are not eliminated and
++ can be used in the constant propagation procedure.
++ We could weeken the equlity test as soon as at least one of the
++ equal fields is to be equal to a constant. It would require a
++ more complicated implementation: we would have to store, in
++ general case, its own constant for each fields from the multiple
++ equality. But at the same time it would allow us to get rid
++ of constant propagation completely: it would be done by the call
++ to build_equal_items_for_cond.
++
++
++ The implementation does not follow exactly the above rules to
++ build a new multiple equality for the equality predicate.
++ If it processes the equality of the form field1=field2, it
++ looks for multiple equalities me1 containig field1 and me2 containing
++ field2. If only one of them is found the fuction expands it with
++ the lacking field. If multiple equalities for both fields are
++ found they are merged. If both searches fail a new multiple equality
++ containing just field1 and field2 is added to the existing
++ multiple equalities.
++ If the function processes the predicate of the form field1=const,
++ it looks for a multiple equality containing field1. If found, the
++ function checks the constant of the multiple equality. If the value
++ is unknown, it is setup to const. Otherwise the value is compared with
++ const and the evaluation of the equality predicate is performed.
++ When expanding/merging equality predicates from the upper levels
++ the function first copies them for the current level. It looks
++ acceptable, as this happens rarely. The implementation without
++ copying would be much more complicated.
++
++ @param left_item left term of the quality to be checked
++ @param right_item right term of the equality to be checked
++ @param item equality item if the equality originates from a condition
++ predicate, 0 if the equality is the result of row
++ elimination
++ @param cond_equal multiple equalities that must hold together with the
++ equality
++
++ @retval
++ TRUE if the predicate is a simple equality predicate to be used
++ for building multiple equalities
++ @retval
++ FALSE otherwise
++*/
++
++static bool check_simple_equality(Item *left_item, Item *right_item,
++ Item *item, COND_EQUAL *cond_equal)
++{
++ if (left_item->type() == Item::REF_ITEM &&
++ ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
++ {
++ if (((Item_ref*)left_item)->depended_from)
++ return FALSE;
++ left_item= left_item->real_item();
++ }
++ if (right_item->type() == Item::REF_ITEM &&
++ ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
++ {
++ if (((Item_ref*)right_item)->depended_from)
++ return FALSE;
++ right_item= right_item->real_item();
++ }
++ if (left_item->type() == Item::FIELD_ITEM &&
++ right_item->type() == Item::FIELD_ITEM &&
++ !((Item_field*)left_item)->depended_from &&
++ !((Item_field*)right_item)->depended_from)
++ {
++ /* The predicate the form field1=field2 is processed */
++
++ Field *left_field= ((Item_field*) left_item)->field;
++ Field *right_field= ((Item_field*) right_item)->field;
++
++ if (!left_field->eq_def(right_field))
++ return FALSE;
++
++ /* Search for multiple equalities containing field1 and/or field2 */
++ bool left_copyfl, right_copyfl;
++ Item_equal *left_item_equal=
++ find_item_equal(cond_equal, left_field, &left_copyfl);
++ Item_equal *right_item_equal=
++ find_item_equal(cond_equal, right_field, &right_copyfl);
++
++ /* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */
++ if (left_field->eq(right_field)) /* f = f */
++ return (!(left_field->maybe_null() && !left_item_equal));
++
++ if (left_item_equal && left_item_equal == right_item_equal)
++ {
++ /*
++ The equality predicate is inference of one of the existing
++ multiple equalities, i.e the condition is already covered
++ by upper level equalities
++ */
++ return TRUE;
++ }
++
++ /* Copy the found multiple equalities at the current level if needed */
++ if (left_copyfl)
++ {
++ /* left_item_equal of an upper level contains left_item */
++ left_item_equal= new Item_equal(left_item_equal);
++ cond_equal->current_level.push_back(left_item_equal);
++ }
++ if (right_copyfl)
++ {
++ /* right_item_equal of an upper level contains right_item */
++ right_item_equal= new Item_equal(right_item_equal);
++ cond_equal->current_level.push_back(right_item_equal);
++ }
++
++ if (left_item_equal)
++ {
++ /* left item was found in the current or one of the upper levels */
++ if (! right_item_equal)
++ left_item_equal->add((Item_field *) right_item);
++ else
++ {
++ /* Merge two multiple equalities forming a new one */
++ left_item_equal->merge(right_item_equal);
++ /* Remove the merged multiple equality from the list */
++ List_iterator<Item_equal> li(cond_equal->current_level);
++ while ((li++) != right_item_equal) ;
++ li.remove();
++ }
++ }
++ else
++ {
++ /* left item was not found neither the current nor in upper levels */
++ if (right_item_equal)
++ right_item_equal->add((Item_field *) left_item);
++ else
++ {
++ /* None of the fields was found in multiple equalities */
++ Item_equal *item_equal= new Item_equal((Item_field *) left_item,
++ (Item_field *) right_item);
++ cond_equal->current_level.push_back(item_equal);
++ }
++ }
++ return TRUE;
++ }
++
++ {
++ /* The predicate of the form field=const/const=field is processed */
++ Item *const_item= 0;
++ Item_field *field_item= 0;
++ if (left_item->type() == Item::FIELD_ITEM &&
++ !((Item_field*)left_item)->depended_from &&
++ right_item->const_item())
++ {
++ field_item= (Item_field*) left_item;
++ const_item= right_item;
++ }
++ else if (right_item->type() == Item::FIELD_ITEM &&
++ !((Item_field*)right_item)->depended_from &&
++ left_item->const_item())
++ {
++ field_item= (Item_field*) right_item;
++ const_item= left_item;
++ }
++
++ if (const_item &&
++ field_item->result_type() == const_item->result_type())
++ {
++ bool copyfl;
++
++ if (field_item->result_type() == STRING_RESULT)
++ {
++ CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
++ if (!item)
++ {
++ Item_func_eq *eq_item;
++ if ((eq_item= new Item_func_eq(left_item, right_item)))
++ return FALSE;
++ eq_item->set_cmp_func();
++ eq_item->quick_fix_field();
++ item= eq_item;
++ }
++ if ((cs != ((Item_func *) item)->compare_collation()) ||
++ !cs->coll->propagate(cs, 0, 0))
++ return FALSE;
++ }
++
++ Item_equal *item_equal = find_item_equal(cond_equal,
++ field_item->field, ©fl);
++ if (copyfl)
++ {
++ item_equal= new Item_equal(item_equal);
++ cond_equal->current_level.push_back(item_equal);
++ }
++ if (item_equal)
++ {
++ /*
++ The flag cond_false will be set to 1 after this, if item_equal
++ already contains a constant and its value is not equal to
++ the value of const_item.
++ */
++ item_equal->add(const_item, field_item);
++ }
++ else
++ {
++ item_equal= new Item_equal(const_item, field_item);
++ cond_equal->current_level.push_back(item_equal);
++ }
++ return TRUE;
++ }
++ }
++ return FALSE;
++}
++
++
++/**
++ Convert row equalities into a conjunction of regular equalities.
++
++ The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
++ into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
++ Ei=E'i the function checks whether it is a simple equality or a row
++ equality. If it is a simple equality it is used to expand multiple
++ equalities of cond_equal. If it is a row equality it converted to a
++ sequence of equalities between row elements. If Ei=E'i is neither a
++ simple equality nor a row equality the item for this predicate is added
++ to eq_list.
++
++ @param thd thread handle
++ @param left_row left term of the row equality to be processed
++ @param right_row right term of the row equality to be processed
++ @param cond_equal multiple equalities that must hold together with the
++ predicate
++ @param eq_list results of conversions of row equalities that are not
++ simple enough to form multiple equalities
++
++ @retval
++ TRUE if conversion has succeeded (no fatal error)
++ @retval
++ FALSE otherwise
++*/
++
++static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
++ COND_EQUAL *cond_equal, List<Item>* eq_list)
++{
++ uint n= left_row->cols();
++ for (uint i= 0 ; i < n; i++)
++ {
++ bool is_converted;
++ Item *left_item= left_row->element_index(i);
++ Item *right_item= right_row->element_index(i);
++ if (left_item->type() == Item::ROW_ITEM &&
++ right_item->type() == Item::ROW_ITEM)
++ {
++ is_converted= check_row_equality(thd,
++ (Item_row *) left_item,
++ (Item_row *) right_item,
++ cond_equal, eq_list);
++ if (!is_converted)
++ thd->lex->current_select->cond_count++;
++ }
++ else
++ {
++ is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
++ thd->lex->current_select->cond_count++;
++ }
++
++ if (!is_converted)
++ {
++ Item_func_eq *eq_item;
++ if (!(eq_item= new Item_func_eq(left_item, right_item)))
++ return FALSE;
++ eq_item->set_cmp_func();
++ eq_item->quick_fix_field();
++ eq_list->push_back(eq_item);
++ }
++ }
++ return TRUE;
++}
++
++
++/**
++ Eliminate row equalities and form multiple equalities predicates.
++
++ This function checks whether the item is a simple equality
++ i.e. the one that equates a field with another field or a constant
++ (field=field_item or field=constant_item), or, a row equality.
++ For a simple equality the function looks for a multiple equality
++ in the lists referenced directly or indirectly by cond_equal inferring
++ the given simple equality. If it doesn't find any, it builds/expands
++ multiple equality that covers the predicate.
++ Row equalities are eliminated substituted for conjunctive regular
++ equalities which are treated in the same way as original equality
++ predicates.
++
++ @param thd thread handle
++ @param item predicate to process
++ @param cond_equal multiple equalities that must hold together with the
++ predicate
++ @param eq_list results of conversions of row equalities that are not
++ simple enough to form multiple equalities
++
++ @retval
++ TRUE if re-writing rules have been applied
++ @retval
++ FALSE otherwise, i.e.
++ if the predicate is not an equality,
++ or, if the equality is neither a simple one nor a row equality,
++ or, if the procedure fails by a fatal error.
++*/
++
++static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
++ List<Item> *eq_list)
++{
++ if (item->type() == Item::FUNC_ITEM &&
++ ((Item_func*) item)->functype() == Item_func::EQ_FUNC)
++ {
++ Item *left_item= ((Item_func*) item)->arguments()[0];
++ Item *right_item= ((Item_func*) item)->arguments()[1];
++
++ if (left_item->type() == Item::ROW_ITEM &&
++ right_item->type() == Item::ROW_ITEM)
++ {
++ thd->lex->current_select->cond_count--;
++ return check_row_equality(thd,
++ (Item_row *) left_item,
++ (Item_row *) right_item,
++ cond_equal, eq_list);
++ }
++ else
++ return check_simple_equality(left_item, right_item, item, cond_equal);
++ }
++ return FALSE;
++}
++
++
++/**
++ Replace all equality predicates in a condition by multiple equality items.
++
++ At each 'and' level the function detects items for equality predicates
++ and replaced them by a set of multiple equality items of class Item_equal,
++ taking into account inherited equalities from upper levels.
++ If an equality predicate is used not in a conjunction it's just
++ replaced by a multiple equality predicate.
++ For each 'and' level the function set a pointer to the inherited
++ multiple equalities in the cond_equal field of the associated
++ object of the type Item_cond_and.
++ The function also traverses the cond tree and and for each field reference
++ sets a pointer to the multiple equality item containing the field, if there
++ is any. If this multiple equality equates fields to a constant the
++ function replaces the field reference by the constant in the cases
++ when the field is not of a string type or when the field reference is
++ just an argument of a comparison predicate.
++ The function also determines the maximum number of members in
++ equality lists of each Item_cond_and object assigning it to
++ thd->lex->current_select->max_equal_elems.
++
++ @note
++ Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
++ f1=f2, .., fn-1=fn. It substitutes any inference from these
++ equality predicates that is equivalent to the conjunction.
++ Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as
++ it is equivalent to ((a1=a2) AND (a2=a3)).
++ The function always makes a substitution of all equality predicates occured
++ in a conjuction for a minimal set of multiple equality predicates.
++ This set can be considered as a canonical representation of the
++ sub-conjunction of the equality predicates.
++ E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
++ (=(t1.a,t2.b,t3.c) AND t2.b>5), not by
++ (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
++ while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
++ (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5),
++ but if additionally =(t4.d,t2.b) is inherited, it
++ will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)
++
++ The function performs the substitution in a recursive descent by
++ the condtion tree, passing to the next AND level a chain of multiple
++ equality predicates which have been built at the upper levels.
++ The Item_equal items built at the level are attached to other
++ non-equality conjucts as a sublist. The pointer to the inherited
++ multiple equalities is saved in the and condition object (Item_cond_and).
++ This chain allows us for any field reference occurence easyly to find a
++ multiple equality that must be held for this occurence.
++ For each AND level we do the following:
++ - scan it for all equality predicate (=) items
++ - join them into disjoint Item_equal() groups
++ - process the included OR conditions recursively to do the same for
++ lower AND levels.
++
++ We need to do things in this order as lower AND levels need to know about
++ all possible Item_equal objects in upper levels.
++
++ @param thd thread handle
++ @param cond condition(expression) where to make replacement
++ @param inherited path to all inherited multiple equality items
++
++ @return
++ pointer to the transformed condition
++*/
++
++static COND *build_equal_items_for_cond(THD *thd, COND *cond,
++ COND_EQUAL *inherited)
++{
++ Item_equal *item_equal;
++ COND_EQUAL cond_equal;
++ cond_equal.upper_levels= inherited;
++
++ if (cond->type() == Item::COND_ITEM)
++ {
++ List<Item> eq_list;
++ bool and_level= ((Item_cond*) cond)->functype() ==
++ Item_func::COND_AND_FUNC;
++ List<Item> *args= ((Item_cond*) cond)->argument_list();
++
++ List_iterator<Item> li(*args);
++ Item *item;
++
++ if (and_level)
++ {
++ /*
++ Retrieve all conjuncts of this level detecting the equality
++ that are subject to substitution by multiple equality items and
++ removing each such predicate from the conjunction after having
++ found/created a multiple equality whose inference the predicate is.
++ */
++ while ((item= li++))
++ {
++ /*
++ PS/SP note: we can safely remove a node from AND-OR
++ structure here because it's restored before each
++ re-execution of any prepared statement/stored procedure.
++ */
++ if (check_equality(thd, item, &cond_equal, &eq_list))
++ li.remove();
++ }
++
++ /*
++ Check if we eliminated all the predicates of the level, e.g.
++ (a=a AND b=b AND a=a).
++ */
++ if (!args->elements &&
++ !cond_equal.current_level.elements &&
++ !eq_list.elements)
++ return new Item_int((longlong) 1, 1);
++
++ List_iterator_fast<Item_equal> it(cond_equal.current_level);
++ while ((item_equal= it++))
++ {
++ item_equal->fix_length_and_dec();
++ item_equal->update_used_tables();
++ set_if_bigger(thd->lex->current_select->max_equal_elems,
++ item_equal->members());
++ }
++
++ ((Item_cond_and*)cond)->cond_equal= cond_equal;
++ inherited= &(((Item_cond_and*)cond)->cond_equal);
++ }
++ /*
++ Make replacement of equality predicates for lower levels
++ of the condition expression.
++ */
++ li.rewind();
++ while ((item= li++))
++ {
++ Item *new_item;
++ if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
++ {
++ /* This replacement happens only for standalone equalities */
++ /*
++ This is ok with PS/SP as the replacement is done for
++ arguments of an AND/OR item, which are restored for each
++ execution of PS/SP.
++ */
++ li.replace(new_item);
++ }
++ }
++ if (and_level)
++ {
++ args->concat(&eq_list);
++ args->concat((List<Item> *)&cond_equal.current_level);
++ }
++ }
++ else if (cond->type() == Item::FUNC_ITEM)
++ {
++ List<Item> eq_list;
++ /*
++ If an equality predicate forms the whole and level,
++ we call it standalone equality and it's processed here.
++ E.g. in the following where condition
++ WHERE a=5 AND (b=5 or a=c)
++ (b=5) and (a=c) are standalone equalities.
++ In general we can't leave alone standalone eqalities:
++ for WHERE a=b AND c=d AND (b=c OR d=5)
++ b=c is replaced by =(a,b,c,d).
++ */
++ if (check_equality(thd, cond, &cond_equal, &eq_list))
++ {
++ int n= cond_equal.current_level.elements + eq_list.elements;
++ if (n == 0)
++ return new Item_int((longlong) 1,1);
++ else if (n == 1)
++ {
++ if ((item_equal= cond_equal.current_level.pop()))
++ {
++ item_equal->fix_length_and_dec();
++ item_equal->update_used_tables();
++ set_if_bigger(thd->lex->current_select->max_equal_elems,
++ item_equal->members());
++ return item_equal;
++ }
++
++ return eq_list.pop();
++ }
++ else
++ {
++ /*
++ Here a new AND level must be created. It can happen only
++ when a row equality is processed as a standalone predicate.
++ */
++ Item_cond_and *and_cond= new Item_cond_and(eq_list);
++ and_cond->quick_fix_field();
++ List<Item> *args= and_cond->argument_list();
++ List_iterator_fast<Item_equal> it(cond_equal.current_level);
++ while ((item_equal= it++))
++ {
++ item_equal->fix_length_and_dec();
++ item_equal->update_used_tables();
++ set_if_bigger(thd->lex->current_select->max_equal_elems,
++ item_equal->members());
++ }
++ and_cond->cond_equal= cond_equal;
++ args->concat((List<Item> *)&cond_equal.current_level);
++
++ return and_cond;
++ }
++ }
++ /*
++ For each field reference in cond, not from equal item predicates,
++ set a pointer to the multiple equality it belongs to (if there is any)
++ as soon the field is not of a string type or the field reference is
++ an argument of a comparison predicate.
++ */
++ uchar *is_subst_valid= (uchar *) 1;
++ cond= cond->compile(&Item::subst_argument_checker,
++ &is_subst_valid,
++ &Item::equal_fields_propagator,
++ (uchar *) inherited);
++ cond->update_used_tables();
++ }
++ return cond;
++}
++
++
++/**
++ Build multiple equalities for a condition and all on expressions that
++ inherit these multiple equalities.
++
++ The function first applies the build_equal_items_for_cond function
++ to build all multiple equalities for condition cond utilizing equalities
++ referred through the parameter inherited. The extended set of
++ equalities is returned in the structure referred by the cond_equal_ref
++ parameter. After this the function calls itself recursively for
++ all on expressions whose direct references can be found in join_list
++ and who inherit directly the multiple equalities just having built.
++
++ @note
++ The on expression used in an outer join operation inherits all equalities
++ from the on expression of the embedding join, if there is any, or
++ otherwise - from the where condition.
++ This fact is not obvious, but presumably can be proved.
++ Consider the following query:
++ @code
++ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
++ WHERE t1.a=t2.a;
++ @endcode
++ If the on expression in the query inherits =(t1.a,t2.a), then we
++ can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
++ the equality t3.a=t4.a. Although the on expression
++ t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one
++ in the query the latter can be replaced by the former: the new query
++ will return the same result set as the original one.
++
++ Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
++ to use t1.a=t3.a AND t3.a=t4.a under the on condition:
++ @code
++ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
++ WHERE t1.a=t2.a
++ @endcode
++ This query equivalent to:
++ @code
++ SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
++ WHERE t1.a=t2.a
++ @endcode
++ Similarly the original query can be rewritten to the query:
++ @code
++ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
++ WHERE t1.a=t2.a
++ @endcode
++ that is equivalent to:
++ @code
++ SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
++ WHERE t1.a=t2.a
++ @endcode
++ Thus, applying equalities from the where condition we basically
++ can get more freedom in performing join operations.
++ Althogh we don't use this property now, it probably makes sense to use
++ it in the future.
++ @param thd Thread handler
++ @param cond condition to build the multiple equalities for
++ @param inherited path to all inherited multiple equality items
++ @param join_list list of join tables to which the condition
++ refers to
++ @param[out] cond_equal_ref pointer to the structure to place built
++ equalities in
++
++ @return
++ pointer to the transformed condition containing multiple equalities
++*/
++
++static COND *build_equal_items(THD *thd, COND *cond,
++ COND_EQUAL *inherited,
++ List<TABLE_LIST> *join_list,
++ COND_EQUAL **cond_equal_ref)
++{
++ COND_EQUAL *cond_equal= 0;
++
++ if (cond)
++ {
++ cond= build_equal_items_for_cond(thd, cond, inherited);
++ cond->update_used_tables();
++ if (cond->type() == Item::COND_ITEM &&
++ ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ cond_equal= &((Item_cond_and*) cond)->cond_equal;
++ else if (cond->type() == Item::FUNC_ITEM &&
++ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
++ {
++ cond_equal= new COND_EQUAL;
++ cond_equal->current_level.push_back((Item_equal *) cond);
++ }
++ }
++ if (cond_equal)
++ {
++ cond_equal->upper_levels= inherited;
++ inherited= cond_equal;
++ }
++ *cond_equal_ref= cond_equal;
++
++ if (join_list)
++ {
++ TABLE_LIST *table;
++ List_iterator<TABLE_LIST> li(*join_list);
++
++ while ((table= li++))
++ {
++ if (table->on_expr)
++ {
++ List<TABLE_LIST> *nested_join_list= table->nested_join ?
++ &table->nested_join->join_list : NULL;
++ /*
++ We can modify table->on_expr because its old value will
++ be restored before re-execution of PS/SP.
++ */
++ table->on_expr= build_equal_items(thd, table->on_expr, inherited,
++ nested_join_list,
++ &table->cond_equal);
++ }
++ }
++ }
++
++ return cond;
++}
++
++
++/**
++ Compare field items by table order in the execution plan.
++
++ field1 considered as better than field2 if the table containing
++ field1 is accessed earlier than the table containing field2.
++ The function finds out what of two fields is better according
++ this criteria.
++
++ @param field1 first field item to compare
++ @param field2 second field item to compare
++ @param table_join_idx index to tables determining table order
++
++ @retval
++ 1 if field1 is better than field2
++ @retval
++ -1 if field2 is better than field1
++ @retval
++ 0 otherwise
++*/
++
++static int compare_fields_by_table_order(Item_field *field1,
++ Item_field *field2,
++ void *table_join_idx)
++{
++ int cmp= 0;
++ bool outer_ref= 0;
++ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
++ {
++ outer_ref= 1;
++ cmp= -1;
++ }
++ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
++ {
++ outer_ref= 1;
++ cmp++;
++ }
++ if (outer_ref)
++ return cmp;
++ JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
++ cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
++ return cmp < 0 ? -1 : (cmp ? 1 : 0);
++}
++
++
++/**
++ Generate minimal set of simple equalities equivalent to a multiple equality.
++
++ The function retrieves the fields of the multiple equality item
++ item_equal and for each field f:
++ - if item_equal contains const it generates the equality f=const_item;
++ - otherwise, if f is not the first field, generates the equality
++ f=item_equal->get_first().
++ All generated equality are added to the cond conjunction.
++
++ @param cond condition to add the generated equality to
++ @param upper_levels structure to access multiple equality of upper levels
++ @param item_equal multiple equality to generate simple equality from
++
++ @note
++ Before generating an equality function checks that it has not
++ been generated for multiple equalities of the upper levels.
++ E.g. for the following where condition
++ WHERE a=5 AND ((a=b AND b=c) OR c>4)
++ the upper level AND condition will contain =(5,a),
++ while the lower level AND condition will contain =(5,a,b,c).
++ When splitting =(5,a,b,c) into a separate equality predicates
++ we should omit 5=a, as we have it already in the upper level.
++ The following where condition gives us a more complicated case:
++ WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ...
++ Given the tables are accessed in the order t1->t2->t3->t4 for
++ the selected query execution plan the lower level multiple
++ equality =(t1.a,t2.b,t3.c,t4.d) formally should be converted to
++ t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be
++ generated for the upper level. Also t3.c=t4.d will be generated there.
++ So only t1.a=t3.c should be left in the lower level.
++ If cond is equal to 0, then not more then one equality is generated
++ and a pointer to it is returned as the result of the function.
++
++ @return
++ - The condition with generated simple equalities or
++ a pointer to the simple generated equality, if success.
++ - 0, otherwise.
++*/
++
++static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
++ Item_equal *item_equal)
++{
++ List<Item> eq_list;
++ Item_func_eq *eq_item= 0;
++ if (((Item *) item_equal)->const_item() && !item_equal->val_int())
++ return new Item_int((longlong) 0,1);
++ Item *item_const= item_equal->get_const();
++ Item_equal_iterator it(*item_equal);
++ Item *head;
++ if (item_const)
++ head= item_const;
++ else
++ {
++ head= item_equal->get_first();
++ it++;
++ }
++ Item_field *item_field;
++ while ((item_field= it++))
++ {
++ Item_equal *upper= item_field->find_item_equal(upper_levels);
++ Item_field *item= item_field;
++ if (upper)
++ {
++ if (item_const && upper->get_const())
++ item= 0;
++ else
++ {
++ Item_equal_iterator li(*item_equal);
++ while ((item= li++) != item_field)
++ {
++ if (item->find_item_equal(upper_levels) == upper)
++ break;
++ }
++ }
++ }
++ if (item == item_field)
++ {
++ if (eq_item)
++ eq_list.push_back(eq_item);
++ eq_item= new Item_func_eq(item_field, head);
++ if (!eq_item)
++ return 0;
++ eq_item->set_cmp_func();
++ eq_item->quick_fix_field();
++ }
++ }
++
++ if (!cond && !eq_list.head())
++ {
++ if (!eq_item)
++ return new Item_int((longlong) 1,1);
++ return eq_item;
++ }
++
++ if (eq_item)
++ eq_list.push_back(eq_item);
++ if (!cond)
++ cond= new Item_cond_and(eq_list);
++ else
++ {
++ DBUG_ASSERT(cond->type() == Item::COND_ITEM);
++ if (eq_list.elements)
++ ((Item_cond *) cond)->add_at_head(&eq_list);
++ }
++
++ cond->quick_fix_field();
++ cond->update_used_tables();
++
++ return cond;
++}
++
++
++/**
++ Substitute every field reference in a condition by the best equal field
++ and eliminate all multiple equality predicates.
++
++ The function retrieves the cond condition and for each encountered
++ multiple equality predicate it sorts the field references in it
++ according to the order of tables specified by the table_join_idx
++ parameter. Then it eliminates the multiple equality predicate it
++ replacing it by the conjunction of simple equality predicates
++ equating every field from the multiple equality to the first
++ field in it, or to the constant, if there is any.
++ After this the function retrieves all other conjuncted
++ predicates substitute every field reference by the field reference
++ to the first equal field or equal constant if there are any.
++ @param cond condition to process
++ @param cond_equal multiple equalities to take into consideration
++ @param table_join_idx index to tables determining field preference
++
++ @note
++ At the first glance full sort of fields in multiple equality
++ seems to be an overkill. Yet it's not the case due to possible
++ new fields in multiple equality item of lower levels. We want
++ the order in them to comply with the order of upper levels.
++
++ @return
++ The transformed condition
++*/
++
++static COND* substitute_for_best_equal_field(COND *cond,
++ COND_EQUAL *cond_equal,
++ void *table_join_idx)
++{
++ Item_equal *item_equal;
++
++ if (cond->type() == Item::COND_ITEM)
++ {
++ List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
++
++ bool and_level= ((Item_cond*) cond)->functype() ==
++ Item_func::COND_AND_FUNC;
++ if (and_level)
++ {
++ cond_equal= &((Item_cond_and *) cond)->cond_equal;
++ cond_list->disjoin((List<Item> *) &cond_equal->current_level);
++
++ List_iterator_fast<Item_equal> it(cond_equal->current_level);
++ while ((item_equal= it++))
++ {
++ item_equal->sort(&compare_fields_by_table_order, table_join_idx);
++ }
++ }
++
++ List_iterator<Item> li(*cond_list);
++ Item *item;
++ while ((item= li++))
++ {
++ Item *new_item =substitute_for_best_equal_field(item, cond_equal,
++ table_join_idx);
++ /*
++ This works OK with PS/SP re-execution as changes are made to
++ the arguments of AND/OR items only
++ */
++ if (new_item != item)
++ li.replace(new_item);
++ }
++
++ if (and_level)
++ {
++ List_iterator_fast<Item_equal> it(cond_equal->current_level);
++ while ((item_equal= it++))
++ {
++ cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
++ // This occurs when eliminate_item_equal() founds that cond is
++ // always false and substitutes it with Item_int 0.
++ // Due to this, value of item_equal will be 0, so just return it.
++ if (cond->type() != Item::COND_ITEM)
++ break;
++ }
++ }
++ if (cond->type() == Item::COND_ITEM &&
++ !((Item_cond*)cond)->argument_list()->elements)
++ cond= new Item_int((int32)cond->val_bool());
++
++ }
++ else if (cond->type() == Item::FUNC_ITEM &&
++ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
++ {
++ item_equal= (Item_equal *) cond;
++ item_equal->sort(&compare_fields_by_table_order, table_join_idx);
++ if (cond_equal && cond_equal->current_level.head() == item_equal)
++ cond_equal= 0;
++ return eliminate_item_equal(0, cond_equal, item_equal);
++ }
++ else
++ cond->transform(&Item::replace_equal_field, 0);
++ return cond;
++}
++
++
++/**
++ Check appearance of new constant items in multiple equalities
++ of a condition after reading a constant table.
++
++ The function retrieves the cond condition and for each encountered
++ multiple equality checks whether new constants have appeared after
++ reading the constant (single row) table tab. If so it adjusts
++ the multiple equality appropriately.
++
++ @param cond condition whose multiple equalities are to be checked
++ @param table constant table that has been read
++*/
++
++static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
++{
++ if (!(cond->used_tables() & tab->table->map))
++ return;
++
++ if (cond->type() == Item::COND_ITEM)
++ {
++ List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
++ List_iterator_fast<Item> li(*cond_list);
++ Item *item;
++ while ((item= li++))
++ update_const_equal_items(item, tab);
++ }
++ else if (cond->type() == Item::FUNC_ITEM &&
++ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
++ {
++ Item_equal *item_equal= (Item_equal *) cond;
++ bool contained_const= item_equal->get_const() != NULL;
++ item_equal->update_const();
++ if (!contained_const && item_equal->get_const())
++ {
++ /* Update keys for range analysis */
++ Item_equal_iterator it(*item_equal);
++ Item_field *item_field;
++ while ((item_field= it++))
++ {
++ Field *field= item_field->field;
++ JOIN_TAB *stat= field->table->reginfo.join_tab;
++ key_map possible_keys= field->key_start;
++ possible_keys.intersect(field->table->keys_in_use_for_query);
++ stat[0].const_keys.merge(possible_keys);
++
++ /*
++ For each field in the multiple equality (for which we know that it
++ is a constant) we have to find its corresponding key part, and set
++ that key part in const_key_parts.
++ */
++ if (!possible_keys.is_clear_all())
++ {
++ TABLE *tab= field->table;
++ KEYUSE *use;
++ for (use= stat->keyuse; use && use->table == tab; use++)
++ if (possible_keys.is_set(use->key) &&
++ tab->key_info[use->key].key_part[use->keypart].field ==
++ field)
++ tab->const_key_parts[use->key]|= use->keypart_map;
++ }
++ }
++ }
++ }
++}
++
++
++/*
++ change field = field to field = const for each found field = const in the
++ and_level
++*/
++
++static void
++change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
++ Item *and_father, Item *cond,
++ Item *field, Item *value)
++{
++ if (cond->type() == Item::COND_ITEM)
++ {
++ bool and_level= ((Item_cond*) cond)->functype() ==
++ Item_func::COND_AND_FUNC;
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
++ field, value);
++ return;
++ }
++ if (cond->eq_cmp_result() == Item::COND_OK)
++ return; // Not a boolean function
++
++ Item_bool_func2 *func= (Item_bool_func2*) cond;
++ Item **args= func->arguments();
++ Item *left_item= args[0];
++ Item *right_item= args[1];
++ Item_func::Functype functype= func->functype();
++
++ if (right_item->eq(field,0) && left_item != value &&
++ right_item->cmp_context == field->cmp_context &&
++ (left_item->result_type() != STRING_RESULT ||
++ value->result_type() != STRING_RESULT ||
++ left_item->collation.collation == value->collation.collation))
++ {
++ Item *tmp=value->clone_item();
++ tmp->collation.set(right_item->collation);
++
++ if (tmp)
++ {
++ thd->change_item_tree(args + 1, tmp);
++ func->update_used_tables();
++ if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
++ && and_father != cond && !left_item->const_item())
++ {
++ cond->marker=1;
++ COND_CMP *tmp2;
++ if ((tmp2=new COND_CMP(and_father,func)))
++ save_list->push_back(tmp2);
++ }
++ func->set_cmp_func();
++ }
++ }
++ else if (left_item->eq(field,0) && right_item != value &&
++ left_item->cmp_context == field->cmp_context &&
++ (right_item->result_type() != STRING_RESULT ||
++ value->result_type() != STRING_RESULT ||
++ right_item->collation.collation == value->collation.collation))
++ {
++ Item *tmp= value->clone_item();
++ tmp->collation.set(left_item->collation);
++
++ if (tmp)
++ {
++ thd->change_item_tree(args, tmp);
++ value= tmp;
++ func->update_used_tables();
++ if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
++ && and_father != cond && !right_item->const_item())
++ {
++ args[0]= args[1]; // For easy check
++ thd->change_item_tree(args + 1, value);
++ cond->marker=1;
++ COND_CMP *tmp2;
++ if ((tmp2=new COND_CMP(and_father,func)))
++ save_list->push_back(tmp2);
++ }
++ func->set_cmp_func();
++ }
++ }
++}
++
++/**
++ Remove additional condition inserted by IN/ALL/ANY transformation.
++
++ @param conds condition for processing
++
++ @return
++ new conditions
++*/
++
++static Item *remove_additional_cond(Item* conds)
++{
++ if (conds->name == in_additional_cond)
++ return 0;
++ if (conds->type() == Item::COND_ITEM)
++ {
++ Item_cond *cnd= (Item_cond*) conds;
++ List_iterator<Item> li(*(cnd->argument_list()));
++ Item *item;
++ while ((item= li++))
++ {
++ if (item->name == in_additional_cond)
++ {
++ li.remove();
++ if (cnd->argument_list()->elements == 1)
++ return cnd->argument_list()->head();
++ return conds;
++ }
++ }
++ }
++ return conds;
++}
++
++static void
++propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
++ COND *and_father, COND *cond)
++{
++ if (cond->type() == Item::COND_ITEM)
++ {
++ bool and_level= ((Item_cond*) cond)->functype() ==
++ Item_func::COND_AND_FUNC;
++ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ I_List<COND_CMP> save;
++ while ((item=li++))
++ {
++ propagate_cond_constants(thd, &save,and_level ? cond : item, item);
++ }
++ if (and_level)
++ { // Handle other found items
++ I_List_iterator<COND_CMP> cond_itr(save);
++ COND_CMP *cond_cmp;
++ while ((cond_cmp=cond_itr++))
++ {
++ Item **args= cond_cmp->cmp_func->arguments();
++ if (!args[0]->const_item())
++ change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
++ cond_cmp->and_level, args[0], args[1]);
++ }
++ }
++ }
++ else if (and_father != cond && !cond->marker) // In a AND group
++ {
++ if (cond->type() == Item::FUNC_ITEM &&
++ (((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
++ ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC))
++ {
++ Item_func_eq *func=(Item_func_eq*) cond;
++ Item **args= func->arguments();
++ bool left_const= args[0]->const_item();
++ bool right_const= args[1]->const_item();
++ if (!(left_const && right_const) &&
++ args[0]->result_type() == args[1]->result_type())
++ {
++ if (right_const)
++ {
++ resolve_const_item(thd, &args[1], args[0]);
++ func->update_used_tables();
++ change_cond_ref_to_const(thd, save_list, and_father, and_father,
++ args[0], args[1]);
++ }
++ else if (left_const)
++ {
++ resolve_const_item(thd, &args[0], args[1]);
++ func->update_used_tables();
++ change_cond_ref_to_const(thd, save_list, and_father, and_father,
++ args[1], args[0]);
++ }
++ }
++ }
++ }
++}
++
++
++/**
++ Simplify joins replacing outer joins by inner joins whenever it's
++ possible.
++
++ The function, during a retrieval of join_list, eliminates those
++ outer joins that can be converted into inner join, possibly nested.
++ It also moves the on expressions for the converted outer joins
++ and from inner joins to conds.
++ The function also calculates some attributes for nested joins:
++ - used_tables
++ - not_null_tables
++ - dep_tables.
++ - on_expr_dep_tables
++ The first two attributes are used to test whether an outer join can
++ be substituted for an inner join. The third attribute represents the
++ relation 'to be dependent on' for tables. If table t2 is dependent
++ on table t1, then in any evaluated execution plan table access to
++ table t2 must precede access to table t2. This relation is used also
++ to check whether the query contains invalid cross-references.
++ The forth attribute is an auxiliary one and is used to calculate
++ dep_tables.
++ As the attribute dep_tables qualifies possibles orders of tables in the
++ execution plan, the dependencies required by the straight join
++ modifiers are reflected in this attribute as well.
++ The function also removes all braces that can be removed from the join
++ expression without changing its meaning.
++
++ @note
++ An outer join can be replaced by an inner join if the where condition
++ or the on expression for an embedding nested join contains a conjunctive
++ predicate rejecting null values for some attribute of the inner tables.
++
++ E.g. in the query:
++ @code
++ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
++ @endcode
++ the predicate t2.b < 5 rejects nulls.
++ The query is converted first to:
++ @code
++ SELECT * FROM t1 INNER JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
++ @endcode
++ then to the equivalent form:
++ @code
++ SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a
++ @endcode
++
++
++ Similarly the following query:
++ @code
++ SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b
++ WHERE t2.c < 5
++ @endcode
++ is converted to:
++ @code
++ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b
++
++ @endcode
++
++ One conversion might trigger another:
++ @code
++ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a
++ LEFT JOIN t3 ON t3.b=t2.b
++ WHERE t3 IS NOT NULL =>
++ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a, t3
++ WHERE t3 IS NOT NULL AND t3.b=t2.b =>
++ SELECT * FROM t1, t2, t3
++ WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a
++ @endcode
++
++ The function removes all unnecessary braces from the expression
++ produced by the conversions.
++ E.g.
++ @code
++ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
++ @endcode
++ finally is converted to:
++ @code
++ SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
++
++ @endcode
++
++
++ It also will remove braces from the following queries:
++ @code
++ SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b
++ SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b.
++ @endcode
++
++ The benefit of this simplification procedure is that it might return
++ a query for which the optimizer can evaluate execution plan with more
++ join orders. With a left join operation the optimizer does not
++ consider any plan where one of the inner tables is before some of outer
++ tables.
++
++
++ The function is implemented by a recursive procedure. On the recursive
++ ascent all attributes are calculated, all outer joins that can be
++ converted are replaced and then all unnecessary braces are removed.
++ As join list contains join tables in the reverse order sequential
++ elimination of outer joins does not require extra recursive calls.
++
++ Here is an example of a join query with invalid cross references:
++ @code
++ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
++ @endcode
++
++ @param join reference to the query info
++ @param join_list list representation of the join to be converted
++ @param conds conditions to add on expressions for converted joins
++ @param top true <=> conds is the where condition
++
++ @return
++ - The new condition, if success
++ - 0, otherwise
++*/
++
++static COND *
++simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
++{
++ TABLE_LIST *table;
++ NESTED_JOIN *nested_join;
++ TABLE_LIST *prev_table= 0;
++ List_iterator<TABLE_LIST> li(*join_list);
++ bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
++ DBUG_ENTER("simplify_joins");
++
++ /*
++ Try to simplify join operations from join_list.
++ The most outer join operation is checked for conversion first.
++ */
++ while ((table= li++))
++ {
++ table_map used_tables;
++ table_map not_null_tables= (table_map) 0;
++
++ if ((nested_join= table->nested_join))
++ {
++ /*
++ If the element of join_list is a nested join apply
++ the procedure to its nested join list first.
++ */
++ if (table->on_expr)
++ {
++ Item *expr= table->on_expr;
++ /*
++ If an on expression E is attached to the table,
++ check all null rejected predicates in this expression.
++ If such a predicate over an attribute belonging to
++ an inner table of an embedded outer join is found,
++ the outer join is converted to an inner join and
++ the corresponding on expression is added to E.
++ */
++ expr= simplify_joins(join, &nested_join->join_list,
++ expr, FALSE);
++
++ if (!table->prep_on_expr || expr != table->on_expr)
++ {
++ DBUG_ASSERT(expr);
++
++ table->on_expr= expr;
++ table->prep_on_expr= expr->copy_andor_structure(join->thd);
++ }
++ }
++ nested_join->used_tables= (table_map) 0;
++ nested_join->not_null_tables=(table_map) 0;
++ conds= simplify_joins(join, &nested_join->join_list, conds, top);
++ used_tables= nested_join->used_tables;
++ not_null_tables= nested_join->not_null_tables;
++ }
++ else
++ {
++ if (!table->prep_on_expr)
++ table->prep_on_expr= table->on_expr;
++ used_tables= table->table->map;
++ if (conds)
++ not_null_tables= conds->not_null_tables();
++ }
++
++ if (table->embedding)
++ {
++ table->embedding->nested_join->used_tables|= used_tables;
++ table->embedding->nested_join->not_null_tables|= not_null_tables;
++ }
++
++ if (!table->outer_join || (used_tables & not_null_tables))
++ {
++ /*
++ For some of the inner tables there are conjunctive predicates
++ that reject nulls => the outer join can be replaced by an inner join.
++ */
++ table->outer_join= 0;
++ if (table->on_expr)
++ {
++ /* Add on expression to the where condition. */
++ if (conds)
++ {
++ conds= and_conds(conds, table->on_expr);
++ conds->top_level_item();
++ /* conds is always a new item as both cond and on_expr existed */
++ DBUG_ASSERT(!conds->fixed);
++ conds->fix_fields(join->thd, &conds);
++ }
++ else
++ conds= table->on_expr;
++ table->prep_on_expr= table->on_expr= 0;
++ }
++ }
++
++ if (!top)
++ continue;
++
++ /*
++ Only inner tables of non-convertible outer joins
++ remain with on_expr.
++ */
++ if (table->on_expr)
++ {
++ table->dep_tables|= table->on_expr->used_tables();
++ if (table->embedding)
++ {
++ table->dep_tables&= ~table->embedding->nested_join->used_tables;
++ /*
++ Embedding table depends on tables used
++ in embedded on expressions.
++ */
++ table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
++ }
++ else
++ table->dep_tables&= ~table->table->map;
++ }
++
++ if (prev_table)
++ {
++ /* The order of tables is reverse: prev_table follows table */
++ if (prev_table->straight || straight_join)
++ prev_table->dep_tables|= used_tables;
++ if (prev_table->on_expr)
++ {
++ prev_table->dep_tables|= table->on_expr_dep_tables;
++ table_map prev_used_tables= prev_table->nested_join ?
++ prev_table->nested_join->used_tables :
++ prev_table->table->map;
++ /*
++ If on expression contains only references to inner tables
++ we still make the inner tables dependent on the outer tables.
++ It would be enough to set dependency only on one outer table
++ for them. Yet this is really a rare case.
++ Note:
++ RAND_TABLE_BIT mask should not be counted as it
++ prevents update of inner table dependences.
++ For example it might happen if RAND() function
++ is used in JOIN ON clause.
++ */
++ if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) &
++ ~prev_used_tables))
++ prev_table->dep_tables|= used_tables;
++ }
++ }
++ prev_table= table;
++ }
++
++ /* Flatten nested joins that can be flattened. */
++ TABLE_LIST *right_neighbor= NULL;
++ li.rewind();
++ while ((table= li++))
++ {
++ bool fix_name_res= FALSE;
++ nested_join= table->nested_join;
++ if (nested_join && !table->on_expr)
++ {
++ TABLE_LIST *tbl;
++ List_iterator<TABLE_LIST> it(nested_join->join_list);
++ while ((tbl= it++))
++ {
++ tbl->embedding= table->embedding;
++ tbl->join_list= table->join_list;
++ }
++ li.replace(nested_join->join_list);
++ /* Need to update the name resolution table chain when flattening joins */
++ fix_name_res= TRUE;
++ table= *li.ref();
++ }
++ if (fix_name_res)
++ table->next_name_resolution_table= right_neighbor ?
++ right_neighbor->first_leaf_for_name_resolution() :
++ NULL;
++ right_neighbor= table;
++ }
++ DBUG_RETURN(conds);
++}
++
++
++/**
++ Assign each nested join structure a bit in nested_join_map.
++
++ Assign each nested join structure (except "confluent" ones - those that
++ embed only one element) a bit in nested_join_map.
++
++ @param join Join being processed
++ @param join_list List of tables
++ @param first_unused Number of first unused bit in nested_join_map before the
++ call
++
++ @note
++ This function is called after simplify_joins(), when there are no
++ redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
++ we will not run out of bits in nested_join_map.
++
++ @return
++ First unused bit in nested_join_map after the call.
++*/
++
++static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
++ uint first_unused)
++{
++ List_iterator<TABLE_LIST> li(*join_list);
++ TABLE_LIST *table;
++ DBUG_ENTER("build_bitmap_for_nested_joins");
++ while ((table= li++))
++ {
++ NESTED_JOIN *nested_join;
++ if ((nested_join= table->nested_join))
++ {
++ /*
++ It is guaranteed by simplify_joins() function that a nested join
++ that has only one child represents a single table VIEW (and the child
++ is an underlying table). We don't assign bits to such nested join
++ structures because
++ 1. it is redundant (a "sequence" of one table cannot be interleaved
++ with anything)
++ 2. we could run out bits in nested_join_map otherwise.
++ */
++ if (nested_join->join_list.elements != 1)
++ {
++ nested_join->nj_map= (nested_join_map) 1 << first_unused++;
++ first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
++ first_unused);
++ }
++ }
++ }
++ DBUG_RETURN(first_unused);
++}
++
++
++/**
++ Set NESTED_JOIN::counter=0 in all nested joins in passed list.
++
++ Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
++ the passed join_list.
++
++ @param join_list List of nested joins to process. It may also contain base
++ tables which will be ignored.
++*/
++
++static void reset_nj_counters(List<TABLE_LIST> *join_list)
++{
++ List_iterator<TABLE_LIST> li(*join_list);
++ TABLE_LIST *table;
++ DBUG_ENTER("reset_nj_counters");
++ while ((table= li++))
++ {
++ NESTED_JOIN *nested_join;
++ if ((nested_join= table->nested_join))
++ {
++ nested_join->counter= 0;
++ reset_nj_counters(&nested_join->join_list);
++ }
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/**
++ Check interleaving with an inner tables of an outer join for
++ extension table.
++
++ Check if table next_tab can be added to current partial join order, and
++ if yes, record that it has been added.
++
++ The function assumes that both current partial join order and its
++ extension with next_tab are valid wrt table dependencies.
++
++ @verbatim
++ IMPLEMENTATION
++ LIMITATIONS ON JOIN ORDER
++ The nested [outer] joins executioner algorithm imposes these limitations
++ on join order:
++ 1. "Outer tables first" - any "outer" table must be before any
++ corresponding "inner" table.
++ 2. "No interleaving" - tables inside a nested join must form a continuous
++ sequence in join order (i.e. the sequence must not be interrupted by
++ tables that are outside of this nested join).
++
++ #1 is checked elsewhere, this function checks #2 provided that #1 has
++ been already checked.
++
++ WHY NEED NON-INTERLEAVING
++ Consider an example:
++
++ select * from t0 join t1 left join (t2 join t3) on cond1
++
++ The join order "t1 t2 t0 t3" is invalid:
++
++ table t0 is outside of the nested join, so WHERE condition for t0 is
++ attached directly to t0 (without triggers, and it may be used to access
++ t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
++ combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
++ null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
++ been produced.
++
++ If table t0 is not between t2 and t3, the problem doesn't exist:
++ If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
++ processing has finished.
++ If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
++ wrapped into condition triggers, which takes care of correct nested
++ join processing.
++
++ HOW IT IS IMPLEMENTED
++ The limitations on join order can be rephrased as follows: for valid
++ join order one must be able to:
++ 1. write down the used tables in the join order on one line.
++ 2. for each nested join, put one '(' and one ')' on the said line
++ 3. write "LEFT JOIN" and "ON (...)" where appropriate
++ 4. get a query equivalent to the query we're trying to execute.
++
++ Calls to check_interleaving_with_nj() are equivalent to writing the
++ above described line from left to right.
++ A single check_interleaving_with_nj(A,B) call is equivalent to writing
++ table B and appropriate brackets on condition that table A and
++ appropriate brackets is the last what was written. Graphically the
++ transition is as follows:
++
++ +---- current position
++ |
++ ... last_tab ))) | ( next_tab ) )..) | ...
++ X Y Z |
++ +- need to move to this
++ position.
++
++ Notes about the position:
++ The caller guarantees that there is no more then one X-bracket by
++ checking "!(remaining_tables & s->dependent)" before calling this
++ function. X-bracket may have a pair in Y-bracket.
++
++ When "writing" we store/update this auxilary info about the current
++ position:
++ 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
++ joins) we've opened but didn't close.
++ 2. {each NESTED_JOIN structure not simplified away}->counter - number
++ of this nested join's children that have already been added to to
++ the partial join order.
++ @endverbatim
++
++ @param next_tab Table we're going to extend the current partial join with
++
++ @retval
++ FALSE Join order extended, nested joins info about current join
++ order (see NOTE section) updated.
++ @retval
++ TRUE Requested join order extension not allowed.
++*/
++
++static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
++{
++ TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
++ JOIN *join= next_tab->join;
++
++ if (join->cur_embedding_map & ~next_tab->embedding_map)
++ {
++ /*
++ next_tab is outside of the "pair of brackets" we're currently in.
++ Cannot add it.
++ */
++ return TRUE;
++ }
++
++ /*
++ Do update counters for "pairs of brackets" that we've left (marked as
++ X,Y,Z in the above picture)
++ */
++ for (;next_emb; next_emb= next_emb->embedding)
++ {
++ next_emb->nested_join->counter++;
++ if (next_emb->nested_join->counter == 1)
++ {
++ /*
++ next_emb is the first table inside a nested join we've "entered". In
++ the picture above, we're looking at the 'X' bracket. Don't exit yet as
++ X bracket might have Y pair bracket.
++ */
++ join->cur_embedding_map |= next_emb->nested_join->nj_map;
++ }
++
++ if (next_emb->nested_join->join_list.elements !=
++ next_emb->nested_join->counter)
++ break;
++
++ /*
++ We're currently at Y or Z-bracket as depicted in the above picture.
++ Mark that we've left it and continue walking up the brackets hierarchy.
++ */
++ join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
++ }
++ return FALSE;
++}
++
++
++/**
++ Nested joins perspective: Remove the last table from the join order.
++
++ The algorithm is the reciprocal of check_interleaving_with_nj(), hence
++ parent join nest nodes are updated only when the last table in its child
++ node is removed. The ASCII graphic below will clarify.
++
++ %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
++ represented by the below join nest tree.
++
++ @verbatim
++ NJ1
++ _/ / \
++ _/ / NJ2
++ _/ / / \
++ / / / \
++ t1 x [ (t2 x t3) x (t4 x t5) ]
++ @endverbatim
++
++ At the point in time when check_interleaving_with_nj() adds the table t5 to
++ the query execution plan, QEP, it also directs the node named NJ2 to mark
++ the table as covered. NJ2 does so by incrementing its @c counter
++ member. Since all of NJ2's tables are now covered by the QEP, the algorithm
++ proceeds up the tree to NJ1, incrementing its counter as well. All join
++ nests are now completely covered by the QEP.
++
++ restore_prev_nj_state() does the above in reverse. As seen above, the node
++ NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
++ that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
++ completely covers NJ2. The removal of t5 from the partial plan will first
++ decrement NJ2's counter to 1. It will then detect that NJ2 went from being
++ completely to partially covered, and hence the algorithm must continue
++ upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
++ will however not influence NJ1 since it did not un-cover the last table in
++ NJ2.
++
++ SYNOPSIS
++ restore_prev_nj_state()
++ last join table to remove, it is assumed to be the last in current
++ partial join order.
++
++ DESCRIPTION
++
++ Remove the last table from the partial join order and update the nested
++ joins counters and join->cur_embedding_map. It is ok to call this
++ function for the first table in join order (for which
++ check_interleaving_with_nj has not been called)
++
++ @param last join table to remove, it is assumed to be the last in current
++ partial join order.
++*/
++
++static void restore_prev_nj_state(JOIN_TAB *last)
++{
++ TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
++ JOIN *join= last->join;
++ for (;last_emb != NULL; last_emb= last_emb->embedding)
++ {
++ NESTED_JOIN *nest= last_emb->nested_join;
++ DBUG_ASSERT(nest->counter > 0);
++
++ bool was_fully_covered= nest->is_fully_covered();
++
++ if (--nest->counter == 0)
++ join->cur_embedding_map&= ~nest->nj_map;
++
++ if (!was_fully_covered)
++ break;
++
++ join->cur_embedding_map|= nest->nj_map;
++ }
++}
++
++
++static COND *
++optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
++ Item::cond_result *cond_value)
++{
++ THD *thd= join->thd;
++ DBUG_ENTER("optimize_cond");
++
++ if (!conds)
++ *cond_value= Item::COND_TRUE;
++ else
++ {
++ /*
++ Build all multiple equality predicates and eliminate equality
++ predicates that can be inferred from these multiple equalities.
++ For each reference of a field included into a multiple equality
++ that occurs in a function set a pointer to the multiple equality
++ predicate. Substitute a constant instead of this field if the
++ multiple equality contains a constant.
++ */
++ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
++ conds= build_equal_items(join->thd, conds, NULL, join_list,
++ &join->cond_equal);
++ DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
++
++ /* change field = field to field = const for each found field = const */
++ propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
++ /*
++ Remove all instances of item == item
++ Remove all and-levels where CONST item != CONST item
++ */
++ DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY););
++ conds= remove_eq_conds(thd, conds, cond_value) ;
++ DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY););
++ }
++ DBUG_RETURN(conds);
++}
++
++
++/**
++ Remove const and eq items.
++
++ @return
++ Return new item, or NULL if no condition @n
++ cond_value is set to according:
++ - COND_OK : query is possible (field = constant)
++ - COND_TRUE : always true ( 1 = 1 )
++ - COND_FALSE : always false ( 1 = 2 )
++*/
++
++COND *
++remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
++{
++ if (cond->type() == Item::COND_ITEM)
++ {
++ bool and_level= ((Item_cond*) cond)->functype()
++ == Item_func::COND_AND_FUNC;
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item::cond_result tmp_cond_value;
++ bool should_fix_fields=0;
++
++ *cond_value=Item::COND_UNDEF;
++ Item *item;
++ while ((item=li++))
++ {
++ Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
++ if (!new_item)
++ li.remove();
++ else if (item != new_item)
++ {
++ VOID(li.replace(new_item));
++ should_fix_fields=1;
++ }
++ if (*cond_value == Item::COND_UNDEF)
++ *cond_value=tmp_cond_value;
++ switch (tmp_cond_value) {
++ case Item::COND_OK: // Not TRUE or FALSE
++ if (and_level || *cond_value == Item::COND_FALSE)
++ *cond_value=tmp_cond_value;
++ break;
++ case Item::COND_FALSE:
++ if (and_level)
++ {
++ *cond_value=tmp_cond_value;
++ return (COND*) 0; // Always false
++ }
++ break;
++ case Item::COND_TRUE:
++ if (!and_level)
++ {
++ *cond_value= tmp_cond_value;
++ return (COND*) 0; // Always true
++ }
++ break;
++ case Item::COND_UNDEF: // Impossible
++ break; /* purecov: deadcode */
++ }
++ }
++ if (should_fix_fields)
++ cond->update_used_tables();
++
++ if (!((Item_cond*) cond)->argument_list()->elements ||
++ *cond_value != Item::COND_OK)
++ return (COND*) 0;
++ if (((Item_cond*) cond)->argument_list()->elements == 1)
++ { // Remove list
++ item= ((Item_cond*) cond)->argument_list()->head();
++ ((Item_cond*) cond)->argument_list()->empty();
++ return item;
++ }
++ }
++ else if (cond->type() == Item::FUNC_ITEM &&
++ ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
++ {
++ /*
++ Handles this special case for some ODBC applications:
++ The are requesting the row that was just updated with a auto_increment
++ value with this construct:
++
++ SELECT * from table_name where auto_increment_column IS NULL
++ This will be changed to:
++ SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
++ */
++
++ Item_func_isnull *func=(Item_func_isnull*) cond;
++ Item **args= func->arguments();
++ if (args[0]->type() == Item::FIELD_ITEM)
++ {
++ Field *field=((Item_field*) args[0])->field;
++ if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
++ (thd->options & OPTION_AUTO_IS_NULL) &&
++ (thd->first_successful_insert_id_in_prev_stmt > 0 &&
++ thd->substitute_null_with_insert_id))
++ {
++#ifdef HAVE_QUERY_CACHE
++ query_cache_abort(&thd->net);
++#endif
++ COND *new_cond;
++ if ((new_cond= new Item_func_eq(args[0],
++ new Item_int("last_insert_id()",
++ thd->read_first_successful_insert_id_in_prev_stmt(),
++ MY_INT64_NUM_DECIMAL_DIGITS))))
++ {
++ cond=new_cond;
++ /*
++ Item_func_eq can't be fixed after creation so we do not check
++ cond->fixed, also it do not need tables so we use 0 as second
++ argument.
++ */
++ cond->fix_fields(thd, &cond);
++ }
++ /*
++ IS NULL should be mapped to LAST_INSERT_ID only for first row, so
++ clear for next row
++ */
++ thd->substitute_null_with_insert_id= FALSE;
++ }
++ /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
++ else if (((field->type() == MYSQL_TYPE_DATE) ||
++ (field->type() == MYSQL_TYPE_DATETIME)) &&
++ (field->flags & NOT_NULL_FLAG) &&
++ !field->table->maybe_null)
++ {
++ COND *new_cond;
++ if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
++ {
++ cond=new_cond;
++ /*
++ Item_func_eq can't be fixed after creation so we do not check
++ cond->fixed, also it do not need tables so we use 0 as second
++ argument.
++ */
++ cond->fix_fields(thd, &cond);
++ }
++ }
++ }
++ if (cond->const_item())
++ {
++ *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
++ return (COND*) 0;
++ }
++ }
++ else if (cond->const_item())
++ {
++ *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
++ return (COND*) 0;
++ }
++ else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
++ { // boolan compare function
++ Item *left_item= ((Item_func*) cond)->arguments()[0];
++ Item *right_item= ((Item_func*) cond)->arguments()[1];
++ if (left_item->eq(right_item,1))
++ {
++ if (!left_item->maybe_null ||
++ ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
++ return (COND*) 0; // Compare of identical items
++ }
++ }
++ *cond_value=Item::COND_OK;
++ return cond; // Point at next and level
++}
++
++/*
++ Check if equality can be used in removing components of GROUP BY/DISTINCT
++
++ SYNOPSIS
++ test_if_equality_guarantees_uniqueness()
++ l the left comparison argument (a field if any)
++ r the right comparison argument (a const of any)
++
++ DESCRIPTION
++ Checks if an equality predicate can be used to take away
++ DISTINCT/GROUP BY because it is known to be true for exactly one
++ distinct value (e.g. <expr> == <const>).
++ Arguments must be of the same type because e.g.
++ <string_field> = <int_const> may match more than 1 distinct value from
++ the column.
++ We must take into consideration and the optimization done for various
++ string constants when compared to dates etc (see Item_int_with_ref) as
++ well as the collation of the arguments.
++
++ RETURN VALUE
++ TRUE can be used
++ FALSE cannot be used
++*/
++static bool
++test_if_equality_guarantees_uniqueness(Item *l, Item *r)
++{
++ return r->const_item() &&
++ /* elements must be compared as dates */
++ (Arg_comparator::can_compare_as_dates(l, r, 0) ||
++ /* or of the same result type */
++ (r->result_type() == l->result_type() &&
++ /* and must have the same collation if compared as strings */
++ (l->result_type() != STRING_RESULT ||
++ l->collation.collation == r->collation.collation)));
++}
++
++/**
++ Return TRUE if the item is a const value in all the WHERE clause.
++*/
++
++static bool
++const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
++{
++ if (cond->type() == Item::COND_ITEM)
++ {
++ bool and_level= (((Item_cond*) cond)->functype()
++ == Item_func::COND_AND_FUNC);
++ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ {
++ bool res=const_expression_in_where(item, comp_item, const_item);
++ if (res) // Is a const value
++ {
++ if (and_level)
++ return 1;
++ }
++ else if (!and_level)
++ return 0;
++ }
++ return and_level ? 0 : 1;
++ }
++ else if (cond->eq_cmp_result() != Item::COND_OK)
++ { // boolan compare function
++ Item_func* func= (Item_func*) cond;
++ if (func->functype() != Item_func::EQUAL_FUNC &&
++ func->functype() != Item_func::EQ_FUNC)
++ return 0;
++ Item *left_item= ((Item_func*) cond)->arguments()[0];
++ Item *right_item= ((Item_func*) cond)->arguments()[1];
++ if (left_item->eq(comp_item,1))
++ {
++ if (test_if_equality_guarantees_uniqueness (left_item, right_item))
++ {
++ if (*const_item)
++ return right_item->eq(*const_item, 1);
++ *const_item=right_item;
++ return 1;
++ }
++ }
++ else if (right_item->eq(comp_item,1))
++ {
++ if (test_if_equality_guarantees_uniqueness (right_item, left_item))
++ {
++ if (*const_item)
++ return left_item->eq(*const_item, 1);
++ *const_item=left_item;
++ return 1;
++ }
++ }
++ }
++ return 0;
++}
++
++/****************************************************************************
++ Create internal temporary table
++****************************************************************************/
++
++/**
++ Create field for temporary table from given field.
++
++ @param thd Thread handler
++ @param org_field field from which new field will be created
++ @param name New field name
++ @param table Temporary table
++ @param item !=NULL if item->result_field should point to new field.
++ This is relevant for how fill_record() is going to work:
++ If item != NULL then fill_record() will update
++ the record in the original table.
++ If item == NULL then fill_record() will update
++ the temporary table
++ @param convert_blob_length If >0 create a varstring(convert_blob_length)
++ field instead of blob.
++
++ @retval
++ NULL on error
++ @retval
++ new_created field
++*/
++
++Field *create_tmp_field_from_field(THD *thd, Field *org_field,
++ const char *name, TABLE *table,
++ Item_field *item, uint convert_blob_length)
++{
++ Field *new_field;
++
++ /*
++ Make sure that the blob fits into a Field_varstring which has
++ 2-byte lenght.
++ */
++ if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
++ (org_field->flags & BLOB_FLAG))
++ new_field= new Field_varstring(convert_blob_length,
++ org_field->maybe_null(),
++ org_field->field_name, table->s,
++ org_field->charset());
++ else
++ new_field= org_field->new_field(thd->mem_root, table,
++ table == org_field->table);
++ if (new_field)
++ {
++ new_field->init(table);
++ new_field->orig_table= org_field->orig_table;
++ if (item)
++ item->result_field= new_field;
++ else
++ new_field->field_name= name;
++ new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
++ if (org_field->maybe_null() || (item && item->maybe_null))
++ new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
++ if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
++ org_field->type() == MYSQL_TYPE_VARCHAR)
++ table->s->db_create_options|= HA_OPTION_PACK_RECORD;
++ else if (org_field->type() == FIELD_TYPE_DOUBLE)
++ ((Field_double *) new_field)->not_fixed= TRUE;
++ }
++ return new_field;
++}
++
++/**
++ Create field for temporary table using type of given item.
++
++ @param thd Thread handler
++ @param item Item to create a field for
++ @param table Temporary table
++ @param copy_func If set and item is a function, store copy of
++ item in this array
++ @param modify_item 1 if item->result_field should point to new
++ item. This is relevent for how fill_record()
++ is going to work:
++ If modify_item is 1 then fill_record() will
++ update the record in the original table.
++ If modify_item is 0 then fill_record() will
++ update the temporary table
++ @param convert_blob_length If >0 create a varstring(convert_blob_length)
++ field instead of blob.
++
++ @retval
++ 0 on error
++ @retval
++ new_created field
++*/
++
++static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
++ Item ***copy_func, bool modify_item,
++ uint convert_blob_length)
++{
++ bool maybe_null= item->maybe_null;
++ Field *new_field;
++ LINT_INIT(new_field);
++
++ switch (item->result_type()) {
++ case REAL_RESULT:
++ new_field= new Field_double(item->max_length, maybe_null,
++ item->name, item->decimals, TRUE);
++ break;
++ case INT_RESULT:
++ /*
++ Select an integer type with the minimal fit precision.
++ MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
++ Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
++ Field_long : make them Field_longlong.
++ */
++ if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
++ new_field=new Field_longlong(item->max_length, maybe_null,
++ item->name, item->unsigned_flag);
++ else
++ new_field=new Field_long(item->max_length, maybe_null,
++ item->name, item->unsigned_flag);
++ break;
++ case STRING_RESULT:
++ DBUG_ASSERT(item->collation.collation);
++
++ enum enum_field_types type;
++ /*
++ DATE/TIME and GEOMETRY fields have STRING_RESULT result type.
++ To preserve type they needed to be handled separately.
++ */
++ if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
++ type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
++ type == MYSQL_TYPE_NEWDATE ||
++ type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
++ new_field= item->tmp_table_field_from_field_type(table, 1);
++ /*
++ Make sure that the blob fits into a Field_varstring which has
++ 2-byte lenght.
++ */
++ else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
++ convert_blob_length <= Field_varstring::MAX_SIZE &&
++ convert_blob_length)
++ new_field= new Field_varstring(convert_blob_length, maybe_null,
++ item->name, table->s,
++ item->collation.collation);
++ else
++ new_field= item->make_string_field(table);
++ new_field->set_derivation(item->collation.derivation);
++ break;
++ case DECIMAL_RESULT:
++ new_field= Field_new_decimal::create_from_item(item);
++ break;
++ case ROW_RESULT:
++ default:
++ // This case should never be choosen
++ DBUG_ASSERT(0);
++ new_field= 0;
++ break;
++ }
++ if (new_field)
++ new_field->init(table);
++
++ if (copy_func && item->is_result_field())
++ *((*copy_func)++) = item; // Save for copy_funcs
++ if (modify_item)
++ item->set_result_field(new_field);
++ if (item->type() == Item::NULL_ITEM)
++ new_field->is_created_from_null_item= TRUE;
++ return new_field;
++}
++
++
++/**
++ Create field for information schema table.
++
++ @param thd Thread handler
++ @param table Temporary table
++ @param item Item to create a field for
++
++ @retval
++ 0 on error
++ @retval
++ new_created field
++*/
++
++Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
++{
++ if (item->field_type() == MYSQL_TYPE_VARCHAR)
++ {
++ Field *field;
++ if (item->max_length > MAX_FIELD_VARCHARLENGTH)
++ field= new Field_blob(item->max_length, item->maybe_null,
++ item->name, item->collation.collation);
++ else
++ field= new Field_varstring(item->max_length, item->maybe_null,
++ item->name,
++ table->s, item->collation.collation);
++ if (field)
++ field->init(table);
++ return field;
++ }
++ return item->tmp_table_field_from_field_type(table, 0);
++}
++
++
++/**
++ Create field for temporary table.
++
++ @param thd Thread handler
++ @param table Temporary table
++ @param item Item to create a field for
++ @param type Type of item (normally item->type)
++ @param copy_func If set and item is a function, store copy of item
++ in this array
++ @param from_field if field will be created using other field as example,
++ pointer example field will be written here
++ @param default_field If field has a default value field, store it here
++ @param group 1 if we are going to do a relative group by on result
++ @param modify_item 1 if item->result_field should point to new item.
++ This is relevent for how fill_record() is going to
++ work:
++ If modify_item is 1 then fill_record() will update
++ the record in the original table.
++ If modify_item is 0 then fill_record() will update
++ the temporary table
++ @param convert_blob_length If >0 create a varstring(convert_blob_length)
++ field instead of blob.
++
++ @retval
++ 0 on error
++ @retval
++ new_created field
++*/
++
++Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
++ Item ***copy_func, Field **from_field,
++ Field **default_field,
++ bool group, bool modify_item,
++ bool table_cant_handle_bit_fields,
++ bool make_copy_field,
++ uint convert_blob_length)
++{
++ Field *result;
++ Item::Type orig_type= type;
++ Item *orig_item= 0;
++
++ if (type != Item::FIELD_ITEM &&
++ item->real_item()->type() == Item::FIELD_ITEM)
++ {
++ orig_item= item;
++ item= item->real_item();
++ type= Item::FIELD_ITEM;
++ }
++
++ switch (type) {
++ case Item::SUM_FUNC_ITEM:
++ {
++ Item_sum *item_sum=(Item_sum*) item;
++ result= item_sum->create_tmp_field(group, table, convert_blob_length);
++ if (!result)
++ thd->fatal_error();
++ return result;
++ }
++ case Item::FIELD_ITEM:
++ case Item::DEFAULT_VALUE_ITEM:
++ {
++ Item_field *field= (Item_field*) item;
++ bool orig_modify= modify_item;
++ if (orig_type == Item::REF_ITEM)
++ modify_item= 0;
++ /*
++ If item have to be able to store NULLs but underlaid field can't do it,
++ create_tmp_field_from_field() can't be used for tmp field creation.
++ */
++ if (field->maybe_null && !field->field->maybe_null())
++ {
++ result= create_tmp_field_from_item(thd, item, table, NULL,
++ modify_item, convert_blob_length);
++ *from_field= field->field;
++ if (result && modify_item)
++ field->result_field= result;
++ }
++ else if (table_cant_handle_bit_fields && field->field->type() ==
++ MYSQL_TYPE_BIT)
++ {
++ *from_field= field->field;
++ result= create_tmp_field_from_item(thd, item, table, copy_func,
++ modify_item, convert_blob_length);
++ if (result && modify_item)
++ field->result_field= result;
++ }
++ else
++ result= create_tmp_field_from_field(thd, (*from_field= field->field),
++ orig_item ? orig_item->name :
++ item->name,
++ table,
++ modify_item ? field :
++ NULL,
++ convert_blob_length);
++ if (orig_type == Item::REF_ITEM && orig_modify)
++ ((Item_ref*)orig_item)->set_result_field(result);
++ /*
++ Fields that are used as arguments to the DEFAULT() function already have
++ their data pointers set to the default value during name resulotion. See
++ Item_default_value::fix_fields.
++ */
++ if (orig_type != Item::DEFAULT_VALUE_ITEM && field->field->eq_def(result))
++ *default_field= field->field;
++ return result;
++ }
++ /* Fall through */
++ case Item::FUNC_ITEM:
++ if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
++ {
++ Item_func_sp *item_func_sp= (Item_func_sp *) item;
++ Field *sp_result_field= item_func_sp->get_sp_result_field();
++
++ if (make_copy_field)
++ {
++ DBUG_ASSERT(item_func_sp->result_field);
++ *from_field= item_func_sp->result_field;
++ }
++ else
++ {
++ *((*copy_func)++)= item;
++ }
++
++ Field *result_field=
++ create_tmp_field_from_field(thd,
++ sp_result_field,
++ item_func_sp->name,
++ table,
++ NULL,
++ convert_blob_length);
++
++ if (modify_item)
++ item->set_result_field(result_field);
++
++ return result_field;
++ }
++
++ /* Fall through */
++ case Item::COND_ITEM:
++ case Item::FIELD_AVG_ITEM:
++ case Item::FIELD_STD_ITEM:
++ case Item::SUBSELECT_ITEM:
++ /* The following can only happen with 'CREATE TABLE ... SELECT' */
++ case Item::PROC_ITEM:
++ case Item::INT_ITEM:
++ case Item::REAL_ITEM:
++ case Item::DECIMAL_ITEM:
++ case Item::STRING_ITEM:
++ case Item::REF_ITEM:
++ case Item::NULL_ITEM:
++ case Item::VARBIN_ITEM:
++ if (make_copy_field)
++ {
++ DBUG_ASSERT(((Item_result_field*)item)->result_field);
++ *from_field= ((Item_result_field*)item)->result_field;
++ }
++ return create_tmp_field_from_item(thd, item, table,
++ (make_copy_field ? 0 : copy_func),
++ modify_item, convert_blob_length);
++ case Item::TYPE_HOLDER:
++ result= ((Item_type_holder *)item)->make_field_by_type(table);
++ result->set_derivation(item->collation.derivation);
++ return result;
++ default: // Dosen't have to be stored
++ return 0;
++ }
++}
++
++/*
++ Set up column usage bitmaps for a temporary table
++
++ IMPLEMENTATION
++ For temporary tables, we need one bitmap with all columns set and
++ a tmp_set bitmap to be used by things like filesort.
++*/
++
++void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
++{
++ uint field_count= table->s->fields;
++ bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
++ FALSE);
++ bitmap_init(&table->tmp_set,
++ (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
++ field_count, FALSE);
++ /* write_set and all_set are copies of read_set */
++ table->def_write_set= table->def_read_set;
++ table->s->all_set= table->def_read_set;
++ bitmap_set_all(&table->s->all_set);
++ table->default_column_bitmaps();
++}
++
++
++/**
++ Create a temp table according to a field list.
++
++ Given field pointers are changed to point at tmp_table for
++ send_fields. The table object is self contained: it's
++ allocated in its own memory root, as well as Field objects
++ created for table columns.
++ This function will replace Item_sum items in 'fields' list with
++ corresponding Item_field items, pointing at the fields in the
++ temporary table, unless this was prohibited by TRUE
++ value of argument save_sum_fields. The Item_field objects
++ are created in THD memory root.
++
++ @param thd thread handle
++ @param param a description used as input to create the table
++ @param fields list of items that will be used to define
++ column types of the table (also see NOTES)
++ @param group TODO document
++ @param distinct should table rows be distinct
++ @param save_sum_fields see NOTES
++ @param select_options
++ @param rows_limit
++ @param table_alias possible name of the temporary table that can
++ be used for name resolving; can be "".
++*/
++
++#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
++#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
++#define RATIO_TO_PACK_ROWS 2
++#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
++
++TABLE *
++create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
++ ORDER *group, bool distinct, bool save_sum_fields,
++ ulonglong select_options, ha_rows rows_limit,
++ char *table_alias)
++{
++ MEM_ROOT *mem_root_save, own_root;
++ TABLE *table;
++ TABLE_SHARE *share;
++ uint i,field_count,null_count,null_pack_length;
++ uint copy_func_count= param->func_count;
++ uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
++ uint blob_count,group_null_items, string_count;
++ uint temp_pool_slot=MY_BIT_NONE;
++ uint fieldnr= 0;
++ ulong reclength, string_total_length;
++ bool using_unique_constraint= 0;
++ bool use_packed_rows= 0;
++ bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
++ char *tmpname,path[FN_REFLEN];
++ uchar *pos, *group_buff, *bitmaps;
++ uchar *null_flags;
++ Field **reg_field, **from_field, **default_field;
++ uint *blob_field;
++ Copy_field *copy=0;
++ KEY *keyinfo;
++ KEY_PART_INFO *key_part_info;
++ Item **copy_func;
++ MI_COLUMNDEF *recinfo;
++ /*
++ total_uneven_bit_length is uneven bit length for visible fields
++ hidden_uneven_bit_length is uneven bit length for hidden fields
++ */
++ uint total_uneven_bit_length= 0, hidden_uneven_bit_length= 0;
++ bool force_copy_fields= param->force_copy_fields;
++ /* Treat sum functions as normal ones when loose index scan is used. */
++ save_sum_fields|= param->precomputed_group_by;
++ DBUG_ENTER("create_tmp_table");
++ DBUG_PRINT("enter",
++ ("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d",
++ (int) distinct, (int) save_sum_fields,
++ (ulong) rows_limit,test(group)));
++
++ status_var_increment(thd->status_var.created_tmp_tables);
++
++ if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
++ temp_pool_slot = bitmap_lock_set_next(&temp_pool);
++
++ if (temp_pool_slot != MY_BIT_NONE) // we got a slot
++ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
++ current_pid, temp_pool_slot);
++ else
++ {
++ /* if we run out of slots or we are not using tempool */
++ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
++ thd->thread_id, thd->tmp_table++);
++ }
++
++ /*
++ No need to change table name to lower case as we are only creating
++ MyISAM or HEAP tables here
++ */
++ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
++
++
++ if (group)
++ {
++ if (!param->quick_group)
++ group=0; // Can't use group key
++ else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
++ {
++ (*tmp->item)->marker=4; // Store null in key
++ if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
++ using_unique_constraint=1;
++ }
++ if (param->group_length >= MAX_BLOB_WIDTH)
++ using_unique_constraint=1;
++ if (group)
++ distinct=0; // Can't use distinct
++ }
++
++ field_count=param->field_count+param->func_count+param->sum_func_count;
++ hidden_field_count=param->hidden_field_count;
++
++ /*
++ When loose index scan is employed as access method, it already
++ computes all groups and the result of all aggregate functions. We
++ make space for the items of the aggregate function in the list of
++ functions TMP_TABLE_PARAM::items_to_copy, so that the values of
++ these items are stored in the temporary table.
++ */
++ if (param->precomputed_group_by)
++ copy_func_count+= param->sum_func_count;
++
++ init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
++
++ if (!multi_alloc_root(&own_root,
++ &table, sizeof(*table),
++ &share, sizeof(*share),
++ ®_field, sizeof(Field*) * (field_count+1),
++ &default_field, sizeof(Field*) * (field_count),
++ &blob_field, sizeof(uint)*(field_count+1),
++ &from_field, sizeof(Field*)*field_count,
++ ©_func, sizeof(*copy_func)*(copy_func_count+1),
++ ¶m->keyinfo, sizeof(*param->keyinfo),
++ &key_part_info,
++ sizeof(*key_part_info)*(param->group_parts+1),
++ ¶m->start_recinfo,
++ sizeof(*param->recinfo)*(field_count*2+4),
++ &tmpname, (uint) strlen(path)+1,
++ &group_buff, (group && ! using_unique_constraint ?
++ param->group_length : 0),
++ &bitmaps, bitmap_buffer_size(field_count)*2,
++ NullS))
++ {
++ if (temp_pool_slot != MY_BIT_NONE)
++ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
++ DBUG_RETURN(NULL); /* purecov: inspected */
++ }
++ /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
++ if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
++ {
++ if (temp_pool_slot != MY_BIT_NONE)
++ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
++ free_root(&own_root, MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(NULL); /* purecov: inspected */
++ }
++ param->items_to_copy= copy_func;
++ strmov(tmpname,path);
++ /* make table according to fields */
++
++ bzero((char*) table,sizeof(*table));
++ bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
++ bzero((char*) default_field, sizeof(Field*) * (field_count));
++ bzero((char*) from_field,sizeof(Field*)*field_count);
++
++ table->mem_root= own_root;
++ mem_root_save= thd->mem_root;
++ thd->mem_root= &table->mem_root;
++
++ table->field=reg_field;
++ table->alias= table_alias;
++ table->reginfo.lock_type=TL_WRITE; /* Will be updated */
++ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
++ table->map=1;
++ table->temp_pool_slot = temp_pool_slot;
++ table->copy_blobs= 1;
++ table->in_use= thd;
++ table->quick_keys.init();
++ table->covering_keys.init();
++ table->merge_keys.init();
++ table->keys_in_use_for_query.init();
++
++ table->s= share;
++ init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
++ share->blob_field= blob_field;
++ share->blob_ptr_size= portable_sizeof_char_ptr;
++ share->db_low_byte_first=1; // True for HEAP and MyISAM
++ share->table_charset= param->table_charset;
++ share->primary_key= MAX_KEY; // Indicate no primary key
++ share->keys_for_keyread.init();
++ share->keys_in_use.init();
++
++ /* Calculate which type of fields we will store in the temporary table */
++
++ reclength= string_total_length= 0;
++ blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
++ param->using_indirect_summary_function=0;
++
++ List_iterator_fast<Item> li(fields);
++ Item *item;
++ Field **tmp_from_field=from_field;
++ while ((item=li++))
++ {
++ Item::Type type=item->type();
++ if (not_all_columns)
++ {
++ if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
++ {
++ if (item->used_tables() & OUTER_REF_TABLE_BIT)
++ item->update_used_tables();
++ if (type == Item::SUBSELECT_ITEM ||
++ (item->used_tables() & ~OUTER_REF_TABLE_BIT))
++ {
++ /*
++ Mark that the we have ignored an item that refers to a summary
++ function. We need to know this if someone is going to use
++ DISTINCT on the result.
++ */
++ param->using_indirect_summary_function=1;
++ continue;
++ }
++ }
++ if (item->const_item() && (int) hidden_field_count <= 0)
++ continue; // We don't have to store this
++ }
++ if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
++ { /* Can't calc group yet */
++ Item_sum *sum_item= (Item_sum *) item;
++ sum_item->result_field=0;
++ for (i=0 ; i < sum_item->get_arg_count() ; i++)
++ {
++ Item *arg= sum_item->get_arg(i);
++ if (!arg->const_item())
++ {
++ Field *new_field=
++ create_tmp_field(thd, table, arg, arg->type(), ©_func,
++ tmp_from_field, &default_field[fieldnr],
++ group != 0,not_all_columns,
++ distinct, 0,
++ param->convert_blob_length);
++ if (!new_field)
++ goto err; // Should be OOM
++ tmp_from_field++;
++ reclength+=new_field->pack_length();
++ if (new_field->flags & BLOB_FLAG)
++ {
++ *blob_field++= fieldnr;
++ blob_count++;
++ }
++ if (new_field->type() == MYSQL_TYPE_BIT)
++ total_uneven_bit_length+= new_field->field_length & 7;
++ *(reg_field++)= new_field;
++ if (new_field->real_type() == MYSQL_TYPE_STRING ||
++ new_field->real_type() == MYSQL_TYPE_VARCHAR)
++ {
++ string_count++;
++ string_total_length+= new_field->pack_length();
++ }
++ thd->mem_root= mem_root_save;
++ arg= sum_item->set_arg(i, thd, new Item_field(new_field));
++ thd->mem_root= &table->mem_root;
++ if (!(new_field->flags & NOT_NULL_FLAG))
++ {
++ null_count++;
++ /*
++ new_field->maybe_null() is still false, it will be
++ changed below. But we have to setup Item_field correctly
++ */
++ arg->maybe_null=1;
++ }
++ new_field->field_index= fieldnr++;
++ }
++ }
++ }
++ else
++ {
++ /*
++ The last parameter to create_tmp_field() is a bit tricky:
++
++ We need to set it to 0 in union, to get fill_record() to modify the
++ temporary table.
++ We need to set it to 1 on multi-table-update and in select to
++ write rows to the temporary table.
++ We here distinguish between UNION and multi-table-updates by the fact
++ that in the later case group is set to the row pointer.
++
++ The test for item->marker == 4 is ensure we don't create a group-by
++ key over a bit field as heap tables can't handle that.
++ */
++ Field *new_field= (param->schema_table) ?
++ create_tmp_field_for_schema(thd, item, table) :
++ create_tmp_field(thd, table, item, type, ©_func,
++ tmp_from_field, &default_field[fieldnr],
++ group != 0,
++ !force_copy_fields &&
++ (not_all_columns || group !=0),
++ item->marker == 4, force_copy_fields,
++ param->convert_blob_length);
++
++ if (!new_field)
++ {
++ if (thd->is_fatal_error)
++ goto err; // Got OOM
++ continue; // Some kindf of const item
++ }
++ if (type == Item::SUM_FUNC_ITEM)
++ ((Item_sum *) item)->result_field= new_field;
++ tmp_from_field++;
++ reclength+=new_field->pack_length();
++ if (!(new_field->flags & NOT_NULL_FLAG))
++ null_count++;
++ if (new_field->type() == MYSQL_TYPE_BIT)
++ total_uneven_bit_length+= new_field->field_length & 7;
++ if (new_field->flags & BLOB_FLAG)
++ {
++ *blob_field++= fieldnr;
++ blob_count++;
++ }
++ if (item->marker == 4 && item->maybe_null)
++ {
++ group_null_items++;
++ new_field->flags|= GROUP_FLAG;
++ }
++ new_field->field_index= fieldnr++;
++ *(reg_field++)= new_field;
++ }
++ if (!--hidden_field_count)
++ {
++ /*
++ This was the last hidden field; Remember how many hidden fields could
++ have null
++ */
++ hidden_null_count=null_count;
++ /*
++ We need to update hidden_field_count as we may have stored group
++ functions with constant arguments
++ */
++ param->hidden_field_count= fieldnr;
++ null_count= 0;
++ /*
++ On last hidden field we store uneven bit length in
++ hidden_uneven_bit_length and proceed calculation of
++ uneven bits for visible fields into
++ total_uneven_bit_length variable.
++ */
++ hidden_uneven_bit_length= total_uneven_bit_length;
++ total_uneven_bit_length= 0;
++ }
++ }
++ DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
++ DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
++ field_count= fieldnr;
++ *reg_field= 0;
++ *blob_field= 0; // End marker
++ share->fields= field_count;
++
++ /* If result table is small; use a heap */
++ /* future: storage engine selection can be made dynamic? */
++ if (blob_count || using_unique_constraint ||
++ (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
++ OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
++ {
++ share->db_plugin= ha_lock_engine(0, myisam_hton);
++ table->file= get_new_handler(share, &table->mem_root,
++ share->db_type());
++ if (group &&
++ (param->group_parts > table->file->max_key_parts() ||
++ param->group_length > table->file->max_key_length()))
++ using_unique_constraint=1;
++ }
++ else
++ {
++ share->db_plugin= ha_lock_engine(0, heap_hton);
++ table->file= get_new_handler(share, &table->mem_root,
++ share->db_type());
++ }
++ if (!table->file)
++ goto err;
++
++
++ if (!using_unique_constraint)
++ reclength+= group_null_items; // null flag is stored separately
++
++ share->blob_fields= blob_count;
++ if (blob_count == 0)
++ {
++ /* We need to ensure that first byte is not 0 for the delete link */
++ if (param->hidden_field_count)
++ hidden_null_count++;
++ else
++ null_count++;
++ }
++ hidden_null_pack_length= (hidden_null_count + 7 +
++ hidden_uneven_bit_length) / 8;
++ null_pack_length= (hidden_null_pack_length +
++ (null_count + total_uneven_bit_length + 7) / 8);
++ reclength+=null_pack_length;
++ if (!reclength)
++ reclength=1; // Dummy select
++ /* Use packed rows if there is blobs or a lot of space to gain */
++ if (blob_count ||
++ (string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS &&
++ (reclength / string_total_length <= RATIO_TO_PACK_ROWS ||
++ string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
++ use_packed_rows= 1;
++
++ share->reclength= reclength;
++ {
++ uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
++ share->rec_buff_length= alloc_length;
++ if (!(table->record[0]= (uchar*)
++ alloc_root(&table->mem_root, alloc_length*3)))
++ goto err;
++ table->record[1]= table->record[0]+alloc_length;
++ share->default_values= table->record[1]+alloc_length;
++ }
++ copy_func[0]=0; // End marker
++ param->func_count= copy_func - param->items_to_copy;
++
++ setup_tmp_table_column_bitmaps(table, bitmaps);
++
++ recinfo=param->start_recinfo;
++ null_flags=(uchar*) table->record[0];
++ pos=table->record[0]+ null_pack_length;
++ if (null_pack_length)
++ {
++ bzero((uchar*) recinfo,sizeof(*recinfo));
++ recinfo->type=FIELD_NORMAL;
++ recinfo->length=null_pack_length;
++ recinfo++;
++ bfill(null_flags,null_pack_length,255); // Set null fields
++
++ table->null_flags= (uchar*) table->record[0];
++ share->null_fields= null_count+ hidden_null_count;
++ share->null_bytes= null_pack_length;
++ }
++ null_count= (blob_count == 0) ? 1 : 0;
++ hidden_field_count=param->hidden_field_count;
++ for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
++ {
++ Field *field= *reg_field;
++ uint length;
++ bzero((uchar*) recinfo,sizeof(*recinfo));
++
++ if (!(field->flags & NOT_NULL_FLAG))
++ {
++ if (field->flags & GROUP_FLAG && !using_unique_constraint)
++ {
++ /*
++ We have to reserve one byte here for NULL bits,
++ as this is updated by 'end_update()'
++ */
++ *pos++=0; // Null is stored here
++ recinfo->length=1;
++ recinfo->type=FIELD_NORMAL;
++ recinfo++;
++ bzero((uchar*) recinfo,sizeof(*recinfo));
++ }
++ else
++ {
++ recinfo->null_bit= 1 << (null_count & 7);
++ recinfo->null_pos= null_count/8;
++ }
++ field->move_field(pos,null_flags+null_count/8,
++ 1 << (null_count & 7));
++ null_count++;
++ }
++ else
++ field->move_field(pos,(uchar*) 0,0);
++ if (field->type() == MYSQL_TYPE_BIT)
++ {
++ /* We have to reserve place for extra bits among null bits */
++ ((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8,
++ null_count & 7);
++ null_count+= (field->field_length & 7);
++ }
++ field->reset();
++
++ /*
++ Test if there is a default field value. The test for ->ptr is to skip
++ 'offset' fields generated by initalize_tables
++ */
++ if (default_field[i] && default_field[i]->ptr)
++ {
++ /*
++ default_field[i] is set only in the cases when 'field' can
++ inherit the default value that is defined for the field referred
++ by the Item_field object from which 'field' has been created.
++ */
++ my_ptrdiff_t diff;
++ Field *orig_field= default_field[i];
++ /* Get the value from default_values */
++ diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
++ orig_field->table->record[0]);
++ orig_field->move_field_offset(diff); // Points now at default_values
++ if (orig_field->is_real_null())
++ field->set_null();
++ else
++ {
++ field->set_notnull();
++ memcpy(field->ptr, orig_field->ptr, field->pack_length());
++ }
++ orig_field->move_field_offset(-diff); // Back to record[0]
++ }
++
++ if (from_field[i])
++ { /* Not a table Item */
++ copy->set(field,from_field[i],save_sum_fields);
++ copy++;
++ }
++ length=field->pack_length();
++ pos+= length;
++
++ /* Make entry for create table */
++ recinfo->length=length;
++ if (field->flags & BLOB_FLAG)
++ recinfo->type= (int) FIELD_BLOB;
++ else if (use_packed_rows &&
++ field->real_type() == MYSQL_TYPE_STRING &&
++ length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
++ recinfo->type=FIELD_SKIP_ENDSPACE;
++ else
++ recinfo->type=FIELD_NORMAL;
++ if (!--hidden_field_count)
++ null_count=(null_count+7) & ~7; // move to next byte
++
++ // fix table name in field entry
++ field->table_name= &table->alias;
++ }
++
++ param->copy_field_end=copy;
++ param->recinfo=recinfo;
++ store_record(table,s->default_values); // Make empty default record
++
++ if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
++ share->max_rows= ~(ha_rows) 0;
++ else
++ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
++ min(thd->variables.tmp_table_size,
++ thd->variables.max_heap_table_size) :
++ thd->variables.tmp_table_size) /
++ share->reclength);
++ set_if_bigger(share->max_rows,1); // For dummy start options
++ /*
++ Push the LIMIT clause to the temporary table creation, so that we
++ materialize only up to 'rows_limit' records instead of all result records.
++ */
++ set_if_smaller(share->max_rows, rows_limit);
++ param->end_write_records= rows_limit;
++
++ keyinfo= param->keyinfo;
++
++ if (group)
++ {
++ DBUG_PRINT("info",("Creating group key in temporary table"));
++ table->group=group; /* Table is grouped by key */
++ param->group_buff=group_buff;
++ share->keys=1;
++ share->uniques= test(using_unique_constraint);
++ table->key_info=keyinfo;
++ keyinfo->key_part=key_part_info;
++ keyinfo->flags=HA_NOSAME;
++ keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
++ keyinfo->key_length=0;
++ keyinfo->rec_per_key=0;
++ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
++ keyinfo->name= (char*) "group_key";
++ ORDER *cur_group= group;
++ for (; cur_group ; cur_group= cur_group->next, key_part_info++)
++ {
++ Field *field=(*cur_group->item)->get_tmp_table_field();
++ DBUG_ASSERT(field->table == table);
++ bool maybe_null=(*cur_group->item)->maybe_null;
++ key_part_info->null_bit=0;
++ key_part_info->field= field;
++ key_part_info->offset= field->offset(table->record[0]);
++ key_part_info->length= (uint16) field->key_length();
++ key_part_info->type= (uint8) field->key_type();
++ key_part_info->key_type =
++ ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
++ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
++ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
++ 0 : FIELDFLAG_BINARY;
++ if (!using_unique_constraint)
++ {
++ cur_group->buff=(char*) group_buff;
++ if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
++ group_buff +
++ test(maybe_null),
++ field->null_ptr,
++ field->null_bit)))
++ goto err; /* purecov: inspected */
++ if (maybe_null)
++ {
++ /*
++ To be able to group on NULL, we reserved place in group_buff
++ for the NULL flag just before the column. (see above).
++ The field data is after this flag.
++ The NULL flag is updated in 'end_update()' and 'end_write()'
++ */
++ keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
++ key_part_info->null_bit=field->null_bit;
++ key_part_info->null_offset= (uint) (field->null_ptr -
++ (uchar*) table->record[0]);
++ cur_group->buff++; // Pointer to field data
++ group_buff++; // Skipp null flag
++ }
++ /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
++ key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
++ group_buff+= cur_group->field->pack_length();
++ }
++ keyinfo->key_length+= key_part_info->length;
++ }
++ }
++
++ if (distinct && field_count != param->hidden_field_count)
++ {
++ /*
++ Create an unique key or an unique constraint over all columns
++ that should be in the result. In the temporary table, there are
++ 'param->hidden_field_count' extra columns, whose null bits are stored
++ in the first 'hidden_null_pack_length' bytes of the row.
++ */
++ DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
++
++ null_pack_length-=hidden_null_pack_length;
++ keyinfo->key_parts= ((field_count-param->hidden_field_count)+
++ test(null_pack_length));
++ table->distinct= 1;
++ share->keys= 1;
++ if (blob_count)
++ {
++ using_unique_constraint=1;
++ share->uniques= 1;
++ }
++ if (!(key_part_info= (KEY_PART_INFO*)
++ alloc_root(&table->mem_root,
++ keyinfo->key_parts * sizeof(KEY_PART_INFO))))
++ goto err;
++ bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
++ table->key_info=keyinfo;
++ keyinfo->key_part=key_part_info;
++ keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
++ keyinfo->key_length=(uint16) reclength;
++ keyinfo->name= (char*) "distinct_key";
++ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
++ keyinfo->rec_per_key=0;
++ if (null_pack_length)
++ {
++ key_part_info->null_bit=0;
++ key_part_info->offset=hidden_null_pack_length;
++ key_part_info->length=null_pack_length;
++ key_part_info->field= new Field_string(table->record[0],
++ (uint32) key_part_info->length,
++ (uchar*) 0,
++ (uint) 0,
++ Field::NONE,
++ NullS, &my_charset_bin);
++ if (!key_part_info->field)
++ goto err;
++ key_part_info->field->init(table);
++ key_part_info->key_type=FIELDFLAG_BINARY;
++ key_part_info->type= HA_KEYTYPE_BINARY;
++ key_part_info++;
++ }
++ /* Create a distinct key over the columns we are going to return */
++ for (i=param->hidden_field_count, reg_field=table->field + i ;
++ i < field_count;
++ i++, reg_field++, key_part_info++)
++ {
++ key_part_info->null_bit=0;
++ key_part_info->field= *reg_field;
++ key_part_info->offset= (*reg_field)->offset(table->record[0]);
++ key_part_info->length= (uint16) (*reg_field)->pack_length();
++ key_part_info->type= (uint8) (*reg_field)->key_type();
++ key_part_info->key_type =
++ ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
++ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
++ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
++ 0 : FIELDFLAG_BINARY;
++ }
++ }
++
++ if (thd->is_fatal_error) // If end of memory
++ goto err; /* purecov: inspected */
++ share->db_record_offset= 1;
++ if (share->db_type() == myisam_hton)
++ {
++ if (create_myisam_tmp_table(table,param,select_options))
++ goto err;
++ }
++ if (open_tmp_table(table))
++ goto err;
++
++ thd->mem_root= mem_root_save;
++
++ DBUG_RETURN(table);
++
++err:
++ thd->mem_root= mem_root_save;
++ free_tmp_table(thd,table); /* purecov: inspected */
++ if (temp_pool_slot != MY_BIT_NONE)
++ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
++ DBUG_RETURN(NULL); /* purecov: inspected */
++}
++
++
++/****************************************************************************/
++
++/**
++ Create a reduced TABLE object with properly set up Field list from a
++ list of field definitions.
++
++ The created table doesn't have a table handler associated with
++ it, has no keys, no group/distinct, no copy_funcs array.
++ The sole purpose of this TABLE object is to use the power of Field
++ class to read/write data to/from table->record[0]. Then one can store
++ the record in any container (RB tree, hash, etc).
++ The table is created in THD mem_root, so are the table's fields.
++ Consequently, if you don't BLOB fields, you don't need to free it.
++
++ @param thd connection handle
++ @param field_list list of column definitions
++
++ @return
++ 0 if out of memory, TABLE object in case of success
++*/
++
++TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
++{
++ uint field_count= field_list.elements;
++ uint blob_count= 0;
++ Field **field;
++ Create_field *cdef; /* column definition */
++ uint record_length= 0;
++ uint null_count= 0; /* number of columns which may be null */
++ uint null_pack_length; /* NULL representation array length */
++ uint *blob_field;
++ uchar *bitmaps;
++ TABLE *table;
++ TABLE_SHARE *share;
++
++ if (!multi_alloc_root(thd->mem_root,
++ &table, sizeof(*table),
++ &share, sizeof(*share),
++ &field, (field_count + 1) * sizeof(Field*),
++ &blob_field, (field_count+1) *sizeof(uint),
++ &bitmaps, bitmap_buffer_size(field_count)*2,
++ NullS))
++ return 0;
++
++ bzero(table, sizeof(*table));
++ bzero(share, sizeof(*share));
++ table->field= field;
++ table->s= share;
++ share->blob_field= blob_field;
++ share->fields= field_count;
++ share->blob_ptr_size= portable_sizeof_char_ptr;
++ setup_tmp_table_column_bitmaps(table, bitmaps);
++
++ /* Create all fields and calculate the total length of record */
++ List_iterator_fast<Create_field> it(field_list);
++ while ((cdef= it++))
++ {
++ *field= make_field(share, 0, cdef->length,
++ (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
++ f_maybe_null(cdef->pack_flag) ? 1 : 0,
++ cdef->pack_flag, cdef->sql_type, cdef->charset,
++ cdef->geom_type, cdef->unireg_check,
++ cdef->interval, cdef->field_name);
++ if (!*field)
++ goto error;
++ (*field)->init(table);
++ record_length+= (*field)->pack_length();
++ if (! ((*field)->flags & NOT_NULL_FLAG))
++ null_count++;
++
++ if ((*field)->flags & BLOB_FLAG)
++ share->blob_field[blob_count++]= (uint) (field - table->field);
++
++ field++;
++ }
++ *field= NULL; /* mark the end of the list */
++ share->blob_field[blob_count]= 0; /* mark the end of the list */
++ share->blob_fields= blob_count;
++
++ null_pack_length= (null_count + 7)/8;
++ share->reclength= record_length + null_pack_length;
++ share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
++ table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
++ if (!table->record[0])
++ goto error;
++
++ if (null_pack_length)
++ {
++ table->null_flags= (uchar*) table->record[0];
++ share->null_fields= null_count;
++ share->null_bytes= null_pack_length;
++ }
++
++ table->in_use= thd; /* field->reset() may access table->in_use */
++ {
++ /* Set up field pointers */
++ uchar *null_pos= table->record[0];
++ uchar *field_pos= null_pos + share->null_bytes;
++ uint null_bit= 1;
++
++ for (field= table->field; *field; ++field)
++ {
++ Field *cur_field= *field;
++ if ((cur_field->flags & NOT_NULL_FLAG))
++ cur_field->move_field(field_pos);
++ else
++ {
++ cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
++ null_bit<<= 1;
++ if (null_bit == (1 << 8))
++ {
++ ++null_pos;
++ null_bit= 1;
++ }
++ }
++ cur_field->reset();
++
++ field_pos+= cur_field->pack_length();
++ }
++ }
++ return table;
++error:
++ for (field= table->field; *field; ++field)
++ delete *field; /* just invokes field destructor */
++ return 0;
++}
++
++
++static bool open_tmp_table(TABLE *table)
++{
++ int error;
++ if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
++ HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ table->db_stat=0;
++ return(1);
++ }
++ (void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
++ return(0);
++}
++
++
++static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
++ ulonglong options)
++{
++ int error;
++ MI_KEYDEF keydef;
++ MI_UNIQUEDEF uniquedef;
++ KEY *keyinfo=param->keyinfo;
++ TABLE_SHARE *share= table->s;
++ DBUG_ENTER("create_myisam_tmp_table");
++
++ if (share->keys)
++ { // Get keys for ni_create
++ bool using_unique_constraint=0;
++ HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
++ sizeof(*seg) * keyinfo->key_parts);
++ if (!seg)
++ goto err;
++
++ bzero(seg, sizeof(*seg) * keyinfo->key_parts);
++ if (keyinfo->key_length >= table->file->max_key_length() ||
++ keyinfo->key_parts > table->file->max_key_parts() ||
++ share->uniques)
++ {
++ /* Can't create a key; Make a unique constraint instead of a key */
++ share->keys= 0;
++ share->uniques= 1;
++ using_unique_constraint=1;
++ bzero((char*) &uniquedef,sizeof(uniquedef));
++ uniquedef.keysegs=keyinfo->key_parts;
++ uniquedef.seg=seg;
++ uniquedef.null_are_equal=1;
++
++ /* Create extra column for hash value */
++ bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
++ param->recinfo->type= FIELD_CHECK;
++ param->recinfo->length=MI_UNIQUE_HASH_LENGTH;
++ param->recinfo++;
++ share->reclength+=MI_UNIQUE_HASH_LENGTH;
++ }
++ else
++ {
++ /* Create an unique key */
++ bzero((char*) &keydef,sizeof(keydef));
++ keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
++ keydef.keysegs= keyinfo->key_parts;
++ keydef.seg= seg;
++ }
++ for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
++ {
++ Field *field=keyinfo->key_part[i].field;
++ seg->flag= 0;
++ seg->language= field->charset()->number;
++ seg->length= keyinfo->key_part[i].length;
++ seg->start= keyinfo->key_part[i].offset;
++ if (field->flags & BLOB_FLAG)
++ {
++ seg->type=
++ ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
++ HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
++ seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
++ seg->flag= HA_BLOB_PART;
++ seg->length=0; // Whole blob in unique constraint
++ }
++ else
++ {
++ seg->type= keyinfo->key_part[i].type;
++ /* Tell handler if it can do suffic space compression */
++ if (field->real_type() == MYSQL_TYPE_STRING &&
++ keyinfo->key_part[i].length > 4)
++ seg->flag|= HA_SPACE_PACK;
++ }
++ if (!(field->flags & NOT_NULL_FLAG))
++ {
++ seg->null_bit= field->null_bit;
++ seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
++ /*
++ We are using a GROUP BY on something that contains NULL
++ In this case we have to tell MyISAM that two NULL should
++ on INSERT be regarded at the same value
++ */
++ if (!using_unique_constraint)
++ keydef.flag|= HA_NULL_ARE_EQUAL;
++ }
++ }
++ }
++ MI_CREATE_INFO create_info;
++ bzero((char*) &create_info,sizeof(create_info));
++
++ if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
++ OPTION_BIG_TABLES)
++ create_info.data_file_length= ~(ulonglong) 0;
++
++ if ((error=mi_create(share->table_name.str, share->keys, &keydef,
++ (uint) (param->recinfo-param->start_recinfo),
++ param->start_recinfo,
++ share->uniques, &uniquedef,
++ &create_info,
++ HA_CREATE_TMP_TABLE)))
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ table->db_stat=0;
++ goto err;
++ }
++ status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
++ share->db_record_offset= 1;
++ DBUG_RETURN(0);
++ err:
++ DBUG_RETURN(1);
++}
++
++
++void
++free_tmp_table(THD *thd, TABLE *entry)
++{
++ MEM_ROOT own_root= entry->mem_root;
++ const char *save_proc_info;
++ DBUG_ENTER("free_tmp_table");
++ DBUG_PRINT("enter",("table: %s",entry->alias));
++
++ save_proc_info=thd->proc_info;
++ thd_proc_info(thd, "removing tmp table");
++
++ // Release latches since this can take a long time
++ ha_release_temporary_latches(thd);
++
++ if (entry->file)
++ {
++ if (entry->db_stat)
++ entry->file->ha_drop_table(entry->s->table_name.str);
++ else
++ entry->file->ha_delete_table(entry->s->table_name.str);
++ delete entry->file;
++ }
++
++ /* free blobs */
++ for (Field **ptr=entry->field ; *ptr ; ptr++)
++ (*ptr)->free();
++ free_io_cache(entry);
++
++ if (entry->temp_pool_slot != MY_BIT_NONE)
++ bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
++
++ plugin_unlock(0, entry->s->db_plugin);
++
++ free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
++ thd_proc_info(thd, save_proc_info);
++
++ DBUG_VOID_RETURN;
++}
++
++/**
++ If a HEAP table gets full, create a MyISAM table and copy all rows
++ to this.
++*/
++
++bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
++ int error, bool ignore_last_dupp_key_error)
++{
++ TABLE new_table;
++ TABLE_SHARE share;
++ const char *save_proc_info;
++ int write_err;
++ DBUG_ENTER("create_myisam_from_heap");
++
++ if (table->s->db_type() != heap_hton ||
++ error != HA_ERR_RECORD_FILE_FULL)
++ {
++ /*
++ We don't want this error to be converted to a warning, e.g. in case of
++ INSERT IGNORE ... SELECT.
++ */
++ thd->fatal_error();
++ table->file->print_error(error,MYF(0));
++ DBUG_RETURN(1);
++ }
++
++ // Release latches since this can take a long time
++ ha_release_temporary_latches(thd);
++
++ new_table= *table;
++ share= *table->s;
++ new_table.s= &share;
++ new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
++ if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
++ new_table.s->db_type())))
++ DBUG_RETURN(1); // End of memory
++
++ save_proc_info=thd->proc_info;
++ thd_proc_info(thd, "converting HEAP to MyISAM");
++
++ if (create_myisam_tmp_table(&new_table, param,
++ thd->lex->select_lex.options | thd->options))
++ goto err2;
++ if (open_tmp_table(&new_table))
++ goto err1;
++ if (table->file->indexes_are_disabled())
++ new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
++ table->file->ha_index_or_rnd_end();
++ table->file->ha_rnd_init(1);
++ if (table->no_rows)
++ {
++ new_table.file->extra(HA_EXTRA_NO_ROWS);
++ new_table.no_rows=1;
++ }
++
++#ifdef TO_BE_DONE_LATER_IN_4_1
++ /*
++ To use start_bulk_insert() (which is new in 4.1) we need to find
++ all places where a corresponding end_bulk_insert() should be put.
++ */
++ table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
++ new_table.file->ha_start_bulk_insert(table->file->stats.records);
++#else
++ /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
++ new_table.file->extra(HA_EXTRA_WRITE_CACHE);
++#endif
++
++ /*
++ copy all old rows from heap table to MyISAM table
++ This is the only code that uses record[1] to read/write but this
++ is safe as this is a temporary MyISAM table without timestamp/autoincrement
++ or partitioning.
++ */
++ while (!table->file->rnd_next(new_table.record[1]))
++ {
++ write_err= new_table.file->ha_write_row(new_table.record[1]);
++ DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
++ if (write_err)
++ goto err;
++ }
++ /* copy row that filled HEAP table */
++ if ((write_err=new_table.file->ha_write_row(table->record[0])))
++ {
++ if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
++ !ignore_last_dupp_key_error)
++ goto err;
++ }
++
++ /* remove heap table and change to use myisam table */
++ (void) table->file->ha_rnd_end();
++ (void) table->file->close(); // This deletes the table !
++ delete table->file;
++ table->file=0;
++ plugin_unlock(0, table->s->db_plugin);
++ share.db_plugin= my_plugin_lock(0, &share.db_plugin);
++ new_table.s= table->s; // Keep old share
++ *table= new_table;
++ *table->s= share;
++
++ table->file->change_table_ptr(table, table->s);
++ table->use_all_columns();
++ if (save_proc_info)
++ thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
++ "Copying to tmp table on disk" : save_proc_info));
++ DBUG_RETURN(0);
++
++ err:
++ DBUG_PRINT("error",("Got error: %d",write_err));
++ table->file->print_error(write_err, MYF(0));
++ (void) table->file->ha_rnd_end();
++ (void) new_table.file->close();
++ err1:
++ new_table.file->ha_delete_table(new_table.s->table_name.str);
++ err2:
++ delete new_table.file;
++ thd_proc_info(thd, save_proc_info);
++ table->mem_root= new_table.mem_root;
++ DBUG_RETURN(1);
++}
++
++
++/**
++ @details
++ Rows produced by a join sweep may end up in a temporary table or be sent
++ to a client. Setup the function of the nested loop join algorithm which
++ handles final fully constructed and matched records.
++
++ @param join join to setup the function for.
++
++ @return
++ end_select function to use. This function can't fail.
++*/
++
++Next_select_func setup_end_select_func(JOIN *join)
++{
++ TABLE *table= join->tmp_table;
++ TMP_TABLE_PARAM *tmp_tbl= &join->tmp_table_param;
++ Next_select_func end_select;
++
++ /* Set up select_end */
++ if (table)
++ {
++ if (table->group && tmp_tbl->sum_func_count &&
++ !tmp_tbl->precomputed_group_by)
++ {
++ if (table->s->keys)
++ {
++ DBUG_PRINT("info",("Using end_update"));
++ end_select=end_update;
++ }
++ else
++ {
++ DBUG_PRINT("info",("Using end_unique_update"));
++ end_select=end_unique_update;
++ }
++ }
++ else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
++ {
++ DBUG_PRINT("info",("Using end_write_group"));
++ end_select=end_write_group;
++ }
++ else
++ {
++ DBUG_PRINT("info",("Using end_write"));
++ end_select=end_write;
++ if (tmp_tbl->precomputed_group_by)
++ {
++ /*
++ A preceding call to create_tmp_table in the case when loose
++ index scan is used guarantees that
++ TMP_TABLE_PARAM::items_to_copy has enough space for the group
++ by functions. It is OK here to use memcpy since we copy
++ Item_sum pointers into an array of Item pointers.
++ */
++ memcpy(tmp_tbl->items_to_copy + tmp_tbl->func_count,
++ join->sum_funcs,
++ sizeof(Item*)*tmp_tbl->sum_func_count);
++ tmp_tbl->items_to_copy[tmp_tbl->func_count+tmp_tbl->sum_func_count]= 0;
++ }
++ }
++ }
++ else
++ {
++ /*
++ Choose method for presenting result to user. Use end_send_group
++ if the query requires grouping (has a GROUP BY clause and/or one or
++ more aggregate functions). Use end_send if the query should not
++ be grouped.
++ */
++ if ((join->sort_and_group ||
++ (join->procedure && join->procedure->flags & PROC_GROUP)) &&
++ !tmp_tbl->precomputed_group_by)
++ end_select= end_send_group;
++ else
++ end_select= end_send;
++ }
++ return end_select;
++}
++
++
++/**
++ Make a join of all tables and write it on socket or to table.
++
++ @retval
++ 0 if ok
++ @retval
++ 1 if error is sent
++ @retval
++ -1 if error should be sent
++*/
++
++static int
++do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
++{
++ int rc= 0;
++ enum_nested_loop_state error= NESTED_LOOP_OK;
++ JOIN_TAB *join_tab= NULL;
++ DBUG_ENTER("do_select");
++
++ join->procedure=procedure;
++ join->tmp_table= table; /* Save for easy recursion */
++ join->fields= fields;
++
++ if (table)
++ {
++ VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
++ empty_record(table);
++ if (table->group && join->tmp_table_param.sum_func_count &&
++ table->s->keys && !table->file->inited)
++ table->file->ha_index_init(0, 0);
++ }
++ /* Set up select_end */
++ Next_select_func end_select= setup_end_select_func(join);
++ if (join->tables)
++ {
++ join->join_tab[join->tables-1].next_select= end_select;
++
++ join_tab=join->join_tab+join->const_tables;
++ }
++ join->send_records=0;
++ if (join->tables == join->const_tables)
++ {
++ /*
++ HAVING will be checked after processing aggregate functions,
++ But WHERE should checkd here (we alredy have read tables)
++ */
++ if (!join->conds || join->conds->val_int())
++ {
++ error= (*end_select)(join, 0, 0);
++ if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
++ error= (*end_select)(join, 0, 1);
++
++ /*
++ If we don't go through evaluate_join_record(), do the counting
++ here. join->send_records is increased on success in end_send(),
++ so we don't touch it here.
++ */
++ join->examined_rows++;
++ join->thd->row_count++;
++ DBUG_ASSERT(join->examined_rows <= 1);
++ }
++ else if (join->send_row_on_empty_set())
++ {
++ List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
++ fields);
++ rc= join->result->send_data(*columns_list);
++ }
++ }
++ else
++ {
++ DBUG_ASSERT(join->tables);
++ error= sub_select(join,join_tab,0);
++ if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
++ error= sub_select(join,join_tab,1);
++ if (error == NESTED_LOOP_QUERY_LIMIT)
++ error= NESTED_LOOP_OK; /* select_limit used */
++ }
++ if (error == NESTED_LOOP_NO_MORE_ROWS)
++ error= NESTED_LOOP_OK;
++
++ if (table == NULL) // If sending data to client
++ /*
++ The following will unlock all cursors if the command wasn't an
++ update command
++ */
++ join->join_free(); // Unlock all cursors
++ if (error == NESTED_LOOP_OK)
++ {
++ /*
++ Sic: this branch works even if rc != 0, e.g. when
++ send_data above returns an error.
++ */
++ if (table == NULL && join->result->send_eof()) // If sending data to client
++ rc= 1; // Don't send error
++ DBUG_PRINT("info",("%ld records output", (long) join->send_records));
++ }
++ else
++ rc= -1;
++ if (table)
++ {
++ int tmp, new_errno= 0;
++ if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
++ {
++ DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed"));
++ new_errno= tmp;
++ }
++ if ((tmp=table->file->ha_index_or_rnd_end()))
++ {
++ DBUG_PRINT("error",("ha_index_or_rnd_end() failed"));
++ new_errno= tmp;
++ }
++ if (new_errno)
++ table->file->print_error(new_errno,MYF(0));
++ }
++#ifndef DBUG_OFF
++ if (rc)
++ {
++ DBUG_PRINT("error",("Error: do_select() failed"));
++ }
++#endif
++ DBUG_RETURN(join->thd->is_error() ? -1 : rc);
++}
++
++
++enum_nested_loop_state
++sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
++{
++ enum_nested_loop_state rc;
++
++ if (end_of_records)
++ {
++ rc= flush_cached_records(join,join_tab,FALSE);
++ if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
++ rc= sub_select(join,join_tab,end_of_records);
++ return rc;
++ }
++ if (join->thd->killed) // If aborted by user
++ {
++ join->thd->send_kill_message();
++ return NESTED_LOOP_KILLED; /* purecov: inspected */
++ }
++ if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
++ {
++ if (!store_record_in_cache(&join_tab->cache))
++ return NESTED_LOOP_OK; // There is more room in cache
++ return flush_cached_records(join,join_tab,FALSE);
++ }
++ rc= flush_cached_records(join, join_tab, TRUE);
++ if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
++ rc= sub_select(join, join_tab, end_of_records);
++ return rc;
++}
++
++/**
++ Retrieve records ends with a given beginning from the result of a join.
++
++ For a given partial join record consisting of records from the tables
++ preceding the table join_tab in the execution plan, the function
++ retrieves all matching full records from the result set and
++ send them to the result set stream.
++
++ @note
++ The function effectively implements the final (n-k) nested loops
++ of nested loops join algorithm, where k is the ordinal number of
++ the join_tab table and n is the total number of tables in the join query.
++ It performs nested loops joins with all conjunctive predicates from
++ the where condition pushed as low to the tables as possible.
++ E.g. for the query
++ @code
++ SELECT * FROM t1,t2,t3
++ WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
++ @endcode
++ the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1,
++ given the selected plan prescribes to nest retrievals of the
++ joined tables in the following order: t1,t2,t3.
++ A pushed down predicate are attached to the table which it pushed to,
++ at the field join_tab->select_cond.
++ When executing a nested loop of level k the function runs through
++ the rows of 'join_tab' and for each row checks the pushed condition
++ attached to the table.
++ If it is false the function moves to the next row of the
++ table. If the condition is true the function recursively executes (n-k-1)
++ remaining embedded nested loops.
++ The situation becomes more complicated if outer joins are involved in
++ the execution plan. In this case the pushed down predicates can be
++ checked only at certain conditions.
++ Suppose for the query
++ @code
++ SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
++ WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
++ @endcode
++ the optimizer has chosen a plan with the table order t1,t2,t3.
++ The predicate P1=t1>2 will be pushed down to the table t1, while the
++ predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table
++ t2. But the second predicate can not be unconditionally tested right
++ after a row from t2 has been read. This can be done only after the
++ first row with t3.a=t1.a has been encountered.
++ Thus, the second predicate P2 is supplied with a guarded value that are
++ stored in the field 'found' of the first inner table for the outer join
++ (table t2). When the first row with t3.a=t1.a for the current row
++ of table t1 appears, the value becomes true. For now on the predicate
++ is evaluated immediately after the row of table t2 has been read.
++ When the first row with t3.a=t1.a has been encountered all
++ conditions attached to the inner tables t2,t3 must be evaluated.
++ Only when all of them are true the row is sent to the output stream.
++ If not, the function returns to the lowest nest level that has a false
++ attached condition.
++ The predicates from on expressions are also pushed down. If in the
++ the above example the on expression were (t3.a=t1.a AND t2.a=t1.a),
++ then t1.a=t2.a would be pushed down to table t2, and without any
++ guard.
++ If after the run through all rows of table t2, the first inner table
++ for the outer join operation, it turns out that no matches are
++ found for the current row of t1, then current row from table t1
++ is complemented by nulls for t2 and t3. Then the pushed down predicates
++ are checked for the composed row almost in the same way as it had
++ been done for the first row with a match. The only difference is
++ the predicates from on expressions are not checked.
++
++ @par
++ @b IMPLEMENTATION
++ @par
++ The function forms output rows for a current partial join of k
++ tables tables recursively.
++ For each partial join record ending with a certain row from
++ join_tab it calls sub_select that builds all possible matching
++ tails from the result set.
++ To be able check predicates conditionally items of the class
++ Item_func_trig_cond are employed.
++ An object of this class is constructed from an item of class COND
++ and a pointer to a guarding boolean variable.
++ When the value of the guard variable is true the value of the object
++ is the same as the value of the predicate, otherwise it's just returns
++ true.
++ To carry out a return to a nested loop level of join table t the pointer
++ to t is remembered in the field 'return_tab' of the join structure.
++ Consider the following query:
++ @code
++ SELECT * FROM t1,
++ LEFT JOIN
++ (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a)
++ ON t4.a=t2.a
++ WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL)
++ @endcode
++ Suppose the chosen execution plan dictates the order t1,t2,t3,t4,t5
++ and suppose for a given joined rows from tables t1,t2,t3 there are
++ no rows in the result set yet.
++ When first row from t5 that satisfies the on condition
++ t5.a=t3.a is found, the pushed down predicate t4.b=2 OR t4.b IS NULL
++ becomes 'activated', as well the predicate t4.a=t2.a. But
++ the predicate (t2.b=5 OR t2.b IS NULL) can not be checked until
++ t4.a=t2.a becomes true.
++ In order not to re-evaluate the predicates that were already evaluated
++ as attached pushed down predicates, a pointer to the the first
++ most inner unmatched table is maintained in join_tab->first_unmatched.
++ Thus, when the first row from t5 with t5.a=t3.a is found
++ this pointer for t5 is changed from t4 to t2.
++
++ @par
++ @b STRUCTURE @b NOTES
++ @par
++ join_tab->first_unmatched points always backwards to the first inner
++ table of the embedding nested join, if any.
++
++ @param join pointer to the structure providing all context info for
++ the query
++ @param join_tab the first next table of the execution plan to be retrieved
++ @param end_records true when we need to perform final steps of retrival
++
++ @return
++ return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
++*/
++
++enum_nested_loop_state
++sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
++{
++ join_tab->table->null_row=0;
++ if (end_of_records)
++ return (*join_tab->next_select)(join,join_tab+1,end_of_records);
++
++ int error;
++ enum_nested_loop_state rc;
++ READ_RECORD *info= &join_tab->read_record;
++
++ if (join->resume_nested_loop)
++ {
++ /* If not the last table, plunge down the nested loop */
++ if (join_tab < join->join_tab + join->tables - 1)
++ rc= (*join_tab->next_select)(join, join_tab + 1, 0);
++ else
++ {
++ join->resume_nested_loop= FALSE;
++ rc= NESTED_LOOP_OK;
++ }
++ }
++ else
++ {
++ join->return_tab= join_tab;
++
++ if (join_tab->last_inner)
++ {
++ /* join_tab is the first inner table for an outer join operation. */
++
++ /* Set initial state of guard variables for this table.*/
++ join_tab->found=0;
++ join_tab->not_null_compl= 1;
++
++ /* Set first_unmatched for the last inner table of this group */
++ join_tab->last_inner->first_unmatched= join_tab;
++ }
++ join->thd->row_count= 0;
++
++ error= (*join_tab->read_first_record)(join_tab);
++ rc= evaluate_join_record(join, join_tab, error);
++ }
++
++ while (rc == NESTED_LOOP_OK)
++ {
++ error= info->read_record(info);
++ rc= evaluate_join_record(join, join_tab, error);
++ }
++
++ if (rc == NESTED_LOOP_NO_MORE_ROWS &&
++ join_tab->last_inner && !join_tab->found)
++ rc= evaluate_null_complemented_join_record(join, join_tab);
++
++ if (rc == NESTED_LOOP_NO_MORE_ROWS)
++ rc= NESTED_LOOP_OK;
++ return rc;
++}
++
++
++/**
++ Process one record of the nested loop join.
++
++ This function will evaluate parts of WHERE/ON clauses that are
++ applicable to the partial record on hand and in case of success
++ submit this record to the next level of the nested loop.
++*/
++
++static enum_nested_loop_state
++evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
++ int error)
++{
++ bool not_used_in_distinct=join_tab->not_used_in_distinct;
++ ha_rows found_records=join->found_records;
++ COND *select_cond= join_tab->select_cond;
++ bool select_cond_result= TRUE;
++
++ if (error > 0 || (join->thd->is_error())) // Fatal error
++ return NESTED_LOOP_ERROR;
++ if (error < 0)
++ return NESTED_LOOP_NO_MORE_ROWS;
++ if (join->thd->killed) // Aborted by user
++ {
++ join->thd->send_kill_message();
++ return NESTED_LOOP_KILLED; /* purecov: inspected */
++ }
++ DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
++
++ if (select_cond)
++ {
++ select_cond_result= test(select_cond->val_int());
++
++ /* check for errors evaluating the condition */
++ if (join->thd->is_error())
++ return NESTED_LOOP_ERROR;
++ }
++
++ if (!select_cond || select_cond_result)
++ {
++ /*
++ There is no select condition or the attached pushed down
++ condition is true => a match is found.
++ */
++ bool found= 1;
++ while (join_tab->first_unmatched && found)
++ {
++ /*
++ The while condition is always false if join_tab is not
++ the last inner join table of an outer join operation.
++ */
++ JOIN_TAB *first_unmatched= join_tab->first_unmatched;
++ /*
++ Mark that a match for current outer table is found.
++ This activates push down conditional predicates attached
++ to the all inner tables of the outer join.
++ */
++ first_unmatched->found= 1;
++ for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
++ {
++ if (tab->table->reginfo.not_exists_optimize)
++ return NESTED_LOOP_NO_MORE_ROWS;
++ /* Check all predicates that has just been activated. */
++ /*
++ Actually all predicates non-guarded by first_unmatched->found
++ will be re-evaluated again. It could be fixed, but, probably,
++ it's not worth doing now.
++ */
++ if (tab->select_cond && !tab->select_cond->val_int())
++ {
++ /* The condition attached to table tab is false */
++ if (tab == join_tab)
++ found= 0;
++ else
++ {
++ /*
++ Set a return point if rejected predicate is attached
++ not to the last table of the current nest level.
++ */
++ join->return_tab= tab;
++ return NESTED_LOOP_OK;
++ }
++ }
++ }
++ /*
++ Check whether join_tab is not the last inner table
++ for another embedding outer join.
++ */
++ if ((first_unmatched= first_unmatched->first_upper) &&
++ first_unmatched->last_inner != join_tab)
++ first_unmatched= 0;
++ join_tab->first_unmatched= first_unmatched;
++ }
++
++ /*
++ It was not just a return to lower loop level when one
++ of the newly activated predicates is evaluated as false
++ (See above join->return_tab= tab).
++ */
++ join->examined_rows++;
++ join->thd->row_count++;
++ DBUG_PRINT("counts", ("join->examined_rows++: %lu",
++ (ulong) join->examined_rows));
++
++ if (found)
++ {
++ enum enum_nested_loop_state rc;
++ /* A match from join_tab is found for the current partial join. */
++ rc= (*join_tab->next_select)(join, join_tab+1, 0);
++ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
++ return rc;
++ if (join->return_tab < join_tab)
++ return NESTED_LOOP_OK;
++ /*
++ Test if this was a SELECT DISTINCT query on a table that
++ was not in the field list; In this case we can abort if
++ we found a row, as no new rows can be added to the result.
++ */
++ if (not_used_in_distinct && found_records != join->found_records)
++ return NESTED_LOOP_NO_MORE_ROWS;
++ }
++ else
++ join_tab->read_record.unlock_row(join_tab);
++ }
++ else
++ {
++ /*
++ The condition pushed down to the table join_tab rejects all rows
++ with the beginning coinciding with the current partial join.
++ */
++ join->examined_rows++;
++ join->thd->row_count++;
++ join_tab->read_record.unlock_row(join_tab);
++ }
++ return NESTED_LOOP_OK;
++}
++
++
++/**
++
++ @details
++ Construct a NULL complimented partial join record and feed it to the next
++ level of the nested loop. This function is used in case we have
++ an OUTER join and no matching record was found.
++*/
++
++static enum_nested_loop_state
++evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
++{
++ /*
++ The table join_tab is the first inner table of a outer join operation
++ and no matches has been found for the current outer row.
++ */
++ JOIN_TAB *last_inner_tab= join_tab->last_inner;
++ /* Cache variables for faster loop */
++ COND *select_cond;
++ for ( ; join_tab <= last_inner_tab ; join_tab++)
++ {
++ /* Change the the values of guard predicate variables. */
++ join_tab->found= 1;
++ join_tab->not_null_compl= 0;
++ /* The outer row is complemented by nulls for each inner tables */
++ restore_record(join_tab->table,s->default_values); // Make empty record
++ mark_as_null_row(join_tab->table); // For group by without error
++ select_cond= join_tab->select_cond;
++ /* Check all attached conditions for inner table rows. */
++ if (select_cond && !select_cond->val_int())
++ return NESTED_LOOP_OK;
++ }
++ join_tab--;
++ /*
++ The row complemented by nulls might be the first row
++ of embedding outer joins.
++ If so, perform the same actions as in the code
++ for the first regular outer join row above.
++ */
++ for ( ; ; )
++ {
++ JOIN_TAB *first_unmatched= join_tab->first_unmatched;
++ if ((first_unmatched= first_unmatched->first_upper) &&
++ first_unmatched->last_inner != join_tab)
++ first_unmatched= 0;
++ join_tab->first_unmatched= first_unmatched;
++ if (!first_unmatched)
++ break;
++ first_unmatched->found= 1;
++ for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
++ {
++ if (tab->select_cond && !tab->select_cond->val_int())
++ {
++ join->return_tab= tab;
++ return NESTED_LOOP_OK;
++ }
++ }
++ }
++ /*
++ The row complemented by nulls satisfies all conditions
++ attached to inner tables.
++ Send the row complemented by nulls to be joined with the
++ remaining tables.
++ */
++ return (*join_tab->next_select)(join, join_tab+1, 0);
++}
++
++
++static enum_nested_loop_state
++flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
++{
++ enum_nested_loop_state rc= NESTED_LOOP_OK;
++ int error;
++ READ_RECORD *info;
++
++ join_tab->table->null_row= 0;
++ if (!join_tab->cache.records)
++ return NESTED_LOOP_OK; /* Nothing to do */
++ if (skip_last)
++ (void) store_record_in_cache(&join_tab->cache); // Must save this for later
++ if (join_tab->use_quick == 2)
++ {
++ if (join_tab->select->quick)
++ { /* Used quick select last. reset it */
++ delete join_tab->select->quick;
++ join_tab->select->quick=0;
++ }
++ }
++ /* read through all records */
++ if ((error=join_init_read_record(join_tab)))
++ {
++ reset_cache_write(&join_tab->cache);
++ return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
++ }
++
++ for (JOIN_TAB *tmp=join->join_tab; tmp != join_tab ; tmp++)
++ {
++ tmp->status=tmp->table->status;
++ tmp->table->status=0;
++ }
++
++ info= &join_tab->read_record;
++ do
++ {
++ if (join->thd->killed)
++ {
++ join->thd->send_kill_message();
++ return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
++ }
++ SQL_SELECT *select=join_tab->select;
++ if (rc == NESTED_LOOP_OK)
++ {
++ bool skip_record= FALSE;
++ if (join_tab->cache.select &&
++ join_tab->cache.select->skip_record(join->thd, &skip_record))
++ {
++ reset_cache_write(&join_tab->cache);
++ return NESTED_LOOP_ERROR;
++ }
++
++ if (!skip_record)
++ {
++ uint i;
++ reset_cache_read(&join_tab->cache);
++ for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
++ {
++ read_cached_record(join_tab);
++ skip_record= FALSE;
++ if (select && select->skip_record(join->thd, &skip_record))
++ {
++ reset_cache_write(&join_tab->cache);
++ return NESTED_LOOP_ERROR;
++ }
++ if (!skip_record)
++ {
++ rc= (join_tab->next_select)(join,join_tab+1,0);
++ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
++ {
++ reset_cache_write(&join_tab->cache);
++ return rc;
++ }
++ }
++ }
++ }
++ }
++ } while (!(error=info->read_record(info)));
++
++ if (skip_last)
++ read_cached_record(join_tab); // Restore current record
++ reset_cache_write(&join_tab->cache);
++ if (error > 0) // Fatal error
++ return NESTED_LOOP_ERROR; /* purecov: inspected */
++ for (JOIN_TAB *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
++ tmp2->table->status=tmp2->status;
++ return NESTED_LOOP_OK;
++}
++
++
++/*****************************************************************************
++ The different ways to read a record
++ Returns -1 if row was not found, 0 if row was found and 1 on errors
++*****************************************************************************/
++
++/** Help function when we get some an error from the table handler. */
++
++int report_error(TABLE *table, int error)
++{
++ if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
++ {
++ table->status= STATUS_GARBAGE;
++ return -1; // key not found; ok
++ }
++ /*
++ Locking reads can legally return also these errors, do not
++ print them to the .err log
++ */
++ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
++ sql_print_error("Got error %d when reading table '%s'",
++ error, table->s->path.str);
++ table->file->print_error(error,MYF(0));
++ return 1;
++}
++
++
++int safe_index_read(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++ if ((error=table->file->index_read_map(table->record[0],
++ tab->ref.key_buff,
++ make_prev_keypart_map(tab->ref.key_parts),
++ HA_READ_KEY_EXACT)))
++ return report_error(table, error);
++ return 0;
++}
++
++
++static int
++join_read_const_table(JOIN_TAB *tab, POSITION *pos)
++{
++ int error;
++ DBUG_ENTER("join_read_const_table");
++ TABLE *table=tab->table;
++ table->const_table=1;
++ table->null_row=0;
++ table->status=STATUS_NO_RECORD;
++
++ if (tab->type == JT_SYSTEM)
++ {
++ if ((error=join_read_system(tab)))
++ { // Info for DESCRIBE
++ tab->info="const row not found";
++ /* Mark for EXPLAIN that the row was not found */
++ pos->records_read=0.0;
++ pos->ref_depend_map= 0;
++ if (!table->maybe_null || error > 0)
++ DBUG_RETURN(error);
++ }
++ }
++ else
++ {
++ if (!table->key_read && table->covering_keys.is_set(tab->ref.key) &&
++ !table->no_keyread &&
++ (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
++ {
++ table->set_keyread(TRUE);
++ tab->index= tab->ref.key;
++ }
++ error=join_read_const(tab);
++ table->set_keyread(FALSE);
++ if (error)
++ {
++ tab->info="unique row not found";
++ /* Mark for EXPLAIN that the row was not found */
++ pos->records_read=0.0;
++ pos->ref_depend_map= 0;
++ if (!table->maybe_null || error > 0)
++ DBUG_RETURN(error);
++ }
++ }
++ if (*tab->on_expr_ref && !table->null_row)
++ {
++ if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
++ mark_as_null_row(table);
++ }
++ if (!table->null_row)
++ table->maybe_null=0;
++
++ /* Check appearance of new constant items in Item_equal objects */
++ JOIN *join= tab->join;
++ if (join->conds)
++ update_const_equal_items(join->conds, tab);
++ TABLE_LIST *tbl;
++ for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
++ {
++ TABLE_LIST *embedded;
++ TABLE_LIST *embedding= tbl;
++ do
++ {
++ embedded= embedding;
++ if (embedded->on_expr)
++ update_const_equal_items(embedded->on_expr, tab);
++ embedding= embedded->embedding;
++ }
++ while (embedding &&
++ embedding->nested_join->join_list.head() == embedded);
++ }
++
++ DBUG_RETURN(0);
++}
++
++
++static int
++join_read_system(JOIN_TAB *tab)
++{
++ TABLE *table= tab->table;
++ int error;
++ if (table->status & STATUS_GARBAGE) // If first read
++ {
++ if ((error=table->file->read_first_row(table->record[0],
++ table->s->primary_key)))
++ {
++ if (error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++ mark_as_null_row(tab->table);
++ empty_record(table); // Make empty record
++ return -1;
++ }
++ store_record(table,record[1]);
++ }
++ else if (!table->status) // Only happens with left join
++ restore_record(table,record[1]); // restore old record
++ table->null_row=0;
++ return table->status ? -1 : 0;
++}
++
++
++/**
++ Read a table when there is at most one matching row.
++
++ @param tab Table to read
++
++ @retval
++ 0 Row was found
++ @retval
++ -1 Row was not found
++ @retval
++ 1 Got an error (other than row not found) during read
++*/
++
++static int
++join_read_const(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++ if (table->status & STATUS_GARBAGE) // If first read
++ {
++ table->status= 0;
++ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
++ error=HA_ERR_KEY_NOT_FOUND;
++ else
++ {
++ error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
++ (uchar*) tab->ref.key_buff,
++ make_prev_keypart_map(tab->ref.key_parts),
++ HA_READ_KEY_EXACT);
++ }
++ if (error)
++ {
++ table->status= STATUS_NOT_FOUND;
++ mark_as_null_row(tab->table);
++ empty_record(table);
++ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++ return -1;
++ }
++ store_record(table,record[1]);
++ }
++ else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
++ {
++ table->status=0;
++ restore_record(table,record[1]); // restore old record
++ }
++ table->null_row=0;
++ return table->status ? -1 : 0;
++}
++
++
++static int
++join_read_key(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++
++ if (!table->file->inited)
++ {
++ table->file->ha_index_init(tab->ref.key, tab->sorted);
++ }
++ if (cmp_buffer_with_ref(tab) ||
++ (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
++ {
++ if (tab->ref.key_err)
++ {
++ table->status=STATUS_NOT_FOUND;
++ return -1;
++ }
++ /*
++ Moving away from the current record. Unlock the row
++ in the handler if it did not match the partial WHERE.
++ */
++ if (tab->ref.has_record && tab->ref.use_count == 0)
++ {
++ tab->read_record.file->unlock_row();
++ tab->ref.has_record= FALSE;
++ }
++ error=table->file->index_read_map(table->record[0],
++ tab->ref.key_buff,
++ make_prev_keypart_map(tab->ref.key_parts),
++ HA_READ_KEY_EXACT);
++ if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++
++ if (! error)
++ {
++ tab->ref.has_record= TRUE;
++ tab->ref.use_count= 1;
++ }
++ }
++ else if (table->status == 0)
++ {
++ DBUG_ASSERT(tab->ref.has_record);
++ tab->ref.use_count++;
++ }
++ table->null_row=0;
++ return table->status ? -1 : 0;
++}
++
++
++/**
++ Since join_read_key may buffer a record, do not unlock
++ it if it was not used in this invocation of join_read_key().
++ Only count locks, thus remembering if the record was left unused,
++ and unlock already when pruning the current value of
++ TABLE_REF buffer.
++ @sa join_read_key()
++*/
++
++static void
++join_read_key_unlock_row(st_join_table *tab)
++{
++ DBUG_ASSERT(tab->ref.use_count);
++ if (tab->ref.use_count)
++ tab->ref.use_count--;
++}
++
++/*
++ ref access method implementation: "read_first" function
++
++ SYNOPSIS
++ join_read_always_key()
++ tab JOIN_TAB of the accessed table
++
++ DESCRIPTION
++ This is "read_fist" function for the "ref" access method.
++
++ The functon must leave the index initialized when it returns.
++ ref_or_null access implementation depends on that.
++
++ RETURN
++ 0 - Ok
++ -1 - Row not found
++ 1 - Error
++*/
++
++static int
++join_read_always_key(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++
++ /* Initialize the index first */
++ if (!table->file->inited)
++ table->file->ha_index_init(tab->ref.key, tab->sorted);
++
++ /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
++ for (uint i= 0 ; i < tab->ref.key_parts ; i++)
++ {
++ if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
++ return -1;
++ }
++
++ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
++ return -1;
++ if ((error=table->file->index_read_map(table->record[0],
++ tab->ref.key_buff,
++ make_prev_keypart_map(tab->ref.key_parts),
++ HA_READ_KEY_EXACT)))
++ {
++ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++ return -1; /* purecov: inspected */
++ }
++ return 0;
++}
++
++
++/**
++ This function is used when optimizing away ORDER BY in
++ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC.
++*/
++
++static int
++join_read_last_key(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++
++ if (!table->file->inited)
++ table->file->ha_index_init(tab->ref.key, tab->sorted);
++ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
++ return -1;
++ if ((error=table->file->index_read_last_map(table->record[0],
++ tab->ref.key_buff,
++ make_prev_keypart_map(tab->ref.key_parts))))
++ {
++ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++ return -1; /* purecov: inspected */
++ }
++ return 0;
++}
++
++
++ /* ARGSUSED */
++static int
++join_no_more_records(READ_RECORD *info __attribute__((unused)))
++{
++ return -1;
++}
++
++
++static int
++join_read_next_same(READ_RECORD *info)
++{
++ int error;
++ TABLE *table= info->table;
++ JOIN_TAB *tab=table->reginfo.join_tab;
++
++ if ((error=table->file->index_next_same(table->record[0],
++ tab->ref.key_buff,
++ tab->ref.key_length)))
++ {
++ if (error != HA_ERR_END_OF_FILE)
++ return report_error(table, error);
++ table->status= STATUS_GARBAGE;
++ return -1;
++ }
++ return 0;
++}
++
++
++static int
++join_read_prev_same(READ_RECORD *info)
++{
++ int error;
++ TABLE *table= info->table;
++ JOIN_TAB *tab=table->reginfo.join_tab;
++
++ if ((error=table->file->index_prev(table->record[0])))
++ return report_error(table, error);
++ if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
++ tab->ref.key_length))
++ {
++ table->status=STATUS_NOT_FOUND;
++ error= -1;
++ }
++ return error;
++}
++
++
++static int
++join_init_quick_read_record(JOIN_TAB *tab)
++{
++ if (test_if_quick_select(tab) == -1)
++ return -1; /* No possible records */
++ return join_init_read_record(tab);
++}
++
++
++int rr_sequential(READ_RECORD *info);
++int init_read_record_seq(JOIN_TAB *tab)
++{
++ tab->read_record.read_record= rr_sequential;
++ if (tab->read_record.file->ha_rnd_init(1))
++ return 1;
++ return (*tab->read_record.read_record)(&tab->read_record);
++}
++
++static int
++test_if_quick_select(JOIN_TAB *tab)
++{
++ delete tab->select->quick;
++ tab->select->quick=0;
++ return tab->select->test_quick_select(tab->join->thd, tab->keys,
++ (table_map) 0, HA_POS_ERROR, 0);
++}
++
++
++static int
++join_init_read_record(JOIN_TAB *tab)
++{
++ if (tab->select && tab->select->quick && tab->select->quick->reset())
++ return 1;
++ init_read_record(&tab->read_record, tab->join->thd, tab->table,
++ tab->select,1,1, FALSE);
++ return (*tab->read_record.read_record)(&tab->read_record);
++}
++
++
++static int
++join_read_first(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table=tab->table;
++ if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
++ table->set_keyread(TRUE);
++ tab->table->status=0;
++ tab->read_record.read_record=join_read_next;
++ tab->read_record.table=table;
++ tab->read_record.file=table->file;
++ tab->read_record.index=tab->index;
++ tab->read_record.record=table->record[0];
++ if (!table->file->inited)
++ table->file->ha_index_init(tab->index, tab->sorted);
++ if ((error=tab->table->file->index_first(tab->table->record[0])))
++ {
++ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
++ report_error(table, error);
++ return -1;
++ }
++ return 0;
++}
++
++
++static int
++join_read_next(READ_RECORD *info)
++{
++ int error;
++ if ((error=info->file->index_next(info->record)))
++ return report_error(info->table, error);
++ return 0;
++}
++
++
++static int
++join_read_last(JOIN_TAB *tab)
++{
++ TABLE *table=tab->table;
++ int error;
++ if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
++ table->set_keyread(TRUE);
++ tab->table->status=0;
++ tab->read_record.read_record=join_read_prev;
++ tab->read_record.table=table;
++ tab->read_record.file=table->file;
++ tab->read_record.index=tab->index;
++ tab->read_record.record=table->record[0];
++ if (!table->file->inited)
++ table->file->ha_index_init(tab->index, 1);
++ if ((error= tab->table->file->index_last(tab->table->record[0])))
++ return report_error(table, error);
++ return 0;
++}
++
++
++static int
++join_read_prev(READ_RECORD *info)
++{
++ int error;
++ if ((error= info->file->index_prev(info->record)))
++ return report_error(info->table, error);
++ return 0;
++}
++
++
++static int
++join_ft_read_first(JOIN_TAB *tab)
++{
++ int error;
++ TABLE *table= tab->table;
++
++ if (!table->file->inited)
++ table->file->ha_index_init(tab->ref.key, 1);
++#if NOT_USED_YET
++ /* as ft-key doesn't use store_key's, see also FT_SELECT::init() */
++ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
++ return -1;
++#endif
++ table->file->ft_init();
++
++ if ((error= table->file->ft_read(table->record[0])))
++ return report_error(table, error);
++ return 0;
++}
++
++static int
++join_ft_read_next(READ_RECORD *info)
++{
++ int error;
++ if ((error= info->file->ft_read(info->table->record[0])))
++ return report_error(info->table, error);
++ return 0;
++}
++
++
++/**
++ Reading of key with key reference and one part that may be NULL.
++*/
++
++int
++join_read_always_key_or_null(JOIN_TAB *tab)
++{
++ int res;
++
++ /* First read according to key which is NOT NULL */
++ *tab->ref.null_ref_key= 0; // Clear null byte
++ if ((res= join_read_always_key(tab)) >= 0)
++ return res;
++
++ /* Then read key with null value */
++ *tab->ref.null_ref_key= 1; // Set null byte
++ return safe_index_read(tab);
++}
++
++
++int
++join_read_next_same_or_null(READ_RECORD *info)
++{
++ int error;
++ if ((error= join_read_next_same(info)) >= 0)
++ return error;
++ JOIN_TAB *tab= info->table->reginfo.join_tab;
++
++ /* Test if we have already done a read after null key */
++ if (*tab->ref.null_ref_key)
++ return -1; // All keys read
++ *tab->ref.null_ref_key= 1; // Set null byte
++ return safe_index_read(tab); // then read null keys
++}
++
++
++/*****************************************************************************
++ DESCRIPTION
++ Functions that end one nested loop iteration. Different functions
++ are used to support GROUP BY clause and to redirect records
++ to a table (e.g. in case of SELECT into a temporary table) or to the
++ network client.
++
++ RETURN VALUES
++ NESTED_LOOP_OK - the record has been successfully handled
++ NESTED_LOOP_ERROR - a fatal error (like table corruption)
++ was detected
++ NESTED_LOOP_KILLED - thread shutdown was requested while processing
++ the record
++ NESTED_LOOP_QUERY_LIMIT - the record has been successfully handled;
++ additionally, the nested loop produced the
++ number of rows specified in the LIMIT clause
++ for the query
++ NESTED_LOOP_CURSOR_LIMIT - the record has been successfully handled;
++ additionally, there is a cursor and the nested
++ loop algorithm produced the number of rows
++ that is specified for current cursor fetch
++ operation.
++ All return values except NESTED_LOOP_OK abort the nested loop.
++*****************************************************************************/
++
++/* ARGSUSED */
++static enum_nested_loop_state
++end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ DBUG_ENTER("end_send");
++ if (!end_of_records)
++ {
++ int error;
++ if (join->having && join->having->val_int() == 0)
++ DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
++ error=0;
++ if (join->procedure)
++ error=join->procedure->send_row(join->procedure_fields_list);
++ else if (join->do_send_rows)
++ error=join->result->send_data(*join->fields);
++ if (error)
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ if (++join->send_records >= join->unit->select_limit_cnt &&
++ join->do_send_rows)
++ {
++ if (join->select_options & OPTION_FOUND_ROWS)
++ {
++ JOIN_TAB *jt=join->join_tab;
++ if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
++ && !join->send_group_parts && !join->having && !jt->select_cond &&
++ !(jt->select && jt->select->quick) &&
++ (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
++ (jt->ref.key < 0))
++ {
++ /* Join over all rows in table; Return number of found rows */
++ TABLE *table=jt->table;
++
++ join->select_options ^= OPTION_FOUND_ROWS;
++ if (table->sort.record_pointers ||
++ (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
++ {
++ /* Using filesort */
++ join->send_records= table->sort.found_records;
++ }
++ else
++ {
++ table->file->info(HA_STATUS_VARIABLE);
++ join->send_records= table->file->stats.records;
++ }
++ }
++ else
++ {
++ join->do_send_rows= 0;
++ if (join->unit->fake_select_lex)
++ join->unit->fake_select_lex->select_limit= 0;
++ DBUG_RETURN(NESTED_LOOP_OK);
++ }
++ }
++ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
++ }
++ else if (join->send_records >= join->fetch_limit)
++ {
++ /*
++ There is a server side cursor and all rows for
++ this fetch request are sent.
++ */
++ DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT);
++ }
++ }
++ else
++ {
++ if (join->procedure && join->procedure->end_of_records())
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ }
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++
++ /* ARGSUSED */
++static enum_nested_loop_state
++end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ int idx= -1;
++ enum_nested_loop_state ok_code= NESTED_LOOP_OK;
++ DBUG_ENTER("end_send_group");
++
++ if (!join->first_record || end_of_records ||
++ (idx=test_if_group_changed(join->group_fields)) >= 0)
++ {
++ if (join->first_record ||
++ (end_of_records && !join->group && !join->group_optimized_away))
++ {
++ if (join->procedure)
++ join->procedure->end_group();
++ if (idx < (int) join->send_group_parts)
++ {
++ int error=0;
++ if (join->procedure)
++ {
++ if (join->having && join->having->val_int() == 0)
++ error= -1; // Didn't satisfy having
++ else
++ {
++ if (join->do_send_rows)
++ error=join->procedure->send_row(*join->fields) ? 1 : 0;
++ join->send_records++;
++ }
++ if (end_of_records && join->procedure->end_of_records())
++ error= 1; // Fatal error
++ }
++ else
++ {
++ if (!join->first_record)
++ {
++ List_iterator_fast<Item> it(*join->fields);
++ Item *item;
++ /* No matching rows for group function */
++ join->clear();
++
++ while ((item= it++))
++ item->no_rows_in_result();
++ }
++ if (join->having && join->having->val_int() == 0)
++ error= -1; // Didn't satisfy having
++ else
++ {
++ if (join->do_send_rows)
++ error=join->result->send_data(*join->fields) ? 1 : 0;
++ join->send_records++;
++ }
++ if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
++ {
++ if (join->rollup_send_data((uint) (idx+1)))
++ error= 1;
++ }
++ }
++ if (error > 0)
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ if (join->send_records >= join->unit->select_limit_cnt &&
++ join->do_send_rows)
++ {
++ if (!(join->select_options & OPTION_FOUND_ROWS))
++ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
++ join->do_send_rows=0;
++ join->unit->select_limit_cnt = HA_POS_ERROR;
++ }
++ else if (join->send_records >= join->fetch_limit)
++ {
++ /*
++ There is a server side cursor and all rows
++ for this fetch request are sent.
++ */
++ /*
++ Preventing code duplication. When finished with the group reset
++ the group functions and copy_fields. We fall through. bug #11904
++ */
++ ok_code= NESTED_LOOP_CURSOR_LIMIT;
++ }
++ }
++ }
++ else
++ {
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ join->first_record=1;
++ VOID(test_if_group_changed(join->group_fields));
++ }
++ if (idx < (int) join->send_group_parts)
++ {
++ /*
++ This branch is executed also for cursors which have finished their
++ fetch limit - the reason for ok_code.
++ */
++ copy_fields(&join->tmp_table_param);
++ if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ if (join->procedure)
++ join->procedure->add();
++ DBUG_RETURN(ok_code);
++ }
++ }
++ if (update_sum_func(join->sum_funcs))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ if (join->procedure)
++ join->procedure->add();
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++
++ /* ARGSUSED */
++static enum_nested_loop_state
++end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ TABLE *table=join->tmp_table;
++ DBUG_ENTER("end_write");
++
++ if (join->thd->killed) // Aborted by user
++ {
++ join->thd->send_kill_message();
++ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
++ }
++ if (!end_of_records)
++ {
++ copy_fields(&join->tmp_table_param);
++ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++
++#ifdef TO_BE_DELETED
++ if (!table->uniques) // If not unique handling
++ {
++ /* Copy null values from group to row */
++ ORDER *group;
++ for (group=table->group ; group ; group=group->next)
++ {
++ Item *item= *group->item;
++ if (item->maybe_null)
++ {
++ Field *field=item->get_tmp_table_field();
++ field->ptr[-1]= (uchar) (field->is_null() ? 1 : 0);
++ }
++ }
++ }
++#endif
++ if (!join->having || join->having->val_int())
++ {
++ int error;
++ join->found_records++;
++ if ((error=table->file->ha_write_row(table->record[0])))
++ {
++ if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
++ goto end;
++ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
++ error,1))
++ DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
++ table->s->uniques=0; // To ensure rows are the same
++ }
++ if (++join->send_records >= join->tmp_table_param.end_write_records &&
++ join->do_send_rows)
++ {
++ if (!(join->select_options & OPTION_FOUND_ROWS))
++ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
++ join->do_send_rows=0;
++ join->unit->select_limit_cnt = HA_POS_ERROR;
++ DBUG_RETURN(NESTED_LOOP_OK);
++ }
++ }
++ }
++end:
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++/* ARGSUSED */
++/** Group by searching after group record and updating it if possible. */
++
++static enum_nested_loop_state
++end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ TABLE *table=join->tmp_table;
++ ORDER *group;
++ int error;
++ DBUG_ENTER("end_update");
++
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ if (join->thd->killed) // Aborted by user
++ {
++ join->thd->send_kill_message();
++ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
++ }
++
++ join->found_records++;
++ copy_fields(&join->tmp_table_param); // Groups are copied twice.
++ /* Make a key of group index */
++ for (group=table->group ; group ; group=group->next)
++ {
++ Item *item= *group->item;
++ item->save_org_in_field(group->field);
++ /* Store in the used key if the field was 0 */
++ if (item->maybe_null)
++ group->buff[-1]= (char) group->field->is_null();
++ }
++ if (!table->file->index_read_map(table->record[1],
++ join->tmp_table_param.group_buff,
++ HA_WHOLE_KEY,
++ HA_READ_KEY_EXACT))
++ { /* Update old record */
++ restore_record(table,record[1]);
++ update_tmptable_sum_func(join->sum_funcs,table);
++ if ((error=table->file->ha_update_row(table->record[1],
++ table->record[0])))
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ }
++ DBUG_RETURN(NESTED_LOOP_OK);
++ }
++
++ /*
++ Copy null bits from group key to table
++ We can't copy all data as the key may have different format
++ as the row data (for example as with VARCHAR keys)
++ */
++ KEY_PART_INFO *key_part;
++ for (group=table->group,key_part=table->key_info[0].key_part;
++ group ;
++ group=group->next,key_part++)
++ {
++ if (key_part->null_bit)
++ memcpy(table->record[0]+key_part->offset, group->buff, 1);
++ }
++ init_tmptable_sum_functions(join->sum_funcs);
++ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ if ((error=table->file->ha_write_row(table->record[0])))
++ {
++ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
++ error, 0))
++ DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
++ /* Change method to update rows */
++ table->file->ha_index_init(0, 0);
++ join->join_tab[join->tables-1].next_select=end_unique_update;
++ }
++ join->send_records++;
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++
++/** Like end_update, but this is done with unique constraints instead of keys. */
++
++static enum_nested_loop_state
++end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ TABLE *table=join->tmp_table;
++ int error;
++ DBUG_ENTER("end_unique_update");
++
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ if (join->thd->killed) // Aborted by user
++ {
++ join->thd->send_kill_message();
++ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
++ }
++
++ init_tmptable_sum_functions(join->sum_funcs);
++ copy_fields(&join->tmp_table_param); // Groups are copied twice.
++ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++
++ if (!(error=table->file->ha_write_row(table->record[0])))
++ join->send_records++; // New group
++ else
++ {
++ if ((int) table->file->get_dup_key(error) < 0)
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ }
++ if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ }
++ restore_record(table,record[1]);
++ update_tmptable_sum_func(join->sum_funcs,table);
++ if ((error=table->file->ha_update_row(table->record[1],
++ table->record[0])))
++ {
++ table->file->print_error(error,MYF(0)); /* purecov: inspected */
++ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
++ }
++ }
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++
++ /* ARGSUSED */
++static enum_nested_loop_state
++end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
++ bool end_of_records)
++{
++ TABLE *table=join->tmp_table;
++ int idx= -1;
++ DBUG_ENTER("end_write_group");
++
++ if (join->thd->killed)
++ { // Aborted by user
++ join->thd->send_kill_message();
++ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
++ }
++ if (!join->first_record || end_of_records ||
++ (idx=test_if_group_changed(join->group_fields)) >= 0)
++ {
++ if (join->first_record || (end_of_records && !join->group))
++ {
++ if (join->procedure)
++ join->procedure->end_group();
++ int send_group_parts= join->send_group_parts;
++ if (idx < send_group_parts)
++ {
++ if (!join->first_record)
++ {
++ /* No matching rows for group function */
++ join->clear();
++ }
++ copy_sum_funcs(join->sum_funcs,
++ join->sum_funcs_end[send_group_parts]);
++ if (!join->having || join->having->val_int())
++ {
++ int error= table->file->ha_write_row(table->record[0]);
++ if (error && create_myisam_from_heap(join->thd, table,
++ &join->tmp_table_param,
++ error, 0))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ }
++ if (join->rollup.state != ROLLUP::STATE_NONE)
++ {
++ if (join->rollup_write_data((uint) (idx+1), table))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ }
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ }
++ }
++ else
++ {
++ if (end_of_records)
++ DBUG_RETURN(NESTED_LOOP_OK);
++ join->first_record=1;
++ VOID(test_if_group_changed(join->group_fields));
++ }
++ if (idx < (int) join->send_group_parts)
++ {
++ copy_fields(&join->tmp_table_param);
++ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ if (join->procedure)
++ join->procedure->add();
++ DBUG_RETURN(NESTED_LOOP_OK);
++ }
++ }
++ if (update_sum_func(join->sum_funcs))
++ DBUG_RETURN(NESTED_LOOP_ERROR);
++ if (join->procedure)
++ join->procedure->add();
++ DBUG_RETURN(NESTED_LOOP_OK);
++}
++
++
++/*****************************************************************************
++ Remove calculation with tables that aren't yet read. Remove also tests
++ against fields that are read through key where the table is not a
++ outer join table.
++ We can't remove tests that are made against columns which are stored
++ in sorted order.
++*****************************************************************************/
++
++/**
++ @return
++ 1 if right_item is used removable reference key on left_item
++*/
++
++static bool test_if_ref(Item_field *left_item,Item *right_item)
++{
++ Field *field=left_item->field;
++ // No need to change const test. We also have to keep tests on LEFT JOIN
++ if (!field->table->const_table && !field->table->maybe_null)
++ {
++ Item *ref_item=part_of_refkey(field->table,field);
++ if (ref_item && ref_item->eq(right_item,1))
++ {
++ right_item= right_item->real_item();
++ if (right_item->type() == Item::FIELD_ITEM)
++ return (field->eq_def(((Item_field *) right_item)->field));
++ /* remove equalities injected by IN->EXISTS transformation */
++ else if (right_item->type() == Item::CACHE_ITEM)
++ return ((Item_cache *)right_item)->eq_def (field);
++ if (right_item->const_item() && !(right_item->is_null()))
++ {
++ /*
++ We can remove binary fields and numerical fields except float,
++ as float comparison isn't 100 % secure
++ We have to keep normal strings to be able to check for end spaces
++ */
++ if (field->binary() &&
++ field->real_type() != MYSQL_TYPE_STRING &&
++ field->real_type() != MYSQL_TYPE_VARCHAR &&
++ (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0))
++ {
++ return !store_val_in_field(field, right_item, CHECK_FIELD_WARN);
++ }
++ }
++ }
++ }
++ return 0; // keep test
++}
++
++
++static COND *
++make_cond_for_table(COND *cond, table_map tables, table_map used_table)
++{
++ if (used_table && !(cond->used_tables() & used_table))
++ return (COND*) 0; // Already checked
++ if (cond->type() == Item::COND_ITEM)
++ {
++ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ {
++ /* Create new top level AND item */
++ Item_cond_and *new_cond=new Item_cond_and;
++ if (!new_cond)
++ return (COND*) 0; // OOM /* purecov: inspected */
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ {
++ Item *fix=make_cond_for_table(item,tables,used_table);
++ if (fix)
++ new_cond->argument_list()->push_back(fix);
++ }
++ switch (new_cond->argument_list()->elements) {
++ case 0:
++ return (COND*) 0; // Always true
++ case 1:
++ return new_cond->argument_list()->head();
++ default:
++ /*
++ Item_cond_and do not need fix_fields for execution, its parameters
++ are fixed or do not need fix_fields, too
++ */
++ new_cond->quick_fix_field();
++ new_cond->used_tables_cache=
++ ((Item_cond_and*) cond)->used_tables_cache &
++ tables;
++ return new_cond;
++ }
++ }
++ else
++ { // Or list
++ Item_cond_or *new_cond=new Item_cond_or;
++ if (!new_cond)
++ return (COND*) 0; // OOM /* purecov: inspected */
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ {
++ Item *fix=make_cond_for_table(item,tables,0L);
++ if (!fix)
++ return (COND*) 0; // Always true
++ new_cond->argument_list()->push_back(fix);
++ }
++ /*
++ Item_cond_and do not need fix_fields for execution, its parameters
++ are fixed or do not need fix_fields, too
++ */
++ new_cond->quick_fix_field();
++ new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
++ new_cond->top_level_item();
++ return new_cond;
++ }
++ }
++
++ /*
++ Because the following test takes a while and it can be done
++ table_count times, we mark each item that we have examined with the result
++ of the test
++ */
++
++ if (cond->marker == 3 || (cond->used_tables() & ~tables))
++ return (COND*) 0; // Can't check this yet
++ if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
++ return cond; // Not boolean op
++
++ if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
++ {
++ Item *left_item= ((Item_func*) cond)->arguments()[0];
++ Item *right_item= ((Item_func*) cond)->arguments()[1];
++ if (left_item->type() == Item::FIELD_ITEM &&
++ test_if_ref((Item_field*) left_item,right_item))
++ {
++ cond->marker=3; // Checked when read
++ return (COND*) 0;
++ }
++ if (right_item->type() == Item::FIELD_ITEM &&
++ test_if_ref((Item_field*) right_item,left_item))
++ {
++ cond->marker=3; // Checked when read
++ return (COND*) 0;
++ }
++ }
++ cond->marker=2;
++ return cond;
++}
++
++static Item *
++part_of_refkey(TABLE *table,Field *field)
++{
++ if (!table->reginfo.join_tab)
++ return (Item*) 0; // field from outer non-select (UPDATE,...)
++
++ uint ref_parts=table->reginfo.join_tab->ref.key_parts;
++ if (ref_parts)
++ {
++ KEY_PART_INFO *key_part=
++ table->key_info[table->reginfo.join_tab->ref.key].key_part;
++
++ for (uint part=0 ; part < ref_parts ; part++,key_part++)
++ if (field->eq(key_part->field) &&
++ !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
++ return table->reginfo.join_tab->ref.items[part];
++ }
++ return (Item*) 0;
++}
++
++
++/**
++ Test if one can use the key to resolve ORDER BY.
++
++ @param order Sort order
++ @param table Table to sort
++ @param idx Index to check
++ @param used_key_parts Return value for used key parts.
++
++
++ @note
++ used_key_parts is set to correct key parts used if return value != 0
++ (On other cases, used_key_part may be changed)
++ Note that the value may actually be greater than the number of index
++ key parts. This can happen for storage engines that have the primary
++ key parts as a suffix for every secondary key.
++
++ @retval
++ 1 key is ok.
++ @retval
++ 0 Key can't be used
++ @retval
++ -1 Reverse key can be used
++*/
++
++static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
++ uint *used_key_parts)
++{
++ KEY_PART_INFO *key_part,*key_part_end;
++ key_part=table->key_info[idx].key_part;
++ key_part_end=key_part+table->key_info[idx].key_parts;
++ key_part_map const_key_parts=table->const_key_parts[idx];
++ int reverse=0;
++ my_bool on_pk_suffix= FALSE;
++ DBUG_ENTER("test_if_order_by_key");
++
++ for (; order ; order=order->next, const_key_parts>>=1)
++ {
++ Field *field=((Item_field*) (*order->item)->real_item())->field;
++ int flag;
++
++ /*
++ Skip key parts that are constants in the WHERE clause.
++ These are already skipped in the ORDER BY by const_expression_in_where()
++ */
++ for (; const_key_parts & 1 ; const_key_parts>>= 1)
++ key_part++;
++
++ if (key_part == key_part_end)
++ {
++ /*
++ We are at the end of the key. Check if the engine has the primary
++ key as a suffix to the secondary keys. If it has continue to check
++ the primary key as a suffix.
++ */
++ if (!on_pk_suffix &&
++ (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
++ table->s->primary_key != MAX_KEY &&
++ table->s->primary_key != idx)
++ {
++ on_pk_suffix= TRUE;
++ key_part= table->key_info[table->s->primary_key].key_part;
++ key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
++ const_key_parts=table->const_key_parts[table->s->primary_key];
++
++ for (; const_key_parts & 1 ; const_key_parts>>= 1)
++ key_part++;
++ /*
++ The primary and secondary key parts were all const (i.e. there's
++ one row). The sorting doesn't matter.
++ */
++ if (key_part == key_part_end && reverse == 0)
++ {
++ *used_key_parts= 0;
++ DBUG_RETURN(1);
++ }
++ }
++ else
++ DBUG_RETURN(0);
++ }
++
++ if (key_part->field != field)
++ DBUG_RETURN(0);
++
++ /* set flag to 1 if we can use read-next on key, else to -1 */
++ flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ?
++ 1 : -1);
++ if (reverse && flag != reverse)
++ DBUG_RETURN(0);
++ reverse=flag; // Remember if reverse
++ key_part++;
++ }
++ if (on_pk_suffix)
++ {
++ uint used_key_parts_secondary= table->key_info[idx].key_parts;
++ uint used_key_parts_pk=
++ (uint) (key_part - table->key_info[table->s->primary_key].key_part);
++ *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
++
++ if (reverse == -1 &&
++ (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
++ HA_READ_PREV) ||
++ !(table->file->index_flags(table->s->primary_key,
++ used_key_parts_pk - 1, 1) & HA_READ_PREV)))
++ reverse= 0; // Index can't be used
++ }
++ else
++ {
++ *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
++ if (reverse == -1 &&
++ !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
++ reverse= 0; // Index can't be used
++ }
++ DBUG_RETURN(reverse);
++}
++
++
++/**
++ Find shortest key suitable for full table scan.
++
++ @param table Table to scan
++ @param usable_keys Allowed keys
++
++ @note
++ As far as
++ 1) clustered primary key entry data set is a set of all record
++ fields (key fields and not key fields) and
++ 2) secondary index entry data is a union of its key fields and
++ primary key fields (at least InnoDB and its derivatives don't
++ duplicate primary key fields there, even if the primary and
++ the secondary keys have a common subset of key fields),
++ then secondary index entry data is always a subset of primary key entry.
++ Unfortunately, key_info[nr].key_length doesn't show the length
++ of key/pointer pair but a sum of key field lengths only, thus
++ we can't estimate index IO volume comparing only this key_length
++ value of secondary keys and clustered PK.
++ So, try secondary keys first, and choose PK only if there are no
++ usable secondary covering keys or found best secondary key include
++ all table fields (i.e. same as PK):
++
++ @return
++ MAX_KEY no suitable key found
++ key index otherwise
++*/
++
++uint find_shortest_key(TABLE *table, const key_map *usable_keys)
++{
++ uint best= MAX_KEY;
++ uint usable_clustered_pk= (table->file->primary_key_is_clustered() &&
++ table->s->primary_key != MAX_KEY &&
++ usable_keys->is_set(table->s->primary_key)) ?
++ table->s->primary_key : MAX_KEY;
++ if (!usable_keys->is_clear_all())
++ {
++ uint min_length= (uint) ~0;
++ for (uint nr=0; nr < table->s->keys ; nr++)
++ {
++ if (nr == usable_clustered_pk)
++ continue;
++ if (usable_keys->is_set(nr))
++ {
++ if (table->key_info[nr].key_length < min_length)
++ {
++ min_length=table->key_info[nr].key_length;
++ best=nr;
++ }
++ }
++ }
++ }
++ if (usable_clustered_pk != MAX_KEY)
++ {
++ /*
++ If the primary key is clustered and found shorter key covers all table
++ fields then primary key scan normally would be faster because amount of
++ data to scan is the same but PK is clustered.
++ It's safe to compare key parts with table fields since duplicate key
++ parts aren't allowed.
++ */
++ if (best == MAX_KEY ||
++ table->key_info[best].key_parts >= table->s->fields)
++ best= usable_clustered_pk;
++ }
++ return best;
++}
++
++/**
++ Test if a second key is the subkey of the first one.
++
++ @param key_part First key parts
++ @param ref_key_part Second key parts
++ @param ref_key_part_end Last+1 part of the second key
++
++ @note
++ Second key MUST be shorter than the first one.
++
++ @retval
++ 1 is a subkey
++ @retval
++ 0 no sub key
++*/
++
++inline bool
++is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
++ KEY_PART_INFO *ref_key_part_end)
++{
++ for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
++ if (!key_part->field->eq(ref_key_part->field))
++ return 0;
++ return 1;
++}
++
++/**
++ Test if we can use one of the 'usable_keys' instead of 'ref' key
++ for sorting.
++
++ @param ref Number of key, used for WHERE clause
++ @param usable_keys Keys for testing
++
++ @return
++ - MAX_KEY If we can't use other key
++ - the number of found key Otherwise
++*/
++
++static uint
++test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
++ const key_map *usable_keys)
++{
++ uint nr;
++ uint min_length= (uint) ~0;
++ uint best= MAX_KEY;
++ uint not_used;
++ KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
++ KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
++
++ for (nr= 0 ; nr < table->s->keys ; nr++)
++ {
++ if (usable_keys->is_set(nr) &&
++ table->key_info[nr].key_length < min_length &&
++ table->key_info[nr].key_parts >= ref_key_parts &&
++ is_subkey(table->key_info[nr].key_part, ref_key_part,
++ ref_key_part_end) &&
++ test_if_order_by_key(order, table, nr, ¬_used))
++ {
++ min_length= table->key_info[nr].key_length;
++ best= nr;
++ }
++ }
++ return best;
++}
++
++
++/**
++ Check if GROUP BY/DISTINCT can be optimized away because the set is
++ already known to be distinct.
++
++ Used in removing the GROUP BY/DISTINCT of the following types of
++ statements:
++ @code
++ SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
++ [GROUP BY <unique_key_cols>,...]
++ @endcode
++
++ If (a,b,c is distinct)
++ then <any combination of a,b,c>,{whatever} is also distinct
++
++ This function checks if all the key parts of any of the unique keys
++ of the table are referenced by a list : either the select list
++ through find_field_in_item_list or GROUP BY list through
++ find_field_in_order_list.
++ If the above holds and the key parts cannot contain NULLs then we
++ can safely remove the GROUP BY/DISTINCT,
++ as no result set can be more distinct than an unique key.
++
++ @param table The table to operate on.
++ @param find_func function to iterate over the list and search
++ for a field
++
++ @retval
++ 1 found
++ @retval
++ 0 not found.
++*/
++
++static bool
++list_contains_unique_index(TABLE *table,
++ bool (*find_func) (Field *, void *), void *data)
++{
++ if (table->pos_in_table_list->outer_join)
++ return 0;
++ for (uint keynr= 0; keynr < table->s->keys; keynr++)
++ {
++ if (keynr == table->s->primary_key ||
++ (table->key_info[keynr].flags & HA_NOSAME))
++ {
++ KEY *keyinfo= table->key_info + keynr;
++ KEY_PART_INFO *key_part, *key_part_end;
++
++ for (key_part=keyinfo->key_part,
++ key_part_end=key_part+ keyinfo->key_parts;
++ key_part < key_part_end;
++ key_part++)
++ {
++ if (key_part->field->real_maybe_null() ||
++ !find_func(key_part->field, data))
++ break;
++ }
++ if (key_part == key_part_end)
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++/**
++ Helper function for list_contains_unique_index.
++ Find a field reference in a list of ORDER structures.
++ Finds a direct reference of the Field in the list.
++
++ @param field The field to search for.
++ @param data ORDER *.The list to search in
++
++ @retval
++ 1 found
++ @retval
++ 0 not found.
++*/
++
++static bool
++find_field_in_order_list (Field *field, void *data)
++{
++ ORDER *group= (ORDER *) data;
++ bool part_found= 0;
++ for (ORDER *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
++ {
++ Item *item= (*tmp_group->item)->real_item();
++ if (item->type() == Item::FIELD_ITEM &&
++ ((Item_field*) item)->field->eq(field))
++ {
++ part_found= 1;
++ break;
++ }
++ }
++ return part_found;
++}
++
++
++/**
++ Helper function for list_contains_unique_index.
++ Find a field reference in a dynamic list of Items.
++ Finds a direct reference of the Field in the list.
++
++ @param[in] field The field to search for.
++ @param[in] data List<Item> *.The list to search in
++
++ @retval
++ 1 found
++ @retval
++ 0 not found.
++*/
++
++static bool
++find_field_in_item_list (Field *field, void *data)
++{
++ List<Item> *fields= (List<Item> *) data;
++ bool part_found= 0;
++ List_iterator<Item> li(*fields);
++ Item *item;
++
++ while ((item= li++))
++ {
++ if (item->type() == Item::FIELD_ITEM &&
++ ((Item_field*) item)->field->eq(field))
++ {
++ part_found= 1;
++ break;
++ }
++ }
++ return part_found;
++}
++
++
++/**
++ Test if we can skip the ORDER BY by using an index.
++
++ If we can use an index, the JOIN_TAB / tab->select struct
++ is changed to use the index.
++
++ The index must cover all fields in <order>, or it will not be considered.
++
++ @param no_changes No changes will be made to the query plan.
++
++ @todo
++ - sergeyp: Results of all index merge selects actually are ordered
++ by clustered PK values.
++
++ @retval
++ 0 We have to use filesort to do the sorting
++ @retval
++ 1 We can use an index.
++*/
++
++static bool
++test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
++ bool no_changes, key_map *map)
++{
++ int ref_key;
++ uint ref_key_parts;
++ int order_direction= 0;
++ uint used_key_parts;
++ TABLE *table=tab->table;
++ SQL_SELECT *select=tab->select;
++ key_map usable_keys;
++ QUICK_SELECT_I *save_quick= 0;
++ int best_key= -1;
++
++ DBUG_ENTER("test_if_skip_sort_order");
++ LINT_INIT(ref_key_parts);
++
++ /*
++ Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
++ been taken into account.
++ */
++ usable_keys= *map;
++
++ for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
++ {
++ Item *item= (*tmp_order->item)->real_item();
++ if (item->type() != Item::FIELD_ITEM)
++ {
++ usable_keys.clear_all();
++ DBUG_RETURN(0);
++ }
++ usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
++ if (usable_keys.is_clear_all())
++ DBUG_RETURN(0); // No usable keys
++ }
++
++ ref_key= -1;
++ /* Test if constant range in WHERE */
++ if (tab->ref.key >= 0 && tab->ref.key_parts)
++ {
++ ref_key= tab->ref.key;
++ ref_key_parts= tab->ref.key_parts;
++ if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT)
++ DBUG_RETURN(0);
++ }
++ else if (select && select->quick) // Range found by opt_range
++ {
++ int quick_type= select->quick->get_type();
++ save_quick= select->quick;
++ /*
++ assume results are not ordered when index merge is used
++ TODO: sergeyp: Results of all index merge selects actually are ordered
++ by clustered PK values.
++ */
++
++ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
++ DBUG_RETURN(0);
++ ref_key= select->quick->index;
++ ref_key_parts= select->quick->used_key_parts;
++ }
++
++ if (ref_key >= 0)
++ {
++ /*
++ We come here when there is a REF key.
++ */
++ if (!usable_keys.is_set(ref_key))
++ {
++ /*
++ We come here when ref_key is not among usable_keys
++ */
++ uint new_ref_key;
++ /*
++ If using index only read, only consider other possible index only
++ keys
++ */
++ if (table->covering_keys.is_set(ref_key))
++ usable_keys.intersect(table->covering_keys);
++ if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
++ &usable_keys)) < MAX_KEY)
++ {
++ /* Found key that can be used to retrieve data in sorted order */
++ if (tab->ref.key >= 0)
++ {
++ /*
++ We'll use ref access method on key new_ref_key. In general case
++ the index search tuple for new_ref_key will be different (e.g.
++ when one index is defined as (part1, part2, ...) and another as
++ (part1, part2(N), ...) and the WHERE clause contains
++ "part1 = const1 AND part2=const2".
++ So we build tab->ref from scratch here.
++ */
++ KEYUSE *keyuse= tab->keyuse;
++ while (keyuse->key != new_ref_key && keyuse->table == tab->table)
++ keyuse++;
++ if (create_ref_for_key(tab->join, tab, keyuse,
++ tab->join->const_table_map))
++ DBUG_RETURN(0);
++
++ pick_table_access_method(tab);
++ }
++ else
++ {
++ /*
++ The range optimizer constructed QUICK_RANGE for ref_key, and
++ we want to use instead new_ref_key as the index. We can't
++ just change the index of the quick select, because this may
++ result in an incosistent QUICK_SELECT object. Below we
++ create a new QUICK_SELECT from scratch so that all its
++ parameres are set correctly by the range optimizer.
++ */
++ key_map new_ref_key_map;
++ new_ref_key_map.clear_all(); // Force the creation of quick select
++ new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
++
++ select->quick= 0;
++ if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
++ (tab->join->select_options &
++ OPTION_FOUND_ROWS) ?
++ HA_POS_ERROR :
++ tab->join->unit->select_limit_cnt,0) <=
++ 0)
++ goto use_filesort;
++ }
++ ref_key= new_ref_key;
++ }
++ }
++ /* Check if we get the rows in requested sorted order by using the key */
++ if (usable_keys.is_set(ref_key) &&
++ (order_direction= test_if_order_by_key(order,table,ref_key,
++ &used_key_parts)))
++ goto check_reverse_order;
++ }
++ {
++ /*
++ Check whether there is an index compatible with the given order
++ usage of which is cheaper than usage of the ref_key index (ref_key>=0)
++ or a table scan.
++ It may be the case if ORDER/GROUP BY is used with LIMIT.
++ */
++ uint nr;
++ key_map keys;
++ uint best_key_parts= 0;
++ uint saved_best_key_parts= 0;
++ int best_key_direction= 0;
++ ha_rows best_records= 0;
++ double read_time;
++ bool is_best_covering= FALSE;
++ double fanout= 1;
++ JOIN *join= tab->join;
++ uint tablenr= tab - join->join_tab;
++ ha_rows table_records= table->file->stats.records;
++ bool group= join->group && order == join->group_list;
++ ha_rows ref_key_quick_rows= HA_POS_ERROR;
++
++ /*
++ If not used with LIMIT, only use keys if the whole query can be
++ resolved with a key; This is because filesort() is usually faster than
++ retrieving all rows through an index.
++ */
++ if (select_limit >= table_records)
++ {
++ keys= *table->file->keys_to_use_for_scanning();
++ keys.merge(table->covering_keys);
++
++ /*
++ We are adding here also the index specified in FORCE INDEX clause,
++ if any.
++ This is to allow users to use index in ORDER BY.
++ */
++ if (table->force_index)
++ keys.merge(group ? table->keys_in_use_for_group_by :
++ table->keys_in_use_for_order_by);
++ keys.intersect(usable_keys);
++ }
++ else
++ keys= usable_keys;
++
++ if (ref_key >= 0 && table->covering_keys.is_set(ref_key))
++ ref_key_quick_rows= table->quick_rows[ref_key];
++
++ read_time= join->best_positions[tablenr].read_time;
++ for (uint i= tablenr+1; i < join->tables; i++)
++ fanout*= join->best_positions[i].records_read; // fanout is always >= 1
++
++ for (nr=0; nr < table->s->keys ; nr++)
++ {
++ int direction;
++
++ if (keys.is_set(nr) &&
++ (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
++ {
++ /*
++ At this point we are sure that ref_key is a non-ordering
++ key (where "ordering key" is a key that will return rows
++ in the order required by ORDER BY).
++ */
++ DBUG_ASSERT (ref_key != (int) nr);
++
++ bool is_covering= table->covering_keys.is_set(nr) ||
++ (nr == table->s->primary_key &&
++ table->file->primary_key_is_clustered());
++
++ /*
++ Don't use an index scan with ORDER BY without limit.
++ For GROUP BY without limit always use index scan
++ if there is a suitable index.
++ Why we hold to this asymmetry hardly can be explained
++ rationally. It's easy to demonstrate that using
++ temporary table + filesort could be cheaper for grouping
++ queries too.
++ */
++ if (is_covering ||
++ select_limit != HA_POS_ERROR ||
++ (ref_key < 0 && (group || table->force_index)))
++ {
++ double rec_per_key;
++ double index_scan_time;
++ KEY *keyinfo= tab->table->key_info+nr;
++ if (select_limit == HA_POS_ERROR)
++ select_limit= table_records;
++ if (group)
++ {
++ /*
++ Used_key_parts can be larger than keyinfo->key_parts
++ when using a secondary index clustered with a primary
++ key (e.g. as in Innodb).
++ See Bug #28591 for details.
++ */
++ rec_per_key= used_key_parts &&
++ used_key_parts <= keyinfo->key_parts ?
++ keyinfo->rec_per_key[used_key_parts-1] : 1;
++ set_if_bigger(rec_per_key, 1);
++ /*
++ With a grouping query each group containing on average
++ rec_per_key records produces only one row that will
++ be included into the result set.
++ */
++ if (select_limit > table_records/rec_per_key)
++ select_limit= table_records;
++ else
++ select_limit= (ha_rows) (select_limit*rec_per_key);
++ }
++ /*
++ If tab=tk is not the last joined table tn then to get first
++ L records from the result set we can expect to retrieve
++ only L/fanout(tk,tn) where fanout(tk,tn) says how many
++ rows in the record set on average will match each row tk.
++ Usually our estimates for fanouts are too pessimistic.
++ So the estimate for L/fanout(tk,tn) will be too optimistic
++ and as result we'll choose an index scan when using ref/range
++ access + filesort will be cheaper.
++ */
++ select_limit= (ha_rows) (select_limit < fanout ?
++ 1 : select_limit/fanout);
++ /*
++ We assume that each of the tested indexes is not correlated
++ with ref_key. Thus, to select first N records we have to scan
++ N/selectivity(ref_key) index entries.
++ selectivity(ref_key) = #scanned_records/#table_records =
++ table->quick_condition_rows/table_records.
++ In any case we can't select more than #table_records.
++ N/(table->quick_condition_rows/table_records) > table_records
++ <=> N > table->quick_condition_rows.
++ */
++ if (select_limit > table->quick_condition_rows)
++ select_limit= table_records;
++ else
++ select_limit= (ha_rows) (select_limit *
++ (double) table_records /
++ table->quick_condition_rows);
++ rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1];
++ set_if_bigger(rec_per_key, 1);
++ /*
++ Here we take into account the fact that rows are
++ accessed in sequences rec_per_key records in each.
++ Rows in such a sequence are supposed to be ordered
++ by rowid/primary key. When reading the data
++ in a sequence we'll touch not more pages than the
++ table file contains.
++ TODO. Use the formula for a disk sweep sequential access
++ to calculate the cost of accessing data rows for one
++ index entry.
++ */
++ index_scan_time= select_limit/rec_per_key *
++ min(rec_per_key, table->file->scan_time());
++ if ((ref_key < 0 && is_covering) ||
++ (ref_key < 0 && (group || table->force_index)) ||
++ index_scan_time < read_time)
++ {
++ ha_rows quick_records= table_records;
++ if ((is_best_covering && !is_covering) ||
++ (is_covering && ref_key_quick_rows < select_limit))
++ continue;
++ if (table->quick_keys.is_set(nr))
++ quick_records= table->quick_rows[nr];
++ if (best_key < 0 ||
++ (select_limit <= min(quick_records,best_records) ?
++ keyinfo->key_parts < best_key_parts :
++ quick_records < best_records))
++ {
++ best_key= nr;
++ best_key_parts= keyinfo->key_parts;
++ saved_best_key_parts= used_key_parts;
++ best_records= quick_records;
++ is_best_covering= is_covering;
++ best_key_direction= direction;
++ }
++ }
++ }
++ }
++ }
++
++ /*
++ filesort() and join cache are usually faster than reading in
++ index order and not using join cache, except in case that chosen
++ index is clustered primary key.
++ */
++ if ((select_limit >= table_records) &&
++ (tab->type == JT_ALL &&
++ tab->join->tables > tab->join->const_tables + 1) &&
++ ((unsigned) best_key != table->s->primary_key ||
++ !table->file->primary_key_is_clustered()))
++ goto use_filesort;
++
++ if (best_key >= 0)
++ {
++ if (table->quick_keys.is_set(best_key) && best_key != ref_key)
++ {
++ key_map map;
++ map.clear_all(); // Force the creation of quick select
++ map.set_bit(best_key); // only best_key.
++ select->quick= 0;
++ select->test_quick_select(join->thd, map, 0,
++ join->select_options & OPTION_FOUND_ROWS ?
++ HA_POS_ERROR :
++ join->unit->select_limit_cnt,
++ 0);
++ }
++ order_direction= best_key_direction;
++ /*
++ saved_best_key_parts is actual number of used keyparts found by the
++ test_if_order_by_key function. It could differ from keyinfo->key_parts,
++ thus we have to restore it in case of desc order as it affects
++ QUICK_SELECT_DESC behaviour.
++ */
++ used_key_parts= (order_direction == -1) ?
++ saved_best_key_parts : best_key_parts;
++ }
++ else
++ goto use_filesort;
++ }
++
++check_reverse_order:
++ DBUG_ASSERT(order_direction != 0);
++
++ if (order_direction == -1) // If ORDER BY ... DESC
++ {
++ if (select && select->quick)
++ {
++ /*
++ Don't reverse the sort order, if it's already done.
++ (In some cases test_if_order_by_key() can be called multiple times
++ */
++ if (select->quick->reverse_sorted())
++ goto skipped_filesort;
++ else
++ {
++ int quick_type= select->quick->get_type();
++ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
++ {
++ tab->limit= 0;
++ goto use_filesort; // Use filesort
++ }
++ }
++ }
++ }
++
++ /*
++ Update query plan with access pattern for doing
++ ordered access according to what we have decided
++ above.
++ */
++ if (!no_changes) // We are allowed to update QEP
++ {
++ if (best_key >= 0)
++ {
++ bool quick_created=
++ (select && select->quick && select->quick!=save_quick);
++
++ /*
++ If ref_key used index tree reading only ('Using index' in EXPLAIN),
++ and best_key doesn't, then revert the decision.
++ */
++ if (!table->covering_keys.is_set(best_key))
++ table->set_keyread(FALSE);
++ if (!quick_created)
++ {
++ if (select) // Throw any existing quick select
++ select->quick= 0; // Cleanup either reset to save_quick,
++ // or 'delete save_quick'
++ tab->index= best_key;
++ tab->read_first_record= order_direction > 0 ?
++ join_read_first:join_read_last;
++ tab->type=JT_NEXT; // Read with index_first(), index_next()
++
++ if (table->covering_keys.is_set(best_key))
++ table->set_keyread(TRUE);
++ table->file->ha_index_or_rnd_end();
++ if (tab->join->select_options & SELECT_DESCRIBE)
++ {
++ tab->ref.key= -1;
++ tab->ref.key_parts= 0;
++ if (select_limit < table->file->stats.records)
++ tab->limit= select_limit;
++ }
++ }
++ else if (tab->type != JT_ALL)
++ {
++ /*
++ We're about to use a quick access to the table.
++ We need to change the access method so as the quick access
++ method is actually used.
++ */
++ DBUG_ASSERT(tab->select->quick);
++ tab->type=JT_ALL;
++ tab->use_quick=1;
++ tab->ref.key= -1;
++ tab->ref.key_parts=0; // Don't use ref key.
++ tab->read_first_record= join_init_read_record;
++ if (tab->is_using_loose_index_scan())
++ tab->join->tmp_table_param.precomputed_group_by= TRUE;
++ /*
++ TODO: update the number of records in join->best_positions[tablenr]
++ */
++ }
++ } // best_key >= 0
++
++ if (order_direction == -1) // If ORDER BY ... DESC
++ {
++ if (select && select->quick)
++ {
++ QUICK_SELECT_DESC *tmp;
++ /* ORDER BY range_key DESC */
++ tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
++ used_key_parts);
++ if (tmp && select->quick == save_quick)
++ save_quick= 0; // ::QUICK_SELECT_DESC consumed it
++
++ if (!tmp || tmp->error)
++ {
++ delete tmp;
++ tab->limit= 0;
++ goto use_filesort; // Reverse sort failed -> filesort
++ }
++ select->quick= tmp;
++ }
++ else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
++ tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
++ {
++ /*
++ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
++
++ Use a traversal function that starts by reading the last row
++ with key part (A) and then traverse the index backwards.
++ */
++ tab->read_first_record= join_read_last_key;
++ tab->read_record.read_record= join_read_prev_same;
++ }
++ }
++ else if (select && select->quick)
++ select->quick->sorted= 1;
++
++ } // QEP has been modified
++
++ /*
++ Cleanup:
++ We may have both a 'select->quick' and 'save_quick' (original)
++ at this point. Delete the one that we wan't use.
++ */
++
++skipped_filesort:
++ // Keep current (ordered) select->quick
++ if (select && save_quick != select->quick)
++ {
++ delete save_quick;
++ save_quick= NULL;
++ }
++ DBUG_RETURN(1);
++
++use_filesort:
++ // Restore original save_quick
++ if (select && select->quick != save_quick)
++ {
++ delete select->quick;
++ select->quick= save_quick;
++ }
++ DBUG_RETURN(0);
++}
++
++
++/*
++ If not selecting by given key, create an index how records should be read
++
++ SYNOPSIS
++ create_sort_index()
++ thd Thread handler
++ tab Table to sort (in join structure)
++ order How table should be sorted
++ filesort_limit Max number of rows that needs to be sorted
++ select_limit Max number of rows in final output
++ Used to decide if we should use index or not
++ is_order_by true if we are sorting on ORDER BY, false if GROUP BY
++ Used to decide if we should use index or not
++
++
++ IMPLEMENTATION
++ - If there is an index that can be used, 'tab' is modified to use
++ this index.
++ - If no index, create with filesort() an index file that can be used to
++ retrieve rows in order (should be done with 'read_record').
++ The sorted data is stored in tab->table and will be freed when calling
++ free_io_cache(tab->table).
++
++ RETURN VALUES
++ 0 ok
++ -1 Some fatal error
++ 1 No records
++*/
++
++static int
++create_sort_index(THD *thd, JOIN *join, ORDER *order,
++ ha_rows filesort_limit, ha_rows select_limit,
++ bool is_order_by)
++{
++ uint length= 0;
++ ha_rows examined_rows;
++ TABLE *table;
++ SQL_SELECT *select;
++ JOIN_TAB *tab;
++ DBUG_ENTER("create_sort_index");
++
++ if (join->tables == join->const_tables)
++ DBUG_RETURN(0); // One row, no need to sort
++ tab= join->join_tab + join->const_tables;
++ table= tab->table;
++ select= tab->select;
++
++ /*
++ When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
++ and thus force sorting on disk unless a group min-max optimization
++ is going to be used as it is applied now only for one table queries
++ with covering indexes.
++ */
++ if ((order != join->group_list ||
++ !(join->select_options & SELECT_BIG_RESULT) ||
++ (select && select->quick &&
++ select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) &&
++ test_if_skip_sort_order(tab,order,select_limit,0,
++ is_order_by ? &table->keys_in_use_for_order_by :
++ &table->keys_in_use_for_group_by))
++ DBUG_RETURN(0);
++ for (ORDER *ord= join->order; ord; ord= ord->next)
++ length++;
++ if (!(join->sortorder=
++ make_unireg_sortorder(order, &length, join->sortorder)))
++ goto err; /* purecov: inspected */
++
++ table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
++ MYF(MY_WME | MY_ZEROFILL));
++ table->status=0; // May be wrong if quick_select
++
++ // If table has a range, move it to select
++ if (select && !select->quick && tab->ref.key >= 0)
++ {
++ if (tab->quick)
++ {
++ select->quick=tab->quick;
++ tab->quick=0;
++ /*
++ We can only use 'Only index' if quick key is same as ref_key
++ and in index_merge 'Only index' cannot be used
++ */
++ if (((uint) tab->ref.key != select->quick->index))
++ table->set_keyread(FALSE);
++ }
++ else
++ {
++ /*
++ We have a ref on a const; Change this to a range that filesort
++ can use.
++ For impossible ranges (like when doing a lookup on NULL on a NOT NULL
++ field, quick will contain an empty record set.
++ */
++ if (!(select->quick= (tab->type == JT_FT ?
++ new FT_SELECT(thd, table, tab->ref.key) :
++ get_quick_select_for_ref(thd, table, &tab->ref,
++ tab->found_records))))
++ goto err;
++ }
++ }
++
++ /* Fill schema tables with data before filesort if it's necessary */
++ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
++ get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
++ goto err;
++
++ if (table->s->tmp_table)
++ table->file->info(HA_STATUS_VARIABLE); // Get record count
++ table->sort.found_records=filesort(thd, table,join->sortorder, length,
++ select, filesort_limit, 0,
++ &examined_rows);
++ tab->records= table->sort.found_records; // For SQL_CALC_ROWS
++ if (select)
++ {
++ /*
++ We need to preserve tablesort's output resultset here, because
++ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT (called by
++ SQL_SELECT::cleanup()) may free it assuming it's the result of the quick
++ select operation that we no longer need. Note that all the other parts of
++ this data structure are cleaned up when
++ QUICK_INDEX_MERGE_SELECT::get_next encounters end of data, so the next
++ SQL_SELECT::cleanup() call changes sort.io_cache alone.
++ */
++ IO_CACHE *tablesort_result_cache;
++
++ tablesort_result_cache= table->sort.io_cache;
++ table->sort.io_cache= NULL;
++
++ select->cleanup(); // filesort did select
++ tab->select= 0;
++ table->quick_keys.clear_all(); // as far as we cleanup select->quick
++ table->sort.io_cache= tablesort_result_cache;
++ }
++ tab->select_cond=0;
++ tab->last_inner= 0;
++ tab->first_unmatched= 0;
++ tab->type=JT_ALL; // Read with normal read_record
++ tab->read_first_record= join_init_read_record;
++ tab->join->examined_rows+=examined_rows;
++ table->set_keyread(FALSE); // Restore if we used indexes
++ DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
++err:
++ DBUG_RETURN(-1);
++}
++
++#ifdef NOT_YET
++/**
++ Add the HAVING criteria to table->select.
++*/
++
++static bool fix_having(JOIN *join, Item **having)
++{
++ (*having)->update_used_tables(); // Some tables may have been const
++ JOIN_TAB *table=&join->join_tab[join->const_tables];
++ table_map used_tables= join->const_table_map | table->table->map;
++
++ DBUG_EXECUTE("where",print_where(*having,"having", QT_ORDINARY););
++ Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
++ if (sort_table_cond)
++ {
++ if (!table->select)
++ if (!(table->select=new SQL_SELECT))
++ return 1;
++ if (!table->select->cond)
++ table->select->cond=sort_table_cond;
++ else // This should never happen
++ if (!(table->select->cond= new Item_cond_and(table->select->cond,
++ sort_table_cond)) ||
++ table->select->cond->fix_fields(join->thd, &table->select->cond))
++ return 1;
++ table->select_cond=table->select->cond;
++ table->select_cond->top_level_item();
++ DBUG_EXECUTE("where",print_where(table->select_cond,
++ "select and having",
++ QT_ORDINARY););
++ *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
++ DBUG_EXECUTE("where",
++ print_where(*having,"having after make_cond", QT_ORDINARY););
++ }
++ return 0;
++}
++#endif
++
++
++/*****************************************************************************
++ Remove duplicates from tmp table
++ This should be recoded to add a unique index to the table and remove
++ duplicates
++ Table is a locked single thread table
++ fields is the number of fields to check (from the end)
++*****************************************************************************/
++
++static bool compare_record(TABLE *table, Field **ptr)
++{
++ for (; *ptr ; ptr++)
++ {
++ if ((*ptr)->cmp_offset(table->s->rec_buff_length))
++ return 1;
++ }
++ return 0;
++}
++
++static bool copy_blobs(Field **ptr)
++{
++ for (; *ptr ; ptr++)
++ {
++ if ((*ptr)->flags & BLOB_FLAG)
++ if (((Field_blob *) (*ptr))->copy())
++ return 1; // Error
++ }
++ return 0;
++}
++
++static void free_blobs(Field **ptr)
++{
++ for (; *ptr ; ptr++)
++ {
++ if ((*ptr)->flags & BLOB_FLAG)
++ ((Field_blob *) (*ptr))->free();
++ }
++}
++
++
++static int
++remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
++{
++ int error;
++ ulong reclength,offset;
++ uint field_count;
++ THD *thd= join->thd;
++ DBUG_ENTER("remove_duplicates");
++
++ entry->reginfo.lock_type=TL_WRITE;
++
++ /* Calculate how many saved fields there is in list */
++ field_count=0;
++ List_iterator<Item> it(fields);
++ Item *item;
++ while ((item=it++))
++ {
++ if (item->get_tmp_table_field() && ! item->const_item())
++ field_count++;
++ }
++
++ if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
++ { // only const items with no OPTION_FOUND_ROWS
++ join->unit->select_limit_cnt= 1; // Only send first row
++ DBUG_RETURN(0);
++ }
++ Field **first_field=entry->field+entry->s->fields - field_count;
++ offset= (field_count ?
++ entry->field[entry->s->fields - field_count]->
++ offset(entry->record[0]) : 0);
++ reclength=entry->s->reclength-offset;
++
++ free_io_cache(entry); // Safety
++ entry->file->info(HA_STATUS_VARIABLE);
++ if (entry->s->db_type() == heap_hton ||
++ (!entry->s->blob_fields &&
++ ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
++ thd->variables.sortbuff_size)))
++ error=remove_dup_with_hash_index(join->thd, entry,
++ field_count, first_field,
++ reclength, having);
++ else
++ error=remove_dup_with_compare(join->thd, entry, first_field, offset,
++ having);
++
++ free_blobs(first_field);
++ DBUG_RETURN(error);
++}
++
++
++static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
++ ulong offset, Item *having)
++{
++ handler *file=table->file;
++ char *org_record,*new_record;
++ uchar *record;
++ int error;
++ ulong reclength= table->s->reclength-offset;
++ DBUG_ENTER("remove_dup_with_compare");
++
++ org_record=(char*) (record=table->record[0])+offset;
++ new_record=(char*) table->record[1]+offset;
++
++ file->ha_rnd_init(1);
++ error=file->rnd_next(record);
++ for (;;)
++ {
++ if (thd->killed)
++ {
++ thd->send_kill_message();
++ error=0;
++ goto err;
++ }
++ if (error)
++ {
++ if (error == HA_ERR_RECORD_DELETED)
++ {
++ error= file->rnd_next(record);
++ continue;
++ }
++ if (error == HA_ERR_END_OF_FILE)
++ break;
++ goto err;
++ }
++ if (having && !having->val_int())
++ {
++ if ((error=file->ha_delete_row(record)))
++ goto err;
++ error=file->rnd_next(record);
++ continue;
++ }
++ if (copy_blobs(first_field))
++ {
++ my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0));
++ error=0;
++ goto err;
++ }
++ memcpy(new_record,org_record,reclength);
++
++ /* Read through rest of file and mark duplicated rows deleted */
++ bool found=0;
++ for (;;)
++ {
++ if ((error=file->rnd_next(record)))
++ {
++ if (error == HA_ERR_RECORD_DELETED)
++ continue;
++ if (error == HA_ERR_END_OF_FILE)
++ break;
++ goto err;
++ }
++ if (compare_record(table, first_field) == 0)
++ {
++ if ((error=file->ha_delete_row(record)))
++ goto err;
++ }
++ else if (!found)
++ {
++ found=1;
++ file->position(record); // Remember position
++ }
++ }
++ if (!found)
++ break; // End of file
++ /* Restart search on next row */
++ error=file->restart_rnd_next(record,file->ref);
++ }
++
++ file->extra(HA_EXTRA_NO_CACHE);
++ DBUG_RETURN(0);
++err:
++ file->extra(HA_EXTRA_NO_CACHE);
++ if (error)
++ file->print_error(error,MYF(0));
++ DBUG_RETURN(1);
++}
++
++
++/**
++ Generate a hash index for each row to quickly find duplicate rows.
++
++ @note
++ Note that this will not work on tables with blobs!
++*/
++
++static int remove_dup_with_hash_index(THD *thd, TABLE *table,
++ uint field_count,
++ Field **first_field,
++ ulong key_length,
++ Item *having)
++{
++ uchar *key_buffer, *key_pos, *record=table->record[0];
++ int error;
++ handler *file= table->file;
++ ulong extra_length= ALIGN_SIZE(key_length)-key_length;
++ uint *field_lengths,*field_length;
++ HASH hash;
++ DBUG_ENTER("remove_dup_with_hash_index");
++
++ if (!my_multi_malloc(MYF(MY_WME),
++ &key_buffer,
++ (uint) ((key_length + extra_length) *
++ (long) file->stats.records),
++ &field_lengths,
++ (uint) (field_count*sizeof(*field_lengths)),
++ NullS))
++ DBUG_RETURN(1);
++
++ {
++ Field **ptr;
++ ulong total_length= 0;
++ for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
++ {
++ uint length= (*ptr)->sort_length();
++ (*field_length++)= length;
++ total_length+= length;
++ }
++ DBUG_PRINT("info",("field_count: %u key_length: %lu total_length: %lu",
++ field_count, key_length, total_length));
++ DBUG_ASSERT(total_length <= key_length);
++ key_length= total_length;
++ extra_length= ALIGN_SIZE(key_length)-key_length;
++ }
++
++ if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0,
++ key_length, (hash_get_key) 0, 0, 0))
++ {
++ my_free((char*) key_buffer,MYF(0));
++ DBUG_RETURN(1);
++ }
++
++ file->ha_rnd_init(1);
++ key_pos=key_buffer;
++ for (;;)
++ {
++ uchar *org_key_pos;
++ if (thd->killed)
++ {
++ thd->send_kill_message();
++ error=0;
++ goto err;
++ }
++ if ((error=file->rnd_next(record)))
++ {
++ if (error == HA_ERR_RECORD_DELETED)
++ continue;
++ if (error == HA_ERR_END_OF_FILE)
++ break;
++ goto err;
++ }
++ if (having && !having->val_int())
++ {
++ if ((error=file->ha_delete_row(record)))
++ goto err;
++ continue;
++ }
++
++ /* copy fields to key buffer */
++ org_key_pos= key_pos;
++ field_length=field_lengths;
++ for (Field **ptr= first_field ; *ptr ; ptr++)
++ {
++ (*ptr)->sort_string(key_pos,*field_length);
++ key_pos+= *field_length++;
++ }
++ /* Check if it exists before */
++ if (hash_search(&hash, org_key_pos, key_length))
++ {
++ /* Duplicated found ; Remove the row */
++ if ((error=file->ha_delete_row(record)))
++ goto err;
++ }
++ else
++ {
++ if (my_hash_insert(&hash, org_key_pos))
++ goto err;
++ }
++ key_pos+=extra_length;
++ }
++ my_free((char*) key_buffer,MYF(0));
++ hash_free(&hash);
++ file->extra(HA_EXTRA_NO_CACHE);
++ (void) file->ha_rnd_end();
++ DBUG_RETURN(0);
++
++err:
++ my_free((char*) key_buffer,MYF(0));
++ hash_free(&hash);
++ file->extra(HA_EXTRA_NO_CACHE);
++ (void) file->ha_rnd_end();
++ if (error)
++ file->print_error(error,MYF(0));
++ DBUG_RETURN(1);
++}
++
++
++SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
++ SORT_FIELD *sortorder)
++{
++ uint count;
++ SORT_FIELD *sort,*pos;
++ DBUG_ENTER("make_unireg_sortorder");
++
++ count=0;
++ for (ORDER *tmp = order; tmp; tmp=tmp->next)
++ count++;
++ if (!sortorder)
++ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
++ (max(count, *length) + 1));
++ pos= sort= sortorder;
++
++ if (!pos)
++ return 0;
++
++ for (;order;order=order->next,pos++)
++ {
++ Item *item= order->item[0]->real_item();
++ pos->field= 0; pos->item= 0;
++ if (item->type() == Item::FIELD_ITEM)
++ pos->field= ((Item_field*) item)->field;
++ else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
++ pos->field= ((Item_sum*) item)->get_tmp_table_field();
++ else if (item->type() == Item::COPY_STR_ITEM)
++ { // Blob patch
++ pos->item= ((Item_copy*) item)->get_item();
++ }
++ else
++ pos->item= *order->item;
++ pos->reverse=! order->asc;
++ }
++ *length=count;
++ DBUG_RETURN(sort);
++}
++
++
++/*****************************************************************************
++ Fill join cache with packed records
++ Records are stored in tab->cache.buffer and last record in
++ last record is stored with pointers to blobs to support very big
++ records
++******************************************************************************/
++
++static int
++join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
++{
++ reg1 uint i;
++ uint length, blobs;
++ size_t size;
++ CACHE_FIELD *copy,**blob_ptr;
++ JOIN_CACHE *cache;
++ JOIN_TAB *join_tab;
++ DBUG_ENTER("join_init_cache");
++
++ cache= &tables[table_count].cache;
++ cache->fields=blobs=0;
++
++ join_tab=tables;
++ for (i=0 ; i < table_count ; i++,join_tab++)
++ {
++ if (!join_tab->used_fieldlength) /* Not calced yet */
++ calc_used_field_length(thd, join_tab);
++ cache->fields+=join_tab->used_fields;
++ blobs+=join_tab->used_blobs;
++ }
++ if (!(cache->field=(CACHE_FIELD*)
++ sql_alloc(sizeof(CACHE_FIELD)*(cache->fields+table_count*2)+(blobs+1)*
++
++ sizeof(CACHE_FIELD*))))
++ {
++ my_free((uchar*) cache->buff,MYF(0)); /* purecov: inspected */
++ cache->buff=0; /* purecov: inspected */
++ DBUG_RETURN(1); /* purecov: inspected */
++ }
++ copy=cache->field;
++ blob_ptr=cache->blob_ptr=(CACHE_FIELD**)
++ (cache->field+cache->fields+table_count*2);
++
++ length=0;
++ for (i=0 ; i < table_count ; i++)
++ {
++ bool have_bit_fields= FALSE;
++ uint null_fields=0,used_fields;
++ Field **f_ptr,*field;
++ MY_BITMAP *read_set= tables[i].table->read_set;
++ for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
++ used_fields ;
++ f_ptr++)
++ {
++ field= *f_ptr;
++ if (bitmap_is_set(read_set, field->field_index))
++ {
++ used_fields--;
++ length+=field->fill_cache_field(copy);
++ if (copy->type == CACHE_BLOB)
++ (*blob_ptr++)=copy;
++ if (field->real_maybe_null())
++ null_fields++;
++ if (field->type() == MYSQL_TYPE_BIT &&
++ ((Field_bit*)field)->bit_len)
++ have_bit_fields= TRUE;
++ copy++;
++ }
++ }
++ /* Copy null bits from table */
++ if (null_fields || have_bit_fields)
++ { /* must copy null bits */
++ copy->str= tables[i].table->null_flags;
++ copy->length= tables[i].table->s->null_bytes;
++ copy->type=0;
++ copy->field=0;
++ length+=copy->length;
++ copy++;
++ cache->fields++;
++ }
++ /* If outer join table, copy null_row flag */
++ if (tables[i].table->maybe_null)
++ {
++ copy->str= (uchar*) &tables[i].table->null_row;
++ copy->length=sizeof(tables[i].table->null_row);
++ copy->type=0;
++ copy->field=0;
++ length+=copy->length;
++ copy++;
++ cache->fields++;
++ }
++ }
++
++ cache->length=length+blobs*sizeof(char*);
++ cache->blobs=blobs;
++ *blob_ptr=0; /* End sequentel */
++ size=max(thd->variables.join_buff_size, cache->length);
++ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
++ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
++ cache->end=cache->buff+size;
++ reset_cache_write(cache);
++ DBUG_RETURN(0);
++}
++
++
++static ulong
++used_blob_length(CACHE_FIELD **ptr)
++{
++ uint length,blob_length;
++ for (length=0 ; *ptr ; ptr++)
++ {
++ Field_blob *field_blob= (Field_blob *) (*ptr)->field;
++ (*ptr)->blob_length=blob_length= field_blob->get_length();
++ length+=blob_length;
++ field_blob->get_ptr(&(*ptr)->str);
++ }
++ return length;
++}
++
++
++static bool
++store_record_in_cache(JOIN_CACHE *cache)
++{
++ uint length;
++ uchar *pos;
++ CACHE_FIELD *copy,*end_field;
++ bool last_record;
++
++ pos=cache->pos;
++ end_field=cache->field+cache->fields;
++
++ length=cache->length;
++ if (cache->blobs)
++ length+=used_blob_length(cache->blob_ptr);
++ if ((last_record= (length + cache->length > (size_t) (cache->end - pos))))
++ cache->ptr_record=cache->records;
++
++ /*
++ There is room in cache. Put record there
++ */
++ cache->records++;
++ for (copy=cache->field ; copy < end_field; copy++)
++ {
++ if (copy->type == CACHE_BLOB)
++ {
++ Field_blob *blob_field= (Field_blob *) copy->field;
++ if (last_record)
++ {
++ blob_field->get_image(pos, copy->length+sizeof(char*),
++ blob_field->charset());
++ pos+=copy->length+sizeof(char*);
++ }
++ else
++ {
++ blob_field->get_image(pos, copy->length, // blob length
++ blob_field->charset());
++ memcpy(pos+copy->length,copy->str,copy->blob_length); // Blob data
++ pos+=copy->length+copy->blob_length;
++ }
++ }
++ else
++ {
++ if (copy->type == CACHE_STRIPPED)
++ {
++ uchar *str,*end;
++ Field *field= copy->field;
++ if (field && field->maybe_null() && field->is_null())
++ end= str= copy->str;
++ else
++ for (str=copy->str,end= str+copy->length;
++ end > str && end[-1] == ' ' ;
++ end--) ;
++ length=(uint) (end-str);
++ memcpy(pos+2, str, length);
++ int2store(pos, length);
++ pos+= length+2;
++ }
++ else
++ {
++ memcpy(pos,copy->str,copy->length);
++ pos+=copy->length;
++ }
++ }
++ }
++ cache->pos=pos;
++ return last_record || (size_t) (cache->end - pos) < cache->length;
++}
++
++
++static void
++reset_cache_read(JOIN_CACHE *cache)
++{
++ cache->record_nr=0;
++ cache->pos=cache->buff;
++}
++
++
++static void reset_cache_write(JOIN_CACHE *cache)
++{
++ reset_cache_read(cache);
++ cache->records= 0;
++ cache->ptr_record= (uint) ~0;
++}
++
++
++static void
++read_cached_record(JOIN_TAB *tab)
++{
++ uchar *pos;
++ uint length;
++ bool last_record;
++ CACHE_FIELD *copy,*end_field;
++
++ last_record=tab->cache.record_nr++ == tab->cache.ptr_record;
++ pos=tab->cache.pos;
++
++ for (copy=tab->cache.field,end_field=copy+tab->cache.fields ;
++ copy < end_field;
++ copy++)
++ {
++ if (copy->type == CACHE_BLOB)
++ {
++ Field_blob *blob_field= (Field_blob *) copy->field;
++ if (last_record)
++ {
++ blob_field->set_image(pos, copy->length+sizeof(char*),
++ blob_field->charset());
++ pos+=copy->length+sizeof(char*);
++ }
++ else
++ {
++ blob_field->set_ptr(pos, pos+copy->length);
++ pos+=copy->length + blob_field->get_length();
++ }
++ }
++ else
++ {
++ if (copy->type == CACHE_STRIPPED)
++ {
++ length= uint2korr(pos);
++ memcpy(copy->str, pos+2, length);
++ memset(copy->str+length, ' ', copy->length-length);
++ pos+= 2 + length;
++ }
++ else
++ {
++ memcpy(copy->str,pos,copy->length);
++ pos+=copy->length;
++ }
++ }
++ }
++ tab->cache.pos=pos;
++ return;
++}
++
++
++static bool
++cmp_buffer_with_ref(JOIN_TAB *tab)
++{
++ bool diff;
++ if (!(diff=tab->ref.key_err))
++ {
++ memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
++ }
++ if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, tab->table,
++ &tab->ref)) ||
++ diff)
++ return 1;
++ return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
++ != 0;
++}
++
++
++bool
++cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
++{
++ enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
++ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
++ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
++ bool result= 0;
++
++ for (store_key **copy=ref->key_copy ; *copy ; copy++)
++ {
++ if ((*copy)->copy() & 1)
++ {
++ result= 1;
++ break;
++ }
++ }
++ thd->count_cuted_fields= save_count_cuted_fields;
++ dbug_tmp_restore_column_map(table->write_set, old_map);
++ return result;
++}
++
++
++/*****************************************************************************
++ Group and order functions
++*****************************************************************************/
++
++/**
++ Resolve an ORDER BY or GROUP BY column reference.
++
++ Given a column reference (represented by 'order') from a GROUP BY or ORDER
++ BY clause, find the actual column it represents. If the column being
++ resolved is from the GROUP BY clause, the procedure searches the SELECT
++ list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
++ the ORDER BY clause, only the SELECT list is being searched.
++
++ If 'order' is resolved to an Item, then order->item is set to the found
++ Item. If there is no item for the found column (that is, it was resolved
++ into a table field), order->item is 'fixed' and is added to all_fields and
++ ref_pointer_array.
++
++ ref_pointer_array and all_fields are updated.
++
++ @param[in] thd Pointer to current thread structure
++ @param[in,out] ref_pointer_array All select, group and order by fields
++ @param[in] tables List of tables to search in (usually
++ FROM clause)
++ @param[in] order Column reference to be resolved
++ @param[in] fields List of fields to search in (usually
++ SELECT list)
++ @param[in,out] all_fields All select, group and order by fields
++ @param[in] is_group_field True if order is a GROUP field, false if
++ ORDER by field
++
++ @retval
++ FALSE if OK
++ @retval
++ TRUE if error occurred
++*/
++
++static bool
++find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
++ ORDER *order, List<Item> &fields, List<Item> &all_fields,
++ bool is_group_field)
++{
++ Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */
++ Item::Type order_item_type;
++ Item **select_item; /* The corresponding item from the SELECT clause. */
++ Field *from_field; /* The corresponding field from the FROM clause. */
++ uint counter;
++ enum_resolution_type resolution;
++
++ /*
++ Local SP variables may be int but are expressions, not positions.
++ (And they can't be used before fix_fields is called for them).
++ */
++ if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
++ { /* Order by position */
++ uint count= (uint) order_item->val_int();
++ if (!count || count > fields.elements)
++ {
++ my_error(ER_BAD_FIELD_ERROR, MYF(0),
++ order_item->full_name(), thd->where);
++ return TRUE;
++ }
++ order->item= ref_pointer_array + count - 1;
++ order->in_field_list= 1;
++ order->counter= count;
++ order->counter_used= 1;
++ return FALSE;
++ }
++ /* Lookup the current GROUP/ORDER field in the SELECT clause. */
++ select_item= find_item_in_list(order_item, fields, &counter,
++ REPORT_EXCEPT_NOT_FOUND, &resolution);
++ if (!select_item)
++ return TRUE; /* The item is not unique, or some other error occured. */
++
++
++ /* Check whether the resolved field is not ambiguos. */
++ if (select_item != not_found_item)
++ {
++ Item *view_ref= NULL;
++ /*
++ If we have found field not by its alias in select list but by its
++ original field name, we should additionaly check if we have conflict
++ for this name (in case if we would perform lookup in all tables).
++ */
++ if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
++ order_item->fix_fields(thd, order->item))
++ return TRUE;
++
++ /* Lookup the current GROUP field in the FROM clause. */
++ order_item_type= order_item->type();
++ from_field= (Field*) not_found_field;
++ if ((is_group_field &&
++ order_item_type == Item::FIELD_ITEM) ||
++ order_item_type == Item::REF_ITEM)
++ {
++ from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
++ NULL, &view_ref, IGNORE_ERRORS, TRUE,
++ FALSE);
++ if (!from_field)
++ from_field= (Field*) not_found_field;
++ }
++
++ if (from_field == not_found_field ||
++ (from_field != view_ref_found ?
++ /* it is field of base table => check that fields are same */
++ ((*select_item)->type() == Item::FIELD_ITEM &&
++ ((Item_field*) (*select_item))->field->eq(from_field)) :
++ /*
++ in is field of view table => check that references on translation
++ table are same
++ */
++ ((*select_item)->type() == Item::REF_ITEM &&
++ view_ref->type() == Item::REF_ITEM &&
++ ((Item_ref *) (*select_item))->ref ==
++ ((Item_ref *) view_ref)->ref)))
++ {
++ /*
++ If there is no such field in the FROM clause, or it is the same field
++ as the one found in the SELECT clause, then use the Item created for
++ the SELECT field. As a result if there was a derived field that
++ 'shadowed' a table field with the same name, the table field will be
++ chosen over the derived field.
++ */
++ order->item= ref_pointer_array + counter;
++ order->in_field_list=1;
++ return FALSE;
++ }
++ else
++ {
++ /*
++ There is a field with the same name in the FROM clause. This
++ is the field that will be chosen. In this case we issue a
++ warning so the user knows that the field from the FROM clause
++ overshadows the column reference from the SELECT list.
++ */
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
++ ER(ER_NON_UNIQ_ERROR),
++ ((Item_ident*) order_item)->field_name,
++ current_thd->where);
++ }
++ }
++
++ order->in_field_list=0;
++ /*
++ The call to order_item->fix_fields() means that here we resolve
++ 'order_item' to a column from a table in the list 'tables', or to
++ a column in some outer query. Exactly because of the second case
++ we come to this point even if (select_item == not_found_item),
++ inspite of that fix_fields() calls find_item_in_list() one more
++ time.
++
++ We check order_item->fixed because Item_func_group_concat can put
++ arguments for which fix_fields already was called.
++
++ group_fix_field= TRUE is to resolve aliases from the SELECT list
++ without creating of Item_ref-s: JOIN::exec() wraps aliased items
++ in SELECT list with Item_copy items. To re-evaluate such a tree
++ that includes Item_copy items we have to refresh Item_copy caches,
++ but:
++ - filesort() never refresh Item_copy items,
++ - end_send_group() checks every record for group boundary by the
++ test_if_group_changed function that obtain data from these
++ Item_copy items, but the copy_fields function that
++ refreshes Item copy items is called after group boundaries only -
++ that is a vicious circle.
++ So we prevent inclusion of Item_copy items.
++ */
++ bool save_group_fix_field= thd->lex->current_select->group_fix_field;
++ if (is_group_field)
++ thd->lex->current_select->group_fix_field= TRUE;
++ bool ret= (!order_item->fixed &&
++ (order_item->fix_fields(thd, order->item) ||
++ (order_item= *order->item)->check_cols(1) ||
++ thd->is_fatal_error));
++ thd->lex->current_select->group_fix_field= save_group_fix_field;
++ if (ret)
++ return TRUE; /* Wrong field. */
++
++ uint el= all_fields.elements;
++ all_fields.push_front(order_item); /* Add new field to field list. */
++ ref_pointer_array[el]= order_item;
++ order->item= ref_pointer_array + el;
++ return FALSE;
++}
++
++
++/**
++ Change order to point at item in select list.
++
++ If item isn't a number and doesn't exits in the select list, add it the
++ the field list.
++*/
++
++int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
++ List<Item> &fields, List<Item> &all_fields, ORDER *order)
++{
++ thd->where="order clause";
++ for (; order; order=order->next)
++ {
++ if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
++ all_fields, FALSE))
++ return 1;
++ }
++ return 0;
++}
++
++
++/**
++ Intitialize the GROUP BY list.
++
++ @param thd Thread handler
++ @param ref_pointer_array We store references to all fields that was
++ not in 'fields' here.
++ @param fields All fields in the select part. Any item in
++ 'order' that is part of these list is replaced
++ by a pointer to this fields.
++ @param all_fields Total list of all unique fields used by the
++ select. All items in 'order' that was not part
++ of fields will be added first to this list.
++ @param order The fields we should do GROUP BY on.
++ @param hidden_group_fields Pointer to flag that is set to 1 if we added
++ any fields to all_fields.
++
++ @todo
++ change ER_WRONG_FIELD_WITH_GROUP to more detailed
++ ER_NON_GROUPING_FIELD_USED
++
++ @retval
++ 0 ok
++ @retval
++ 1 error (probably out of memory)
++*/
++
++int
++setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
++ List<Item> &fields, List<Item> &all_fields, ORDER *order,
++ bool *hidden_group_fields)
++{
++ *hidden_group_fields=0;
++ ORDER *ord;
++
++ if (!order)
++ return 0; /* Everything is ok */
++
++ uint org_fields=all_fields.elements;
++
++ thd->where="group statement";
++ for (ord= order; ord; ord= ord->next)
++ {
++ if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
++ all_fields, TRUE))
++ return 1;
++ (*ord->item)->marker= UNDEF_POS; /* Mark found */
++ if ((*ord->item)->with_sum_func)
++ {
++ my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
++ return 1;
++ }
++ }
++ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
++ {
++ /*
++ Don't allow one to use fields that is not used in GROUP BY
++ For each select a list of field references that aren't under an
++ aggregate function is created. Each field in this list keeps the
++ position of the select list expression which it belongs to.
++
++ First we check an expression from the select list against the GROUP BY
++ list. If it's found there then it's ok. It's also ok if this expression
++ is a constant or an aggregate function. Otherwise we scan the list
++ of non-aggregated fields and if we'll find at least one field reference
++ that belongs to this expression and doesn't occur in the GROUP BY list
++ we throw an error. If there are no fields in the created list for a
++ select list expression this means that all fields in it are used under
++ aggregate functions.
++ */
++ Item *item;
++ Item_field *field;
++ int cur_pos_in_select_list= 0;
++ List_iterator<Item> li(fields);
++ List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
++
++ field= naf_it++;
++ while (field && (item=li++))
++ {
++ if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 &&
++ !item->const_item() &&
++ !(item->real_item()->type() == Item::FIELD_ITEM &&
++ item->used_tables() & OUTER_REF_TABLE_BIT))
++ {
++ while (field)
++ {
++ /* Skip fields from previous expressions. */
++ if (field->marker < cur_pos_in_select_list)
++ goto next_field;
++ /* Found a field from the next expression. */
++ if (field->marker > cur_pos_in_select_list)
++ break;
++ /*
++ Check whether the field occur in the GROUP BY list.
++ Throw the error later if the field isn't found.
++ */
++ for (ord= order; ord; ord= ord->next)
++ if ((*ord->item)->eq((Item*)field, 0))
++ goto next_field;
++ /*
++ TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
++ ER_NON_GROUPING_FIELD_USED
++ */
++ my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
++ return 1;
++next_field:
++ field= naf_it++;
++ }
++ }
++ cur_pos_in_select_list++;
++ }
++ }
++ if (org_fields != all_fields.elements)
++ *hidden_group_fields=1; // group fields is not used
++ return 0;
++}
++
++/**
++ Add fields with aren't used at start of field list.
++
++ @return
++ FALSE if ok
++*/
++
++static bool
++setup_new_fields(THD *thd, List<Item> &fields,
++ List<Item> &all_fields, ORDER *new_field)
++{
++ Item **item;
++ uint counter;
++ enum_resolution_type not_used;
++ DBUG_ENTER("setup_new_fields");
++
++ thd->mark_used_columns= MARK_COLUMNS_READ; // Not really needed, but...
++ for (; new_field ; new_field= new_field->next)
++ {
++ if ((item= find_item_in_list(*new_field->item, fields, &counter,
++ IGNORE_ERRORS, ¬_used)))
++ new_field->item=item; /* Change to shared Item */
++ else
++ {
++ thd->where="procedure list";
++ if ((*new_field->item)->fix_fields(thd, new_field->item))
++ DBUG_RETURN(1); /* purecov: inspected */
++ all_fields.push_front(*new_field->item);
++ new_field->item=all_fields.head_ref();
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++/**
++ Create a group by that consist of all non const fields.
++
++ Try to use the fields in the order given by 'order' to allow one to
++ optimize away 'order by'.
++*/
++
++static ORDER *
++create_distinct_group(THD *thd, Item **ref_pointer_array,
++ ORDER *order_list, List<Item> &fields,
++ List<Item> &all_fields,
++ bool *all_order_by_fields_used)
++{
++ List_iterator<Item> li(fields);
++ Item *item, **orig_ref_pointer_array= ref_pointer_array;
++ ORDER *order,*group,**prev;
++
++ *all_order_by_fields_used= 1;
++ while ((item=li++))
++ item->marker=0; /* Marker that field is not used */
++
++ prev= &group; group=0;
++ for (order=order_list ; order; order=order->next)
++ {
++ if (order->in_field_list)
++ {
++ ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER));
++ if (!ord)
++ return 0;
++ *prev=ord;
++ prev= &ord->next;
++ (*ord->item)->marker=1;
++ }
++ else
++ *all_order_by_fields_used= 0;
++ }
++
++ li.rewind();
++ while ((item=li++))
++ {
++ if (!item->const_item() && !item->with_sum_func && !item->marker)
++ {
++ /*
++ Don't put duplicate columns from the SELECT list into the
++ GROUP BY list.
++ */
++ ORDER *ord_iter;
++ for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
++ if ((*ord_iter->item)->eq(item, 1))
++ goto next_item;
++
++ ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
++ if (!ord)
++ return 0;
++
++ if (item->type() == Item::FIELD_ITEM &&
++ item->field_type() == MYSQL_TYPE_BIT)
++ {
++ /*
++ Because HEAP tables can't index BIT fields we need to use an
++ additional hidden field for grouping because later it will be
++ converted to a LONG field. Original field will remain of the
++ BIT type and will be returned to a client.
++ */
++ Item_field *new_item= new Item_field(thd, (Item_field*)item);
++ int el= all_fields.elements;
++ orig_ref_pointer_array[el]= new_item;
++ all_fields.push_front(new_item);
++ ord->item= orig_ref_pointer_array + el;
++ }
++ else
++ {
++ /*
++ We have here only field_list (not all_field_list), so we can use
++ simple indexing of ref_pointer_array (order in the array and in the
++ list are same)
++ */
++ ord->item= ref_pointer_array;
++ }
++ ord->asc=1;
++ *prev=ord;
++ prev= &ord->next;
++ }
++next_item:
++ ref_pointer_array++;
++ }
++ *prev=0;
++ return group;
++}
++
++
++/**
++ Update join with count of the different type of fields.
++*/
++
++void
++count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
++ List<Item> &fields, bool reset_with_sum_func)
++{
++ List_iterator<Item> li(fields);
++ Item *field;
++
++ param->field_count=param->sum_func_count=param->func_count=
++ param->hidden_field_count=0;
++ param->quick_group=1;
++ while ((field=li++))
++ {
++ Item::Type real_type= field->real_item()->type();
++ if (real_type == Item::FIELD_ITEM)
++ param->field_count++;
++ else if (real_type == Item::SUM_FUNC_ITEM)
++ {
++ if (! field->const_item())
++ {
++ Item_sum *sum_item=(Item_sum*) field->real_item();
++ if (!sum_item->depended_from() ||
++ sum_item->depended_from() == select_lex)
++ {
++ if (!sum_item->quick_group)
++ param->quick_group=0; // UDF SUM function
++ param->sum_func_count++;
++
++ for (uint i=0 ; i < sum_item->get_arg_count() ; i++)
++ {
++ if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM)
++ param->field_count++;
++ else
++ param->func_count++;
++ }
++ }
++ param->func_count++;
++ }
++ }
++ else
++ {
++ param->func_count++;
++ if (reset_with_sum_func)
++ field->with_sum_func=0;
++ }
++ }
++}
++
++
++/**
++ Return 1 if second is a subpart of first argument.
++
++ If first parts has different direction, change it to second part
++ (group is sorted like order)
++*/
++
++static bool
++test_if_subpart(ORDER *a,ORDER *b)
++{
++ for (; a && b; a=a->next,b=b->next)
++ {
++ if ((*a->item)->eq(*b->item,1))
++ a->asc=b->asc;
++ else
++ return 0;
++ }
++ return test(!b);
++}
++
++/**
++ Return table number if there is only one table in sort order
++ and group and order is compatible, else return 0.
++*/
++
++static TABLE *
++get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
++{
++ table_map map= (table_map) 0;
++ DBUG_ENTER("get_sort_by_table");
++
++ if (!a)
++ a=b; // Only one need to be given
++ else if (!b)
++ b=a;
++
++ for (; a && b; a=a->next,b=b->next)
++ {
++ if (!(*a->item)->eq(*b->item,1))
++ DBUG_RETURN(0);
++ map|=a->item[0]->used_tables();
++ }
++ if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
++ DBUG_RETURN(0);
++
++ for (; !(map & tables->table->map); tables= tables->next_leaf) ;
++ if (map != tables->table->map)
++ DBUG_RETURN(0); // More than one table
++ DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
++ DBUG_RETURN(tables->table);
++}
++
++
++/**
++ calc how big buffer we need for comparing group entries.
++*/
++
++static void
++calc_group_buffer(JOIN *join,ORDER *group)
++{
++ uint key_length=0, parts=0, null_parts=0;
++
++ if (group)
++ join->group= 1;
++ for (; group ; group=group->next)
++ {
++ Item *group_item= *group->item;
++ Field *field= group_item->get_tmp_table_field();
++ if (field)
++ {
++ enum_field_types type;
++ if ((type= field->type()) == MYSQL_TYPE_BLOB)
++ key_length+=MAX_BLOB_WIDTH; // Can't be used as a key
++ else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING)
++ key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
++ else if (type == MYSQL_TYPE_BIT)
++ {
++ /* Bit is usually stored as a longlong key for group fields */
++ key_length+= 8; // Big enough
++ }
++ else
++ key_length+= field->pack_length();
++ }
++ else
++ {
++ switch (group_item->result_type()) {
++ case REAL_RESULT:
++ key_length+= sizeof(double);
++ break;
++ case INT_RESULT:
++ key_length+= sizeof(longlong);
++ break;
++ case DECIMAL_RESULT:
++ key_length+= my_decimal_get_binary_size(group_item->max_length -
++ (group_item->decimals ? 1 : 0),
++ group_item->decimals);
++ break;
++ case STRING_RESULT:
++ {
++ enum enum_field_types type= group_item->field_type();
++ /*
++ As items represented as DATE/TIME fields in the group buffer
++ have STRING_RESULT result type, we increase the length
++ by 8 as maximum pack length of such fields.
++ */
++ if (type == MYSQL_TYPE_TIME ||
++ type == MYSQL_TYPE_DATE ||
++ type == MYSQL_TYPE_DATETIME ||
++ type == MYSQL_TYPE_TIMESTAMP)
++ {
++ key_length+= 8;
++ }
++ else if (type == MYSQL_TYPE_BLOB)
++ key_length+= MAX_BLOB_WIDTH; // Can't be used as a key
++ else
++ {
++ /*
++ Group strings are taken as varstrings and require an length field.
++ A field is not yet created by create_tmp_field()
++ and the sizes should match up.
++ */
++ key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
++ }
++ break;
++ }
++ default:
++ /* This case should never be choosen */
++ DBUG_ASSERT(0);
++ my_error(ER_OUT_OF_RESOURCES, MYF(0));
++ join->thd->fatal_error();
++ }
++ }
++ parts++;
++ if (group_item->maybe_null)
++ null_parts++;
++ }
++ join->tmp_table_param.group_length=key_length+null_parts;
++ join->tmp_table_param.group_parts=parts;
++ join->tmp_table_param.group_null_parts=null_parts;
++}
++
++
++/**
++ allocate group fields or take prepared (cached).
++
++ @param main_join join of current select
++ @param curr_join current join (join of current select or temporary copy
++ of it)
++
++ @retval
++ 0 ok
++ @retval
++ 1 failed
++*/
++
++static bool
++make_group_fields(JOIN *main_join, JOIN *curr_join)
++{
++ if (main_join->group_fields_cache.elements)
++ {
++ curr_join->group_fields= main_join->group_fields_cache;
++ curr_join->sort_and_group= 1;
++ }
++ else
++ {
++ if (alloc_group_fields(curr_join, curr_join->group_list))
++ return (1);
++ main_join->group_fields_cache= curr_join->group_fields;
++ }
++ return (0);
++}
++
++
++/**
++ Get a list of buffers for saveing last group.
++
++ Groups are saved in reverse order for easyer check loop.
++*/
++
++static bool
++alloc_group_fields(JOIN *join,ORDER *group)
++{
++ if (group)
++ {
++ for (; group ; group=group->next)
++ {
++ Cached_item *tmp=new_Cached_item(join->thd, *group->item);
++ if (!tmp || join->group_fields.push_front(tmp))
++ return TRUE;
++ }
++ }
++ join->sort_and_group=1; /* Mark for do_select */
++ return FALSE;
++}
++
++
++static int
++test_if_group_changed(List<Cached_item> &list)
++{
++ DBUG_ENTER("test_if_group_changed");
++ List_iterator<Cached_item> li(list);
++ int idx= -1,i;
++ Cached_item *buff;
++
++ for (i=(int) list.elements-1 ; (buff=li++) ; i--)
++ {
++ if (buff->cmp())
++ idx=i;
++ }
++ DBUG_PRINT("info", ("idx: %d", idx));
++ DBUG_RETURN(idx);
++}
++
++
++/**
++ Setup copy_fields to save fields at start of new group.
++
++ Setup copy_fields to save fields at start of new group
++
++ Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
++ Change old item_field to use a new field with points at saved fieldvalue
++ This function is only called before use of send_fields.
++
++ @param thd THD pointer
++ @param param temporary table parameters
++ @param ref_pointer_array array of pointers to top elements of filed list
++ @param res_selected_fields new list of items of select item list
++ @param res_all_fields new list of all items
++ @param elements number of elements in select item list
++ @param all_fields all fields list
++
++ @todo
++ In most cases this result will be sent to the user.
++ This should be changed to use copy_int or copy_real depending
++ on how the value is to be used: In some cases this may be an
++ argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
++
++ @retval
++ 0 ok
++ @retval
++ !=0 error
++*/
++
++bool
++setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
++ Item **ref_pointer_array,
++ List<Item> &res_selected_fields, List<Item> &res_all_fields,
++ uint elements, List<Item> &all_fields)
++{
++ Item *pos;
++ List_iterator_fast<Item> li(all_fields);
++ Copy_field *copy= NULL;
++ IF_DBUG(Copy_field *copy_start);
++ res_selected_fields.empty();
++ res_all_fields.empty();
++ List_iterator_fast<Item> itr(res_all_fields);
++ List<Item> extra_funcs;
++ uint i, border= all_fields.elements - elements;
++ DBUG_ENTER("setup_copy_fields");
++
++ if (param->field_count &&
++ !(copy=param->copy_field= new Copy_field[param->field_count]))
++ goto err2;
++
++ param->copy_funcs.empty();
++ IF_DBUG(copy_start= copy);
++ for (i= 0; (pos= li++); i++)
++ {
++ Field *field;
++ uchar *tmp;
++ Item *real_pos= pos->real_item();
++ /*
++ Aggregate functions can be substituted for fields (by e.g. temp tables).
++ We need to filter those substituted fields out.
++ */
++ if (real_pos->type() == Item::FIELD_ITEM &&
++ !(real_pos != pos &&
++ ((Item_ref *)pos)->ref_type() == Item_ref::AGGREGATE_REF))
++ {
++ Item_field *item;
++ if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
++ goto err;
++ if (pos->type() == Item::REF_ITEM)
++ {
++ /* preserve the names of the ref when dereferncing */
++ Item_ref *ref= (Item_ref *) pos;
++ item->db_name= ref->db_name;
++ item->table_name= ref->table_name;
++ item->name= ref->name;
++ }
++ pos= item;
++ if (item->field->flags & BLOB_FLAG)
++ {
++ if (!(pos= Item_copy::create(pos)))
++ goto err;
++ /*
++ Item_copy_string::copy for function can call
++ Item_copy_string::val_int for blob via Item_ref.
++ But if Item_copy_string::copy for blob isn't called before,
++ it's value will be wrong
++ so let's insert Item_copy_string for blobs in the beginning of
++ copy_funcs
++ (to see full test case look at having.test, BUG #4358)
++ */
++ if (param->copy_funcs.push_front(pos))
++ goto err;
++ }
++ else
++ {
++ /*
++ set up save buffer and change result_field to point at
++ saved value
++ */
++ field= item->field;
++ item->result_field=field->new_field(thd->mem_root,field->table, 1);
++ /*
++ We need to allocate one extra byte for null handling and
++ another extra byte to not get warnings from purify in
++ Field_string::val_int
++ */
++ if (!(tmp= (uchar*) sql_alloc(field->pack_length()+2)))
++ goto err;
++ if (copy)
++ {
++ DBUG_ASSERT (param->field_count > (uint) (copy - copy_start));
++ copy->set(tmp, item->result_field);
++ item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
++#ifdef HAVE_purify
++ copy->to_ptr[copy->from_length]= 0;
++#endif
++ copy++;
++ }
++ }
++ }
++ else if ((real_pos->type() == Item::FUNC_ITEM ||
++ real_pos->type() == Item::SUBSELECT_ITEM ||
++ real_pos->type() == Item::CACHE_ITEM ||
++ real_pos->type() == Item::COND_ITEM) &&
++ !real_pos->with_sum_func)
++ { // Save for send fields
++ pos= real_pos;
++ /* TODO:
++ In most cases this result will be sent to the user.
++ This should be changed to use copy_int or copy_real depending
++ on how the value is to be used: In some cases this may be an
++ argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
++ */
++ if (!(pos= Item_copy::create(pos)))
++ goto err;
++ if (i < border) // HAVING, ORDER and GROUP BY
++ {
++ if (extra_funcs.push_back(pos))
++ goto err;
++ }
++ else if (param->copy_funcs.push_back(pos))
++ goto err;
++ }
++ res_all_fields.push_back(pos);
++ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
++ pos;
++ }
++ param->copy_field_end= copy;
++
++ for (i= 0; i < border; i++)
++ itr++;
++ itr.sublist(res_selected_fields, elements);
++ /*
++ Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
++ reference used in these will resolve to a item that is already calculated
++ */
++ param->copy_funcs.concat(&extra_funcs);
++
++ DBUG_RETURN(0);
++
++ err:
++ if (copy)
++ delete [] param->copy_field; // This is never 0
++ param->copy_field=0;
++err2:
++ DBUG_RETURN(TRUE);
++}
++
++
++/**
++ Make a copy of all simple SELECT'ed items.
++
++ This is done at the start of a new group so that we can retrieve
++ these later when the group changes.
++*/
++
++void
++copy_fields(TMP_TABLE_PARAM *param)
++{
++ Copy_field *ptr=param->copy_field;
++ Copy_field *end=param->copy_field_end;
++
++ for (; ptr != end; ptr++)
++ (*ptr->do_copy)(ptr);
++
++ List_iterator_fast<Item> it(param->copy_funcs);
++ Item_copy *item;
++ while ((item = (Item_copy*) it++))
++ item->copy();
++}
++
++
++/**
++ Make an array of pointers to sum_functions to speed up
++ sum_func calculation.
++
++ @retval
++ 0 ok
++ @retval
++ 1 Error
++*/
++
++bool JOIN::alloc_func_list()
++{
++ uint func_count, group_parts;
++ DBUG_ENTER("alloc_func_list");
++
++ func_count= tmp_table_param.sum_func_count;
++ /*
++ If we are using rollup, we need a copy of the summary functions for
++ each level
++ */
++ if (rollup.state != ROLLUP::STATE_NONE)
++ func_count*= (send_group_parts+1);
++
++ group_parts= send_group_parts;
++ /*
++ If distinct, reserve memory for possible
++ disctinct->group_by optimization
++ */
++ if (select_distinct)
++ {
++ group_parts+= fields_list.elements;
++ /*
++ If the ORDER clause is specified then it's possible that
++ it also will be optimized, so reserve space for it too
++ */
++ if (order)
++ {
++ ORDER *ord;
++ for (ord= order; ord; ord= ord->next)
++ group_parts++;
++ }
++ }
++
++ /* This must use calloc() as rollup_make_fields depends on this */
++ sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
++ sizeof(Item_sum***) * (group_parts+1));
++ sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
++ DBUG_RETURN(sum_funcs == 0);
++}
++
++
++/**
++ Initialize 'sum_funcs' array with all Item_sum objects.
++
++ @param field_list All items
++ @param send_fields Items in select list
++ @param before_group_by Set to 1 if this is called before GROUP BY handling
++ @param recompute Set to TRUE if sum_funcs must be recomputed
++
++ @retval
++ 0 ok
++ @retval
++ 1 error
++*/
++
++bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
++ bool before_group_by, bool recompute)
++{
++ List_iterator_fast<Item> it(field_list);
++ Item_sum **func;
++ Item *item;
++ DBUG_ENTER("make_sum_func_list");
++
++ if (*sum_funcs && !recompute)
++ DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */
++
++ func= sum_funcs;
++ while ((item=it++))
++ {
++ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
++ (!((Item_sum*) item)->depended_from() ||
++ ((Item_sum *)item)->depended_from() == select_lex))
++ *func++= (Item_sum*) item;
++ }
++ if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
++ {
++ rollup.state= ROLLUP::STATE_READY;
++ if (rollup_make_fields(field_list, send_fields, &func))
++ DBUG_RETURN(TRUE); // Should never happen
++ }
++ else if (rollup.state == ROLLUP::STATE_NONE)
++ {
++ for (uint i=0 ; i <= send_group_parts ;i++)
++ sum_funcs_end[i]= func;
++ }
++ else if (rollup.state == ROLLUP::STATE_READY)
++ DBUG_RETURN(FALSE); // Don't put end marker
++ *func=0; // End marker
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Change all funcs and sum_funcs to fields in tmp table, and create
++ new list of all items.
++
++ @param thd THD pointer
++ @param ref_pointer_array array of pointers to top elements of filed list
++ @param res_selected_fields new list of items of select item list
++ @param res_all_fields new list of all items
++ @param elements number of elements in select item list
++ @param all_fields all fields list
++
++ @retval
++ 0 ok
++ @retval
++ !=0 error
++*/
++
++static bool
++change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
++ List<Item> &res_selected_fields,
++ List<Item> &res_all_fields,
++ uint elements, List<Item> &all_fields)
++{
++ List_iterator_fast<Item> it(all_fields);
++ Item *item_field,*item;
++ DBUG_ENTER("change_to_use_tmp_fields");
++
++ res_selected_fields.empty();
++ res_all_fields.empty();
++
++ uint i, border= all_fields.elements - elements;
++ for (i= 0; (item= it++); i++)
++ {
++ Field *field;
++
++ if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) ||
++ (item->type() == Item::FUNC_ITEM &&
++ ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC))
++ item_field= item;
++ else
++ {
++ if (item->type() == Item::FIELD_ITEM)
++ {
++ item_field= item->get_tmp_table_item(thd);
++ }
++ else if ((field= item->get_tmp_table_field()))
++ {
++ if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
++ item_field= ((Item_sum*) item)->result_item(field);
++ else
++ item_field= (Item*) new Item_field(field);
++ if (!item_field)
++ DBUG_RETURN(TRUE); // Fatal error
++
++ if (item->real_item()->type() != Item::FIELD_ITEM)
++ field->orig_table= 0;
++ item_field->name= item->name;
++ if (item->type() == Item::REF_ITEM)
++ {
++ Item_field *ifield= (Item_field *) item_field;
++ Item_ref *iref= (Item_ref *) item;
++ ifield->table_name= iref->table_name;
++ ifield->db_name= iref->db_name;
++ }
++#ifndef DBUG_OFF
++ if (!item_field->name)
++ {
++ char buff[256];
++ String str(buff,sizeof(buff),&my_charset_bin);
++ str.length(0);
++ item->print(&str, QT_ORDINARY);
++ item_field->name= sql_strmake(str.ptr(),str.length());
++ }
++#endif
++ }
++ else
++ item_field= item;
++ }
++ res_all_fields.push_back(item_field);
++ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
++ item_field;
++ }
++
++ List_iterator_fast<Item> itr(res_all_fields);
++ for (i= 0; i < border; i++)
++ itr++;
++ itr.sublist(res_selected_fields, elements);
++ DBUG_RETURN(FALSE);
++}
++
++
++/**
++ Change all sum_func refs to fields to point at fields in tmp table.
++ Change all funcs to be fields in tmp table.
++
++ @param thd THD pointer
++ @param ref_pointer_array array of pointers to top elements of filed list
++ @param res_selected_fields new list of items of select item list
++ @param res_all_fields new list of all items
++ @param elements number of elements in select item list
++ @param all_fields all fields list
++
++ @retval
++ 0 ok
++ @retval
++ 1 error
++*/
++
++static bool
++change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
++ List<Item> &res_selected_fields,
++ List<Item> &res_all_fields, uint elements,
++ List<Item> &all_fields)
++{
++ List_iterator_fast<Item> it(all_fields);
++ Item *item, *new_item;
++ res_selected_fields.empty();
++ res_all_fields.empty();
++
++ uint i, border= all_fields.elements - elements;
++ for (i= 0; (item= it++); i++)
++ {
++ res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
++ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
++ new_item;
++ }
++
++ List_iterator_fast<Item> itr(res_all_fields);
++ for (i= 0; i < border; i++)
++ itr++;
++ itr.sublist(res_selected_fields, elements);
++
++ return thd->is_fatal_error;
++}
++
++
++
++/******************************************************************************
++ Code for calculating functions
++******************************************************************************/
++
++
++/**
++ Call ::setup for all sum functions.
++
++ @param thd thread handler
++ @param func_ptr sum function list
++
++ @retval
++ FALSE ok
++ @retval
++ TRUE error
++*/
++
++static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
++{
++ Item_sum *func;
++ DBUG_ENTER("setup_sum_funcs");
++ while ((func= *(func_ptr++)))
++ {
++ if (func->setup(thd))
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++static void
++init_tmptable_sum_functions(Item_sum **func_ptr)
++{
++ Item_sum *func;
++ while ((func= *(func_ptr++)))
++ func->reset_field();
++}
++
++
++/** Update record 0 in tmp_table from record 1. */
++
++static void
++update_tmptable_sum_func(Item_sum **func_ptr,
++ TABLE *tmp_table __attribute__((unused)))
++{
++ Item_sum *func;
++ while ((func= *(func_ptr++)))
++ func->update_field();
++}
++
++
++/** Copy result of sum functions to record in tmp_table. */
++
++static void
++copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr)
++{
++ for (; func_ptr != end_ptr ; func_ptr++)
++ (void) (*func_ptr)->save_in_result_field(1);
++ return;
++}
++
++
++static bool
++init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
++{
++ for (; func_ptr != end_ptr ;func_ptr++)
++ {
++ if ((*func_ptr)->reset())
++ return 1;
++ }
++ /* If rollup, calculate the upper sum levels */
++ for ( ; *func_ptr ; func_ptr++)
++ {
++ if ((*func_ptr)->add())
++ return 1;
++ }
++ return 0;
++}
++
++
++static bool
++update_sum_func(Item_sum **func_ptr)
++{
++ Item_sum *func;
++ for (; (func= (Item_sum*) *func_ptr) ; func_ptr++)
++ if (func->add())
++ return 1;
++ return 0;
++}
++
++/**
++ Copy result of functions to record in tmp_table.
++
++ Uses the thread pointer to check for errors in
++ some of the val_xxx() methods called by the
++ save_in_result_field() function.
++ TODO: make the Item::val_xxx() return error code
++
++ @param func_ptr array of the function Items to copy to the tmp table
++ @param thd pointer to the current thread for error checking
++ @retval
++ FALSE if OK
++ @retval
++ TRUE on error
++*/
++
++bool
++copy_funcs(Item **func_ptr, const THD *thd)
++{
++ Item *func;
++ for (; (func = *func_ptr) ; func_ptr++)
++ {
++ func->save_in_result_field(1);
++ /*
++ Need to check the THD error state because Item::val_xxx() don't
++ return error code, but can generate errors
++ TODO: change it for a real status check when Item::val_xxx()
++ are extended to return status code.
++ */
++ if (thd->is_error())
++ return TRUE;
++ }
++ return FALSE;
++}
++
++
++/**
++ Create a condition for a const reference and add this to the
++ currenct select for the table.
++*/
++
++static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
++{
++ DBUG_ENTER("add_ref_to_table_cond");
++ if (!join_tab->ref.key_parts)
++ DBUG_RETURN(FALSE);
++
++ Item_cond_and *cond=new Item_cond_and();
++ TABLE *table=join_tab->table;
++ int error= 0;
++ if (!cond)
++ DBUG_RETURN(TRUE);
++
++ for (uint i=0 ; i < join_tab->ref.key_parts ; i++)
++ {
++ Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
++ fieldnr-1];
++ Item *value=join_tab->ref.items[i];
++ cond->add(new Item_func_equal(new Item_field(field), value));
++ }
++ if (thd->is_fatal_error)
++ DBUG_RETURN(TRUE);
++
++ if (!cond->fixed)
++ cond->fix_fields(thd, (Item**)&cond);
++ if (join_tab->select)
++ {
++ if (join_tab->select->cond)
++ error=(int) cond->add(join_tab->select->cond);
++ join_tab->select_cond=join_tab->select->cond=cond;
++ }
++ else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
++ &error)))
++ join_tab->select_cond=cond;
++
++ DBUG_RETURN(error ? TRUE : FALSE);
++}
++
++
++/**
++ Free joins of subselect of this select.
++
++ @param thd THD pointer
++ @param select pointer to st_select_lex which subselects joins we will free
++*/
++
++void free_underlaid_joins(THD *thd, SELECT_LEX *select)
++{
++ for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
++ unit;
++ unit= unit->next_unit())
++ unit->cleanup();
++}
++
++/****************************************************************************
++ ROLLUP handling
++****************************************************************************/
++
++/**
++ Replace occurences of group by fields in an expression by ref items.
++
++ The function replaces occurrences of group by fields in expr
++ by ref objects for these fields unless they are under aggregate
++ functions.
++ The function also corrects value of the the maybe_null attribute
++ for the items of all subexpressions containing group by fields.
++
++ @b EXAMPLES
++ @code
++ SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
++ SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
++ @endcode
++
++ @b IMPLEMENTATION
++
++ The function recursively traverses the tree of the expr expression,
++ looks for occurrences of the group by fields that are not under
++ aggregate functions and replaces them for the corresponding ref items.
++
++ @note
++ This substitution is needed GROUP BY queries with ROLLUP if
++ SELECT list contains expressions over group by attributes.
++
++ @param thd reference to the context
++ @param expr expression to make replacement
++ @param group_list list of references to group by items
++ @param changed out: returns 1 if item contains a replaced field item
++
++ @todo
++ - TODO: Some functions are not null-preserving. For those functions
++ updating of the maybe_null attribute is an overkill.
++
++ @retval
++ 0 if ok
++ @retval
++ 1 on error
++*/
++
++static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
++ bool *changed)
++{
++ if (expr->arg_count)
++ {
++ Name_resolution_context *context= &thd->lex->current_select->context;
++ Item **arg,**arg_end;
++ bool arg_changed= FALSE;
++ for (arg= expr->arguments(),
++ arg_end= expr->arguments()+expr->arg_count;
++ arg != arg_end; arg++)
++ {
++ Item *item= *arg;
++ if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
++ {
++ ORDER *group_tmp;
++ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
++ {
++ if (item->eq(*group_tmp->item,0))
++ {
++ Item *new_item;
++ if (!(new_item= new Item_ref(context, group_tmp->item, 0,
++ item->name)))
++ return 1; // fatal_error is set
++ thd->change_item_tree(arg, new_item);
++ arg_changed= TRUE;
++ }
++ }
++ }
++ else if (item->type() == Item::FUNC_ITEM)
++ {
++ if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
++ return 1;
++ }
++ }
++ if (arg_changed)
++ {
++ expr->maybe_null= 1;
++ *changed= TRUE;
++ }
++ }
++ return 0;
++}
++
++
++/** Allocate memory needed for other rollup functions. */
++
++bool JOIN::rollup_init()
++{
++ uint i,j;
++ Item **ref_array;
++
++ tmp_table_param.quick_group= 0; // Can't create groups in tmp table
++ rollup.state= ROLLUP::STATE_INITED;
++
++ /*
++ Create pointers to the different sum function groups
++ These are updated by rollup_make_fields()
++ */
++ tmp_table_param.group_parts= send_group_parts;
++
++ if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
++ sizeof(Item**) +
++ sizeof(List<Item>) +
++ ref_pointer_array_size)
++ * send_group_parts )))
++ return 1;
++
++ rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
++ rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
++ ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
++
++ /*
++ Prepare space for field list for the different levels
++ These will be filled up in rollup_make_fields()
++ */
++ for (i= 0 ; i < send_group_parts ; i++)
++ {
++ rollup.null_items[i]= new (thd->mem_root) Item_null_result();
++ List<Item> *rollup_fields= &rollup.fields[i];
++ rollup_fields->empty();
++ rollup.ref_pointer_arrays[i]= ref_array;
++ ref_array+= all_fields.elements;
++ }
++ for (i= 0 ; i < send_group_parts; i++)
++ {
++ for (j=0 ; j < fields_list.elements ; j++)
++ rollup.fields[i].push_back(rollup.null_items[i]);
++ }
++ List_iterator<Item> it(all_fields);
++ Item *item;
++ while ((item= it++))
++ {
++ ORDER *group_tmp;
++ bool found_in_group= 0;
++
++ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
++ {
++ if (*group_tmp->item == item)
++ {
++ item->maybe_null= 1;
++ found_in_group= 1;
++ break;
++ }
++ }
++ if (item->type() == Item::FUNC_ITEM && !found_in_group)
++ {
++ bool changed= FALSE;
++ if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
++ return 1;
++ /*
++ We have to prevent creation of a field in a temporary table for
++ an expression that contains GROUP BY attributes.
++ Marking the expression item as 'with_sum_func' will ensure this.
++ */
++ if (changed)
++ item->with_sum_func= 1;
++ }
++ }
++ return 0;
++}
++
++/**
++ Wrap all constant Items in GROUP BY list.
++
++ For ROLLUP queries each constant item referenced in GROUP BY list
++ is wrapped up into an Item_func object yielding the same value
++ as the constant item. The objects of the wrapper class are never
++ considered as constant items and besides they inherit all
++ properties of the Item_result_field class.
++ This wrapping allows us to ensure writing constant items
++ into temporary tables whenever the result of the ROLLUP
++ operation has to be written into a temporary table, e.g. when
++ ROLLUP is used together with DISTINCT in the SELECT list.
++ Usually when creating temporary tables for a intermidiate
++ result we do not include fields for constant expressions.
++
++ @retval
++ 0 if ok
++ @retval
++ 1 on error
++*/
++
++bool JOIN::rollup_process_const_fields()
++{
++ ORDER *group_tmp;
++ Item *item;
++ List_iterator<Item> it(all_fields);
++
++ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
++ {
++ if (!(*group_tmp->item)->const_item())
++ continue;
++ while ((item= it++))
++ {
++ if (*group_tmp->item == item)
++ {
++ Item* new_item= new Item_func_rollup_const(item);
++ if (!new_item)
++ return 1;
++ new_item->fix_fields(thd, (Item **) 0);
++ thd->change_item_tree(it.ref(), new_item);
++ for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
++ {
++ if (*tmp->item == item)
++ thd->change_item_tree(tmp->item, new_item);
++ }
++ break;
++ }
++ }
++ it.rewind();
++ }
++ return 0;
++}
++
++
++/**
++ Fill up rollup structures with pointers to fields to use.
++
++ Creates copies of item_sum items for each sum level.
++
++ @param fields_arg List of all fields (hidden and real ones)
++ @param sel_fields Pointer to selected fields
++ @param func Store here a pointer to all fields
++
++ @retval
++ 0 if ok;
++ In this case func is pointing to next not used element.
++ @retval
++ 1 on error
++*/
++
++bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
++ Item_sum ***func)
++{
++ List_iterator_fast<Item> it(fields_arg);
++ Item *first_field= sel_fields.head();
++ uint level;
++
++ /*
++ Create field lists for the different levels
++
++ The idea here is to have a separate field list for each rollup level to
++ avoid all runtime checks of which columns should be NULL.
++
++ The list is stored in reverse order to get sum function in such an order
++ in func that it makes it easy to reset them with init_sum_functions()
++
++ Assuming: SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
++
++ rollup.fields[0] will contain list where a,b,c is NULL
++ rollup.fields[1] will contain list where b,c is NULL
++ ...
++ rollup.ref_pointer_array[#] points to fields for rollup.fields[#]
++ ...
++ sum_funcs_end[0] points to all sum functions
++ sum_funcs_end[1] points to all sum functions, except grand totals
++ ...
++ */
++
++ for (level=0 ; level < send_group_parts ; level++)
++ {
++ uint i;
++ uint pos= send_group_parts - level -1;
++ bool real_fields= 0;
++ Item *item;
++ List_iterator<Item> new_it(rollup.fields[pos]);
++ Item **ref_array_start= rollup.ref_pointer_arrays[pos];
++ ORDER *start_group;
++
++ /* Point to first hidden field */
++ Item **ref_array= ref_array_start + fields_arg.elements-1;
++
++ /* Remember where the sum functions ends for the previous level */
++ sum_funcs_end[pos+1]= *func;
++
++ /* Find the start of the group for this level */
++ for (i= 0, start_group= group_list ;
++ i++ < pos ;
++ start_group= start_group->next)
++ ;
++
++ it.rewind();
++ while ((item= it++))
++ {
++ if (item == first_field)
++ {
++ real_fields= 1; // End of hidden fields
++ ref_array= ref_array_start;
++ }
++
++ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
++ (!((Item_sum*) item)->depended_from() ||
++ ((Item_sum *)item)->depended_from() == select_lex))
++
++ {
++ /*
++ This is a top level summary function that must be replaced with
++ a sum function that is reset for this level.
++
++ NOTE: This code creates an object which is not that nice in a
++ sub select. Fortunately it's not common to have rollup in
++ sub selects.
++ */
++ item= item->copy_or_same(thd);
++ ((Item_sum*) item)->make_unique();
++ *(*func)= (Item_sum*) item;
++ (*func)++;
++ }
++ else
++ {
++ /* Check if this is something that is part of this group by */
++ ORDER *group_tmp;
++ for (group_tmp= start_group, i= pos ;
++ group_tmp ; group_tmp= group_tmp->next, i++)
++ {
++ if (*group_tmp->item == item)
++ {
++ /*
++ This is an element that is used by the GROUP BY and should be
++ set to NULL in this level
++ */
++ Item_null_result *null_item= new (thd->mem_root) Item_null_result();
++ if (!null_item)
++ return 1;
++ item->maybe_null= 1; // Value will be null sometimes
++ null_item->result_field= item->get_tmp_table_field();
++ item= null_item;
++ break;
++ }
++ }
++ }
++ *ref_array= item;
++ if (real_fields)
++ {
++ (void) new_it++; // Point to next item
++ new_it.replace(item); // Replace previous
++ ref_array++;
++ }
++ else
++ ref_array--;
++ }
++ }
++ sum_funcs_end[0]= *func; // Point to last function
++ return 0;
++}
++
++/**
++ Send all rollup levels higher than the current one to the client.
++
++ @b SAMPLE
++ @code
++ SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
++ @endcode
++
++ @param idx Level we are on:
++ - 0 = Total sum level
++ - 1 = First group changed (a)
++ - 2 = Second group changed (a,b)
++
++ @retval
++ 0 ok
++ @retval
++ 1 If send_data_failed()
++*/
++
++int JOIN::rollup_send_data(uint idx)
++{
++ uint i;
++ for (i= send_group_parts ; i-- > idx ; )
++ {
++ /* Get reference pointers to sum functions in place */
++ memcpy((char*) ref_pointer_array,
++ (char*) rollup.ref_pointer_arrays[i],
++ ref_pointer_array_size);
++ if ((!having || having->val_int()))
++ {
++ if (send_records < unit->select_limit_cnt && do_send_rows &&
++ result->send_data(rollup.fields[i]))
++ return 1;
++ send_records++;
++ }
++ }
++ /* Restore ref_pointer_array */
++ set_items_ref_array(current_ref_pointer_array);
++ return 0;
++}
++
++/**
++ Write all rollup levels higher than the current one to a temp table.
++
++ @b SAMPLE
++ @code
++ SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP
++ @endcode
++
++ @param idx Level we are on:
++ - 0 = Total sum level
++ - 1 = First group changed (a)
++ - 2 = Second group changed (a,b)
++ @param table reference to temp table
++
++ @retval
++ 0 ok
++ @retval
++ 1 if write_data_failed()
++*/
++
++int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
++{
++ uint i;
++ for (i= send_group_parts ; i-- > idx ; )
++ {
++ /* Get reference pointers to sum functions in place */
++ memcpy((char*) ref_pointer_array,
++ (char*) rollup.ref_pointer_arrays[i],
++ ref_pointer_array_size);
++ if ((!having || having->val_int()))
++ {
++ int write_error;
++ Item *item;
++ List_iterator_fast<Item> it(rollup.fields[i]);
++ while ((item= it++))
++ {
++ if (item->type() == Item::NULL_ITEM && item->is_result_field())
++ item->save_in_result_field(1);
++ }
++ copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
++ if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
++ {
++ if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
++ write_error, 0))
++ return 1;
++ }
++ }
++ }
++ /* Restore ref_pointer_array */
++ set_items_ref_array(current_ref_pointer_array);
++ return 0;
++}
++
++/**
++ clear results if there are not rows found for group
++ (end_send_group/end_write_group)
++*/
++
++void JOIN::clear()
++{
++ clear_tables(this);
++ copy_fields(&tmp_table_param);
++
++ if (sum_funcs)
++ {
++ Item_sum *func, **func_ptr= sum_funcs;
++ while ((func= *(func_ptr++)))
++ func->clear();
++ }
++}
++
++/**
++ EXPLAIN handling.
++
++ Send a description about what how the select will be done to stdout.
++*/
++
++static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
++ bool distinct,const char *message)
++{
++ List<Item> field_list;
++ List<Item> item_list;
++ THD *thd=join->thd;
++ select_result *result=join->result;
++ Item *item_null= new Item_null();
++ CHARSET_INFO *cs= system_charset_info;
++ int quick_type;
++ DBUG_ENTER("select_describe");
++ DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
++ (ulong)join->select_lex, join->select_lex->type,
++ message ? message : "NULL"));
++ /* Don't log this into the slow query log */
++ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
++ join->unit->offset_limit_cnt= 0;
++
++ /*
++ NOTE: the number/types of items pushed into item_list must be in sync with
++ EXPLAIN column types as they're "defined" in THD::send_explain_fields()
++ */
++ if (message)
++ {
++ item_list.push_back(new Item_int((int32)
++ join->select_lex->select_number));
++ item_list.push_back(new Item_string(join->select_lex->type,
++ strlen(join->select_lex->type), cs));
++ for (uint i=0 ; i < 7; i++)
++ item_list.push_back(item_null);
++ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
++ item_list.push_back(item_null);
++ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
++ item_list.push_back(item_null);
++
++ item_list.push_back(new Item_string(message,strlen(message),cs));
++ if (result->send_data(item_list))
++ join->error= 1;
++ }
++ else if (join->select_lex == join->unit->fake_select_lex)
++ {
++ /*
++ here we assume that the query will return at least two rows, so we
++ show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
++ and no filesort will be actually done, but executing all selects in
++ the UNION to provide precise EXPLAIN information will hardly be
++ appreciated :)
++ */
++ char table_name_buffer[NAME_LEN];
++ item_list.empty();
++ /* id */
++ item_list.push_back(new Item_null);
++ /* select_type */
++ item_list.push_back(new Item_string(join->select_lex->type,
++ strlen(join->select_lex->type),
++ cs));
++ /* table */
++ {
++ SELECT_LEX *sl= join->unit->first_select();
++ uint len= 6, lastop= 0;
++ memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
++ for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
++ {
++ len+= lastop;
++ lastop= my_snprintf(table_name_buffer + len, NAME_LEN - len,
++ "%u,", sl->select_number);
++ }
++ if (sl || len + lastop >= NAME_LEN)
++ {
++ memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
++ len+= 4;
++ }
++ else
++ {
++ len+= lastop;
++ table_name_buffer[len - 1]= '>'; // change ',' to '>'
++ }
++ item_list.push_back(new Item_string(table_name_buffer, len, cs));
++ }
++ /* partitions */
++ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
++ item_list.push_back(item_null);
++ /* type */
++ item_list.push_back(new Item_string(join_type_str[JT_ALL],
++ strlen(join_type_str[JT_ALL]),
++ cs));
++ /* possible_keys */
++ item_list.push_back(item_null);
++ /* key*/
++ item_list.push_back(item_null);
++ /* key_len */
++ item_list.push_back(item_null);
++ /* ref */
++ item_list.push_back(item_null);
++ /* in_rows */
++ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
++ item_list.push_back(item_null);
++ /* rows */
++ item_list.push_back(item_null);
++ /* extra */
++ if (join->unit->global_parameters->order_list.first)
++ item_list.push_back(new Item_string("Using filesort",
++ 14, cs));
++ else
++ item_list.push_back(new Item_string("", 0, cs));
++
++ if (result->send_data(item_list))
++ join->error= 1;
++ }
++ else
++ {
++ table_map used_tables=0;
++ for (uint i=0 ; i < join->tables ; i++)
++ {
++ JOIN_TAB *tab=join->join_tab+i;
++ TABLE *table=tab->table;
++ TABLE_LIST *table_list= tab->table->pos_in_table_list;
++ char buff[512];
++ char buff1[512], buff2[512], buff3[512];
++ char keylen_str_buf[64];
++ String extra(buff, sizeof(buff),cs);
++ char table_name_buffer[NAME_LEN];
++ String tmp1(buff1,sizeof(buff1),cs);
++ String tmp2(buff2,sizeof(buff2),cs);
++ String tmp3(buff3,sizeof(buff3),cs);
++ extra.length(0);
++ tmp1.length(0);
++ tmp2.length(0);
++ tmp3.length(0);
++
++ quick_type= -1;
++ item_list.empty();
++ /* id */
++ item_list.push_back(new Item_uint((uint32)
++ join->select_lex->select_number));
++ /* select_type */
++ item_list.push_back(new Item_string(join->select_lex->type,
++ strlen(join->select_lex->type),
++ cs));
++ if (tab->type == JT_ALL && tab->select && tab->select->quick)
++ {
++ quick_type= tab->select->quick->get_type();
++ if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
++ (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
++ (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
++ tab->type = JT_INDEX_MERGE;
++ else
++ tab->type = JT_RANGE;
++ }
++ /* table */
++ if (table->derived_select_number)
++ {
++ /* Derived table name generation */
++ int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
++ "<derived%u>",
++ table->derived_select_number);
++ item_list.push_back(new Item_string(table_name_buffer, len, cs));
++ }
++ else
++ {
++ TABLE_LIST *real_table= table->pos_in_table_list;
++ item_list.push_back(new Item_string(real_table->alias,
++ strlen(real_table->alias),
++ cs));
++ }
++ /* "partitions" column */
++ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
++ {
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ partition_info *part_info;
++ if (!table->derived_select_number &&
++ (part_info= table->part_info))
++ {
++ Item_string *item_str= new Item_string(cs);
++ make_used_partitions_str(part_info, &item_str->str_value);
++ item_list.push_back(item_str);
++ }
++ else
++ item_list.push_back(item_null);
++#else
++ /* just produce empty column if partitioning is not compiled in */
++ item_list.push_back(item_null);
++#endif
++ }
++ /* "type" column */
++ item_list.push_back(new Item_string(join_type_str[tab->type],
++ strlen(join_type_str[tab->type]),
++ cs));
++ /* Build "possible_keys" value and add it to item_list */
++ if (!tab->keys.is_clear_all())
++ {
++ uint j;
++ for (j=0 ; j < table->s->keys ; j++)
++ {
++ if (tab->keys.is_set(j))
++ {
++ if (tmp1.length())
++ tmp1.append(',');
++ tmp1.append(table->key_info[j].name,
++ strlen(table->key_info[j].name),
++ system_charset_info);
++ }
++ }
++ }
++ if (tmp1.length())
++ item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
++ else
++ item_list.push_back(item_null);
++
++ /* Build "key", "key_len", and "ref" values and add them to item_list */
++ if (tab->ref.key_parts)
++ {
++ KEY *key_info=table->key_info+ tab->ref.key;
++ register uint length;
++ item_list.push_back(new Item_string(key_info->name,
++ strlen(key_info->name),
++ system_charset_info));
++ length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
++ keylen_str_buf;
++ item_list.push_back(new Item_string(keylen_str_buf, length,
++ system_charset_info));
++ for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
++ {
++ if (tmp2.length())
++ tmp2.append(',');
++ tmp2.append((*ref)->name(), strlen((*ref)->name()),
++ system_charset_info);
++ }
++ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
++ }
++ else if (tab->type == JT_NEXT)
++ {
++ KEY *key_info=table->key_info+ tab->index;
++ register uint length;
++ item_list.push_back(new Item_string(key_info->name,
++ strlen(key_info->name),cs));
++ length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
++ keylen_str_buf;
++ item_list.push_back(new Item_string(keylen_str_buf,
++ length,
++ system_charset_info));
++ item_list.push_back(item_null);
++ }
++ else if (tab->select && tab->select->quick)
++ {
++ tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
++ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
++ item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
++ item_list.push_back(item_null);
++ }
++ else
++ {
++ if (table_list->schema_table &&
++ table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
++ {
++ const char *tmp_buff;
++ int f_idx;
++ if (table_list->has_db_lookup_value)
++ {
++ f_idx= table_list->schema_table->idx_field1;
++ tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
++ tmp2.append(tmp_buff, strlen(tmp_buff), cs);
++ }
++ if (table_list->has_table_lookup_value)
++ {
++ if (table_list->has_db_lookup_value)
++ tmp2.append(',');
++ f_idx= table_list->schema_table->idx_field2;
++ tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
++ tmp2.append(tmp_buff, strlen(tmp_buff), cs);
++ }
++ if (tmp2.length())
++ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
++ else
++ item_list.push_back(item_null);
++ }
++ else
++ item_list.push_back(item_null);
++ item_list.push_back(item_null);
++ item_list.push_back(item_null);
++ }
++
++ /* Add "rows" field to item_list. */
++ if (table_list->schema_table)
++ {
++ /* in_rows */
++ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
++ item_list.push_back(item_null);
++ /* rows */
++ item_list.push_back(item_null);
++ }
++ else
++ {
++ ha_rows examined_rows;
++ if (tab->select && tab->select->quick)
++ examined_rows= tab->select->quick->records;
++ else if (tab->type == JT_NEXT || tab->type == JT_ALL)
++ {
++ if (tab->limit)
++ examined_rows= tab->limit;
++ else
++ {
++ tab->table->file->info(HA_STATUS_VARIABLE);
++ examined_rows= tab->table->file->stats.records;
++ }
++ }
++ else
++ examined_rows=(ha_rows)join->best_positions[i].records_read;
++
++ item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows,
++ MY_INT64_NUM_DECIMAL_DIGITS));
++
++ /* Add "filtered" field to item_list. */
++ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
++ {
++ float f= 0.0;
++ if (examined_rows)
++ f= (float) (100.0 * join->best_positions[i].records_read /
++ examined_rows);
++ item_list.push_back(new Item_float(f, 2));
++ }
++ }
++
++ /* Build "Extra" field and add it to item_list. */
++ my_bool key_read=table->key_read;
++ if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
++ table->covering_keys.is_set(tab->index))
++ key_read=1;
++ if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
++ !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
++ key_read=1;
++
++ if (tab->info)
++ item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
++ else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
++ {
++ if (tab->packed_info & TAB_INFO_USING_INDEX)
++ extra.append(STRING_WITH_LEN("; Using index"));
++ if (tab->packed_info & TAB_INFO_USING_WHERE)
++ extra.append(STRING_WITH_LEN("; Using where"));
++ if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
++ extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
++ /* Skip initial "; "*/
++ const char *str= extra.ptr();
++ uint32 len= extra.length();
++ if (len)
++ {
++ str += 2;
++ len -= 2;
++ }
++ item_list.push_back(new Item_string(str, len, cs));
++ }
++ else
++ {
++ if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
++ quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
++ {
++ extra.append(STRING_WITH_LEN("; Using "));
++ tab->select->quick->add_info_string(&extra);
++ }
++ if (tab->select)
++ {
++ if (tab->use_quick == 2)
++ {
++ /* 4 bits per 1 hex digit + terminating '\0' */
++ char buf[MAX_KEY / 4 + 1];
++ extra.append(STRING_WITH_LEN("; Range checked for each "
++ "record (index map: 0x"));
++ extra.append(tab->keys.print(buf));
++ extra.append(')');
++ }
++ else if (tab->select->cond)
++ {
++ const COND *pushed_cond= tab->table->file->pushed_cond;
++
++ if (thd->variables.engine_condition_pushdown && pushed_cond)
++ {
++ extra.append(STRING_WITH_LEN("; Using where with pushed "
++ "condition"));
++ if (thd->lex->describe & DESCRIBE_EXTENDED)
++ {
++ extra.append(STRING_WITH_LEN(": "));
++ ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
++ }
++ }
++ else
++ extra.append(STRING_WITH_LEN("; Using where"));
++ }
++ }
++ if (table_list->schema_table &&
++ table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
++ {
++ if (!table_list->table_open_method)
++ extra.append(STRING_WITH_LEN("; Skip_open_table"));
++ else if (table_list->table_open_method == OPEN_FRM_ONLY)
++ extra.append(STRING_WITH_LEN("; Open_frm_only"));
++ else
++ extra.append(STRING_WITH_LEN("; Open_full_table"));
++ if (table_list->has_db_lookup_value &&
++ table_list->has_table_lookup_value)
++ extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
++ else if (table_list->has_db_lookup_value ||
++ table_list->has_table_lookup_value)
++ extra.append(STRING_WITH_LEN("; Scanned 1 database"));
++ else
++ extra.append(STRING_WITH_LEN("; Scanned all databases"));
++ }
++ if (key_read)
++ {
++ if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
++ extra.append(STRING_WITH_LEN("; Using index for group-by"));
++ else
++ extra.append(STRING_WITH_LEN("; Using index"));
++ }
++ if (table->reginfo.not_exists_optimize)
++ extra.append(STRING_WITH_LEN("; Not exists"));
++ if (need_tmp_table)
++ {
++ need_tmp_table=0;
++ extra.append(STRING_WITH_LEN("; Using temporary"));
++ }
++ if (need_order)
++ {
++ need_order=0;
++ extra.append(STRING_WITH_LEN("; Using filesort"));
++ }
++ if (distinct & test_all_bits(used_tables,thd->used_tables))
++ extra.append(STRING_WITH_LEN("; Distinct"));
++
++ for (uint part= 0; part < tab->ref.key_parts; part++)
++ {
++ if (tab->ref.cond_guards[part])
++ {
++ extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
++ break;
++ }
++ }
++ if (i > 0 && tab[-1].next_select == sub_select_cache)
++ extra.append(STRING_WITH_LEN("; Using join buffer"));
++
++ /* Skip initial "; "*/
++ const char *str= extra.ptr();
++ uint32 len= extra.length();
++ if (len)
++ {
++ str += 2;
++ len -= 2;
++ }
++ item_list.push_back(new Item_string(str, len, cs));
++ }
++ // For next iteration
++ used_tables|=table->map;
++ if (result->send_data(item_list))
++ join->error= 1;
++ }
++ }
++ for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
++ unit;
++ unit= unit->next_unit())
++ {
++ if (mysql_explain_union(thd, unit, result))
++ DBUG_VOID_RETURN;
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
++{
++ DBUG_ENTER("mysql_explain_union");
++ bool res= 0;
++ SELECT_LEX *first= unit->first_select();
++
++ for (SELECT_LEX *sl= first;
++ sl;
++ sl= sl->next_select())
++ {
++ // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
++ uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
++ sl->type= (((&thd->lex->select_lex)==sl)?
++ (sl->first_inner_unit() || sl->next_select() ?
++ "PRIMARY" : "SIMPLE"):
++ ((sl == first)?
++ ((sl->linkage == DERIVED_TABLE_TYPE) ?
++ "DERIVED":
++ ((uncacheable & UNCACHEABLE_DEPENDENT) ?
++ "DEPENDENT SUBQUERY":
++ (uncacheable?"UNCACHEABLE SUBQUERY":
++ "SUBQUERY"))):
++ ((uncacheable & UNCACHEABLE_DEPENDENT) ?
++ "DEPENDENT UNION":
++ uncacheable?"UNCACHEABLE UNION":
++ "UNION")));
++ sl->options|= SELECT_DESCRIBE;
++ }
++ if (unit->is_union())
++ {
++ unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
++ unit->fake_select_lex->type= "UNION RESULT";
++ unit->fake_select_lex->options|= SELECT_DESCRIBE;
++ if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
++ res= unit->exec();
++ res|= unit->cleanup();
++ }
++ else
++ {
++ thd->lex->current_select= first;
++ unit->set_limit(unit->global_parameters);
++ res= mysql_select(thd, &first->ref_pointer_array,
++ first->table_list.first,
++ first->with_wild, first->item_list,
++ first->where,
++ first->order_list.elements +
++ first->group_list.elements,
++ first->order_list.first,
++ first->group_list.first,
++ first->having,
++ thd->lex->proc_list.first,
++ first->options | thd->options | SELECT_DESCRIBE,
++ result, unit, first);
++ }
++ DBUG_RETURN(res || thd->is_error());
++}
++
++
++/**
++ Print joins from the FROM clause.
++
++ @param thd thread handler
++ @param str string where table should be printed
++ @param tables list of tables in join
++ @query_type type of the query is being generated
++*/
++
++static void print_join(THD *thd,
++ String *str,
++ List<TABLE_LIST> *tables,
++ enum_query_type query_type)
++{
++ /* List is reversed => we should reverse it before using */
++ List_iterator_fast<TABLE_LIST> ti(*tables);
++ TABLE_LIST **table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) *
++ tables->elements);
++ if (table == 0)
++ return; // out of memory
++
++ for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--)
++ *t= ti++;
++
++ DBUG_ASSERT(tables->elements >= 1);
++ (*table)->print(thd, str, query_type);
++
++ TABLE_LIST **end= table + tables->elements;
++ for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
++ {
++ TABLE_LIST *curr= *tbl;
++ if (curr->outer_join)
++ {
++ /* MySQL converts right to left joins */
++ str->append(STRING_WITH_LEN(" left join "));
++ }
++ else if (curr->straight)
++ str->append(STRING_WITH_LEN(" straight_join "));
++ else
++ str->append(STRING_WITH_LEN(" join "));
++ curr->print(thd, str, query_type);
++ if (curr->on_expr)
++ {
++ str->append(STRING_WITH_LEN(" on("));
++ curr->on_expr->print(str, query_type);
++ str->append(')');
++ }
++ }
++}
++
++
++/**
++ @brief Print an index hint
++
++ @details Prints out the USE|FORCE|IGNORE index hint.
++
++ @param thd the current thread
++ @param[out] str appends the index hint here
++ @param hint what the hint is (as string : "USE INDEX"|
++ "FORCE INDEX"|"IGNORE INDEX")
++ @param hint_length the length of the string in 'hint'
++ @param indexes a list of index names for the hint
++*/
++
++void
++Index_hint::print(THD *thd, String *str)
++{
++ switch (type)
++ {
++ case INDEX_HINT_IGNORE: str->append(STRING_WITH_LEN("IGNORE INDEX")); break;
++ case INDEX_HINT_USE: str->append(STRING_WITH_LEN("USE INDEX")); break;
++ case INDEX_HINT_FORCE: str->append(STRING_WITH_LEN("FORCE INDEX")); break;
++ }
++ str->append (STRING_WITH_LEN(" ("));
++ if (key_name.length)
++ {
++ if (thd && !my_strnncoll(system_charset_info,
++ (const uchar *)key_name.str, key_name.length,
++ (const uchar *)primary_key_name,
++ strlen(primary_key_name)))
++ str->append(primary_key_name);
++ else
++ append_identifier(thd, str, key_name.str, key_name.length);
++ }
++ str->append(')');
++}
++
++
++/**
++ Print table as it should be in join list.
++
++ @param str string where table should be printed
++*/
++
++void TABLE_LIST::print(THD *thd, String *str, enum_query_type query_type)
++{
++ if (nested_join)
++ {
++ str->append('(');
++ print_join(thd, str, &nested_join->join_list, query_type);
++ str->append(')');
++ }
++ else
++ {
++ const char *cmp_name; // Name to compare with alias
++ if (view_name.str)
++ {
++ // A view
++
++ if (!(belong_to_view &&
++ belong_to_view->compact_view_format))
++ {
++ append_identifier(thd, str, view_db.str, view_db.length);
++ str->append('.');
++ }
++ append_identifier(thd, str, view_name.str, view_name.length);
++ cmp_name= view_name.str;
++ }
++ else if (derived)
++ {
++ // A derived table
++ str->append('(');
++ derived->print(str, query_type);
++ str->append(')');
++ cmp_name= ""; // Force printing of alias
++ }
++ else
++ {
++ // A normal table
++
++ if (!(belong_to_view &&
++ belong_to_view->compact_view_format))
++ {
++ append_identifier(thd, str, db, db_length);
++ str->append('.');
++ }
++ if (schema_table)
++ {
++ append_identifier(thd, str, schema_table_name,
++ strlen(schema_table_name));
++ cmp_name= schema_table_name;
++ }
++ else
++ {
++ append_identifier(thd, str, table_name, table_name_length);
++ cmp_name= table_name;
++ }
++ }
++ if (my_strcasecmp(table_alias_charset, cmp_name, alias))
++ {
++ char t_alias_buff[MAX_ALIAS_NAME];
++ const char *t_alias= alias;
++
++ str->append(' ');
++ if (lower_case_table_names== 1)
++ {
++ if (alias && alias[0])
++ {
++ strmov(t_alias_buff, alias);
++ my_casedn_str(files_charset_info, t_alias_buff);
++ t_alias= t_alias_buff;
++ }
++ }
++
++ append_identifier(thd, str, t_alias, strlen(t_alias));
++ }
++
++ if (index_hints)
++ {
++ List_iterator<Index_hint> it(*index_hints);
++ Index_hint *hint;
++
++ while ((hint= it++))
++ {
++ str->append (STRING_WITH_LEN(" "));
++ hint->print (thd, str);
++ }
++ }
++ }
++}
++
++
++void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
++{
++ /* QQ: thd may not be set for sub queries, but this should be fixed */
++ if (!thd)
++ thd= current_thd;
++
++ str->append(STRING_WITH_LEN("select "));
++
++ /* First add options */
++ if (options & SELECT_STRAIGHT_JOIN)
++ str->append(STRING_WITH_LEN("straight_join "));
++ if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
++ (this == &thd->lex->select_lex))
++ str->append(STRING_WITH_LEN("high_priority "));
++ if (options & SELECT_DISTINCT)
++ str->append(STRING_WITH_LEN("distinct "));
++ if (options & SELECT_SMALL_RESULT)
++ str->append(STRING_WITH_LEN("sql_small_result "));
++ if (options & SELECT_BIG_RESULT)
++ str->append(STRING_WITH_LEN("sql_big_result "));
++ if (options & OPTION_BUFFER_RESULT)
++ str->append(STRING_WITH_LEN("sql_buffer_result "));
++ if (options & OPTION_FOUND_ROWS)
++ str->append(STRING_WITH_LEN("sql_calc_found_rows "));
++ switch (sql_cache)
++ {
++ case SQL_NO_CACHE:
++ str->append(STRING_WITH_LEN("sql_no_cache "));
++ break;
++ case SQL_CACHE:
++ str->append(STRING_WITH_LEN("sql_cache "));
++ break;
++ case SQL_CACHE_UNSPECIFIED:
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++
++ //Item List
++ bool first= 1;
++ List_iterator_fast<Item> it(item_list);
++ Item *item;
++ while ((item= it++))
++ {
++ if (first)
++ first= 0;
++ else
++ str->append(',');
++
++ if (master_unit()->item && item->is_autogenerated_name)
++ {
++ /*
++ Do not print auto-generated aliases in subqueries. It has no purpose
++ in a view definition or other contexts where the query is printed.
++ */
++ item->print(str, query_type);
++ }
++ else
++ item->print_item_w_name(str, query_type);
++ }
++
++ /*
++ from clause
++ TODO: support USING/FORCE/IGNORE index
++ */
++ if (table_list.elements)
++ {
++ str->append(STRING_WITH_LEN(" from "));
++ /* go through join tree */
++ print_join(thd, str, &top_join_list, query_type);
++ }
++ else if (where)
++ {
++ /*
++ "SELECT 1 FROM DUAL WHERE 2" should not be printed as
++ "SELECT 1 WHERE 2": the 1st syntax is valid, but the 2nd is not.
++ */
++ str->append(STRING_WITH_LEN(" from DUAL "));
++ }
++
++ // Where
++ Item *cur_where= where;
++ if (join)
++ cur_where= join->conds;
++ if (cur_where || cond_value != Item::COND_UNDEF)
++ {
++ str->append(STRING_WITH_LEN(" where "));
++ if (cur_where)
++ cur_where->print(str, query_type);
++ else
++ str->append(cond_value != Item::COND_FALSE ? "1" : "0");
++ }
++
++ // group by & olap
++ if (group_list.elements)
++ {
++ str->append(STRING_WITH_LEN(" group by "));
++ print_order(str, group_list.first, query_type);
++ switch (olap)
++ {
++ case CUBE_TYPE:
++ str->append(STRING_WITH_LEN(" with cube"));
++ break;
++ case ROLLUP_TYPE:
++ str->append(STRING_WITH_LEN(" with rollup"));
++ break;
++ default:
++ ; //satisfy compiler
++ }
++ }
++
++ // having
++ Item *cur_having= having;
++ if (join)
++ cur_having= join->having;
++
++ if (cur_having || having_value != Item::COND_UNDEF)
++ {
++ str->append(STRING_WITH_LEN(" having "));
++ if (cur_having)
++ cur_having->print(str, query_type);
++ else
++ str->append(having_value != Item::COND_FALSE ? "1" : "0");
++ }
++
++ if (order_list.elements)
++ {
++ str->append(STRING_WITH_LEN(" order by "));
++ print_order(str, order_list.first, query_type);
++ }
++
++ // limit
++ print_limit(thd, str, query_type);
++
++ // PROCEDURE unsupported here
++}
++
++
++/**
++ change select_result object of JOIN.
++
++ @param res new select_result object
++
++ @retval
++ FALSE OK
++ @retval
++ TRUE error
++*/
++
++bool JOIN::change_result(select_result *res)
++{
++ DBUG_ENTER("JOIN::change_result");
++ result= res;
++ if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
++ result->prepare2()))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++/**
++ @} (end of group Query_Optimizer)
++*/
+diff -urN mysql-old/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql-old/sql/sql_show.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_show.cc 2011-05-10 17:56:01.596682375 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1871,7 +1871,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2002,7 +2002,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3168,7 +3168,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7044,7 +7044,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -urN mysql-old/sql/sql_show.cc.orig mysql/sql/sql_show.cc.orig
+--- mysql-old/sql/sql_show.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/sql_show.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,7275 @@
++/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License along
++ with this program; if not, write to the Free Software Foundation, Inc.,
++ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
++
++
++/* Function with list databases, tables or fields */
++
++#include "mysql_priv.h"
++#include "sql_select.h" // For select_describe
++#include "sql_show.h"
++#include "repl_failsafe.h"
++#include "sp.h"
++#include "sp_head.h"
++#include "sql_trigger.h"
++#include "authors.h"
++#include "contributors.h"
++#ifdef HAVE_EVENT_SCHEDULER
++#include "events.h"
++#include "event_data_objects.h"
++#endif
++#include <my_dir.h>
++#include "debug_sync.h"
++
++#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++#include "ha_partition.h"
++#endif
++enum enum_i_s_events_fields
++{
++ ISE_EVENT_CATALOG= 0,
++ ISE_EVENT_SCHEMA,
++ ISE_EVENT_NAME,
++ ISE_DEFINER,
++ ISE_TIME_ZONE,
++ ISE_EVENT_BODY,
++ ISE_EVENT_DEFINITION,
++ ISE_EVENT_TYPE,
++ ISE_EXECUTE_AT,
++ ISE_INTERVAL_VALUE,
++ ISE_INTERVAL_FIELD,
++ ISE_SQL_MODE,
++ ISE_STARTS,
++ ISE_ENDS,
++ ISE_STATUS,
++ ISE_ON_COMPLETION,
++ ISE_CREATED,
++ ISE_LAST_ALTERED,
++ ISE_LAST_EXECUTED,
++ ISE_EVENT_COMMENT,
++ ISE_ORIGINATOR,
++ ISE_CLIENT_CS,
++ ISE_CONNECTION_CL,
++ ISE_DB_CL
++};
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++static const char *grant_names[]={
++ "select","insert","update","delete","create","drop","reload","shutdown",
++ "process","file","grant","references","index","alter"};
++
++static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
++ "grant_types",
++ grant_names, NULL};
++#endif
++
++static void store_key_options(THD *thd, String *packet, TABLE *table,
++ KEY *key_info);
++
++static void
++append_algorithm(TABLE_LIST *table, String *buff);
++
++static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
++
++/***************************************************************************
++** List all table types supported
++***************************************************************************/
++
++static int make_version_string(char *buf, int buf_length, uint version)
++{
++ return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
++}
++
++static my_bool show_plugins(THD *thd, plugin_ref plugin,
++ void *arg)
++{
++ TABLE *table= (TABLE*) arg;
++ struct st_mysql_plugin *plug= plugin_decl(plugin);
++ struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
++ CHARSET_INFO *cs= system_charset_info;
++ char version_buf[20];
++
++ restore_record(table, s->default_values);
++
++ table->field[0]->store(plugin_name(plugin)->str,
++ plugin_name(plugin)->length, cs);
++
++ table->field[1]->store(version_buf,
++ make_version_string(version_buf, sizeof(version_buf), plug->version),
++ cs);
++
++
++ switch (plugin_state(plugin)) {
++ /* case PLUGIN_IS_FREED: does not happen */
++ case PLUGIN_IS_DELETED:
++ table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
++ break;
++ case PLUGIN_IS_UNINITIALIZED:
++ table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
++ break;
++ case PLUGIN_IS_READY:
++ table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
++ break;
++ case PLUGIN_IS_DISABLED:
++ table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++
++ table->field[3]->store(plugin_type_names[plug->type].str,
++ plugin_type_names[plug->type].length,
++ cs);
++ table->field[4]->store(version_buf,
++ make_version_string(version_buf, sizeof(version_buf),
++ *(uint *)plug->info), cs);
++
++ if (plugin_dl)
++ {
++ table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
++ table->field[5]->set_notnull();
++ table->field[6]->store(version_buf,
++ make_version_string(version_buf, sizeof(version_buf),
++ plugin_dl->version),
++ cs);
++ table->field[6]->set_notnull();
++ }
++ else
++ {
++ table->field[5]->set_null();
++ table->field[6]->set_null();
++ }
++
++
++ if (plug->author)
++ {
++ table->field[7]->store(plug->author, strlen(plug->author), cs);
++ table->field[7]->set_notnull();
++ }
++ else
++ table->field[7]->set_null();
++
++ if (plug->descr)
++ {
++ table->field[8]->store(plug->descr, strlen(plug->descr), cs);
++ table->field[8]->set_notnull();
++ }
++ else
++ table->field[8]->set_null();
++
++ switch (plug->license) {
++ case PLUGIN_LICENSE_GPL:
++ table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
++ strlen(PLUGIN_LICENSE_GPL_STRING), cs);
++ break;
++ case PLUGIN_LICENSE_BSD:
++ table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
++ strlen(PLUGIN_LICENSE_BSD_STRING), cs);
++ break;
++ default:
++ table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
++ strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
++ break;
++ }
++ table->field[9]->set_notnull();
++
++ return schema_table_store_record(thd, table);
++}
++
++
++int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_plugins");
++ TABLE *table= tables->table;
++
++ if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
++ ~PLUGIN_IS_FREED, table))
++ DBUG_RETURN(1);
++
++ DBUG_RETURN(0);
++}
++
++
++/***************************************************************************
++** List all Authors.
++** If you can update it, you get to be in it :)
++***************************************************************************/
++
++bool mysqld_show_authors(THD *thd)
++{
++ List<Item> field_list;
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysqld_show_authors");
++
++ field_list.push_back(new Item_empty_string("Name",40));
++ field_list.push_back(new Item_empty_string("Location",40));
++ field_list.push_back(new Item_empty_string("Comment",80));
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ show_table_authors_st *authors;
++ for (authors= show_table_authors; authors->name; authors++)
++ {
++ protocol->prepare_for_resend();
++ protocol->store(authors->name, system_charset_info);
++ protocol->store(authors->location, system_charset_info);
++ protocol->store(authors->comment, system_charset_info);
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++ }
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++
++/***************************************************************************
++** List all Contributors.
++** Please get permission before updating
++***************************************************************************/
++
++bool mysqld_show_contributors(THD *thd)
++{
++ List<Item> field_list;
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysqld_show_contributors");
++
++ field_list.push_back(new Item_empty_string("Name",40));
++ field_list.push_back(new Item_empty_string("Location",40));
++ field_list.push_back(new Item_empty_string("Comment",80));
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ show_table_contributors_st *contributors;
++ for (contributors= show_table_contributors; contributors->name; contributors++)
++ {
++ protocol->prepare_for_resend();
++ protocol->store(contributors->name, system_charset_info);
++ protocol->store(contributors->location, system_charset_info);
++ protocol->store(contributors->comment, system_charset_info);
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++ }
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++
++/***************************************************************************
++ List all privileges supported
++***************************************************************************/
++
++struct show_privileges_st {
++ const char *privilege;
++ const char *context;
++ const char *comment;
++};
++
++static struct show_privileges_st sys_privileges[]=
++{
++ {"Alter", "Tables", "To alter the table"},
++ {"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"},
++ {"Create", "Databases,Tables,Indexes", "To create new databases and tables"},
++ {"Create routine","Databases","To use CREATE FUNCTION/PROCEDURE"},
++ {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
++ {"Create view", "Tables", "To create new views"},
++ {"Create user", "Server Admin", "To create new users"},
++ {"Delete", "Tables", "To delete existing rows"},
++ {"Drop", "Databases,Tables", "To drop databases, tables, and views"},
++#ifdef HAVE_EVENT_SCHEDULER
++ {"Event","Server Admin","To create, alter, drop and execute events"},
++#endif
++ {"Execute", "Functions,Procedures", "To execute stored routines"},
++ {"File", "File access on server", "To read and write files on the server"},
++ {"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
++ {"Index", "Tables", "To create or drop indexes"},
++ {"Insert", "Tables", "To insert data into tables"},
++ {"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
++ {"Process", "Server Admin", "To view the plain text of currently executing queries"},
++ {"References", "Databases,Tables", "To have references on tables"},
++ {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
++ {"Replication client","Server Admin","To ask where the slave or master servers are"},
++ {"Replication slave","Server Admin","To read binary log events from the master"},
++ {"Select", "Tables", "To retrieve rows from table"},
++ {"Show databases","Server Admin","To see all databases with SHOW DATABASES"},
++ {"Show view","Tables","To see views with SHOW CREATE VIEW"},
++ {"Shutdown","Server Admin", "To shut down the server"},
++ {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
++ {"Trigger","Tables", "To use triggers"},
++ {"Update", "Tables", "To update existing rows"},
++ {"Usage","Server Admin","No privileges - allow connect only"},
++ {NullS, NullS, NullS}
++};
++
++bool mysqld_show_privileges(THD *thd)
++{
++ List<Item> field_list;
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysqld_show_privileges");
++
++ field_list.push_back(new Item_empty_string("Privilege",10));
++ field_list.push_back(new Item_empty_string("Context",15));
++ field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ show_privileges_st *privilege= sys_privileges;
++ for (privilege= sys_privileges; privilege->privilege ; privilege++)
++ {
++ protocol->prepare_for_resend();
++ protocol->store(privilege->privilege, system_charset_info);
++ protocol->store(privilege->context, system_charset_info);
++ protocol->store(privilege->comment, system_charset_info);
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++ }
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++
++/***************************************************************************
++ List all column types
++***************************************************************************/
++
++struct show_column_type_st
++{
++ const char *type;
++ uint size;
++ const char *min_value;
++ const char *max_value;
++ uint precision;
++ uint scale;
++ const char *nullable;
++ const char *auto_increment;
++ const char *unsigned_attr;
++ const char *zerofill;
++ const char *searchable;
++ const char *case_sensitivity;
++ const char *default_value;
++ const char *comment;
++};
++
++/* TODO: Add remaning types */
++
++static struct show_column_type_st sys_column_types[]=
++{
++ {"tinyint",
++ 1, "-128", "127", 0, 0, "YES", "YES",
++ "NO", "YES", "YES", "NO", "NULL,0",
++ "A very small integer"},
++ {"tinyint unsigned",
++ 1, "0" , "255", 0, 0, "YES", "YES",
++ "YES", "YES", "YES", "NO", "NULL,0",
++ "A very small integer"},
++};
++
++bool mysqld_show_column_types(THD *thd)
++{
++ List<Item> field_list;
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysqld_show_column_types");
++
++ field_list.push_back(new Item_empty_string("Type",30));
++ field_list.push_back(new Item_int("Size",(longlong) 1,
++ MY_INT64_NUM_DECIMAL_DIGITS));
++ field_list.push_back(new Item_empty_string("Min_Value",20));
++ field_list.push_back(new Item_empty_string("Max_Value",20));
++ field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT));
++ field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT));
++ field_list.push_back(new Item_empty_string("Nullable",4));
++ field_list.push_back(new Item_empty_string("Auto_Increment",4));
++ field_list.push_back(new Item_empty_string("Unsigned",4));
++ field_list.push_back(new Item_empty_string("Zerofill",4));
++ field_list.push_back(new Item_empty_string("Searchable",4));
++ field_list.push_back(new Item_empty_string("Case_Sensitive",4));
++ field_list.push_back(new Item_empty_string("Default",NAME_CHAR_LEN));
++ field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ /* TODO: Change the loop to not use 'i' */
++ for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
++ {
++ protocol->prepare_for_resend();
++ protocol->store(sys_column_types[i].type, system_charset_info);
++ protocol->store((ulonglong) sys_column_types[i].size);
++ protocol->store(sys_column_types[i].min_value, system_charset_info);
++ protocol->store(sys_column_types[i].max_value, system_charset_info);
++ protocol->store_short((longlong) sys_column_types[i].precision);
++ protocol->store_short((longlong) sys_column_types[i].scale);
++ protocol->store(sys_column_types[i].nullable, system_charset_info);
++ protocol->store(sys_column_types[i].auto_increment, system_charset_info);
++ protocol->store(sys_column_types[i].unsigned_attr, system_charset_info);
++ protocol->store(sys_column_types[i].zerofill, system_charset_info);
++ protocol->store(sys_column_types[i].searchable, system_charset_info);
++ protocol->store(sys_column_types[i].case_sensitivity, system_charset_info);
++ protocol->store(sys_column_types[i].default_value, system_charset_info);
++ protocol->store(sys_column_types[i].comment, system_charset_info);
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++ }
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ find_files() - find files in a given directory.
++
++ SYNOPSIS
++ find_files()
++ thd thread handler
++ files put found files in this list
++ db database name to set in TABLE_LIST structure
++ path path to database
++ wild filter for found files
++ dir read databases in path if TRUE, read .frm files in
++ database otherwise
++
++ RETURN
++ FIND_FILES_OK success
++ FIND_FILES_OOM out of memory error
++ FIND_FILES_DIR no such directory, or directory can't be read
++*/
++
++
++find_files_result
++find_files(THD *thd, List<LEX_STRING> *files, const char *db,
++ const char *path, const char *wild, bool dir)
++{
++ uint i;
++ char *ext;
++ MY_DIR *dirp;
++ FILEINFO *file;
++ LEX_STRING *file_name= 0;
++ uint file_name_len;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ uint col_access=thd->col_access;
++#endif
++ uint wild_length= 0;
++ TABLE_LIST table_list;
++ DBUG_ENTER("find_files");
++
++ if (wild)
++ {
++ if (!wild[0])
++ wild= 0;
++ else
++ wild_length= strlen(wild);
++ }
++
++
++
++ bzero((char*) &table_list,sizeof(table_list));
++
++ if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
++ {
++ if (my_errno == ENOENT)
++ my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
++ else
++ my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
++ DBUG_RETURN(FIND_FILES_DIR);
++ }
++
++ for (i=0 ; i < (uint) dirp->number_off_files ; i++)
++ {
++ char uname[NAME_LEN + 1]; /* Unencoded name */
++ file=dirp->dir_entry+i;
++ if (dir)
++ { /* Return databases */
++ if ((file->name[0] == '.' &&
++ ((file->name[1] == '.' && file->name[2] == '\0') ||
++ file->name[1] == '\0')))
++ continue; /* . or .. */
++#ifdef USE_SYMDIR
++ char *ext;
++ char buff[FN_REFLEN];
++ if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
++ {
++ /* Only show the sym file if it points to a directory */
++ char *end;
++ *ext=0; /* Remove extension */
++ unpack_dirname(buff, file->name);
++ end= strend(buff);
++ if (end != buff && end[-1] == FN_LIBCHAR)
++ end[-1]= 0; // Remove end FN_LIBCHAR
++ if (!my_stat(buff, file->mystat, MYF(0)))
++ continue;
++ }
++#endif
++ if (!MY_S_ISDIR(file->mystat->st_mode))
++ continue;
++
++ file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
++ if (wild)
++ {
++ if (lower_case_table_names)
++ {
++ if (my_wildcmp(files_charset_info,
++ uname, uname + file_name_len,
++ wild, wild + wild_length,
++ wild_prefix, wild_one,wild_many))
++ continue;
++ }
++ else if (wild_compare(uname, wild, 0))
++ continue;
++ }
++ }
++ else
++ {
++ // Return only .frm files which aren't temp files.
++ if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
++ is_prefix(file->name, tmp_file_prefix))
++ continue;
++ *ext=0;
++ file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
++ if (wild)
++ {
++ if (lower_case_table_names)
++ {
++ if (my_wildcmp(files_charset_info,
++ uname, uname + file_name_len,
++ wild, wild + wild_length,
++ wild_prefix, wild_one,wild_many))
++ continue;
++ }
++ else if (wild_compare(uname, wild, 0))
++ continue;
++ }
++ }
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ /* Don't show tables where we don't have any privileges */
++ if (db && !(col_access & TABLE_ACLS))
++ {
++ table_list.db= (char*) db;
++ table_list.db_length= strlen(db);
++ table_list.table_name= uname;
++ table_list.table_name_length= file_name_len;
++ table_list.grant.privilege=col_access;
++ if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
++ continue;
++ }
++#endif
++ if (!(file_name=
++ thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
++ files->push_back(file_name))
++ {
++ my_dirend(dirp);
++ DBUG_RETURN(FIND_FILES_OOM);
++ }
++ }
++ DBUG_PRINT("info",("found: %d files", files->elements));
++ my_dirend(dirp);
++
++ VOID(ha_find_files(thd, db, path, wild, dir, files));
++
++ DBUG_RETURN(FIND_FILES_OK);
++}
++
++
++/**
++ An Internal_error_handler that suppresses errors regarding views'
++ underlying tables that occur during privilege checking within SHOW CREATE
++ VIEW commands. This happens in the cases when
++
++ - A view's underlying table (e.g. referenced in its SELECT list) does not
++ exist. There should not be an error as no attempt was made to access it
++ per se.
++
++ - Access is denied for some table, column, function or stored procedure
++ such as mentioned above. This error gets raised automatically, since we
++ can't untangle its access checking from that of the view itself.
++ */
++class Show_create_error_handler : public Internal_error_handler {
++
++ TABLE_LIST *m_top_view;
++ bool m_handling;
++ Security_context *m_sctx;
++
++ char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
++ char *m_view_access_denied_message_ptr;
++
++public:
++
++ /**
++ Creates a new Show_create_error_handler for the particular security
++ context and view.
++
++ @thd Thread context, used for security context information if needed.
++ @top_view The view. We do not verify at this point that top_view is in
++ fact a view since, alas, these things do not stay constant.
++ */
++ explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) :
++ m_top_view(top_view), m_handling(FALSE),
++ m_view_access_denied_message_ptr(NULL)
++ {
++
++ m_sctx = test(m_top_view->security_ctx) ?
++ m_top_view->security_ctx : thd->security_ctx;
++ }
++
++ /**
++ Lazy instantiation of 'view access denied' message. The purpose of the
++ Show_create_error_handler is to hide details of underlying tables for
++ which we have no privileges behind ER_VIEW_INVALID messages. But this
++ obviously does not apply if we lack privileges on the view itself.
++ Unfortunately the information about for which table privilege checking
++ failed is not available at this point. The only way for us to check is by
++ reconstructing the actual error message and see if it's the same.
++ */
++ char* get_view_access_denied_message()
++ {
++ if (!m_view_access_denied_message_ptr)
++ {
++ m_view_access_denied_message_ptr= m_view_access_denied_message;
++ my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
++ ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
++ m_sctx->priv_user,
++ m_sctx->host_or_ip, m_top_view->get_table_name());
++ }
++ return m_view_access_denied_message_ptr;
++ }
++
++ bool handle_error(uint sql_errno, const char *message,
++ MYSQL_ERROR::enum_warning_level level, THD *thd) {
++ /*
++ The handler does not handle the errors raised by itself.
++ At this point we know if top_view is really a view.
++ */
++ if (m_handling || !m_top_view->view)
++ return FALSE;
++
++ m_handling= TRUE;
++
++ bool is_handled;
++
++ switch (sql_errno)
++ {
++ case ER_TABLEACCESS_DENIED_ERROR:
++ if (!strcmp(get_view_access_denied_message(), message))
++ {
++ /* Access to top view is not granted, don't interfere. */
++ is_handled= FALSE;
++ break;
++ }
++ case ER_COLUMNACCESS_DENIED_ERROR:
++ case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
++ case ER_PROCACCESS_DENIED_ERROR:
++ is_handled= TRUE;
++ break;
++
++ case ER_NO_SUCH_TABLE:
++ /* Established behavior: warn if underlying tables are missing. */
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_VIEW_INVALID,
++ ER(ER_VIEW_INVALID),
++ m_top_view->get_db_name(),
++ m_top_view->get_table_name());
++ is_handled= TRUE;
++ break;
++
++ case ER_SP_DOES_NOT_EXIST:
++ /* Established behavior: warn if underlying functions are missing. */
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_VIEW_INVALID,
++ ER(ER_VIEW_INVALID),
++ m_top_view->get_db_name(),
++ m_top_view->get_table_name());
++ is_handled= TRUE;
++ break;
++ default:
++ is_handled= FALSE;
++ }
++
++ m_handling= FALSE;
++ return is_handled;
++ }
++};
++
++
++bool
++mysqld_show_create(THD *thd, TABLE_LIST *table_list)
++{
++ Protocol *protocol= thd->protocol;
++ char buff[2048];
++ String buffer(buff, sizeof(buff), system_charset_info);
++ DBUG_ENTER("mysqld_show_create");
++ DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
++ table_list->table_name));
++
++ /* We want to preserve the tree for views. */
++ thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
++
++ {
++ Show_create_error_handler view_error_suppressor(thd, table_list);
++ thd->push_internal_handler(&view_error_suppressor);
++ bool error= open_normal_and_derived_tables(thd, table_list, 0);
++ thd->pop_internal_handler();
++ if (error && (thd->killed || thd->main_da.is_error()))
++ DBUG_RETURN(TRUE);
++ }
++
++ /* TODO: add environment variables show when it become possible */
++ if (thd->lex->only_view && !table_list->view)
++ {
++ my_error(ER_WRONG_OBJECT, MYF(0),
++ table_list->db, table_list->table_name, "VIEW");
++ DBUG_RETURN(TRUE);
++ }
++
++ buffer.length(0);
++
++ if (table_list->view)
++ buffer.set_charset(table_list->view_creation_ctx->get_client_cs());
++
++ if ((table_list->view ?
++ view_store_create_info(thd, table_list, &buffer) :
++ store_create_info(thd, table_list, &buffer, NULL,
++ FALSE /* show_database */)))
++ DBUG_RETURN(TRUE);
++
++ List<Item> field_list;
++ if (table_list->view)
++ {
++ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
++ field_list.push_back(new Item_empty_string("Create View",
++ max(buffer.length(),1024)));
++ field_list.push_back(new Item_empty_string("character_set_client",
++ MY_CS_NAME_SIZE));
++ field_list.push_back(new Item_empty_string("collation_connection",
++ MY_CS_NAME_SIZE));
++ }
++ else
++ {
++ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
++ // 1024 is for not to confuse old clients
++ field_list.push_back(new Item_empty_string("Create Table",
++ max(buffer.length(),1024)));
++ }
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++ protocol->prepare_for_resend();
++ if (table_list->view)
++ protocol->store(table_list->view_name.str, system_charset_info);
++ else
++ {
++ if (table_list->schema_table)
++ protocol->store(table_list->schema_table->table_name,
++ system_charset_info);
++ else
++ protocol->store(table_list->table->alias, system_charset_info);
++ }
++
++ if (table_list->view)
++ {
++ protocol->store(buffer.ptr(), buffer.length(),
++ table_list->view_creation_ctx->get_client_cs());
++
++ protocol->store(table_list->view_creation_ctx->get_client_cs()->csname,
++ system_charset_info);
++
++ protocol->store(table_list->view_creation_ctx->get_connection_cl()->name,
++ system_charset_info);
++ }
++ else
++ protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
++
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++bool mysqld_show_create_db(THD *thd, char *dbname,
++ HA_CREATE_INFO *create_info)
++{
++ char buff[2048];
++ String buffer(buff, sizeof(buff), system_charset_info);
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ Security_context *sctx= thd->security_ctx;
++ uint db_access;
++#endif
++ HA_CREATE_INFO create;
++ uint create_options = create_info ? create_info->options : 0;
++ Protocol *protocol=thd->protocol;
++ DBUG_ENTER("mysql_show_create_db");
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (test_all_bits(sctx->master_access, DB_ACLS))
++ db_access=DB_ACLS;
++ else
++ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
++ sctx->master_access);
++ if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
++ {
++ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
++ sctx->priv_user, sctx->host_or_ip, dbname);
++ general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
++ sctx->priv_user, sctx->host_or_ip, dbname);
++ DBUG_RETURN(TRUE);
++ }
++#endif
++ if (is_schema_db(dbname))
++ {
++ dbname= INFORMATION_SCHEMA_NAME.str;
++ create.default_table_charset= system_charset_info;
++ }
++ else
++ {
++ if (check_db_dir_existence(dbname))
++ {
++ my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
++ DBUG_RETURN(TRUE);
++ }
++
++ load_db_opt_by_name(thd, dbname, &create);
++ }
++ List<Item> field_list;
++ field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
++ field_list.push_back(new Item_empty_string("Create Database",1024));
++
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ protocol->prepare_for_resend();
++ protocol->store(dbname, strlen(dbname), system_charset_info);
++ buffer.length(0);
++ buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
++ if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
++ append_identifier(thd, &buffer, dbname, strlen(dbname));
++
++ if (create.default_table_charset)
++ {
++ buffer.append(STRING_WITH_LEN(" /*!40100"));
++ buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
++ buffer.append(create.default_table_charset->csname);
++ if (!(create.default_table_charset->state & MY_CS_PRIMARY))
++ {
++ buffer.append(STRING_WITH_LEN(" COLLATE "));
++ buffer.append(create.default_table_charset->name);
++ }
++ buffer.append(STRING_WITH_LEN(" */"));
++ }
++ protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
++
++ if (protocol->write())
++ DBUG_RETURN(TRUE);
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++}
++
++
++
++/****************************************************************************
++ Return only fields for API mysql_list_fields
++ Use "show table wildcard" in mysql instead of this
++****************************************************************************/
++
++void
++mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
++{
++ TABLE *table;
++ DBUG_ENTER("mysqld_list_fields");
++ DBUG_PRINT("enter",("table: %s",table_list->table_name));
++
++ if (open_normal_and_derived_tables(thd, table_list, 0))
++ DBUG_VOID_RETURN;
++ table= table_list->table;
++
++ List<Item> field_list;
++
++ Field **ptr,*field;
++ for (ptr=table->field ; (field= *ptr); ptr++)
++ {
++ if (!wild || !wild[0] ||
++ !wild_case_compare(system_charset_info, field->field_name,wild))
++ {
++ if (table_list->view)
++ field_list.push_back(new Item_ident_for_show(field,
++ table_list->view_db.str,
++ table_list->view_name.str));
++ else
++ field_list.push_back(new Item_field(field));
++ }
++ }
++ restore_record(table, s->default_values); // Get empty record
++ table->use_all_columns();
++ if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
++ DBUG_VOID_RETURN;
++ my_eof(thd);
++ DBUG_VOID_RETURN;
++}
++
++
++int
++mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
++{
++ Protocol *protocol= thd->protocol;
++ String *packet= protocol->storage_packet();
++ DBUG_ENTER("mysqld_dump_create_info");
++ DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
++
++ protocol->prepare_for_resend();
++ if (store_create_info(thd, table_list, packet, NULL,
++ FALSE /* show_database */))
++ DBUG_RETURN(-1);
++
++ if (fd < 0)
++ {
++ if (protocol->write())
++ DBUG_RETURN(-1);
++ protocol->flush();
++ }
++ else
++ {
++ if (my_write(fd, (const uchar*) packet->ptr(), packet->length(),
++ MYF(MY_WME)))
++ DBUG_RETURN(-1);
++ }
++ DBUG_RETURN(0);
++}
++
++/*
++ Go through all character combinations and ensure that sql_lex.cc can
++ parse it as an identifier.
++
++ SYNOPSIS
++ require_quotes()
++ name attribute name
++ name_length length of name
++
++ RETURN
++ # Pointer to conflicting character
++ 0 No conflicting character
++*/
++
++static const char *require_quotes(const char *name, uint name_length)
++{
++ uint length;
++ bool pure_digit= TRUE;
++ const char *end= name + name_length;
++
++ for (; name < end ; name++)
++ {
++ uchar chr= (uchar) *name;
++ length= my_mbcharlen(system_charset_info, chr);
++ if (length == 1 && !system_charset_info->ident_map[chr])
++ return name;
++ if (length == 1 && (chr < '0' || chr > '9'))
++ pure_digit= FALSE;
++ }
++ if (pure_digit)
++ return name;
++ return 0;
++}
++
++
++/*
++ Quote the given identifier if needed and append it to the target string.
++ If the given identifier is empty, it will be quoted.
++
++ SYNOPSIS
++ append_identifier()
++ thd thread handler
++ packet target string
++ name the identifier to be appended
++ name_length length of the appending identifier
++*/
++
++void
++append_identifier(THD *thd, String *packet, const char *name, uint length)
++{
++ const char *name_end;
++ char quote_char;
++ int q= get_quote_char_for_identifier(thd, name, length);
++
++ if (q == EOF)
++ {
++ packet->append(name, length, packet->charset());
++ return;
++ }
++
++ /*
++ The identifier must be quoted as it includes a quote character or
++ it's a keyword
++ */
++
++ VOID(packet->reserve(length*2 + 2));
++ quote_char= (char) q;
++ packet->append("e_char, 1, system_charset_info);
++
++ for (name_end= name+length ; name < name_end ; name+= length)
++ {
++ uchar chr= (uchar) *name;
++ length= my_mbcharlen(system_charset_info, chr);
++ /*
++ my_mbcharlen can return 0 on a wrong multibyte
++ sequence. It is possible when upgrading from 4.0,
++ and identifier contains some accented characters.
++ The manual says it does not work. So we'll just
++ change length to 1 not to hang in the endless loop.
++ */
++ if (!length)
++ length= 1;
++ if (length == 1 && chr == (uchar) quote_char)
++ packet->append("e_char, 1, system_charset_info);
++ packet->append(name, length, system_charset_info);
++ }
++ packet->append("e_char, 1, system_charset_info);
++}
++
++
++/*
++ Get the quote character for displaying an identifier.
++
++ SYNOPSIS
++ get_quote_char_for_identifier()
++ thd Thread handler
++ name name to quote
++ length length of name
++
++ IMPLEMENTATION
++ Force quoting in the following cases:
++ - name is empty (for one, it is possible when we use this function for
++ quoting user and host names for DEFINER clause);
++ - name is a keyword;
++ - name includes a special character;
++ Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
++ is set.
++
++ RETURN
++ EOF No quote character is needed
++ # Quote character
++*/
++
++int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
++{
++ if (length &&
++ !is_keyword(name,length) &&
++ !require_quotes(name, length) &&
++ !(thd->options & OPTION_QUOTE_SHOW_CREATE))
++ return EOF;
++ if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
++ return '"';
++ return '`';
++}
++
++
++/* Append directory name (if exists) to CREATE INFO */
++
++static void append_directory(THD *thd, String *packet, const char *dir_type,
++ const char *filename)
++{
++ if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
++ {
++ uint length= dirname_length(filename);
++ packet->append(' ');
++ packet->append(dir_type);
++ packet->append(STRING_WITH_LEN(" DIRECTORY='"));
++#ifdef __WIN__
++ /* Convert \ to / to be able to create table on unix */
++ char *winfilename= (char*) thd->memdup(filename, length);
++ char *pos, *end;
++ for (pos= winfilename, end= pos+length ; pos < end ; pos++)
++ {
++ if (*pos == '\\')
++ *pos = '/';
++ }
++ filename= winfilename;
++#endif
++ packet->append(filename, length);
++ packet->append('\'');
++ }
++}
++
++
++#define LIST_PROCESS_HOST_LEN 64
++
++static bool get_field_default_value(THD *thd, TABLE *table,
++ Field *field, String *def_value,
++ bool quoted)
++{
++ bool has_default;
++ bool has_now_default;
++ enum enum_field_types field_type= field->type();
++ /*
++ We are using CURRENT_TIMESTAMP instead of NOW because it is
++ more standard
++ */
++ has_now_default= table->timestamp_field == field &&
++ field->unireg_check != Field::TIMESTAMP_UN_FIELD;
++
++ has_default= (field_type != FIELD_TYPE_BLOB &&
++ !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
++ field->unireg_check != Field::NEXT_NUMBER &&
++ !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
++ && has_now_default));
++
++ def_value->length(0);
++ if (has_default)
++ {
++ if (has_now_default)
++ def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
++ else if (!field->is_null())
++ { // Not null by default
++ char tmp[MAX_FIELD_WIDTH];
++ String type(tmp, sizeof(tmp), field->charset());
++ if (field_type == MYSQL_TYPE_BIT)
++ {
++ longlong dec= field->val_int();
++ char *ptr= longlong2str(dec, tmp + 2, 2);
++ uint32 length= (uint32) (ptr - tmp);
++ tmp[0]= 'b';
++ tmp[1]= '\'';
++ tmp[length]= '\'';
++ type.length(length + 1);
++ quoted= 0;
++ }
++ else
++ field->val_str(&type);
++ if (type.length())
++ {
++ String def_val;
++ uint dummy_errors;
++ /* convert to system_charset_info == utf8 */
++ def_val.copy(type.ptr(), type.length(), field->charset(),
++ system_charset_info, &dummy_errors);
++ if (quoted)
++ append_unescaped(def_value, def_val.ptr(), def_val.length());
++ else
++ def_value->append(def_val.ptr(), def_val.length());
++ }
++ else if (quoted)
++ def_value->append(STRING_WITH_LEN("''"));
++ }
++ else if (field->maybe_null() && quoted)
++ def_value->append(STRING_WITH_LEN("NULL")); // Null as default
++ else
++ return 0;
++
++ }
++ return has_default;
++}
++
++/*
++ Build a CREATE TABLE statement for a table.
++
++ SYNOPSIS
++ store_create_info()
++ thd The thread
++ table_list A list containing one table to write statement
++ for.
++ packet Pointer to a string where statement will be
++ written.
++ create_info_arg Pointer to create information that can be used
++ to tailor the format of the statement. Can be
++ NULL, in which case only SQL_MODE is considered
++ when building the statement.
++
++ NOTE
++ Currently always return 0, but might return error code in the
++ future.
++
++ RETURN
++ 0 OK
++ */
++
++int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
++ HA_CREATE_INFO *create_info_arg, bool show_database)
++{
++ List<Item> field_list;
++ char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
++ const char *alias;
++ String type(tmp, sizeof(tmp), system_charset_info);
++ String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
++ Field **ptr,*field;
++ uint primary_key;
++ KEY *key_info;
++ TABLE *table= table_list->table;
++ handler *file= table->file;
++ TABLE_SHARE *share= table->s;
++ HA_CREATE_INFO create_info;
++ bool show_table_options= FALSE;
++ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
++ MODE_ORACLE |
++ MODE_MSSQL |
++ MODE_DB2 |
++ MODE_MAXDB |
++ MODE_ANSI)) != 0;
++ bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS |
++ MODE_MYSQL323 |
++ MODE_MYSQL40)) != 0;
++ my_bitmap_map *old_map;
++ DBUG_ENTER("store_create_info");
++ DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
++
++ restore_record(table, s->default_values); // Get empty record
++
++ if (share->tmp_table)
++ packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
++ else
++ packet->append(STRING_WITH_LEN("CREATE TABLE "));
++ if (create_info_arg &&
++ (create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
++ packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
++ if (table_list->schema_table)
++ alias= table_list->schema_table->table_name;
++ else
++ {
++ if (lower_case_table_names == 2)
++ alias= table->alias;
++ else
++ {
++ alias= share->table_name.str;
++ }
++ }
++
++ /*
++ Print the database before the table name if told to do that. The
++ database name is only printed in the event that it is different
++ from the current database. The main reason for doing this is to
++ avoid having to update gazillions of tests and result files, but
++ it also saves a few bytes of the binary log.
++ */
++ if (show_database)
++ {
++ const LEX_STRING *const db=
++ table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db;
++ if (!thd->db || strcmp(db->str, thd->db))
++ {
++ append_identifier(thd, packet, db->str, db->length);
++ packet->append(STRING_WITH_LEN("."));
++ }
++ }
++
++ append_identifier(thd, packet, alias, strlen(alias));
++ packet->append(STRING_WITH_LEN(" (\n"));
++ /*
++ We need this to get default values from the table
++ We have to restore the read_set if we are called from insert in case
++ of row based replication.
++ */
++ old_map= tmp_use_all_columns(table, table->read_set);
++
++ for (ptr=table->field ; (field= *ptr); ptr++)
++ {
++ uint flags = field->flags;
++
++ if (ptr != table->field)
++ packet->append(STRING_WITH_LEN(",\n"));
++
++ packet->append(STRING_WITH_LEN(" "));
++ append_identifier(thd,packet,field->field_name, strlen(field->field_name));
++ packet->append(' ');
++ // check for surprises from the previous call to Field::sql_type()
++ if (type.ptr() != tmp)
++ type.set(tmp, sizeof(tmp), system_charset_info);
++ else
++ type.set_charset(system_charset_info);
++
++ field->sql_type(type);
++ packet->append(type.ptr(), type.length(), system_charset_info);
++
++ if (field->has_charset() &&
++ !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
++ {
++ if (field->charset() != share->table_charset)
++ {
++ packet->append(STRING_WITH_LEN(" CHARACTER SET "));
++ packet->append(field->charset()->csname);
++ }
++ /*
++ For string types dump collation name only if
++ collation is not primary for the given charset
++ */
++ if (!(field->charset()->state & MY_CS_PRIMARY))
++ {
++ packet->append(STRING_WITH_LEN(" COLLATE "));
++ packet->append(field->charset()->name);
++ }
++ }
++
++ if (flags & NOT_NULL_FLAG)
++ packet->append(STRING_WITH_LEN(" NOT NULL"));
++ else if (field->type() == MYSQL_TYPE_TIMESTAMP)
++ {
++ /*
++ TIMESTAMP field require explicit NULL flag, because unlike
++ all other fields they are treated as NOT NULL by default.
++ */
++ packet->append(STRING_WITH_LEN(" NULL"));
++ }
++
++ if (get_field_default_value(thd, table, field, &def_value, 1))
++ {
++ packet->append(STRING_WITH_LEN(" DEFAULT "));
++ packet->append(def_value.ptr(), def_value.length(), system_charset_info);
++ }
++
++ if (!limited_mysql_mode && table->timestamp_field == field &&
++ field->unireg_check != Field::TIMESTAMP_DN_FIELD)
++ packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
++
++ if (field->unireg_check == Field::NEXT_NUMBER &&
++ !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
++ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
++
++ if (field->comment.length)
++ {
++ packet->append(STRING_WITH_LEN(" COMMENT "));
++ append_unescaped(packet, field->comment.str, field->comment.length);
++ }
++ }
++
++ key_info= table->key_info;
++ bzero((char*) &create_info, sizeof(create_info));
++ /* Allow update_create_info to update row type */
++ create_info.row_type= share->row_type;
++ file->update_create_info(&create_info);
++ primary_key= share->primary_key;
++
++ for (uint i=0 ; i < share->keys ; i++,key_info++)
++ {
++ KEY_PART_INFO *key_part= key_info->key_part;
++ bool found_primary=0;
++ packet->append(STRING_WITH_LEN(",\n "));
++
++ if (i == primary_key && !strcmp(key_info->name, primary_key_name))
++ {
++ found_primary=1;
++ /*
++ No space at end, because a space will be added after where the
++ identifier would go, but that is not added for primary key.
++ */
++ packet->append(STRING_WITH_LEN("PRIMARY KEY"));
++ }
++ else if (key_info->flags & HA_NOSAME)
++ packet->append(STRING_WITH_LEN("UNIQUE KEY "));
++ else if (key_info->flags & HA_FULLTEXT)
++ packet->append(STRING_WITH_LEN("FULLTEXT KEY "));
++ else if (key_info->flags & HA_SPATIAL)
++ packet->append(STRING_WITH_LEN("SPATIAL KEY "));
++ else
++ packet->append(STRING_WITH_LEN("KEY "));
++
++ if (!found_primary)
++ append_identifier(thd, packet, key_info->name, strlen(key_info->name));
++
++ packet->append(STRING_WITH_LEN(" ("));
++
++ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
++ {
++ if (j)
++ packet->append(',');
++
++ if (key_part->field)
++ append_identifier(thd,packet,key_part->field->field_name,
++ strlen(key_part->field->field_name));
++ if (key_part->field &&
++ (key_part->length !=
++ table->field[key_part->fieldnr-1]->key_length() &&
++ !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))))
++ {
++ char *end;
++ buff[0] = '(';
++ end= int10_to_str((long) key_part->length /
++ key_part->field->charset()->mbmaxlen,
++ buff + 1,10);
++ *end++ = ')';
++ packet->append(buff,(uint) (end-buff));
++ }
++ }
++ packet->append(')');
++ store_key_options(thd, packet, table, key_info);
++ if (key_info->parser)
++ {
++ LEX_STRING *parser_name= plugin_name(key_info->parser);
++ packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER "));
++ append_identifier(thd, packet, parser_name->str, parser_name->length);
++ packet->append(STRING_WITH_LEN(" */ "));
++ }
++ }
++
++ /*
++ Get possible foreign key definitions stored in InnoDB and append them
++ to the CREATE TABLE statement
++ */
++
++ if ((for_str= file->get_foreign_key_create_info()))
++ {
++ packet->append(for_str, strlen(for_str));
++ file->free_foreign_key_create_info(for_str);
++ }
++
++ packet->append(STRING_WITH_LEN("\n)"));
++ if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
++ {
++ show_table_options= TRUE;
++ /*
++ Get possible table space definitions and append them
++ to the CREATE TABLE statement
++ */
++
++ if ((for_str= file->get_tablespace_name(thd,0,0)))
++ {
++ packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE "));
++ packet->append(for_str, strlen(for_str));
++ packet->append(STRING_WITH_LEN(" STORAGE DISK */"));
++ my_free(for_str, MYF(0));
++ }
++
++ /*
++ IF check_create_info
++ THEN add ENGINE only if it was used when creating the table
++ */
++ if (!create_info_arg ||
++ (create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
++ {
++ if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
++ packet->append(STRING_WITH_LEN(" TYPE="));
++ else
++ packet->append(STRING_WITH_LEN(" ENGINE="));
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (table->part_info)
++ packet->append(ha_resolve_storage_engine_name(
++ table->part_info->default_engine_type));
++ else
++ packet->append(file->table_type());
++#else
++ packet->append(file->table_type());
++#endif
++ }
++
++ /*
++ Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
++ and NEXT_ID > 1 (the default). We must not print the clause
++ for engines that do not support this as it would break the
++ import of dumps, but as of this writing, the test for whether
++ AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
++ is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
++ Because of that, we do not explicitly test for the feature,
++ but may extrapolate its existence from that of an AUTO_INCREMENT column.
++ */
++
++ if (create_info.auto_increment_value > 1)
++ {
++ char *end;
++ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
++ end= longlong10_to_str(create_info.auto_increment_value, buff,10);
++ packet->append(buff, (uint) (end - buff));
++ }
++
++
++ if (share->table_charset &&
++ !(thd->variables.sql_mode & MODE_MYSQL323) &&
++ !(thd->variables.sql_mode & MODE_MYSQL40))
++ {
++ /*
++ IF check_create_info
++ THEN add DEFAULT CHARSET only if it was used when creating the table
++ */
++ if (!create_info_arg ||
++ (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
++ {
++ packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
++ packet->append(share->table_charset->csname);
++ if (!(share->table_charset->state & MY_CS_PRIMARY))
++ {
++ packet->append(STRING_WITH_LEN(" COLLATE="));
++ packet->append(table->s->table_charset->name);
++ }
++ }
++ }
++
++ if (share->min_rows)
++ {
++ char *end;
++ packet->append(STRING_WITH_LEN(" MIN_ROWS="));
++ end= longlong10_to_str(share->min_rows, buff, 10);
++ packet->append(buff, (uint) (end- buff));
++ }
++
++ if (share->max_rows && !table_list->schema_table)
++ {
++ char *end;
++ packet->append(STRING_WITH_LEN(" MAX_ROWS="));
++ end= longlong10_to_str(share->max_rows, buff, 10);
++ packet->append(buff, (uint) (end - buff));
++ }
++
++ if (share->avg_row_length)
++ {
++ char *end;
++ packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
++ end= longlong10_to_str(share->avg_row_length, buff,10);
++ packet->append(buff, (uint) (end - buff));
++ }
++
++ if (share->db_create_options & HA_OPTION_PACK_KEYS)
++ packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
++ if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
++ packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
++ /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
++ if (share->db_create_options & HA_OPTION_CHECKSUM)
++ packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
++ if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
++ packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
++ if (create_info.row_type != ROW_TYPE_DEFAULT)
++ {
++ packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
++ packet->append(ha_row_type[(uint) create_info.row_type]);
++ }
++ if (table->s->key_block_size)
++ {
++ char *end;
++ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
++ end= longlong10_to_str(table->s->key_block_size, buff, 10);
++ packet->append(buff, (uint) (end - buff));
++ }
++ table->file->append_create_info(packet);
++ if (share->comment.length)
++ {
++ packet->append(STRING_WITH_LEN(" COMMENT="));
++ append_unescaped(packet, share->comment.str, share->comment.length);
++ }
++ if (share->connect_string.length)
++ {
++ packet->append(STRING_WITH_LEN(" CONNECTION="));
++ append_unescaped(packet, share->connect_string.str, share->connect_string.length);
++ }
++ append_directory(thd, packet, "DATA", create_info.data_file_name);
++ append_directory(thd, packet, "INDEX", create_info.index_file_name);
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ {
++ /*
++ Partition syntax for CREATE TABLE is at the end of the syntax.
++ */
++ uint part_syntax_len;
++ char *part_syntax;
++ if (table->part_info &&
++ (!table->part_info->is_auto_partitioned) &&
++ ((part_syntax= generate_partition_syntax(table->part_info,
++ &part_syntax_len,
++ FALSE,
++ show_table_options))))
++ {
++ packet->append(STRING_WITH_LEN("\n/*!50100"));
++ packet->append(part_syntax, part_syntax_len);
++ packet->append(STRING_WITH_LEN(" */"));
++ my_free(part_syntax, MYF(0));
++ }
++ }
++#endif
++ tmp_restore_column_map(table->read_set, old_map);
++ DBUG_RETURN(0);
++}
++
++
++static void store_key_options(THD *thd, String *packet, TABLE *table,
++ KEY *key_info)
++{
++ bool limited_mysql_mode= (thd->variables.sql_mode &
++ (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
++ MODE_MYSQL40)) != 0;
++ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
++ MODE_ORACLE |
++ MODE_MSSQL |
++ MODE_DB2 |
++ MODE_MAXDB |
++ MODE_ANSI)) != 0;
++ char *end, buff[32];
++
++ if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
++ !limited_mysql_mode && !foreign_db_mode)
++ {
++
++ if (key_info->algorithm == HA_KEY_ALG_BTREE)
++ packet->append(STRING_WITH_LEN(" USING BTREE"));
++
++ if (key_info->algorithm == HA_KEY_ALG_HASH)
++ packet->append(STRING_WITH_LEN(" USING HASH"));
++
++ /* send USING only in non-default case: non-spatial rtree */
++ if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
++ !(key_info->flags & HA_SPATIAL))
++ packet->append(STRING_WITH_LEN(" USING RTREE"));
++
++ if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
++ table->s->key_block_size != key_info->block_size)
++ {
++ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
++ end= longlong10_to_str(key_info->block_size, buff, 10);
++ packet->append(buff, (uint) (end - buff));
++ }
++ }
++}
++
++
++void
++view_store_options(THD *thd, TABLE_LIST *table, String *buff)
++{
++ append_algorithm(table, buff);
++ append_definer(thd, buff, &table->definer.user, &table->definer.host);
++ if (table->view_suid)
++ buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER "));
++ else
++ buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
++}
++
++
++/*
++ Append DEFINER clause to the given buffer.
++
++ SYNOPSIS
++ append_definer()
++ thd [in] thread handle
++ buffer [inout] buffer to hold DEFINER clause
++ definer_user [in] user name part of definer
++ definer_host [in] host name part of definer
++*/
++
++static void append_algorithm(TABLE_LIST *table, String *buff)
++{
++ buff->append(STRING_WITH_LEN("ALGORITHM="));
++ switch ((int8)table->algorithm) {
++ case VIEW_ALGORITHM_UNDEFINED:
++ buff->append(STRING_WITH_LEN("UNDEFINED "));
++ break;
++ case VIEW_ALGORITHM_TMPTABLE:
++ buff->append(STRING_WITH_LEN("TEMPTABLE "));
++ break;
++ case VIEW_ALGORITHM_MERGE:
++ buff->append(STRING_WITH_LEN("MERGE "));
++ break;
++ default:
++ DBUG_ASSERT(0); // never should happen
++ }
++}
++
++/*
++ Append DEFINER clause to the given buffer.
++
++ SYNOPSIS
++ append_definer()
++ thd [in] thread handle
++ buffer [inout] buffer to hold DEFINER clause
++ definer_user [in] user name part of definer
++ definer_host [in] host name part of definer
++*/
++
++void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
++ const LEX_STRING *definer_host)
++{
++ buffer->append(STRING_WITH_LEN("DEFINER="));
++ append_identifier(thd, buffer, definer_user->str, definer_user->length);
++ buffer->append('@');
++ append_identifier(thd, buffer, definer_host->str, definer_host->length);
++ buffer->append(' ');
++}
++
++
++int
++view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
++{
++ my_bool compact_view_name= TRUE;
++ my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
++ MODE_ORACLE |
++ MODE_MSSQL |
++ MODE_DB2 |
++ MODE_MAXDB |
++ MODE_ANSI)) != 0;
++
++ if (!thd->db || strcmp(thd->db, table->view_db.str))
++ /*
++ print compact view name if the view belongs to the current database
++ */
++ compact_view_name= table->compact_view_format= FALSE;
++ else
++ {
++ /*
++ Compact output format for view body can be used
++ if this view only references table inside it's own db
++ */
++ TABLE_LIST *tbl;
++ table->compact_view_format= TRUE;
++ for (tbl= thd->lex->query_tables;
++ tbl;
++ tbl= tbl->next_global)
++ {
++ if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
++ {
++ table->compact_view_format= FALSE;
++ break;
++ }
++ }
++ }
++
++ buff->append(STRING_WITH_LEN("CREATE "));
++ if (!foreign_db_mode)
++ {
++ view_store_options(thd, table, buff);
++ }
++ buff->append(STRING_WITH_LEN("VIEW "));
++ if (!compact_view_name)
++ {
++ append_identifier(thd, buff, table->view_db.str, table->view_db.length);
++ buff->append('.');
++ }
++ append_identifier(thd, buff, table->view_name.str, table->view_name.length);
++ buff->append(STRING_WITH_LEN(" AS "));
++
++ /*
++ We can't just use table->query, because our SQL_MODE may trigger
++ a different syntax, like when ANSI_QUOTES is defined.
++ */
++ table->view->unit.print(buff, QT_ORDINARY);
++
++ if (table->with_check != VIEW_CHECK_NONE)
++ {
++ if (table->with_check == VIEW_CHECK_LOCAL)
++ buff->append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
++ else
++ buff->append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
++ }
++ return 0;
++}
++
++
++/****************************************************************************
++ Return info about all processes
++ returns for each thread: thread id, user, host, db, command, info
++****************************************************************************/
++
++class thread_info :public ilink {
++public:
++ static void *operator new(size_t size)
++ {
++ return (void*) sql_alloc((uint) size);
++ }
++ static void operator delete(void *ptr __attribute__((unused)),
++ size_t size __attribute__((unused)))
++ { TRASH(ptr, size); }
++
++ ulong thread_id;
++ time_t start_time;
++ uint command;
++ const char *user,*host,*db,*proc_info,*state_info;
++ char *query;
++};
++
++#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
++template class I_List<thread_info>;
++#endif
++
++void mysqld_list_processes(THD *thd,const char *user, bool verbose)
++{
++ Item *field;
++ List<Item> field_list;
++ I_List<thread_info> thread_infos;
++ ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
++ PROCESS_LIST_WIDTH);
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysqld_list_processes");
++
++ field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
++ field_list.push_back(new Item_empty_string("User",16));
++ field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
++ field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
++ field->maybe_null=1;
++ field_list.push_back(new Item_empty_string("Command",16));
++ field_list.push_back(field= new Item_return_int("Time",7, MYSQL_TYPE_LONG));
++ field->unsigned_flag= 0;
++ field_list.push_back(field=new Item_empty_string("State",30));
++ field->maybe_null=1;
++ field_list.push_back(field=new Item_empty_string("Info",max_query_length));
++ field->maybe_null=1;
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_VOID_RETURN;
++
++ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
++ if (!thd->killed)
++ {
++ I_List_iterator<THD> it(threads);
++ THD *tmp;
++ while ((tmp=it++))
++ {
++ Security_context *tmp_sctx= tmp->security_ctx;
++ struct st_my_thread_var *mysys_var;
++ if ((tmp->vio_ok() || tmp->system_thread) &&
++ (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
++ {
++ thread_info *thd_info= new thread_info;
++
++ thd_info->thread_id=tmp->thread_id;
++ thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
++ (tmp->system_thread ?
++ "system user" : "unauthenticated user"));
++ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
++ thd->security_ctx->host_or_ip[0])
++ {
++ if ((thd_info->host= (char*) thd->alloc(LIST_PROCESS_HOST_LEN+1)))
++ my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
++ "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
++ }
++ else
++ thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
++ tmp_sctx->host_or_ip :
++ tmp_sctx->host ? tmp_sctx->host : "");
++ if ((thd_info->db=tmp->db)) // Safe test
++ thd_info->db=thd->strdup(thd_info->db);
++ thd_info->command=(int) tmp->command;
++ if ((mysys_var= tmp->mysys_var))
++ pthread_mutex_lock(&mysys_var->mutex);
++ thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
++#ifndef EMBEDDED_LIBRARY
++ thd_info->state_info= (char*) (tmp->locked ? "Locked" :
++ tmp->net.reading_or_writing ?
++ (tmp->net.reading_or_writing == 2 ?
++ "Writing to net" :
++ thd_info->command == COM_SLEEP ? "" :
++ "Reading from net") :
++ tmp->proc_info ? tmp->proc_info :
++ tmp->mysys_var &&
++ tmp->mysys_var->current_cond ?
++ "Waiting on cond" : NullS);
++#else
++ thd_info->state_info= (char*)"Writing to net";
++#endif
++ if (mysys_var)
++ pthread_mutex_unlock(&mysys_var->mutex);
++
++ thd_info->start_time= tmp->start_time;
++ thd_info->query=0;
++ /* Lock THD mutex that protects its data when looking at it. */
++ pthread_mutex_lock(&tmp->LOCK_thd_data);
++ if (tmp->query())
++ {
++ uint length= min(max_query_length, tmp->query_length());
++ thd_info->query= (char*) thd->strmake(tmp->query(),length);
++ }
++ pthread_mutex_unlock(&tmp->LOCK_thd_data);
++ thread_infos.append(thd_info);
++ }
++ }
++ }
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++
++ thread_info *thd_info;
++ time_t now= my_time(0);
++ while ((thd_info=thread_infos.get()))
++ {
++ protocol->prepare_for_resend();
++ protocol->store((ulonglong) thd_info->thread_id);
++ protocol->store(thd_info->user, system_charset_info);
++ protocol->store(thd_info->host, system_charset_info);
++ protocol->store(thd_info->db, system_charset_info);
++ if (thd_info->proc_info)
++ protocol->store(thd_info->proc_info, system_charset_info);
++ else
++ protocol->store(command_name[thd_info->command].str, system_charset_info);
++ if (thd_info->start_time)
++ protocol->store_long ((longlong) (now - thd_info->start_time));
++ else
++ protocol->store_null();
++ protocol->store(thd_info->state_info, system_charset_info);
++ protocol->store(thd_info->query, system_charset_info);
++ if (protocol->write())
++ break; /* purecov: inspected */
++ }
++ my_eof(thd);
++ DBUG_VOID_RETURN;
++}
++
++int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ CHARSET_INFO *cs= system_charset_info;
++ char *user;
++ time_t now= my_time(0);
++ DBUG_ENTER("fill_process_list");
++
++ user= thd->security_ctx->master_access & PROCESS_ACL ?
++ NullS : thd->security_ctx->priv_user;
++
++ VOID(pthread_mutex_lock(&LOCK_thread_count));
++
++ if (!thd->killed)
++ {
++ I_List_iterator<THD> it(threads);
++ THD* tmp;
++
++ while ((tmp= it++))
++ {
++ Security_context *tmp_sctx= tmp->security_ctx;
++ struct st_my_thread_var *mysys_var;
++ const char *val;
++
++ if ((!tmp->vio_ok() && !tmp->system_thread) ||
++ (user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
++ continue;
++
++ restore_record(table, s->default_values);
++ /* ID */
++ table->field[0]->store((longlong) tmp->thread_id, TRUE);
++ /* USER */
++ val= tmp_sctx->user ? tmp_sctx->user :
++ (tmp->system_thread ? "system user" : "unauthenticated user");
++ table->field[1]->store(val, strlen(val), cs);
++ /* HOST */
++ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
++ thd->security_ctx->host_or_ip[0])
++ {
++ char host[LIST_PROCESS_HOST_LEN + 1];
++ my_snprintf(host, LIST_PROCESS_HOST_LEN, "%s:%u",
++ tmp_sctx->host_or_ip, tmp->peer_port);
++ table->field[2]->store(host, strlen(host), cs);
++ }
++ else
++ table->field[2]->store(tmp_sctx->host_or_ip,
++ strlen(tmp_sctx->host_or_ip), cs);
++ /* DB */
++ if (tmp->db)
++ {
++ table->field[3]->store(tmp->db, strlen(tmp->db), cs);
++ table->field[3]->set_notnull();
++ }
++
++ if ((mysys_var= tmp->mysys_var))
++ pthread_mutex_lock(&mysys_var->mutex);
++ /* COMMAND */
++ if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
++ table->field[4]->store(val, strlen(val), cs);
++ else
++ table->field[4]->store(command_name[tmp->command].str,
++ command_name[tmp->command].length, cs);
++ /* MYSQL_TIME */
++ table->field[5]->store((longlong)(tmp->start_time ?
++ now - tmp->start_time : 0), FALSE);
++ /* STATE */
++#ifndef EMBEDDED_LIBRARY
++ val= (char*) (tmp->locked ? "Locked" :
++ tmp->net.reading_or_writing ?
++ (tmp->net.reading_or_writing == 2 ?
++ "Writing to net" :
++ tmp->command == COM_SLEEP ? "" :
++ "Reading from net") :
++ tmp->proc_info ? tmp->proc_info :
++ tmp->mysys_var &&
++ tmp->mysys_var->current_cond ?
++ "Waiting on cond" : NullS);
++#else
++ val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
++#endif
++ if (val)
++ {
++ table->field[6]->store(val, strlen(val), cs);
++ table->field[6]->set_notnull();
++ }
++
++ if (mysys_var)
++ pthread_mutex_unlock(&mysys_var->mutex);
++
++ /* INFO */
++ /* Lock THD mutex that protects its data when looking at it. */
++ pthread_mutex_lock(&tmp->LOCK_thd_data);
++ if (tmp->query())
++ {
++ table->field[7]->store(tmp->query(),
++ min(PROCESS_LIST_INFO_WIDTH,
++ tmp->query_length()), cs);
++ table->field[7]->set_notnull();
++ }
++ pthread_mutex_unlock(&tmp->LOCK_thd_data);
++
++ if (schema_table_store_record(thd, table))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ DBUG_RETURN(1);
++ }
++ }
++ }
++
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ DBUG_RETURN(0);
++}
++
++/*****************************************************************************
++ Status functions
++*****************************************************************************/
++
++static DYNAMIC_ARRAY all_status_vars;
++static bool status_vars_inited= 0;
++static int show_var_cmp(const void *var1, const void *var2)
++{
++ return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
++}
++
++/*
++ deletes all the SHOW_UNDEF elements from the array and calls
++ delete_dynamic() if it's completely empty.
++*/
++static void shrink_var_array(DYNAMIC_ARRAY *array)
++{
++ uint a,b;
++ SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
++
++ for (a= b= 0; b < array->elements; b++)
++ if (all[b].type != SHOW_UNDEF)
++ all[a++]= all[b];
++ if (a)
++ {
++ bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
++ array->elements= a;
++ }
++ else // array is completely empty - delete it
++ delete_dynamic(array);
++}
++
++/*
++ Adds an array of SHOW_VAR entries to the output of SHOW STATUS
++
++ SYNOPSIS
++ add_status_vars(SHOW_VAR *list)
++ list - an array of SHOW_VAR entries to add to all_status_vars
++ the last entry must be {0,0,SHOW_UNDEF}
++
++ NOTE
++ The handling of all_status_vars[] is completely internal, it's allocated
++ automatically when something is added to it, and deleted completely when
++ the last entry is removed.
++
++ As a special optimization, if add_status_vars() is called before
++ init_status_vars(), it assumes "startup mode" - neither concurrent access
++ to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
++
++ The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
++*/
++int add_status_vars(SHOW_VAR *list)
++{
++ int res= 0;
++ if (status_vars_inited)
++ pthread_mutex_lock(&LOCK_status);
++ if (!all_status_vars.buffer && // array is not allocated yet - do it now
++ my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
++ {
++ res= 1;
++ goto err;
++ }
++ while (list->name)
++ res|= insert_dynamic(&all_status_vars, (uchar*)list++);
++ res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
++ all_status_vars.elements--; // but next insert_dynamic should overwite it
++ if (status_vars_inited)
++ sort_dynamic(&all_status_vars, show_var_cmp);
++err:
++ if (status_vars_inited)
++ pthread_mutex_unlock(&LOCK_status);
++ return res;
++}
++
++/*
++ Make all_status_vars[] usable for SHOW STATUS
++
++ NOTE
++ See add_status_vars(). Before init_status_vars() call, add_status_vars()
++ works in a special fast "startup" mode. Thus init_status_vars()
++ should be called as late as possible but before enabling multi-threading.
++*/
++void init_status_vars()
++{
++ status_vars_inited=1;
++ sort_dynamic(&all_status_vars, show_var_cmp);
++}
++
++void reset_status_vars()
++{
++ SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
++ SHOW_VAR *last= ptr + all_status_vars.elements;
++ for (; ptr < last; ptr++)
++ {
++ /* Note that SHOW_LONG_NOFLUSH variables are not reset */
++ if (ptr->type == SHOW_LONG)
++ *(ulong*) ptr->value= 0;
++ }
++}
++
++/*
++ catch-all cleanup function, cleans up everything no matter what
++
++ DESCRIPTION
++ This function is not strictly required if all add_to_status/
++ remove_status_vars are properly paired, but it's a safety measure that
++ deletes everything from the all_status_vars[] even if some
++ remove_status_vars were forgotten
++*/
++void free_status_vars()
++{
++ delete_dynamic(&all_status_vars);
++}
++
++/*
++ Removes an array of SHOW_VAR entries from the output of SHOW STATUS
++
++ SYNOPSIS
++ remove_status_vars(SHOW_VAR *list)
++ list - an array of SHOW_VAR entries to remove to all_status_vars
++ the last entry must be {0,0,SHOW_UNDEF}
++
++ NOTE
++ there's lots of room for optimizing this, especially in non-sorted mode,
++ but nobody cares - it may be called only in case of failed plugin
++ initialization in the mysqld startup.
++*/
++
++void remove_status_vars(SHOW_VAR *list)
++{
++ if (status_vars_inited)
++ {
++ pthread_mutex_lock(&LOCK_status);
++ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
++ int a= 0, b= all_status_vars.elements, c= (a+b)/2;
++
++ for (; list->name; list++)
++ {
++ int res= 0;
++ for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
++ {
++ res= show_var_cmp(list, all+c);
++ if (res < 0)
++ b= c;
++ else if (res > 0)
++ a= c;
++ else
++ break;
++ }
++ if (res == 0)
++ all[c].type= SHOW_UNDEF;
++ }
++ shrink_var_array(&all_status_vars);
++ pthread_mutex_unlock(&LOCK_status);
++ }
++ else
++ {
++ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
++ uint i;
++ for (; list->name; list++)
++ {
++ for (i= 0; i < all_status_vars.elements; i++)
++ {
++ if (show_var_cmp(list, all+i))
++ continue;
++ all[i].type= SHOW_UNDEF;
++ break;
++ }
++ }
++ shrink_var_array(&all_status_vars);
++ }
++}
++
++inline void make_upper(char *buf)
++{
++ for (; *buf; buf++)
++ *buf= my_toupper(system_charset_info, *buf);
++}
++
++static bool show_status_array(THD *thd, const char *wild,
++ SHOW_VAR *variables,
++ enum enum_var_type value_type,
++ struct system_status_var *status_var,
++ const char *prefix, TABLE *table,
++ bool ucase_names,
++ COND *cond)
++{
++ my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer;
++ char * const buff= buffer.data;
++ char *prefix_end;
++ /* the variable name should not be longer than 64 characters */
++ char name_buffer[64];
++ int len;
++ LEX_STRING null_lex_str;
++ SHOW_VAR tmp, *var;
++ COND *partial_cond= 0;
++ enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
++ bool res= FALSE;
++ CHARSET_INFO *charset= system_charset_info;
++ DBUG_ENTER("show_status_array");
++
++ thd->count_cuted_fields= CHECK_FIELD_WARN;
++ null_lex_str.str= 0; // For sys_var->value_ptr()
++ null_lex_str.length= 0;
++
++ prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
++ if (*prefix)
++ *prefix_end++= '_';
++ len=name_buffer + sizeof(name_buffer) - prefix_end;
++ partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list);
++
++ for (; variables->name; variables++)
++ {
++ strnmov(prefix_end, variables->name, len);
++ name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
++ if (ucase_names)
++ make_upper(name_buffer);
++
++ restore_record(table, s->default_values);
++ table->field[0]->store(name_buffer, strlen(name_buffer),
++ system_charset_info);
++ /*
++ if var->type is SHOW_FUNC, call the function.
++ Repeat as necessary, if new var is again SHOW_FUNC
++ */
++ for (var=variables; var->type == SHOW_FUNC; var= &tmp)
++ ((mysql_show_var_func)(var->value))(thd, &tmp, buff);
++
++ SHOW_TYPE show_type=var->type;
++ if (show_type == SHOW_ARRAY)
++ {
++ show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
++ status_var, name_buffer, table, ucase_names, partial_cond);
++ }
++ else
++ {
++ if (!(wild && wild[0] && wild_case_compare(system_charset_info,
++ name_buffer, wild)) &&
++ (!partial_cond || partial_cond->val_int()))
++ {
++ char *value=var->value;
++ const char *pos, *end; // We assign a lot of const's
++
++ pthread_mutex_lock(&LOCK_global_system_variables);
++
++ if (show_type == SHOW_SYS)
++ {
++ sys_var *var= ((sys_var *) value);
++ show_type= var->show_type();
++ value= (char*) var->value_ptr(thd, value_type, &null_lex_str);
++ charset= var->charset(thd);
++ }
++
++ pos= end= buff;
++ /*
++ note that value may be == buff. All SHOW_xxx code below
++ should still work in this case
++ */
++ switch (show_type) {
++ case SHOW_DOUBLE_STATUS:
++ value= ((char *) status_var + (ulong) value);
++ /* fall through */
++ case SHOW_DOUBLE:
++ end= buff + sprintf(buff, "%f", *(double*) value);
++ break;
++ case SHOW_LONG_STATUS:
++ value= ((char *) status_var + (ulong) value);
++ /* fall through */
++ case SHOW_LONG:
++ case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
++ end= int10_to_str(*(long*) value, buff, 10);
++ break;
++ case SHOW_LONGLONG_STATUS:
++ value= ((char *) status_var + (ulonglong) value);
++ /* fall through */
++ case SHOW_LONGLONG:
++ end= longlong10_to_str(*(longlong*) value, buff, 10);
++ break;
++ case SHOW_HA_ROWS:
++ end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
++ break;
++ case SHOW_BOOL:
++ end= strmov(buff, *(bool*) value ? "ON" : "OFF");
++ break;
++ case SHOW_MY_BOOL:
++ end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
++ break;
++ case SHOW_INT:
++ end= int10_to_str((long) *(uint32*) value, buff, 10);
++ break;
++ case SHOW_HAVE:
++ {
++ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
++ pos= show_comp_option_name[(int) tmp];
++ end= strend(pos);
++ break;
++ }
++ case SHOW_CHAR:
++ {
++ if (!(pos= value))
++ pos= "";
++ end= strend(pos);
++ break;
++ }
++ case SHOW_CHAR_PTR:
++ {
++ if (!(pos= *(char**) value))
++ pos= "";
++ end= strend(pos);
++ break;
++ }
++ case SHOW_KEY_CACHE_LONG:
++ value= (char*) dflt_key_cache + (ulong)value;
++ end= int10_to_str(*(long*) value, buff, 10);
++ break;
++ case SHOW_KEY_CACHE_LONGLONG:
++ value= (char*) dflt_key_cache + (ulong)value;
++ end= longlong10_to_str(*(longlong*) value, buff, 10);
++ break;
++ case SHOW_UNDEF:
++ break; // Return empty string
++ case SHOW_SYS: // Cannot happen
++ default:
++ DBUG_ASSERT(0);
++ break;
++ }
++ table->field[1]->store(pos, (uint32) (end - pos), charset);
++ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
++ table->field[1]->set_notnull();
++
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++
++ if (schema_table_store_record(thd, table))
++ {
++ res= TRUE;
++ goto end;
++ }
++ }
++ }
++ }
++end:
++ thd->count_cuted_fields= save_count_cuted_fields;
++ DBUG_RETURN(res);
++}
++
++
++/* collect status for all running threads */
++
++void calc_sum_of_all_status(STATUS_VAR *to)
++{
++ DBUG_ENTER("calc_sum_of_all_status");
++
++ /* Ensure that thread id not killed during loop */
++ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
++
++ I_List_iterator<THD> it(threads);
++ THD *tmp;
++
++ /* Get global values as base */
++ *to= global_status_var;
++
++ /* Add to this status from existing threads */
++ while ((tmp= it++))
++ add_to_status(to, &tmp->status_var);
++
++ VOID(pthread_mutex_unlock(&LOCK_thread_count));
++ DBUG_VOID_RETURN;
++}
++
++
++/* This is only used internally, but we need it here as a forward reference */
++extern ST_SCHEMA_TABLE schema_tables[];
++
++typedef struct st_lookup_field_values
++{
++ LEX_STRING db_value, table_value;
++ bool wild_db_value, wild_table_value;
++} LOOKUP_FIELD_VALUES;
++
++
++/*
++ Store record to I_S table, convert HEAP table
++ to MyISAM if necessary
++
++ SYNOPSIS
++ schema_table_store_record()
++ thd thread handler
++ table Information schema table to be updated
++
++ RETURN
++ 0 success
++ 1 error
++*/
++
++bool schema_table_store_record(THD *thd, TABLE *table)
++{
++ int error;
++ if ((error= table->file->ha_write_row(table->record[0])))
++ {
++ if (create_myisam_from_heap(thd, table,
++ table->pos_in_table_list->schema_table_param,
++ error, 0))
++ return 1;
++ }
++ return 0;
++}
++
++
++int make_table_list(THD *thd, SELECT_LEX *sel,
++ LEX_STRING *db_name, LEX_STRING *table_name)
++{
++ Table_ident *table_ident;
++ table_ident= new Table_ident(thd, *db_name, *table_name, 1);
++ sel->init_query();
++ if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
++ return 1;
++ return 0;
++}
++
++
++/**
++ @brief Get lookup value from the part of 'WHERE' condition
++
++ @details This function gets lookup value from
++ the part of 'WHERE' condition if it's possible and
++ fill appropriate lookup_field_vals struct field
++ with this value.
++
++ @param[in] thd thread handler
++ @param[in] item_func part of WHERE condition
++ @param[in] table I_S table
++ @param[in, out] lookup_field_vals Struct which holds lookup values
++
++ @return
++ 0 success
++ 1 error, there can be no matching records for the condition
++*/
++
++bool get_lookup_value(THD *thd, Item_func *item_func,
++ TABLE_LIST *table,
++ LOOKUP_FIELD_VALUES *lookup_field_vals)
++{
++ ST_SCHEMA_TABLE *schema_table= table->schema_table;
++ ST_FIELD_INFO *field_info= schema_table->fields_info;
++ const char *field_name1= schema_table->idx_field1 >= 0 ?
++ field_info[schema_table->idx_field1].field_name : "";
++ const char *field_name2= schema_table->idx_field2 >= 0 ?
++ field_info[schema_table->idx_field2].field_name : "";
++
++ if (item_func->functype() == Item_func::EQ_FUNC ||
++ item_func->functype() == Item_func::EQUAL_FUNC)
++ {
++ int idx_field, idx_val;
++ char tmp[MAX_FIELD_WIDTH];
++ String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
++ Item_field *item_field;
++ CHARSET_INFO *cs= system_charset_info;
++
++ if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
++ item_func->arguments()[1]->const_item())
++ {
++ idx_field= 0;
++ idx_val= 1;
++ }
++ else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
++ item_func->arguments()[0]->const_item())
++ {
++ idx_field= 1;
++ idx_val= 0;
++ }
++ else
++ return 0;
++
++ item_field= (Item_field*) item_func->arguments()[idx_field];
++ if (table->table != item_field->field->table)
++ return 0;
++ tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
++
++ /* impossible value */
++ if (!tmp_str)
++ return 1;
++
++ /* Lookup value is database name */
++ if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
++ (uchar *) item_field->field_name,
++ strlen(item_field->field_name), 0))
++ {
++ thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
++ tmp_str->length(), FALSE);
++ }
++ /* Lookup value is table name */
++ else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
++ strlen(field_name2),
++ (uchar *) item_field->field_name,
++ strlen(item_field->field_name), 0))
++ {
++ thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
++ tmp_str->length(), FALSE);
++ }
++ }
++ return 0;
++}
++
++
++/**
++ @brief Calculates lookup values from 'WHERE' condition
++
++ @details This function calculates lookup value(database name, table name)
++ from 'WHERE' condition if it's possible and
++ fill lookup_field_vals struct fields with these values.
++
++ @param[in] thd thread handler
++ @param[in] cond WHERE condition
++ @param[in] table I_S table
++ @param[in, out] lookup_field_vals Struct which holds lookup values
++
++ @return
++ 0 success
++ 1 error, there can be no matching records for the condition
++*/
++
++bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
++ LOOKUP_FIELD_VALUES *lookup_field_vals)
++{
++ if (!cond)
++ return 0;
++
++ if (cond->type() == Item::COND_ITEM)
++ {
++ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ {
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item= li++))
++ {
++ if (item->type() == Item::FUNC_ITEM)
++ {
++ if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
++ return 1;
++ }
++ else
++ {
++ if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
++ return 1;
++ }
++ }
++ }
++ return 0;
++ }
++ else if (cond->type() == Item::FUNC_ITEM &&
++ get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
++ return 1;
++ return 0;
++}
++
++
++bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
++{
++ if (item->type() == Item::FUNC_ITEM)
++ {
++ Item_func *item_func= (Item_func*)item;
++ for (uint i=0; i<item_func->argument_count(); i++)
++ {
++ if (!uses_only_table_name_fields(item_func->arguments()[i], table))
++ return 0;
++ }
++ }
++ else if (item->type() == Item::FIELD_ITEM)
++ {
++ Item_field *item_field= (Item_field*)item;
++ CHARSET_INFO *cs= system_charset_info;
++ ST_SCHEMA_TABLE *schema_table= table->schema_table;
++ ST_FIELD_INFO *field_info= schema_table->fields_info;
++ const char *field_name1= schema_table->idx_field1 >= 0 ?
++ field_info[schema_table->idx_field1].field_name : "";
++ const char *field_name2= schema_table->idx_field2 >= 0 ?
++ field_info[schema_table->idx_field2].field_name : "";
++ if (table->table != item_field->field->table ||
++ (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
++ (uchar *) item_field->field_name,
++ strlen(item_field->field_name), 0) &&
++ cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
++ (uchar *) item_field->field_name,
++ strlen(item_field->field_name), 0)))
++ return 0;
++ }
++ else if (item->type() == Item::REF_ITEM)
++ return uses_only_table_name_fields(item->real_item(), table);
++
++ if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
++ return 0;
++
++ return 1;
++}
++
++
++static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
++{
++ if (!cond)
++ return (COND*) 0;
++ if (cond->type() == Item::COND_ITEM)
++ {
++ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
++ {
++ /* Create new top level AND item */
++ Item_cond_and *new_cond=new Item_cond_and;
++ if (!new_cond)
++ return (COND*) 0;
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ {
++ Item *fix= make_cond_for_info_schema(item, table);
++ if (fix)
++ new_cond->argument_list()->push_back(fix);
++ }
++ switch (new_cond->argument_list()->elements) {
++ case 0:
++ return (COND*) 0;
++ case 1:
++ return new_cond->argument_list()->head();
++ default:
++ new_cond->quick_fix_field();
++ return new_cond;
++ }
++ }
++ else
++ { // Or list
++ Item_cond_or *new_cond=new Item_cond_or;
++ if (!new_cond)
++ return (COND*) 0;
++ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
++ Item *item;
++ while ((item=li++))
++ {
++ Item *fix=make_cond_for_info_schema(item, table);
++ if (!fix)
++ return (COND*) 0;
++ new_cond->argument_list()->push_back(fix);
++ }
++ new_cond->quick_fix_field();
++ new_cond->top_level_item();
++ return new_cond;
++ }
++ }
++
++ if (!uses_only_table_name_fields(cond, table))
++ return (COND*) 0;
++ return cond;
++}
++
++
++/**
++ @brief Calculate lookup values(database name, table name)
++
++ @details This function calculates lookup values(database name, table name)
++ from 'WHERE' condition or wild values (for 'SHOW' commands only)
++ from LEX struct and fill lookup_field_vals struct field
++ with these values.
++
++ @param[in] thd thread handler
++ @param[in] cond WHERE condition
++ @param[in] tables I_S table
++ @param[in, out] lookup_field_values Struct which holds lookup values
++
++ @return
++ 0 success
++ 1 error, there can be no matching records for the condition
++*/
++
++bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
++ LOOKUP_FIELD_VALUES *lookup_field_values)
++{
++ LEX *lex= thd->lex;
++ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
++ bool rc= 0;
++
++ bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
++ switch (lex->sql_command) {
++ case SQLCOM_SHOW_DATABASES:
++ if (wild)
++ {
++ thd->make_lex_string(&lookup_field_values->db_value,
++ wild, strlen(wild), 0);
++ lookup_field_values->wild_db_value= 1;
++ }
++ break;
++ case SQLCOM_SHOW_TABLES:
++ case SQLCOM_SHOW_TABLE_STATUS:
++ case SQLCOM_SHOW_TRIGGERS:
++ case SQLCOM_SHOW_EVENTS:
++ thd->make_lex_string(&lookup_field_values->db_value,
++ lex->select_lex.db, strlen(lex->select_lex.db), 0);
++ if (wild)
++ {
++ thd->make_lex_string(&lookup_field_values->table_value,
++ wild, strlen(wild), 0);
++ lookup_field_values->wild_table_value= 1;
++ }
++ break;
++ default:
++ /*
++ The "default" is for queries over I_S.
++ All previous cases handle SHOW commands.
++ */
++ rc= calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
++ break;
++ }
++
++ if (lower_case_table_names && !rc)
++ {
++ /*
++ We can safely do in-place upgrades here since all of the above cases
++ are allocating a new memory buffer for these strings.
++ */
++ if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0])
++ my_casedn_str(system_charset_info, lookup_field_values->db_value.str);
++ if (lookup_field_values->table_value.str &&
++ lookup_field_values->table_value.str[0])
++ my_casedn_str(system_charset_info, lookup_field_values->table_value.str);
++ }
++
++ return rc;
++}
++
++
++enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
++{
++ return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
++}
++
++
++/*
++ Create db names list. Information schema name always is first in list
++
++ SYNOPSIS
++ make_db_list()
++ thd thread handler
++ files list of db names
++ wild wild string
++ idx_field_vals idx_field_vals->db_name contains db name or
++ wild string
++ with_i_schema returns 1 if we added 'IS' name to list
++ otherwise returns 0
++
++ RETURN
++ zero success
++ non-zero error
++*/
++
++int make_db_list(THD *thd, List<LEX_STRING> *files,
++ LOOKUP_FIELD_VALUES *lookup_field_vals,
++ bool *with_i_schema)
++{
++ LEX_STRING *i_s_name_copy= 0;
++ i_s_name_copy= thd->make_lex_string(i_s_name_copy,
++ INFORMATION_SCHEMA_NAME.str,
++ INFORMATION_SCHEMA_NAME.length, TRUE);
++ *with_i_schema= 0;
++ if (lookup_field_vals->wild_db_value)
++ {
++ /*
++ This part of code is only for SHOW DATABASES command.
++ idx_field_vals->db_value can be 0 when we don't use
++ LIKE clause (see also get_index_field_values() function)
++ */
++ if (!lookup_field_vals->db_value.str ||
++ !wild_case_compare(system_charset_info,
++ INFORMATION_SCHEMA_NAME.str,
++ lookup_field_vals->db_value.str))
++ {
++ *with_i_schema= 1;
++ if (files->push_back(i_s_name_copy))
++ return 1;
++ }
++ return (find_files(thd, files, NullS, mysql_data_home,
++ lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
++ }
++
++
++ /*
++ If we have db lookup vaule we just add it to list and
++ exit from the function
++ */
++ if (lookup_field_vals->db_value.str)
++ {
++ if (is_schema_db(lookup_field_vals->db_value.str,
++ lookup_field_vals->db_value.length))
++ {
++ *with_i_schema= 1;
++ if (files->push_back(i_s_name_copy))
++ return 1;
++ return 0;
++ }
++ if (files->push_back(&lookup_field_vals->db_value))
++ return 1;
++ return 0;
++ }
++
++ /*
++ Create list of existing databases. It is used in case
++ of select from information schema table
++ */
++ if (files->push_back(i_s_name_copy))
++ return 1;
++ *with_i_schema= 1;
++ return (find_files(thd, files, NullS,
++ mysql_data_home, NullS, 1) != FIND_FILES_OK);
++}
++
++
++struct st_add_schema_table
++{
++ List<LEX_STRING> *files;
++ const char *wild;
++};
++
++
++static my_bool add_schema_table(THD *thd, plugin_ref plugin,
++ void* p_data)
++{
++ LEX_STRING *file_name= 0;
++ st_add_schema_table *data= (st_add_schema_table *)p_data;
++ List<LEX_STRING> *file_list= data->files;
++ const char *wild= data->wild;
++ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
++ DBUG_ENTER("add_schema_table");
++
++ if (schema_table->hidden)
++ DBUG_RETURN(0);
++ if (wild)
++ {
++ if (lower_case_table_names)
++ {
++ if (wild_case_compare(files_charset_info,
++ schema_table->table_name,
++ wild))
++ DBUG_RETURN(0);
++ }
++ else if (wild_compare(schema_table->table_name, wild, 0))
++ DBUG_RETURN(0);
++ }
++
++ if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
++ strlen(schema_table->table_name),
++ TRUE)) &&
++ !file_list->push_back(file_name))
++ DBUG_RETURN(0);
++ DBUG_RETURN(1);
++}
++
++
++int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
++{
++ LEX_STRING *file_name= 0;
++ ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
++ st_add_schema_table add_data;
++ DBUG_ENTER("schema_tables_add");
++
++ for (; tmp_schema_table->table_name; tmp_schema_table++)
++ {
++ if (tmp_schema_table->hidden)
++ continue;
++ if (wild)
++ {
++ if (lower_case_table_names)
++ {
++ if (wild_case_compare(files_charset_info,
++ tmp_schema_table->table_name,
++ wild))
++ continue;
++ }
++ else if (wild_compare(tmp_schema_table->table_name, wild, 0))
++ continue;
++ }
++ if ((file_name=
++ thd->make_lex_string(file_name, tmp_schema_table->table_name,
++ strlen(tmp_schema_table->table_name), TRUE)) &&
++ !files->push_back(file_name))
++ continue;
++ DBUG_RETURN(1);
++ }
++
++ add_data.files= files;
++ add_data.wild= wild;
++ if (plugin_foreach(thd, add_schema_table,
++ MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
++ DBUG_RETURN(1);
++
++ DBUG_RETURN(0);
++}
++
++
++/**
++ @brief Create table names list
++
++ @details The function creates the list of table names in
++ database
++
++ @param[in] thd thread handler
++ @param[in] table_names List of table names in database
++ @param[in] lex pointer to LEX struct
++ @param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
++ @param[in] with_i_schema TRUE means that we add I_S tables to list
++ @param[in] db_name database name
++
++ @return Operation status
++ @retval 0 ok
++ @retval 1 fatal error
++ @retval 2 Not fatal error; Safe to ignore this file list
++*/
++
++static int
++make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
++ LOOKUP_FIELD_VALUES *lookup_field_vals,
++ bool with_i_schema, LEX_STRING *db_name)
++{
++ char path[FN_REFLEN + 1];
++ build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0);
++ if (!lookup_field_vals->wild_table_value &&
++ lookup_field_vals->table_value.str)
++ {
++ if (with_i_schema)
++ {
++ LEX_STRING *name;
++ ST_SCHEMA_TABLE *schema_table=
++ find_schema_table(thd, lookup_field_vals->table_value.str);
++ if (schema_table && !schema_table->hidden)
++ {
++ if (!(name=
++ thd->make_lex_string(NULL, schema_table->table_name,
++ strlen(schema_table->table_name), TRUE)) ||
++ table_names->push_back(name))
++ return 1;
++ }
++ }
++ else
++ {
++ if (table_names->push_back(&lookup_field_vals->table_value))
++ return 1;
++ /*
++ Check that table is relevant in current transaction.
++ (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc)
++ */
++ VOID(ha_find_files(thd, db_name->str, path,
++ lookup_field_vals->table_value.str, 0,
++ table_names));
++ }
++ return 0;
++ }
++
++ /*
++ This call will add all matching the wildcards (if specified) IS tables
++ to the list
++ */
++ if (with_i_schema)
++ return (schema_tables_add(thd, table_names,
++ lookup_field_vals->table_value.str));
++
++ find_files_result res= find_files(thd, table_names, db_name->str, path,
++ lookup_field_vals->table_value.str, 0);
++ if (res != FIND_FILES_OK)
++ {
++ /*
++ Downgrade errors about problems with database directory to
++ warnings if this is not a 'SHOW' command. Another thread
++ may have dropped database, and we may still have a name
++ for that directory.
++ */
++ if (res == FIND_FILES_DIR)
++ {
++ if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
++ return 1;
++ thd->clear_error();
++ return 2;
++ }
++ return 1;
++ }
++ return 0;
++}
++
++
++/**
++ @brief Fill I_S table for SHOW COLUMNS|INDEX commands
++
++ @param[in] thd thread handler
++ @param[in] tables TABLE_LIST for I_S table
++ @param[in] schema_table pointer to I_S structure
++ @param[in] open_tables_state_backup pointer to Open_tables_state object
++ which is used to save|restore original
++ status of variables related to
++ open tables state
++
++ @return Operation status
++ @retval 0 success
++ @retval 1 error
++*/
++
++static int
++fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
++ ST_SCHEMA_TABLE *schema_table,
++ Open_tables_state *open_tables_state_backup)
++{
++ LEX *lex= thd->lex;
++ bool res;
++ LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
++ enum_sql_command save_sql_command= lex->sql_command;
++ TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first;
++ TABLE *table= tables->table;
++ int error= 1;
++ DBUG_ENTER("fill_schema_show");
++
++ lex->all_selects_list= tables->schema_select_lex;
++ /*
++ Restore thd->temporary_tables to be able to process
++ temporary tables(only for 'show index' & 'show columns').
++ This should be changed when processing of temporary tables for
++ I_S tables will be done.
++ */
++ thd->temporary_tables= open_tables_state_backup->temporary_tables;
++ /*
++ Let us set fake sql_command so views won't try to merge
++ themselves into main statement. If we don't do this,
++ SELECT * from information_schema.xxxx will cause problems.
++ SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
++ */
++ lex->sql_command= SQLCOM_SHOW_FIELDS;
++ res= open_normal_and_derived_tables(thd, show_table_list,
++ MYSQL_LOCK_IGNORE_FLUSH);
++ lex->sql_command= save_sql_command;
++ /*
++ get_all_tables() returns 1 on failure and 0 on success thus
++ return only these and not the result code of ::process_table()
++
++ We should use show_table_list->alias instead of
++ show_table_list->table_name because table_name
++ could be changed during opening of I_S tables. It's safe
++ to use alias because alias contains original table name
++ in this case(this part of code is used only for
++ 'show columns' & 'show statistics' commands).
++ */
++ table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
++ strlen(show_table_list->alias), FALSE);
++ if (!show_table_list->view)
++ db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
++ show_table_list->db_length, FALSE);
++ else
++ db_name= &show_table_list->view_db;
++
++
++ error= test(schema_table->process_table(thd, show_table_list,
++ table, res, db_name,
++ table_name));
++ thd->temporary_tables= 0;
++ close_tables_for_reopen(thd, &show_table_list);
++ DBUG_RETURN(error);
++}
++
++
++/**
++ @brief Fill I_S table for SHOW TABLE NAMES commands
++
++ @param[in] thd thread handler
++ @param[in] table TABLE struct for I_S table
++ @param[in] db_name database name
++ @param[in] table_name table name
++ @param[in] with_i_schema I_S table if TRUE
++
++ @return Operation status
++ @retval 0 success
++ @retval 1 error
++*/
++
++static int fill_schema_table_names(THD *thd, TABLE *table,
++ LEX_STRING *db_name, LEX_STRING *table_name,
++ bool with_i_schema)
++{
++ if (with_i_schema)
++ {
++ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
++ system_charset_info);
++ }
++ else
++ {
++ enum legacy_db_type not_used;
++ char path[FN_REFLEN + 1];
++ (void) build_table_filename(path, sizeof(path) - 1, db_name->str,
++ table_name->str, reg_ext, 0);
++ switch (mysql_frm_type(thd, path, ¬_used)) {
++ case FRMTYPE_ERROR:
++ table->field[3]->store(STRING_WITH_LEN("ERROR"),
++ system_charset_info);
++ break;
++ case FRMTYPE_TABLE:
++ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
++ system_charset_info);
++ break;
++ case FRMTYPE_VIEW:
++ table->field[3]->store(STRING_WITH_LEN("VIEW"),
++ system_charset_info);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
++ {
++ thd->clear_error();
++ return 0;
++ }
++ }
++ if (schema_table_store_record(thd, table))
++ return 1;
++ return 0;
++}
++
++
++/**
++ @brief Get open table method
++
++ @details The function calculates the method which will be used
++ for table opening:
++ SKIP_OPEN_TABLE - do not open table
++ OPEN_FRM_ONLY - open FRM file only
++ OPEN_FULL_TABLE - open FRM, data, index files
++ @param[in] tables I_S table table_list
++ @param[in] schema_table I_S table struct
++ @param[in] schema_table_idx I_S table index
++
++ @return return a set of flags
++ @retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
++*/
++
++uint get_table_open_method(TABLE_LIST *tables,
++ ST_SCHEMA_TABLE *schema_table,
++ enum enum_schema_tables schema_table_idx)
++{
++ /*
++ determine which method will be used for table opening
++ */
++ if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
++ {
++ Field **ptr, *field;
++ int table_open_method= 0, field_indx= 0;
++ uint star_table_open_method= OPEN_FULL_TABLE;
++ bool used_star= true; // true if '*' is used in select
++ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
++ {
++ star_table_open_method=
++ min(star_table_open_method,
++ schema_table->fields_info[field_indx].open_method);
++ if (bitmap_is_set(tables->table->read_set, field->field_index))
++ {
++ used_star= false;
++ table_open_method|= schema_table->fields_info[field_indx].open_method;
++ }
++ field_indx++;
++ }
++ if (used_star)
++ return star_table_open_method;
++ return table_open_method;
++ }
++ /* I_S tables which use get_all_tables but can not be optimized */
++ return (uint) OPEN_FULL_TABLE;
++}
++
++
++/**
++ @brief Fill I_S table with data from FRM file only
++
++ @param[in] thd thread handler
++ @param[in] table TABLE struct for I_S table
++ @param[in] schema_table I_S table struct
++ @param[in] db_name database name
++ @param[in] table_name table name
++ @param[in] schema_table_idx I_S table index
++
++ @return Operation status
++ @retval 0 Table is processed and we can continue
++ with new table
++ @retval 1 It's view and we have to use
++ open_tables function for this table
++*/
++
++static int fill_schema_table_from_frm(THD *thd,TABLE *table,
++ ST_SCHEMA_TABLE *schema_table,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name,
++ enum enum_schema_tables schema_table_idx)
++{
++ TABLE_SHARE *share;
++ TABLE tbl;
++ TABLE_LIST table_list;
++ uint res= 0;
++ int error;
++ char key[MAX_DBKEY_LENGTH];
++ uint key_length;
++
++ bzero((char*) &table_list, sizeof(TABLE_LIST));
++ bzero((char*) &tbl, sizeof(TABLE));
++
++ table_list.table_name= table_name->str;
++ table_list.db= db_name->str;
++ key_length= create_table_def_key(thd, key, &table_list, 0);
++ pthread_mutex_lock(&LOCK_open);
++ share= get_table_share(thd, &table_list, key,
++ key_length, OPEN_VIEW, &error);
++ if (!share)
++ {
++ res= 0;
++ goto err;
++ }
++
++ if (share->is_view)
++ {
++ if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY)
++ {
++ /* skip view processing */
++ res= 0;
++ goto err1;
++ }
++ else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL)
++ {
++ /*
++ tell get_all_tables() to fall back to
++ open_normal_and_derived_tables()
++ */
++ res= 1;
++ goto err1;
++ }
++ }
++
++ if (share->is_view ||
++ !open_table_from_share(thd, share, table_name->str, 0,
++ (READ_KEYINFO | COMPUTE_TYPES |
++ EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
++ thd->open_options, &tbl, FALSE))
++ {
++ tbl.s= share;
++ table_list.table= &tbl;
++ table_list.view= (st_lex*) share->is_view;
++ res= schema_table->process_table(thd, &table_list, table,
++ res, db_name, table_name);
++ closefrm(&tbl, true);
++ goto err;
++ }
++
++err1:
++ release_table_share(share, RELEASE_NORMAL);
++
++err:
++ pthread_mutex_unlock(&LOCK_open);
++ thd->clear_error();
++ return res;
++}
++
++
++
++/**
++ @brief Fill I_S tables whose data are retrieved
++ from frm files and storage engine
++
++ @details The information schema tables are internally represented as
++ temporary tables that are filled at query execution time.
++ Those I_S tables whose data are retrieved
++ from frm files and storage engine are filled by the function
++ get_all_tables().
++
++ @param[in] thd thread handler
++ @param[in] tables I_S table
++ @param[in] cond 'WHERE' condition
++
++ @return Operation status
++ @retval 0 success
++ @retval 1 error
++*/
++
++int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ LEX *lex= thd->lex;
++ TABLE *table= tables->table;
++ SELECT_LEX *old_all_select_lex= lex->all_selects_list;
++ enum_sql_command save_sql_command= lex->sql_command;
++ SELECT_LEX *lsel= tables->schema_select_lex;
++ ST_SCHEMA_TABLE *schema_table= tables->schema_table;
++ SELECT_LEX sel;
++ LOOKUP_FIELD_VALUES lookup_field_vals;
++ LEX_STRING *db_name, *table_name;
++ bool with_i_schema;
++ enum enum_schema_tables schema_table_idx;
++ List<LEX_STRING> db_names;
++ List_iterator_fast<LEX_STRING> it(db_names);
++ COND *partial_cond= 0;
++ uint derived_tables= lex->derived_tables;
++ int error= 1;
++ Open_tables_state open_tables_state_backup;
++ uint8 save_context_analysis_only= lex->context_analysis_only;
++ Query_tables_list query_tables_list_backup;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ Security_context *sctx= thd->security_ctx;
++#endif
++ uint table_open_method;
++ DBUG_ENTER("get_all_tables");
++
++ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
++ lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
++
++ /*
++ We should not introduce deadlocks even if we already have some
++ tables open and locked, since we won't lock tables which we will
++ open and will ignore possible name-locks for these tables.
++ */
++ thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
++
++ /*
++ this branch processes SHOW FIELDS, SHOW INDEXES commands.
++ see sql_parse.cc, prepare_schema_table() function where
++ this values are initialized
++ */
++ if (lsel && lsel->table_list.first)
++ {
++ error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
++ &open_tables_state_backup);
++ goto err;
++ }
++
++ schema_table_idx= get_schema_table_idx(schema_table);
++ if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
++ {
++ error= 0;
++ goto err;
++ }
++
++ DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
++ STR_OR_NIL(lookup_field_vals.db_value.str),
++ STR_OR_NIL(lookup_field_vals.table_value.str)));
++
++ if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
++ {
++ /*
++ if lookup value is empty string then
++ it's impossible table name or db name
++ */
++ if ((lookup_field_vals.db_value.str &&
++ !lookup_field_vals.db_value.str[0]) ||
++ (lookup_field_vals.table_value.str &&
++ !lookup_field_vals.table_value.str[0]))
++ {
++ error= 0;
++ goto err;
++ }
++ }
++
++ if (lookup_field_vals.db_value.length &&
++ !lookup_field_vals.wild_db_value)
++ tables->has_db_lookup_value= TRUE;
++ if (lookup_field_vals.table_value.length &&
++ !lookup_field_vals.wild_table_value)
++ tables->has_table_lookup_value= TRUE;
++
++ if (tables->has_db_lookup_value && tables->has_table_lookup_value)
++ partial_cond= 0;
++ else
++ partial_cond= make_cond_for_info_schema(cond, tables);
++
++ tables->table_open_method= table_open_method=
++ get_table_open_method(tables, schema_table, schema_table_idx);
++
++ if (lex->describe)
++ {
++ /* EXPLAIN SELECT */
++ error= 0;
++ goto err;
++ }
++
++ if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
++ goto err;
++ it.rewind(); /* To get access to new elements in basis list */
++ while ((db_name= it++))
++ {
++ LEX_STRING orig_db_name;
++
++ /* db_name can be changed in make_table_list() func */
++ if (!thd->make_lex_string(&orig_db_name, db_name->str,
++ db_name->length, FALSE))
++ goto err;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (!(check_access(thd,SELECT_ACL, db_name->str,
++ &thd->col_access, 0, 1, with_i_schema) ||
++ (!thd->col_access && check_grant_db(thd, db_name->str))) ||
++ sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
++ acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
++#endif
++ {
++ thd->no_warnings_for_error= 1;
++ List<LEX_STRING> table_names;
++ int res= make_table_name_list(thd, &table_names, lex,
++ &lookup_field_vals,
++ with_i_schema, db_name);
++ if (res == 2) /* Not fatal error, continue */
++ continue;
++ if (res)
++ goto err;
++
++ List_iterator_fast<LEX_STRING> it_files(table_names);
++ while ((table_name= it_files++))
++ {
++ restore_record(table, s->default_values);
++ table->field[schema_table->idx_field1]->
++ store(db_name->str, db_name->length, system_charset_info);
++ table->field[schema_table->idx_field2]->
++ store(table_name->str, table_name->length, system_charset_info);
++
++ if (!partial_cond || partial_cond->val_int())
++ {
++ /*
++ If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
++ we can skip table opening and we don't have lookup value for
++ table name or lookup value is wild string(table name list is
++ already created by make_table_name_list() function).
++ */
++ if (!table_open_method && schema_table_idx == SCH_TABLES &&
++ (!lookup_field_vals.table_value.length ||
++ lookup_field_vals.wild_table_value))
++ {
++ if (schema_table_store_record(thd, table))
++ goto err; /* Out of space in temporary table */
++ continue;
++ }
++
++ /* SHOW TABLE NAMES command */
++ if (schema_table_idx == SCH_TABLE_NAMES)
++ {
++ if (fill_schema_table_names(thd, tables->table, db_name,
++ table_name, with_i_schema))
++ continue;
++ }
++ else
++ {
++ if (!(table_open_method & ~OPEN_FRM_ONLY) &&
++ !with_i_schema)
++ {
++ if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
++ table_name, schema_table_idx))
++ continue;
++ }
++
++ int res;
++ LEX_STRING tmp_lex_string;
++ /*
++ Set the parent lex of 'sel' because it is needed by
++ sel.init_query() which is called inside make_table_list.
++ */
++ thd->no_warnings_for_error= 1;
++ sel.parent_lex= lex;
++ if (make_table_list(thd, &sel, db_name, table_name))
++ goto err;
++ TABLE_LIST *show_table_list= sel.table_list.first;
++ lex->all_selects_list= &sel;
++ lex->derived_tables= 0;
++ lex->sql_command= SQLCOM_SHOW_FIELDS;
++ show_table_list->i_s_requested_object=
++ schema_table->i_s_requested_object;
++ DEBUG_SYNC(thd, "before_open_in_get_all_tables");
++ res= open_normal_and_derived_tables(thd, show_table_list,
++ MYSQL_LOCK_IGNORE_FLUSH);
++ lex->sql_command= save_sql_command;
++ /*
++ XXX: show_table_list has a flag i_is_requested,
++ and when it's set, open_normal_and_derived_tables()
++ can return an error without setting an error message
++ in THD, which is a hack. This is why we have to
++ check for res, then for thd->is_error() only then
++ for thd->main_da.sql_errno().
++ */
++ if (res && thd->is_error() &&
++ thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
++ {
++ /*
++ Hide error for not existing table.
++ This error can occur for example when we use
++ where condition with db name and table name and this
++ table does not exist.
++ */
++ res= 0;
++ thd->clear_error();
++ }
++ else
++ {
++ /*
++ We should use show_table_list->alias instead of
++ show_table_list->table_name because table_name
++ could be changed during opening of I_S tables. It's safe
++ to use alias because alias contains original table name
++ in this case.
++ */
++ thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
++ strlen(show_table_list->alias), FALSE);
++ res= schema_table->process_table(thd, show_table_list, table,
++ res, &orig_db_name,
++ &tmp_lex_string);
++ close_tables_for_reopen(thd, &show_table_list);
++ }
++ DBUG_ASSERT(!lex->query_tables_own_last);
++ if (res)
++ goto err;
++ }
++ }
++ }
++ /*
++ If we have information schema its always the first table and only
++ the first table. Reset for other tables.
++ */
++ with_i_schema= 0;
++ }
++ }
++
++ error= 0;
++err:
++ thd->restore_backup_open_tables_state(&open_tables_state_backup);
++ lex->restore_backup_query_tables_list(&query_tables_list_backup);
++ lex->derived_tables= derived_tables;
++ lex->all_selects_list= old_all_select_lex;
++ lex->context_analysis_only= save_context_analysis_only;
++ lex->sql_command= save_sql_command;
++ DBUG_RETURN(error);
++}
++
++
++bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
++ CHARSET_INFO *cs)
++{
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, system_charset_info);
++ table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
++ table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
++ return schema_table_store_record(thd, table);
++}
++
++
++int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ /*
++ TODO: fill_schema_shemata() is called when new client is connected.
++ Returning error status in this case leads to client hangup.
++ */
++
++ LOOKUP_FIELD_VALUES lookup_field_vals;
++ List<LEX_STRING> db_names;
++ LEX_STRING *db_name;
++ bool with_i_schema;
++ HA_CREATE_INFO create;
++ TABLE *table= tables->table;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ Security_context *sctx= thd->security_ctx;
++#endif
++ DBUG_ENTER("fill_schema_shemata");
++
++ if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
++ DBUG_RETURN(0);
++ DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
++ lookup_field_vals.db_value.str,
++ lookup_field_vals.table_value.str));
++ if (make_db_list(thd, &db_names, &lookup_field_vals,
++ &with_i_schema))
++ DBUG_RETURN(1);
++
++ /*
++ If we have lookup db value we should check that the database exists
++ */
++ if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
++ !with_i_schema)
++ {
++ char path[FN_REFLEN+16];
++ uint path_len;
++ MY_STAT stat_info;
++ if (!lookup_field_vals.db_value.str[0])
++ DBUG_RETURN(0);
++ path_len= build_table_filename(path, sizeof(path) - 1,
++ lookup_field_vals.db_value.str, "", "", 0);
++ path[path_len-1]= 0;
++ if (!my_stat(path,&stat_info,MYF(0)))
++ DBUG_RETURN(0);
++ }
++
++ List_iterator_fast<LEX_STRING> it(db_names);
++ while ((db_name=it++))
++ {
++ if (with_i_schema) // information schema name is always first in list
++ {
++ if (store_schema_shemata(thd, table, db_name,
++ system_charset_info))
++ DBUG_RETURN(1);
++ with_i_schema= 0;
++ continue;
++ }
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
++ acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
++ !check_grant_db(thd, db_name->str))
++#endif
++ {
++ load_db_opt_by_name(thd, db_name->str, &create);
++ if (store_schema_shemata(thd, table, db_name,
++ create.default_table_charset))
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++
++static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ const char *tmp_buff;
++ MYSQL_TIME time;
++ int info_error= 0;
++ CHARSET_INFO *cs= system_charset_info;
++ DBUG_ENTER("get_schema_tables_record");
++
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(table_name->str, table_name->length, cs);
++
++ if (res)
++ {
++ /* There was a table open error, so set the table type and return */
++ if (tables->view)
++ table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
++ else if (tables->schema_table)
++ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
++ else
++ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
++
++ goto err;
++ }
++
++ if (tables->view)
++ {
++ table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
++ table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
++ }
++ else
++ {
++ char option_buff[350],*ptr;
++ TABLE *show_table= tables->table;
++ TABLE_SHARE *share= show_table->s;
++ handler *file= show_table->file;
++ handlerton *tmp_db_type= share->db_type();
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ bool is_partitioned= FALSE;
++#endif
++ if (share->tmp_table == SYSTEM_TMP_TABLE)
++ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
++ else if (share->tmp_table)
++ table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
++ else
++ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
++
++ for (int i= 4; i < 20; i++)
++ {
++ if (i == 7 || (i > 12 && i < 17) || i == 18)
++ continue;
++ table->field[i]->set_notnull();
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (share->db_type() == partition_hton &&
++ share->partition_info_len)
++ {
++ tmp_db_type= share->default_part_db_type;
++ is_partitioned= TRUE;
++ }
++#endif
++ tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
++ table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
++ table->field[5]->store((longlong) share->frm_version, TRUE);
++
++ ptr=option_buff;
++ if (share->min_rows)
++ {
++ ptr=strmov(ptr," min_rows=");
++ ptr=longlong10_to_str(share->min_rows,ptr,10);
++ }
++ if (share->max_rows)
++ {
++ ptr=strmov(ptr," max_rows=");
++ ptr=longlong10_to_str(share->max_rows,ptr,10);
++ }
++ if (share->avg_row_length)
++ {
++ ptr=strmov(ptr," avg_row_length=");
++ ptr=longlong10_to_str(share->avg_row_length,ptr,10);
++ }
++ if (share->db_create_options & HA_OPTION_PACK_KEYS)
++ ptr=strmov(ptr," pack_keys=1");
++ if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
++ ptr=strmov(ptr," pack_keys=0");
++ /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
++ if (share->db_create_options & HA_OPTION_CHECKSUM)
++ ptr=strmov(ptr," checksum=1");
++ if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
++ ptr=strmov(ptr," delay_key_write=1");
++ if (share->row_type != ROW_TYPE_DEFAULT)
++ ptr=strxmov(ptr, " row_format=",
++ ha_row_type[(uint) share->row_type],
++ NullS);
++ if (share->key_block_size)
++ {
++ ptr= strmov(ptr, " KEY_BLOCK_SIZE=");
++ ptr= longlong10_to_str(share->key_block_size, ptr, 10);
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (is_partitioned)
++ ptr= strmov(ptr, " partitioned");
++#endif
++ table->field[19]->store(option_buff+1,
++ (ptr == option_buff ? 0 :
++ (uint) (ptr-option_buff)-1), cs);
++
++ tmp_buff= (share->table_charset ?
++ share->table_charset->name : "default");
++ table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
++
++ if (share->comment.str)
++ table->field[20]->store(share->comment.str, share->comment.length, cs);
++
++ if (file)
++ {
++ /* If info() fails, then there's nothing else to do */
++ if ((info_error= file->info(HA_STATUS_VARIABLE |
++ HA_STATUS_TIME |
++ HA_STATUS_AUTO)) != 0)
++ goto err;
++
++ enum row_type row_type = file->get_row_type();
++ switch (row_type) {
++ case ROW_TYPE_NOT_USED:
++ case ROW_TYPE_DEFAULT:
++ tmp_buff= ((share->db_options_in_use &
++ HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
++ (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
++ "Dynamic" : "Fixed");
++ break;
++ case ROW_TYPE_FIXED:
++ tmp_buff= "Fixed";
++ break;
++ case ROW_TYPE_DYNAMIC:
++ tmp_buff= "Dynamic";
++ break;
++ case ROW_TYPE_COMPRESSED:
++ tmp_buff= "Compressed";
++ break;
++ case ROW_TYPE_REDUNDANT:
++ tmp_buff= "Redundant";
++ break;
++ case ROW_TYPE_COMPACT:
++ tmp_buff= "Compact";
++ break;
++ case ROW_TYPE_PAGE:
++ tmp_buff= "Paged";
++ break;
++ }
++ table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
++ if (!tables->schema_table)
++ {
++ table->field[7]->store((longlong) file->stats.records, TRUE);
++ table->field[7]->set_notnull();
++ }
++ table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
++ table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
++ if (file->stats.max_data_file_length)
++ {
++ table->field[10]->store((longlong) file->stats.max_data_file_length,
++ TRUE);
++ }
++ table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
++ table->field[12]->store((longlong) file->stats.delete_length, TRUE);
++ if (show_table->found_next_number_field)
++ {
++ table->field[13]->store((longlong) file->stats.auto_increment_value,
++ TRUE);
++ table->field[13]->set_notnull();
++ }
++ if (file->stats.create_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t) file->stats.create_time);
++ table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[14]->set_notnull();
++ }
++ if (file->stats.update_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t) file->stats.update_time);
++ table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[15]->set_notnull();
++ }
++ if (file->stats.check_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t) file->stats.check_time);
++ table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[16]->set_notnull();
++ }
++ if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
++ {
++ table->field[18]->store((longlong) file->checksum(), TRUE);
++ table->field[18]->set_notnull();
++ }
++ }
++ }
++
++err:
++ if (res || info_error)
++ {
++ /*
++ If an error was encountered, push a warning, set the TABLE COMMENT
++ column with the error text, and clear the error so that the operation
++ can continue.
++ */
++ const char *error= thd->is_error() ? thd->main_da.message() : "";
++ table->field[20]->store(error, strlen(error), cs);
++
++ if (thd->is_error())
++ {
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ }
++ }
++
++ DBUG_RETURN(schema_table_store_record(thd, table));
++}
++
++
++static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ LEX *lex= thd->lex;
++ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
++ CHARSET_INFO *cs= system_charset_info;
++ TABLE *show_table;
++ Field **ptr,*field;
++ int count;
++ DBUG_ENTER("get_schema_column_record");
++
++ if (res)
++ {
++ if (lex->sql_command != SQLCOM_SHOW_FIELDS)
++ {
++ /*
++ I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
++ rather than in SHOW COLUMNS
++ */
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ res= 0;
++ }
++ DBUG_RETURN(res);
++ }
++
++ show_table= tables->table;
++ count= 0;
++ restore_record(show_table, s->default_values);
++ show_table->use_all_columns(); // Required for default
++
++ for (ptr= show_table->field; (field= *ptr) ; ptr++)
++ {
++ const char *tmp_buff;
++ uchar *pos;
++ bool is_blob;
++ uint flags=field->flags;
++ char tmp[MAX_FIELD_WIDTH];
++ String type(tmp,sizeof(tmp), system_charset_info);
++ int decimals, field_length;
++
++ if (wild && wild[0] &&
++ wild_case_compare(system_charset_info, field->field_name,wild))
++ continue;
++
++ flags= field->flags;
++ count++;
++ /* Get default row, with all NULL fields set to NULL */
++ restore_record(table, s->default_values);
++
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ uint col_access;
++ check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
++ &tables->grant.privilege, 0, 0, test(tables->schema_table));
++ col_access= get_column_grant(thd, &tables->grant,
++ db_name->str, table_name->str,
++ field->field_name) & COL_ACLS;
++ if (!tables->schema_table && !col_access)
++ continue;
++ char *end= tmp;
++ for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
++ {
++ if (col_access & 1)
++ {
++ *end++=',';
++ end=strmov(end,grant_types.type_names[bitnr]);
++ }
++ }
++ table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
++
++#endif
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(table_name->str, table_name->length, cs);
++ table->field[3]->store(field->field_name, strlen(field->field_name),
++ cs);
++ table->field[4]->store((longlong) count, TRUE);
++ field->sql_type(type);
++ table->field[14]->store(type.ptr(), type.length(), cs);
++ /*
++ MySQL column type has the following format:
++ base_type [(dimension)] [unsigned] [zerofill].
++ For DATA_TYPE column we extract only base type.
++ */
++ tmp_buff= strchr(type.ptr(), '(');
++ if (!tmp_buff)
++ /*
++ if there is no dimention part then check the presence of
++ [unsigned] [zerofill] attributes and cut them of if exist.
++ */
++ tmp_buff= strchr(type.ptr(), ' ');
++ table->field[7]->store(type.ptr(),
++ (tmp_buff ? tmp_buff - type.ptr() :
++ type.length()), cs);
++
++ if (get_field_default_value(thd, show_table, field, &type, 0))
++ {
++ table->field[5]->store(type.ptr(), type.length(), cs);
++ table->field[5]->set_notnull();
++ }
++ pos=(uchar*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES");
++ table->field[6]->store((const char*) pos,
++ strlen((const char*) pos), cs);
++ is_blob= (field->type() == MYSQL_TYPE_BLOB);
++ if (field->has_charset() || is_blob ||
++ field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
++ field->real_type() == MYSQL_TYPE_STRING) // For binary type
++ {
++ uint32 octet_max_length= field->max_display_length();
++ if (is_blob && octet_max_length != (uint32) 4294967295U)
++ octet_max_length /= field->charset()->mbmaxlen;
++ longlong char_max_len= is_blob ?
++ (longlong) octet_max_length / field->charset()->mbminlen :
++ (longlong) octet_max_length / field->charset()->mbmaxlen;
++ table->field[8]->store(char_max_len, TRUE);
++ table->field[8]->set_notnull();
++ table->field[9]->store((longlong) octet_max_length, TRUE);
++ table->field[9]->set_notnull();
++ }
++
++ /*
++ Calculate field_length and decimals.
++ They are set to -1 if they should not be set (we should return NULL)
++ */
++
++ decimals= field->decimals();
++ switch (field->type()) {
++ case MYSQL_TYPE_NEWDECIMAL:
++ field_length= ((Field_new_decimal*) field)->precision;
++ break;
++ case MYSQL_TYPE_DECIMAL:
++ field_length= field->field_length - (decimals ? 2 : 1);
++ break;
++ case MYSQL_TYPE_TINY:
++ case MYSQL_TYPE_SHORT:
++ case MYSQL_TYPE_LONG:
++ case MYSQL_TYPE_INT24:
++ field_length= field->max_display_length() - 1;
++ break;
++ case MYSQL_TYPE_LONGLONG:
++ field_length= field->max_display_length() -
++ ((field->flags & UNSIGNED_FLAG) ? 0 : 1);
++ break;
++ case MYSQL_TYPE_BIT:
++ field_length= field->max_display_length();
++ decimals= -1; // return NULL
++ break;
++ case MYSQL_TYPE_FLOAT:
++ case MYSQL_TYPE_DOUBLE:
++ field_length= field->field_length;
++ if (decimals == NOT_FIXED_DEC)
++ decimals= -1; // return NULL
++ break;
++ default:
++ field_length= decimals= -1;
++ break;
++ }
++
++ if (field_length >= 0)
++ {
++ table->field[10]->store((longlong) field_length, TRUE);
++ table->field[10]->set_notnull();
++ }
++ if (decimals >= 0)
++ {
++ table->field[11]->store((longlong) decimals, TRUE);
++ table->field[11]->set_notnull();
++ }
++
++ if (field->has_charset())
++ {
++ pos=(uchar*) field->charset()->csname;
++ table->field[12]->store((const char*) pos,
++ strlen((const char*) pos), cs);
++ table->field[12]->set_notnull();
++ pos=(uchar*) field->charset()->name;
++ table->field[13]->store((const char*) pos,
++ strlen((const char*) pos), cs);
++ table->field[13]->set_notnull();
++ }
++ pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
++ (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
++ (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
++ table->field[15]->store((const char*) pos,
++ strlen((const char*) pos), cs);
++
++ if (field->unireg_check == Field::NEXT_NUMBER)
++ table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
++ if (show_table->timestamp_field == field &&
++ field->unireg_check != Field::TIMESTAMP_DN_FIELD)
++ table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
++ cs);
++
++ table->field[18]->store(field->comment.str, field->comment.length, cs);
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++}
++
++
++
++int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ CHARSET_INFO **cs;
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ TABLE *table= tables->table;
++ CHARSET_INFO *scs= system_charset_info;
++
++ for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
++ {
++ CHARSET_INFO *tmp_cs= cs[0];
++ if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
++ (tmp_cs->state & MY_CS_AVAILABLE) &&
++ !(tmp_cs->state & MY_CS_HIDDEN) &&
++ !(wild && wild[0] &&
++ wild_case_compare(scs, tmp_cs->csname,wild)))
++ {
++ const char *comment;
++ restore_record(table, s->default_values);
++ table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
++ table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
++ comment= tmp_cs->comment ? tmp_cs->comment : "";
++ table->field[2]->store(comment, strlen(comment), scs);
++ table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
++ if (schema_table_store_record(thd, table))
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
++ void *ptable)
++{
++ TABLE *table= (TABLE *) ptable;
++ handlerton *hton= plugin_data(plugin, handlerton *);
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ CHARSET_INFO *scs= system_charset_info;
++ handlerton *default_type= ha_default_handlerton(thd);
++ DBUG_ENTER("iter_schema_engines");
++
++
++ /* Disabled plugins */
++ if (plugin_state(plugin) != PLUGIN_IS_READY)
++ {
++
++ struct st_mysql_plugin *plug= plugin_decl(plugin);
++ if (!(wild && wild[0] &&
++ wild_case_compare(scs, plug->name,wild)))
++ {
++ restore_record(table, s->default_values);
++ table->field[0]->store(plug->name, strlen(plug->name), scs);
++ table->field[1]->store(C_STRING_WITH_LEN("NO"), scs);
++ table->field[2]->store(plug->descr, strlen(plug->descr), scs);
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++ }
++
++ if (!(hton->flags & HTON_HIDDEN))
++ {
++ LEX_STRING *name= plugin_name(plugin);
++ if (!(wild && wild[0] &&
++ wild_case_compare(scs, name->str,wild)))
++ {
++ LEX_STRING yesno[2]= {{ C_STRING_WITH_LEN("NO") },
++ { C_STRING_WITH_LEN("YES") }};
++ LEX_STRING *tmp;
++ const char *option_name= show_comp_option_name[(int) hton->state];
++ restore_record(table, s->default_values);
++
++ table->field[0]->store(name->str, name->length, scs);
++ if (hton->state == SHOW_OPTION_YES && default_type == hton)
++ option_name= "DEFAULT";
++ table->field[1]->store(option_name, strlen(option_name), scs);
++ table->field[2]->store(plugin_decl(plugin)->descr,
++ strlen(plugin_decl(plugin)->descr), scs);
++ tmp= &yesno[test(hton->commit)];
++ table->field[3]->store(tmp->str, tmp->length, scs);
++ table->field[3]->set_notnull();
++ tmp= &yesno[test(hton->prepare)];
++ table->field[4]->store(tmp->str, tmp->length, scs);
++ table->field[4]->set_notnull();
++ tmp= &yesno[test(hton->savepoint_set)];
++ table->field[5]->store(tmp->str, tmp->length, scs);
++ table->field[5]->set_notnull();
++
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_schema_engines");
++ if (plugin_foreach_with_mask(thd, iter_schema_engines,
++ MYSQL_STORAGE_ENGINE_PLUGIN,
++ ~PLUGIN_IS_FREED, tables->table))
++ DBUG_RETURN(1);
++ DBUG_RETURN(0);
++}
++
++
++int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ CHARSET_INFO **cs;
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ TABLE *table= tables->table;
++ CHARSET_INFO *scs= system_charset_info;
++ for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
++ {
++ CHARSET_INFO **cl;
++ CHARSET_INFO *tmp_cs= cs[0];
++ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
++ (tmp_cs->state & MY_CS_HIDDEN) ||
++ !(tmp_cs->state & MY_CS_PRIMARY))
++ continue;
++ for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
++ {
++ CHARSET_INFO *tmp_cl= cl[0];
++ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
++ !my_charset_same(tmp_cs, tmp_cl))
++ continue;
++ if (!(wild && wild[0] &&
++ wild_case_compare(scs, tmp_cl->name,wild)))
++ {
++ const char *tmp_buff;
++ restore_record(table, s->default_values);
++ table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
++ table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
++ table->field[2]->store((longlong) tmp_cl->number, TRUE);
++ tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
++ table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
++ tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
++ table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
++ table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
++ if (schema_table_store_record(thd, table))
++ return 1;
++ }
++ }
++ }
++ return 0;
++}
++
++
++int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ CHARSET_INFO **cs;
++ TABLE *table= tables->table;
++ CHARSET_INFO *scs= system_charset_info;
++ for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
++ {
++ CHARSET_INFO **cl;
++ CHARSET_INFO *tmp_cs= cs[0];
++ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
++ !(tmp_cs->state & MY_CS_PRIMARY))
++ continue;
++ for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
++ {
++ CHARSET_INFO *tmp_cl= cl[0];
++ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
++ !my_charset_same(tmp_cs,tmp_cl))
++ continue;
++ restore_record(table, s->default_values);
++ table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
++ table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
++ if (schema_table_store_record(thd, table))
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++static inline void copy_field_as_string(Field *to_field, Field *from_field)
++{
++ char buff[MAX_FIELD_WIDTH];
++ String tmp_str(buff, sizeof(buff), system_charset_info);
++ from_field->val_str(&tmp_str);
++ to_field->store(tmp_str.ptr(), tmp_str.length(), system_charset_info);
++}
++
++
++bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
++ const char *wild, bool full_access, const char *sp_user)
++{
++ MYSQL_TIME time;
++ LEX *lex= thd->lex;
++ CHARSET_INFO *cs= system_charset_info;
++ char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
++ definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2];
++ String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
++ String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
++ String definer(definer_buff, sizeof(definer_buff), cs);
++
++ proc_table->field[0]->val_str(&sp_db);
++ proc_table->field[1]->val_str(&sp_name);
++ proc_table->field[11]->val_str(&definer);
++
++ if (!full_access)
++ full_access= !strcmp(sp_user, definer.c_ptr_safe());
++ if (!full_access &&
++ check_some_routine_access(thd, sp_db.c_ptr_safe(), sp_name.c_ptr_safe(),
++ proc_table->field[2]->val_int() ==
++ TYPE_ENUM_PROCEDURE))
++ return 0;
++
++ if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
++ proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) ||
++ (lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
++ proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) ||
++ (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
++ {
++ restore_record(table, s->default_values);
++ if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0))
++ {
++ int enum_idx= (int) proc_table->field[5]->val_int();
++ table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
++ copy_field_as_string(table->field[0], proc_table->field[3]);
++ table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
++ copy_field_as_string(table->field[4], proc_table->field[2]);
++ if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
++ {
++ copy_field_as_string(table->field[5], proc_table->field[9]);
++ table->field[5]->set_notnull();
++ }
++ if (full_access)
++ {
++ copy_field_as_string(table->field[7], proc_table->field[19]);
++ table->field[7]->set_notnull();
++ }
++ table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
++ table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
++ copy_field_as_string(table->field[11], proc_table->field[6]);
++ table->field[12]->store(sp_data_access_name[enum_idx].str,
++ sp_data_access_name[enum_idx].length , cs);
++ copy_field_as_string(table->field[14], proc_table->field[7]);
++
++ bzero((char *)&time, sizeof(time));
++ ((Field_timestamp *) proc_table->field[12])->get_time(&time);
++ table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ bzero((char *)&time, sizeof(time));
++ ((Field_timestamp *) proc_table->field[13])->get_time(&time);
++ table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ copy_field_as_string(table->field[17], proc_table->field[14]);
++ copy_field_as_string(table->field[18], proc_table->field[15]);
++ table->field[19]->store(definer.ptr(), definer.length(), cs);
++ copy_field_as_string(table->field[20], proc_table->field[16]);
++ copy_field_as_string(table->field[21], proc_table->field[17]);
++ copy_field_as_string(table->field[22], proc_table->field[18]);
++
++ return schema_table_store_record(thd, table);
++ }
++ }
++ return 0;
++}
++
++
++int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ TABLE *proc_table;
++ TABLE_LIST proc_tables;
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ int res= 0;
++ TABLE *table= tables->table;
++ bool full_access;
++ char definer[USER_HOST_BUFF_SIZE];
++ Open_tables_state open_tables_state_backup;
++ DBUG_ENTER("fill_schema_proc");
++
++ strxmov(definer, thd->security_ctx->priv_user, "@",
++ thd->security_ctx->priv_host, NullS);
++ /* We use this TABLE_LIST instance only for checking of privileges. */
++ bzero((char*) &proc_tables,sizeof(proc_tables));
++ proc_tables.db= (char*) "mysql";
++ proc_tables.db_length= 5;
++ proc_tables.table_name= proc_tables.alias= (char*) "proc";
++ proc_tables.table_name_length= 4;
++ proc_tables.lock_type= TL_READ;
++ full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE);
++ if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
++ {
++ DBUG_RETURN(1);
++ }
++ proc_table->file->ha_index_init(0, 1);
++ if ((res= proc_table->file->index_first(proc_table->record[0])))
++ {
++ res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
++ goto err;
++ }
++ if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
++ {
++ res= 1;
++ goto err;
++ }
++ while (!proc_table->file->index_next(proc_table->record[0]))
++ {
++ if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
++ {
++ res= 1;
++ goto err;
++ }
++ }
++
++err:
++ proc_table->file->ha_index_end();
++ close_system_tables(thd, &open_tables_state_backup);
++ DBUG_RETURN(res);
++}
++
++
++static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ DBUG_ENTER("get_schema_stat_record");
++ if (res)
++ {
++ if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
++ {
++ /*
++ I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
++ rather than in SHOW KEYS
++ */
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ res= 0;
++ }
++ DBUG_RETURN(res);
++ }
++ else if (!tables->view)
++ {
++ TABLE *show_table= tables->table;
++ KEY *key_info=show_table->s->key_info;
++ if (show_table->file)
++ show_table->file->info(HA_STATUS_VARIABLE |
++ HA_STATUS_NO_LOCK |
++ HA_STATUS_TIME);
++ for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
++ {
++ KEY_PART_INFO *key_part= key_info->key_part;
++ const char *str;
++ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
++ {
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(table_name->str, table_name->length, cs);
++ table->field[3]->store((longlong) ((key_info->flags &
++ HA_NOSAME) ? 0 : 1), TRUE);
++ table->field[4]->store(db_name->str, db_name->length, cs);
++ table->field[5]->store(key_info->name, strlen(key_info->name), cs);
++ table->field[6]->store((longlong) (j+1), TRUE);
++ str=(key_part->field ? key_part->field->field_name :
++ "?unknown field?");
++ table->field[7]->store(str, strlen(str), cs);
++ if (show_table->file)
++ {
++ if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
++ {
++ table->field[8]->store(((key_part->key_part_flag &
++ HA_REVERSE_SORT) ?
++ "D" : "A"), 1, cs);
++ table->field[8]->set_notnull();
++ }
++ KEY *key=show_table->key_info+i;
++ if (key->rec_per_key[j])
++ {
++ ha_rows records=(show_table->file->stats.records /
++ key->rec_per_key[j]);
++ table->field[9]->store((longlong) records, TRUE);
++ table->field[9]->set_notnull();
++ }
++ str= show_table->file->index_type(i);
++ table->field[13]->store(str, strlen(str), cs);
++ }
++ if (!(key_info->flags & HA_FULLTEXT) &&
++ (key_part->field &&
++ key_part->length !=
++ show_table->s->field[key_part->fieldnr-1]->key_length()))
++ {
++ table->field[10]->store((longlong) key_part->length /
++ key_part->field->charset()->mbmaxlen, TRUE);
++ table->field[10]->set_notnull();
++ }
++ uint flags= key_part->field ? key_part->field->flags : 0;
++ const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
++ table->field[12]->store(pos, strlen(pos), cs);
++ if (!show_table->s->keys_in_use.is_set(i))
++ table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
++ else
++ table->field[14]->store("", 0, cs);
++ table->field[14]->set_notnull();
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ }
++ DBUG_RETURN(res);
++}
++
++
++static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ DBUG_ENTER("get_schema_views_record");
++ LEX_STRING *tmp_db_name, *tmp_table_name;
++ char definer[USER_HOST_BUFF_SIZE];
++ uint definer_len;
++ bool updatable_view;
++ /*
++ if SELECT FROM I_S.VIEWS uses only fields
++ which have OPEN_FRM_ONLY flag then 'tables'
++ structure is zeroed and only tables->view is set.
++ (see fill_schema_table_from_frm() function).
++ So we should disable other fields filling.
++ */
++ bool only_share= !tables->definer.user.str;
++
++ if (tables->view)
++ {
++ Security_context *sctx= thd->security_ctx;
++ if (!only_share && !tables->allowed_show)
++ {
++ if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
++ sctx->priv_user) &&
++ !my_strcasecmp(system_charset_info, tables->definer.host.str,
++ sctx->priv_host))
++ tables->allowed_show= TRUE;
++#ifndef NO_EMBEDDED_ACCESS_CHECKS
++ else
++ {
++ if ((thd->col_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
++ (SHOW_VIEW_ACL|SELECT_ACL))
++ tables->allowed_show= TRUE;
++ else
++ {
++ TABLE_LIST table_list;
++ uint view_access;
++ memset(&table_list, 0, sizeof(table_list));
++ table_list.db= tables->view_db.str;
++ table_list.table_name= tables->view_name.str;
++ table_list.grant.privilege= thd->col_access;
++ view_access= get_table_grant(thd, &table_list);
++ if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
++ (SHOW_VIEW_ACL|SELECT_ACL))
++ tables->allowed_show= TRUE;
++ }
++ }
++#endif
++ }
++ restore_record(table, s->default_values);
++ tmp_db_name= &tables->view_db;
++ tmp_table_name= &tables->view_name;
++ if (only_share)
++ {
++ tmp_db_name= db_name;
++ tmp_table_name= table_name;
++ }
++ table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs);
++ table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs);
++ if (!only_share)
++ {
++ if (tables->allowed_show)
++ {
++ table->field[3]->store(tables->view_body_utf8.str,
++ tables->view_body_utf8.length,
++ cs);
++ }
++
++ if (tables->with_check != VIEW_CHECK_NONE)
++ {
++ if (tables->with_check == VIEW_CHECK_LOCAL)
++ table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
++ else
++ table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
++ }
++ else
++ table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
++
++ updatable_view= 0;
++ if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
++ {
++ /*
++ We should use tables->view->select_lex.item_list here and
++ can not use Field_iterator_view because the view always uses
++ temporary algorithm during opening for I_S and
++ TABLE_LIST fields 'field_translation' & 'field_translation_end'
++ are uninitialized is this case.
++ */
++ List<Item> *fields= &tables->view->select_lex.item_list;
++ List_iterator<Item> it(*fields);
++ Item *item;
++ Item_field *field;
++ /*
++ check that at least one column in view is updatable
++ */
++ while ((item= it++))
++ {
++ if ((field= item->filed_for_view_update()) && field->field &&
++ !field->field->table->pos_in_table_list->schema_table)
++ {
++ updatable_view= 1;
++ break;
++ }
++ }
++ if (updatable_view && !tables->view->can_be_merged())
++ updatable_view= 0;
++ }
++ if (updatable_view)
++ table->field[5]->store(STRING_WITH_LEN("YES"), cs);
++ else
++ table->field[5]->store(STRING_WITH_LEN("NO"), cs);
++ definer_len= (strxmov(definer, tables->definer.user.str, "@",
++ tables->definer.host.str, NullS) - definer);
++ table->field[6]->store(definer, definer_len, cs);
++ if (tables->view_suid)
++ table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
++ else
++ table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
++
++ table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname,
++ strlen(tables->view_creation_ctx->
++ get_client_cs()->csname), cs);
++
++ table->field[9]->store(tables->view_creation_ctx->
++ get_connection_cl()->name,
++ strlen(tables->view_creation_ctx->
++ get_connection_cl()->name), cs);
++ }
++
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ if (res && thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ }
++ if (res)
++ thd->clear_error();
++ DBUG_RETURN(0);
++}
++
++
++bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
++ LEX_STRING *table_name, const char *key_name,
++ uint key_len, const char *con_type, uint con_len)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(key_name, key_len, cs);
++ table->field[3]->store(db_name->str, db_name->length, cs);
++ table->field[4]->store(table_name->str, table_name->length, cs);
++ table->field[5]->store(con_type, con_len, cs);
++ return schema_table_store_record(thd, table);
++}
++
++
++static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ DBUG_ENTER("get_schema_constraints_record");
++ if (res)
++ {
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ DBUG_RETURN(0);
++ }
++ else if (!tables->view)
++ {
++ List<FOREIGN_KEY_INFO> f_key_list;
++ TABLE *show_table= tables->table;
++ KEY *key_info=show_table->key_info;
++ uint primary_key= show_table->s->primary_key;
++
++ // This is not needed since no statistics are displayed.
++ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
++
++ for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
++ {
++ if (i != primary_key && !(key_info->flags & HA_NOSAME))
++ continue;
++
++ if (i == primary_key && !strcmp(key_info->name, primary_key_name))
++ {
++ if (store_constraints(thd, table, db_name, table_name, key_info->name,
++ strlen(key_info->name),
++ STRING_WITH_LEN("PRIMARY KEY")))
++ DBUG_RETURN(1);
++ }
++ else if (key_info->flags & HA_NOSAME)
++ {
++ if (store_constraints(thd, table, db_name, table_name, key_info->name,
++ strlen(key_info->name),
++ STRING_WITH_LEN("UNIQUE")))
++ DBUG_RETURN(1);
++ }
++ }
++
++ show_table->file->get_foreign_key_list(thd, &f_key_list);
++ FOREIGN_KEY_INFO *f_key_info;
++ List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
++ while ((f_key_info=it++))
++ {
++ if (store_constraints(thd, table, db_name, table_name,
++ f_key_info->forein_id->str,
++ strlen(f_key_info->forein_id->str),
++ "FOREIGN KEY", 11))
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(res);
++}
++
++
++static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
++ LEX_STRING *table_name, LEX_STRING *trigger_name,
++ enum trg_event_type event,
++ enum trg_action_time_type timing,
++ LEX_STRING *trigger_stmt,
++ ulong sql_mode,
++ LEX_STRING *definer_buffer,
++ LEX_STRING *client_cs_name,
++ LEX_STRING *connection_cl_name,
++ LEX_STRING *db_cl_name)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ LEX_STRING sql_mode_rep;
++
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(trigger_name->str, trigger_name->length, cs);
++ table->field[3]->store(trg_event_type_names[event].str,
++ trg_event_type_names[event].length, cs);
++ table->field[5]->store(db_name->str, db_name->length, cs);
++ table->field[6]->store(table_name->str, table_name->length, cs);
++ table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
++ table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
++ table->field[11]->store(trg_action_time_type_names[timing].str,
++ trg_action_time_type_names[timing].length, cs);
++ table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
++ table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
++
++ sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
++ &sql_mode_rep);
++ table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
++ table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
++ table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
++ table->field[20]->store(connection_cl_name->str,
++ connection_cl_name->length, cs);
++ table->field[21]->store(db_cl_name->str, db_cl_name->length, cs);
++
++ return schema_table_store_record(thd, table);
++}
++
++
++static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ DBUG_ENTER("get_schema_triggers_record");
++ /*
++ res can be non zero value when processed table is a view or
++ error happened during opening of processed table.
++ */
++ if (res)
++ {
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ DBUG_RETURN(0);
++ }
++ if (!tables->view && tables->table->triggers)
++ {
++ Table_triggers_list *triggers= tables->table->triggers;
++ int event, timing;
++
++ if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE))
++ goto ret;
++
++ for (event= 0; event < (int)TRG_EVENT_MAX; event++)
++ {
++ for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
++ {
++ LEX_STRING trigger_name;
++ LEX_STRING trigger_stmt;
++ ulong sql_mode;
++ char definer_holder[USER_HOST_BUFF_SIZE];
++ LEX_STRING definer_buffer;
++ LEX_STRING client_cs_name;
++ LEX_STRING connection_cl_name;
++ LEX_STRING db_cl_name;
++
++ definer_buffer.str= definer_holder;
++ if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
++ (enum trg_action_time_type)timing,
++ &trigger_name, &trigger_stmt,
++ &sql_mode,
++ &definer_buffer,
++ &client_cs_name,
++ &connection_cl_name,
++ &db_cl_name))
++ continue;
++
++ if (store_trigger(thd, table, db_name, table_name, &trigger_name,
++ (enum trg_event_type) event,
++ (enum trg_action_time_type) timing, &trigger_stmt,
++ sql_mode,
++ &definer_buffer,
++ &client_cs_name,
++ &connection_cl_name,
++ &db_cl_name))
++ DBUG_RETURN(1);
++ }
++ }
++ }
++ret:
++ DBUG_RETURN(0);
++}
++
++
++void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
++ LEX_STRING *table_name, const char *key_name,
++ uint key_len, const char *con_type, uint con_len,
++ longlong idx)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(key_name, key_len, cs);
++ table->field[4]->store(db_name->str, db_name->length, cs);
++ table->field[5]->store(table_name->str, table_name->length, cs);
++ table->field[6]->store(con_type, con_len, cs);
++ table->field[7]->store((longlong) idx, TRUE);
++}
++
++
++static int get_schema_key_column_usage_record(THD *thd,
++ TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ DBUG_ENTER("get_schema_key_column_usage_record");
++ if (res)
++ {
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ DBUG_RETURN(0);
++ }
++ else if (!tables->view)
++ {
++ List<FOREIGN_KEY_INFO> f_key_list;
++ TABLE *show_table= tables->table;
++ KEY *key_info=show_table->key_info;
++ uint primary_key= show_table->s->primary_key;
++
++ // This is not needed since no statistics are displayed.
++ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
++
++ for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
++ {
++ if (i != primary_key && !(key_info->flags & HA_NOSAME))
++ continue;
++ uint f_idx= 0;
++ KEY_PART_INFO *key_part= key_info->key_part;
++ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
++ {
++ if (key_part->field)
++ {
++ f_idx++;
++ restore_record(table, s->default_values);
++ store_key_column_usage(table, db_name, table_name,
++ key_info->name,
++ strlen(key_info->name),
++ key_part->field->field_name,
++ strlen(key_part->field->field_name),
++ (longlong) f_idx);
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ }
++
++ show_table->file->get_foreign_key_list(thd, &f_key_list);
++ FOREIGN_KEY_INFO *f_key_info;
++ List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
++ while ((f_key_info= fkey_it++))
++ {
++ LEX_STRING *f_info;
++ LEX_STRING *r_info;
++ List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
++ it1(f_key_info->referenced_fields);
++ uint f_idx= 0;
++ while ((f_info= it++))
++ {
++ r_info= it1++;
++ f_idx++;
++ restore_record(table, s->default_values);
++ store_key_column_usage(table, db_name, table_name,
++ f_key_info->forein_id->str,
++ f_key_info->forein_id->length,
++ f_info->str, f_info->length,
++ (longlong) f_idx);
++ table->field[8]->store((longlong) f_idx, TRUE);
++ table->field[8]->set_notnull();
++ table->field[9]->store(f_key_info->referenced_db->str,
++ f_key_info->referenced_db->length,
++ system_charset_info);
++ table->field[9]->set_notnull();
++ table->field[10]->store(f_key_info->referenced_table->str,
++ f_key_info->referenced_table->length,
++ system_charset_info);
++ table->field[10]->set_notnull();
++ table->field[11]->store(r_info->str, r_info->length,
++ system_charset_info);
++ table->field[11]->set_notnull();
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ }
++ DBUG_RETURN(res);
++}
++
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++static void collect_partition_expr(List<char> &field_list, String *str)
++{
++ List_iterator<char> part_it(field_list);
++ ulong no_fields= field_list.elements;
++ const char *field_str;
++ str->length(0);
++ while ((field_str= part_it++))
++ {
++ str->append(field_str);
++ if (--no_fields != 0)
++ str->append(",");
++ }
++ return;
++}
++#endif
++
++
++static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
++ TABLE *showing_table,
++ partition_element *part_elem,
++ handler *file, uint part_id)
++{
++ TABLE* table= schema_table;
++ CHARSET_INFO *cs= system_charset_info;
++ PARTITION_INFO stat_info;
++ MYSQL_TIME time;
++ file->get_dynamic_partition_info(&stat_info, part_id);
++ table->field[12]->store((longlong) stat_info.records, TRUE);
++ table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
++ table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
++ if (stat_info.max_data_file_length)
++ {
++ table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
++ table->field[15]->set_notnull();
++ }
++ table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
++ table->field[17]->store((longlong) stat_info.delete_length, TRUE);
++ if (stat_info.create_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t)stat_info.create_time);
++ table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[18]->set_notnull();
++ }
++ if (stat_info.update_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t)stat_info.update_time);
++ table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[19]->set_notnull();
++ }
++ if (stat_info.check_time)
++ {
++ thd->variables.time_zone->gmt_sec_to_TIME(&time,
++ (my_time_t)stat_info.check_time);
++ table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ table->field[20]->set_notnull();
++ }
++ if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
++ {
++ table->field[21]->store((longlong) stat_info.check_sum, TRUE);
++ table->field[21]->set_notnull();
++ }
++ if (part_elem)
++ {
++ if (part_elem->part_comment)
++ table->field[22]->store(part_elem->part_comment,
++ strlen(part_elem->part_comment), cs);
++ else
++ table->field[22]->store(STRING_WITH_LEN(""), cs);
++ if (part_elem->nodegroup_id != UNDEF_NODEGROUP)
++ table->field[23]->store((longlong) part_elem->nodegroup_id, TRUE);
++ else
++ table->field[23]->store(STRING_WITH_LEN("default"), cs);
++
++ table->field[24]->set_notnull();
++ if (part_elem->tablespace_name)
++ table->field[24]->store(part_elem->tablespace_name,
++ strlen(part_elem->tablespace_name), cs);
++ else
++ {
++ char *ts= showing_table->file->get_tablespace_name(thd,0,0);
++ if(ts)
++ {
++ table->field[24]->store(ts, strlen(ts), cs);
++ my_free(ts, MYF(0));
++ }
++ else
++ table->field[24]->set_null();
++ }
++ }
++ return;
++}
++
++
++static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name,
++ LEX_STRING *table_name)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ char buff[61];
++ String tmp_res(buff, sizeof(buff), cs);
++ String tmp_str;
++ TABLE *show_table= tables->table;
++ handler *file;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ partition_info *part_info;
++#endif
++ DBUG_ENTER("get_schema_partitions_record");
++
++ if (res)
++ {
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ DBUG_RETURN(0);
++ }
++ file= show_table->file;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ part_info= show_table->part_info;
++ if (part_info)
++ {
++ partition_element *part_elem;
++ List_iterator<partition_element> part_it(part_info->partitions);
++ uint part_pos= 0, part_id= 0;
++
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[2]->store(table_name->str, table_name->length, cs);
++
++
++ /* Partition method*/
++ switch (part_info->part_type) {
++ case RANGE_PARTITION:
++ table->field[7]->store(partition_keywords[PKW_RANGE].str,
++ partition_keywords[PKW_RANGE].length, cs);
++ break;
++ case LIST_PARTITION:
++ table->field[7]->store(partition_keywords[PKW_LIST].str,
++ partition_keywords[PKW_LIST].length, cs);
++ break;
++ case HASH_PARTITION:
++ tmp_res.length(0);
++ if (part_info->linear_hash_ind)
++ tmp_res.append(partition_keywords[PKW_LINEAR].str,
++ partition_keywords[PKW_LINEAR].length);
++ if (part_info->list_of_part_fields)
++ tmp_res.append(partition_keywords[PKW_KEY].str,
++ partition_keywords[PKW_KEY].length);
++ else
++ tmp_res.append(partition_keywords[PKW_HASH].str,
++ partition_keywords[PKW_HASH].length);
++ table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ my_error(ER_OUT_OF_RESOURCES, MYF(0));
++ current_thd->fatal_error();
++ DBUG_RETURN(1);
++ }
++ table->field[7]->set_notnull();
++
++ /* Partition expression */
++ if (part_info->part_expr)
++ {
++ table->field[9]->store(part_info->part_func_string,
++ part_info->part_func_len, cs);
++ }
++ else if (part_info->list_of_part_fields)
++ {
++ collect_partition_expr(part_info->part_field_list, &tmp_str);
++ table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs);
++ }
++ table->field[9]->set_notnull();
++
++ if (part_info->is_sub_partitioned())
++ {
++ /* Subpartition method */
++ tmp_res.length(0);
++ if (part_info->linear_hash_ind)
++ tmp_res.append(partition_keywords[PKW_LINEAR].str,
++ partition_keywords[PKW_LINEAR].length);
++ if (part_info->list_of_subpart_fields)
++ tmp_res.append(partition_keywords[PKW_KEY].str,
++ partition_keywords[PKW_KEY].length);
++ else
++ tmp_res.append(partition_keywords[PKW_HASH].str,
++ partition_keywords[PKW_HASH].length);
++ table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
++ table->field[8]->set_notnull();
++
++ /* Subpartition expression */
++ if (part_info->subpart_expr)
++ {
++ table->field[10]->store(part_info->subpart_func_string,
++ part_info->subpart_func_len, cs);
++ }
++ else if (part_info->list_of_subpart_fields)
++ {
++ collect_partition_expr(part_info->subpart_field_list, &tmp_str);
++ table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs);
++ }
++ table->field[10]->set_notnull();
++ }
++
++ while ((part_elem= part_it++))
++ {
++ table->field[3]->store(part_elem->partition_name,
++ strlen(part_elem->partition_name), cs);
++ table->field[3]->set_notnull();
++ /* PARTITION_ORDINAL_POSITION */
++ table->field[5]->store((longlong) ++part_pos, TRUE);
++ table->field[5]->set_notnull();
++
++ /* Partition description */
++ if (part_info->part_type == RANGE_PARTITION)
++ {
++ if (part_elem->range_value != LONGLONG_MAX)
++ table->field[11]->store((longlong) part_elem->range_value, FALSE);
++ else
++ table->field[11]->store(partition_keywords[PKW_MAXVALUE].str,
++ partition_keywords[PKW_MAXVALUE].length, cs);
++ table->field[11]->set_notnull();
++ }
++ else if (part_info->part_type == LIST_PARTITION)
++ {
++ List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
++ part_elem_value *list_value;
++ uint no_items= part_elem->list_val_list.elements;
++ tmp_str.length(0);
++ tmp_res.length(0);
++ if (part_elem->has_null_value)
++ {
++ tmp_str.append("NULL");
++ if (no_items > 0)
++ tmp_str.append(",");
++ }
++ while ((list_value= list_val_it++))
++ {
++ if (!list_value->unsigned_flag)
++ tmp_res.set(list_value->value, cs);
++ else
++ tmp_res.set((ulonglong)list_value->value, cs);
++ tmp_str.append(tmp_res);
++ if (--no_items != 0)
++ tmp_str.append(",");
++ };
++ table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
++ table->field[11]->set_notnull();
++ }
++
++ if (part_elem->subpartitions.elements)
++ {
++ List_iterator<partition_element> sub_it(part_elem->subpartitions);
++ partition_element *subpart_elem;
++ uint subpart_pos= 0;
++
++ while ((subpart_elem= sub_it++))
++ {
++ table->field[4]->store(subpart_elem->partition_name,
++ strlen(subpart_elem->partition_name), cs);
++ table->field[4]->set_notnull();
++ /* SUBPARTITION_ORDINAL_POSITION */
++ table->field[6]->store((longlong) ++subpart_pos, TRUE);
++ table->field[6]->set_notnull();
++
++ store_schema_partitions_record(thd, table, show_table, subpart_elem,
++ file, part_id);
++ part_id++;
++ if(schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ else
++ {
++ store_schema_partitions_record(thd, table, show_table, part_elem,
++ file, part_id);
++ part_id++;
++ if(schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++ }
++ else
++#endif
++ {
++ store_schema_partitions_record(thd, table, show_table, 0, file, 0);
++ if(schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++}
++
++
++#ifdef NOT_USED
++static interval_type get_real_interval_type(interval_type i_type)
++{
++ switch (i_type) {
++ case INTERVAL_YEAR:
++ return INTERVAL_YEAR;
++
++ case INTERVAL_QUARTER:
++ case INTERVAL_YEAR_MONTH:
++ case INTERVAL_MONTH:
++ return INTERVAL_MONTH;
++
++ case INTERVAL_WEEK:
++ case INTERVAL_DAY:
++ return INTERVAL_DAY;
++
++ case INTERVAL_DAY_HOUR:
++ case INTERVAL_HOUR:
++ return INTERVAL_HOUR;
++
++ case INTERVAL_DAY_MINUTE:
++ case INTERVAL_HOUR_MINUTE:
++ case INTERVAL_MINUTE:
++ return INTERVAL_MINUTE;
++
++ case INTERVAL_DAY_SECOND:
++ case INTERVAL_HOUR_SECOND:
++ case INTERVAL_MINUTE_SECOND:
++ case INTERVAL_SECOND:
++ return INTERVAL_SECOND;
++
++ case INTERVAL_DAY_MICROSECOND:
++ case INTERVAL_HOUR_MICROSECOND:
++ case INTERVAL_MINUTE_MICROSECOND:
++ case INTERVAL_SECOND_MICROSECOND:
++ case INTERVAL_MICROSECOND:
++ return INTERVAL_MICROSECOND;
++ case INTERVAL_LAST:
++ DBUG_ASSERT(0);
++ }
++ DBUG_ASSERT(0);
++ return INTERVAL_SECOND;
++}
++
++#endif
++
++#ifdef HAVE_EVENT_SCHEDULER
++/*
++ Loads an event from mysql.event and copies it's data to a row of
++ I_S.EVENTS
++
++ Synopsis
++ copy_event_to_schema_table()
++ thd Thread
++ sch_table The schema table (information_schema.event)
++ event_table The event table to use for loading (mysql.event).
++
++ Returns
++ 0 OK
++ 1 Error
++*/
++
++int
++copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
++{
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ CHARSET_INFO *scs= system_charset_info;
++ MYSQL_TIME time;
++ Event_timed et;
++ DBUG_ENTER("copy_event_to_schema_table");
++
++ restore_record(sch_table, s->default_values);
++
++ if (et.load_from_row(thd, event_table))
++ {
++ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias);
++ DBUG_RETURN(1);
++ }
++
++ if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
++ DBUG_RETURN(0);
++
++ /*
++ Skip events in schemas one does not have access to. The check is
++ optimized. It's guaranteed in case of SHOW EVENTS that the user
++ has access.
++ */
++ if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
++ check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
++ is_schema_db(et.dbname.str, et.dbname.length)))
++ DBUG_RETURN(0);
++
++ /* ->field[0] is EVENT_CATALOG and is by default NULL */
++
++ sch_table->field[ISE_EVENT_SCHEMA]->
++ store(et.dbname.str, et.dbname.length,scs);
++ sch_table->field[ISE_EVENT_NAME]->
++ store(et.name.str, et.name.length, scs);
++ sch_table->field[ISE_DEFINER]->
++ store(et.definer.str, et.definer.length, scs);
++ const String *tz_name= et.time_zone->get_name();
++ sch_table->field[ISE_TIME_ZONE]->
++ store(tz_name->ptr(), tz_name->length(), scs);
++ sch_table->field[ISE_EVENT_BODY]->
++ store(STRING_WITH_LEN("SQL"), scs);
++ sch_table->field[ISE_EVENT_DEFINITION]->store(
++ et.body_utf8.str, et.body_utf8.length, scs);
++
++ /* SQL_MODE */
++ {
++ LEX_STRING sql_mode;
++ sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
++ &sql_mode);
++ sch_table->field[ISE_SQL_MODE]->
++ store(sql_mode.str, sql_mode.length, scs);
++ }
++
++ int not_used=0;
++
++ if (et.expression)
++ {
++ String show_str;
++ /* type */
++ sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("RECURRING"), scs);
++
++ if (Events::reconstruct_interval_expression(&show_str, et.interval,
++ et.expression))
++ DBUG_RETURN(1);
++
++ sch_table->field[ISE_INTERVAL_VALUE]->set_notnull();
++ sch_table->field[ISE_INTERVAL_VALUE]->
++ store(show_str.ptr(), show_str.length(), scs);
++
++ LEX_STRING *ival= &interval_type_to_name[et.interval];
++ sch_table->field[ISE_INTERVAL_FIELD]->set_notnull();
++ sch_table->field[ISE_INTERVAL_FIELD]->store(ival->str, ival->length, scs);
++
++ /* starts & ends . STARTS is always set - see sql_yacc.yy */
++ et.time_zone->gmt_sec_to_TIME(&time, et.starts);
++ sch_table->field[ISE_STARTS]->set_notnull();
++ sch_table->field[ISE_STARTS]->
++ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++
++ if (!et.ends_null)
++ {
++ et.time_zone->gmt_sec_to_TIME(&time, et.ends);
++ sch_table->field[ISE_ENDS]->set_notnull();
++ sch_table->field[ISE_ENDS]->
++ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ }
++ }
++ else
++ {
++ /* type */
++ sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("ONE TIME"), scs);
++
++ et.time_zone->gmt_sec_to_TIME(&time, et.execute_at);
++ sch_table->field[ISE_EXECUTE_AT]->set_notnull();
++ sch_table->field[ISE_EXECUTE_AT]->
++ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ }
++
++ /* status */
++
++ switch (et.status)
++ {
++ case Event_parse_data::ENABLED:
++ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs);
++ break;
++ case Event_parse_data::SLAVESIDE_DISABLED:
++ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("SLAVESIDE_DISABLED"),
++ scs);
++ break;
++ case Event_parse_data::DISABLED:
++ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs);
++ break;
++ default:
++ DBUG_ASSERT(0);
++ }
++ sch_table->field[ISE_ORIGINATOR]->store(et.originator, TRUE);
++
++ /* on_completion */
++ if (et.on_completion == Event_parse_data::ON_COMPLETION_DROP)
++ sch_table->field[ISE_ON_COMPLETION]->
++ store(STRING_WITH_LEN("NOT PRESERVE"), scs);
++ else
++ sch_table->field[ISE_ON_COMPLETION]->
++ store(STRING_WITH_LEN("PRESERVE"), scs);
++
++ number_to_datetime(et.created, &time, 0, ¬_used);
++ DBUG_ASSERT(not_used==0);
++ sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++
++ number_to_datetime(et.modified, &time, 0, ¬_used);
++ DBUG_ASSERT(not_used==0);
++ sch_table->field[ISE_LAST_ALTERED]->
++ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++
++ if (et.last_executed)
++ {
++ et.time_zone->gmt_sec_to_TIME(&time, et.last_executed);
++ sch_table->field[ISE_LAST_EXECUTED]->set_notnull();
++ sch_table->field[ISE_LAST_EXECUTED]->
++ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
++ }
++
++ sch_table->field[ISE_EVENT_COMMENT]->
++ store(et.comment.str, et.comment.length, scs);
++
++ sch_table->field[ISE_CLIENT_CS]->set_notnull();
++ sch_table->field[ISE_CLIENT_CS]->store(
++ et.creation_ctx->get_client_cs()->csname,
++ strlen(et.creation_ctx->get_client_cs()->csname),
++ scs);
++
++ sch_table->field[ISE_CONNECTION_CL]->set_notnull();
++ sch_table->field[ISE_CONNECTION_CL]->store(
++ et.creation_ctx->get_connection_cl()->name,
++ strlen(et.creation_ctx->get_connection_cl()->name),
++ scs);
++
++ sch_table->field[ISE_DB_CL]->set_notnull();
++ sch_table->field[ISE_DB_CL]->store(
++ et.creation_ctx->get_db_cl()->name,
++ strlen(et.creation_ctx->get_db_cl()->name),
++ scs);
++
++ if (schema_table_store_record(thd, sch_table))
++ DBUG_RETURN(1);
++
++ DBUG_RETURN(0);
++}
++#endif
++
++int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_open_tables");
++ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
++ TABLE *table= tables->table;
++ CHARSET_INFO *cs= system_charset_info;
++ OPEN_TABLE_LIST *open_list;
++ if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
++ && thd->is_fatal_error)
++ DBUG_RETURN(1);
++
++ for (; open_list ; open_list=open_list->next)
++ {
++ restore_record(table, s->default_values);
++ table->field[0]->store(open_list->db, strlen(open_list->db), cs);
++ table->field[1]->store(open_list->table, strlen(open_list->table), cs);
++ table->field[2]->store((longlong) open_list->in_use, TRUE);
++ table->field[3]->store((longlong) open_list->locked, TRUE);
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++}
++
++
++int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_variables");
++ int res= 0;
++ LEX *lex= thd->lex;
++ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
++ enum enum_schema_tables schema_table_idx=
++ get_schema_table_idx(tables->schema_table);
++ enum enum_var_type option_type= OPT_SESSION;
++ bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
++ bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
++
++ if (lex->option_type == OPT_GLOBAL ||
++ schema_table_idx == SCH_GLOBAL_VARIABLES)
++ option_type= OPT_GLOBAL;
++
++ rw_rdlock(&LOCK_system_variables_hash);
++ res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
++ option_type, NULL, "", tables->table, upper_case_names, cond);
++ rw_unlock(&LOCK_system_variables_hash);
++ DBUG_RETURN(res);
++}
++
++
++int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_status");
++ LEX *lex= thd->lex;
++ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
++ int res= 0;
++ STATUS_VAR *tmp1, tmp;
++ enum enum_schema_tables schema_table_idx=
++ get_schema_table_idx(tables->schema_table);
++ enum enum_var_type option_type;
++ bool upper_case_names= (schema_table_idx != SCH_STATUS);
++
++ if (schema_table_idx == SCH_STATUS)
++ {
++ option_type= lex->option_type;
++ if (option_type == OPT_GLOBAL)
++ tmp1= &tmp;
++ else
++ tmp1= thd->initial_status_var;
++ }
++ else if (schema_table_idx == SCH_GLOBAL_STATUS)
++ {
++ option_type= OPT_GLOBAL;
++ tmp1= &tmp;
++ }
++ else
++ {
++ option_type= OPT_SESSION;
++ tmp1= &thd->status_var;
++ }
++
++ pthread_mutex_lock(&LOCK_status);
++ if (option_type == OPT_GLOBAL)
++ calc_sum_of_all_status(&tmp);
++ res= show_status_array(thd, wild,
++ (SHOW_VAR *)all_status_vars.buffer,
++ option_type, tmp1, "", tables->table,
++ upper_case_names, cond);
++ pthread_mutex_unlock(&LOCK_status);
++ DBUG_RETURN(res);
++}
++
++
++/*
++ Fill and store records into I_S.referential_constraints table
++
++ SYNOPSIS
++ get_referential_constraints_record()
++ thd thread handle
++ tables table list struct(processed table)
++ table I_S table
++ res 1 means the error during opening of the processed table
++ 0 means processed table is opened without error
++ base_name db name
++ file_name table name
++
++ RETURN
++ 0 ok
++ # error
++*/
++
++static int
++get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
++ TABLE *table, bool res,
++ LEX_STRING *db_name, LEX_STRING *table_name)
++{
++ CHARSET_INFO *cs= system_charset_info;
++ DBUG_ENTER("get_referential_constraints_record");
++
++ if (res)
++ {
++ if (thd->is_error())
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ thd->main_da.sql_errno(), thd->main_da.message());
++ thd->clear_error();
++ DBUG_RETURN(0);
++ }
++ if (!tables->view)
++ {
++ List<FOREIGN_KEY_INFO> f_key_list;
++ TABLE *show_table= tables->table;
++
++ // This is not needed since no statistics are displayed.
++ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
++
++ show_table->file->get_foreign_key_list(thd, &f_key_list);
++ FOREIGN_KEY_INFO *f_key_info;
++ List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
++ while ((f_key_info= it++))
++ {
++ restore_record(table, s->default_values);
++ table->field[1]->store(db_name->str, db_name->length, cs);
++ table->field[9]->store(table_name->str, table_name->length, cs);
++ table->field[2]->store(f_key_info->forein_id->str,
++ f_key_info->forein_id->length, cs);
++ table->field[4]->store(f_key_info->referenced_db->str,
++ f_key_info->referenced_db->length, cs);
++ table->field[10]->store(f_key_info->referenced_table->str,
++ f_key_info->referenced_table->length, cs);
++ if (f_key_info->referenced_key_name)
++ {
++ table->field[5]->store(f_key_info->referenced_key_name->str,
++ f_key_info->referenced_key_name->length, cs);
++ table->field[5]->set_notnull();
++ }
++ else
++ table->field[5]->set_null();
++ table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
++ table->field[7]->store(f_key_info->update_method->str,
++ f_key_info->update_method->length, cs);
++ table->field[8]->store(f_key_info->delete_method->str,
++ f_key_info->delete_method->length, cs);
++ if (schema_table_store_record(thd, table))
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++struct schema_table_ref
++{
++ const char *table_name;
++ ST_SCHEMA_TABLE *schema_table;
++};
++
++
++/*
++ Find schema_tables elment by name
++
++ SYNOPSIS
++ find_schema_table_in_plugin()
++ thd thread handler
++ plugin plugin
++ table_name table name
++
++ RETURN
++ 0 table not found
++ 1 found the schema table
++*/
++static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
++ void* p_table)
++{
++ schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
++ const char* table_name= p_schema_table->table_name;
++ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
++ DBUG_ENTER("find_schema_table_in_plugin");
++
++ if (!my_strcasecmp(system_charset_info,
++ schema_table->table_name,
++ table_name)) {
++ p_schema_table->schema_table= schema_table;
++ DBUG_RETURN(1);
++ }
++
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Find schema_tables elment by name
++
++ SYNOPSIS
++ find_schema_table()
++ thd thread handler
++ table_name table name
++
++ RETURN
++ 0 table not found
++ # pointer to 'schema_tables' element
++*/
++
++ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
++{
++ schema_table_ref schema_table_a;
++ ST_SCHEMA_TABLE *schema_table= schema_tables;
++ DBUG_ENTER("find_schema_table");
++
++ for (; schema_table->table_name; schema_table++)
++ {
++ if (!my_strcasecmp(system_charset_info,
++ schema_table->table_name,
++ table_name))
++ DBUG_RETURN(schema_table);
++ }
++
++ schema_table_a.table_name= table_name;
++ if (plugin_foreach(thd, find_schema_table_in_plugin,
++ MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
++ DBUG_RETURN(schema_table_a.schema_table);
++
++ DBUG_RETURN(NULL);
++}
++
++
++ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
++{
++ return &schema_tables[schema_table_idx];
++}
++
++
++/**
++ Create information_schema table using schema_table data.
++
++ @note
++ For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
++ into it two numbers, based on modulus of base-10 numbers. In the ones
++ position is the number of decimals. Tens position is unused. In the
++ hundreds and thousands position is a two-digit decimal number representing
++ length. Encode this value with (decimals*100)+length , where
++ 0<decimals<10 and 0<=length<100 .
++
++ @param
++ thd thread handler
++
++ @param table_list Used to pass I_S table information(fields info, tables
++ parameters etc) and table name.
++
++ @retval \# Pointer to created table
++ @retval NULL Can't create table
++*/
++
++TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
++{
++ int field_count= 0;
++ Item *item;
++ TABLE *table;
++ List<Item> field_list;
++ ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
++ ST_FIELD_INFO *fields_info= schema_table->fields_info;
++ CHARSET_INFO *cs= system_charset_info;
++ DBUG_ENTER("create_schema_table");
++
++ for (; fields_info->field_name; fields_info++)
++ {
++ switch (fields_info->field_type) {
++ case MYSQL_TYPE_TINY:
++ case MYSQL_TYPE_LONG:
++ case MYSQL_TYPE_SHORT:
++ case MYSQL_TYPE_LONGLONG:
++ case MYSQL_TYPE_INT24:
++ if (!(item= new Item_return_int(fields_info->field_name,
++ fields_info->field_length,
++ fields_info->field_type,
++ fields_info->value)))
++ {
++ DBUG_RETURN(0);
++ }
++ item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
++ break;
++ case MYSQL_TYPE_DATE:
++ case MYSQL_TYPE_TIME:
++ case MYSQL_TYPE_TIMESTAMP:
++ case MYSQL_TYPE_DATETIME:
++ if (!(item=new Item_return_date_time(fields_info->field_name,
++ fields_info->field_type)))
++ {
++ DBUG_RETURN(0);
++ }
++ break;
++ case MYSQL_TYPE_FLOAT:
++ case MYSQL_TYPE_DOUBLE:
++ if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
++ fields_info->field_length)) == NULL)
++ DBUG_RETURN(NULL);
++ break;
++ case MYSQL_TYPE_DECIMAL:
++ case MYSQL_TYPE_NEWDECIMAL:
++ if (!(item= new Item_decimal((longlong) fields_info->value, false)))
++ {
++ DBUG_RETURN(0);
++ }
++ item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
++ item->decimals= fields_info->field_length%10;
++ item->max_length= (fields_info->field_length/100)%100;
++ if (item->unsigned_flag == 0)
++ item->max_length+= 1;
++ if (item->decimals > 0)
++ item->max_length+= 1;
++ item->set_name(fields_info->field_name,
++ strlen(fields_info->field_name), cs);
++ break;
++ case MYSQL_TYPE_TINY_BLOB:
++ case MYSQL_TYPE_MEDIUM_BLOB:
++ case MYSQL_TYPE_LONG_BLOB:
++ case MYSQL_TYPE_BLOB:
++ if (!(item= new Item_blob(fields_info->field_name,
++ fields_info->field_length)))
++ {
++ DBUG_RETURN(0);
++ }
++ break;
++ default:
++ /* Don't let unimplemented types pass through. Could be a grave error. */
++ DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
++
++ if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
++ {
++ DBUG_RETURN(0);
++ }
++ item->set_name(fields_info->field_name,
++ strlen(fields_info->field_name), cs);
++ break;
++ }
++ field_list.push_back(item);
++ item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
++ field_count++;
++ }
++ TMP_TABLE_PARAM *tmp_table_param =
++ (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
++ tmp_table_param->init();
++ tmp_table_param->table_charset= cs;
++ tmp_table_param->field_count= field_count;
++ tmp_table_param->schema_table= 1;
++ SELECT_LEX *select_lex= thd->lex->current_select;
++ if (!(table= create_tmp_table(thd, tmp_table_param,
++ field_list, (ORDER*) 0, 0, 0,
++ (select_lex->options | thd->options |
++ TMP_TABLE_ALL_COLUMNS),
++ HA_POS_ERROR, table_list->alias)))
++ DBUG_RETURN(0);
++ my_bitmap_map* bitmaps=
++ (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
++ bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
++ FALSE);
++ table->read_set= &table->def_read_set;
++ bitmap_clear_all(table->read_set);
++ table_list->schema_table_param= tmp_table_param;
++ DBUG_RETURN(table);
++}
++
++
++/*
++ For old SHOW compatibility. It is used when
++ old SHOW doesn't have generated column names
++ Make list of fields for SHOW
++
++ SYNOPSIS
++ make_old_format()
++ thd thread handler
++ schema_table pointer to 'schema_tables' element
++
++ RETURN
++ 1 error
++ 0 success
++*/
++
++int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ ST_FIELD_INFO *field_info= schema_table->fields_info;
++ Name_resolution_context *context= &thd->lex->select_lex.context;
++ for (; field_info->field_name; field_info++)
++ {
++ if (field_info->old_name)
++ {
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (field)
++ {
++ field->set_name(field_info->old_name,
++ strlen(field_info->old_name),
++ system_charset_info);
++ if (add_item_to_list(thd, field))
++ return 1;
++ }
++ }
++ }
++ return 0;
++}
++
++
++int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ char tmp[128];
++ LEX *lex= thd->lex;
++ SELECT_LEX *sel= lex->current_select;
++ Name_resolution_context *context= &sel->context;
++
++ if (!sel->item_list.elements)
++ {
++ ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
++ String buffer(tmp,sizeof(tmp), system_charset_info);
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (!field || add_item_to_list(thd, field))
++ return 1;
++ buffer.length(0);
++ buffer.append(field_info->old_name);
++ if (lex->wild && lex->wild->ptr())
++ {
++ buffer.append(STRING_WITH_LEN(" ("));
++ buffer.append(lex->wild->ptr());
++ buffer.append(')');
++ }
++ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
++ }
++ return 0;
++}
++
++
++int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ char tmp[128];
++ String buffer(tmp,sizeof(tmp), thd->charset());
++ LEX *lex= thd->lex;
++ Name_resolution_context *context= &lex->select_lex.context;
++
++ ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
++ buffer.length(0);
++ buffer.append(field_info->old_name);
++ buffer.append(lex->select_lex.db);
++ if (lex->wild && lex->wild->ptr())
++ {
++ buffer.append(STRING_WITH_LEN(" ("));
++ buffer.append(lex->wild->ptr());
++ buffer.append(')');
++ }
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (add_item_to_list(thd, field))
++ return 1;
++ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
++ if (thd->lex->verbose)
++ {
++ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
++ field_info= &schema_table->fields_info[3];
++ field= new Item_field(context, NullS, NullS, field_info->field_name);
++ if (add_item_to_list(thd, field))
++ return 1;
++ field->set_name(field_info->old_name, strlen(field_info->old_name),
++ system_charset_info);
++ }
++ return 0;
++}
++
++
++int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
++ int *field_num= fields_arr;
++ ST_FIELD_INFO *field_info;
++ Name_resolution_context *context= &thd->lex->select_lex.context;
++
++ for (; *field_num >= 0; field_num++)
++ {
++ field_info= &schema_table->fields_info[*field_num];
++ if (!thd->lex->verbose && (*field_num == 13 ||
++ *field_num == 17 ||
++ *field_num == 18))
++ continue;
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (field)
++ {
++ field->set_name(field_info->old_name,
++ strlen(field_info->old_name),
++ system_charset_info);
++ if (add_item_to_list(thd, field))
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ int fields_arr[]= {0, 2, 1, 3, -1};
++ int *field_num= fields_arr;
++ ST_FIELD_INFO *field_info;
++ Name_resolution_context *context= &thd->lex->select_lex.context;
++
++ for (; *field_num >= 0; field_num++)
++ {
++ field_info= &schema_table->fields_info[*field_num];
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (field)
++ {
++ field->set_name(field_info->old_name,
++ strlen(field_info->old_name),
++ system_charset_info);
++ if (add_item_to_list(thd, field))
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
++{
++ int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, 20, 21, 22, -1};
++ int *field_num= fields_arr;
++ ST_FIELD_INFO *field_info;
++ Name_resolution_context *context= &thd->lex->select_lex.context;
++
++ for (; *field_num >= 0; field_num++)
++ {
++ field_info= &schema_table->fields_info[*field_num];
++ Item_field *field= new Item_field(context,
++ NullS, NullS, field_info->field_name);
++ if (field)
++ {
++ field->set_name(field_info->old_name,
++ strlen(field_info->old_name),
++ system_charset_info);
++ if (add_item_to_list(thd, field))
++ return 1;
++ }
++ }
++ return 0;
++}
++
++
++/*
++ Create information_schema table
++
++ SYNOPSIS
++ mysql_schema_table()
++ thd thread handler
++ lex pointer to LEX
++ table_list pointer to table_list
++
++ RETURN
++ 0 success
++ 1 error
++*/
++
++int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
++{
++ TABLE *table;
++ DBUG_ENTER("mysql_schema_table");
++ if (!(table= table_list->schema_table->create_table(thd, table_list)))
++ DBUG_RETURN(1);
++ table->s->tmp_table= SYSTEM_TMP_TABLE;
++ table->grant.privilege= SELECT_ACL;
++ /*
++ This test is necessary to make
++ case insensitive file systems +
++ upper case table names(information schema tables) +
++ views
++ working correctly
++ */
++ if (table_list->schema_table_name)
++ table->alias_name_used= my_strcasecmp(table_alias_charset,
++ table_list->schema_table_name,
++ table_list->alias);
++ table_list->table_name= table->s->table_name.str;
++ table_list->table_name_length= table->s->table_name.length;
++ table_list->table= table;
++ table->next= thd->derived_tables;
++ thd->derived_tables= table;
++ table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
++ lex->safe_to_cache_query= 0;
++
++ if (table_list->schema_table_reformed) // show command
++ {
++ SELECT_LEX *sel= lex->current_select;
++ Item *item;
++ Field_translator *transl, *org_transl;
++
++ if (table_list->field_translation)
++ {
++ Field_translator *end= table_list->field_translation_end;
++ for (transl= table_list->field_translation; transl < end; transl++)
++ {
++ if (!transl->item->fixed &&
++ transl->item->fix_fields(thd, &transl->item))
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++ }
++ List_iterator_fast<Item> it(sel->item_list);
++ if (!(transl=
++ (Field_translator*)(thd->stmt_arena->
++ alloc(sel->item_list.elements *
++ sizeof(Field_translator)))))
++ {
++ DBUG_RETURN(1);
++ }
++ for (org_transl= transl; (item= it++); transl++)
++ {
++ transl->item= item;
++ transl->name= item->name;
++ if (!item->fixed && item->fix_fields(thd, &transl->item))
++ {
++ DBUG_RETURN(1);
++ }
++ }
++ table_list->field_translation= org_transl;
++ table_list->field_translation_end= transl;
++ }
++
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Generate select from information_schema table
++
++ SYNOPSIS
++ make_schema_select()
++ thd thread handler
++ sel pointer to SELECT_LEX
++ schema_table_idx index of 'schema_tables' element
++
++ RETURN
++ 0 success
++ 1 error
++*/
++
++int make_schema_select(THD *thd, SELECT_LEX *sel,
++ enum enum_schema_tables schema_table_idx)
++{
++ ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
++ LEX_STRING db, table;
++ DBUG_ENTER("make_schema_select");
++ DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name));
++ /*
++ We have to make non const db_name & table_name
++ because of lower_case_table_names
++ */
++ thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
++ INFORMATION_SCHEMA_NAME.length, 0);
++ thd->make_lex_string(&table, schema_table->table_name,
++ strlen(schema_table->table_name), 0);
++ if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
++ !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
++ 0, 0, TL_READ))
++ {
++ DBUG_RETURN(1);
++ }
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Fill temporary schema tables before SELECT
++
++ SYNOPSIS
++ get_schema_tables_result()
++ join join which use schema tables
++ executed_place place where I_S table processed
++
++ RETURN
++ FALSE success
++ TRUE error
++*/
++
++bool get_schema_tables_result(JOIN *join,
++ enum enum_schema_table_state executed_place)
++{
++ JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
++ THD *thd= join->thd;
++ LEX *lex= thd->lex;
++ bool result= 0;
++ DBUG_ENTER("get_schema_tables_result");
++
++ thd->no_warnings_for_error= 1;
++ for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
++ {
++ if (!tab->table || !tab->table->pos_in_table_list)
++ break;
++
++ TABLE_LIST *table_list= tab->table->pos_in_table_list;
++ if (table_list->schema_table && thd->fill_information_schema_tables())
++ {
++ bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
++ lex->current_select->master_unit()->item);
++
++ /* A value of 0 indicates a dummy implementation */
++ if (table_list->schema_table->fill_table == 0)
++ continue;
++
++ /* skip I_S optimizations specific to get_all_tables */
++ if (thd->lex->describe &&
++ (table_list->schema_table->fill_table != get_all_tables))
++ continue;
++
++ /*
++ If schema table is already processed and
++ the statement is not a subselect then
++ we don't need to fill this table again.
++ If schema table is already processed and
++ schema_table_state != executed_place then
++ table is already processed and
++ we should skip second data processing.
++ */
++ if (table_list->schema_table_state &&
++ (!is_subselect || table_list->schema_table_state != executed_place))
++ continue;
++
++ /*
++ if table is used in a subselect and
++ table has been processed earlier with the same
++ 'executed_place' value then we should refresh the table.
++ */
++ if (table_list->schema_table_state && is_subselect)
++ {
++ table_list->table->file->extra(HA_EXTRA_NO_CACHE);
++ table_list->table->file->extra(HA_EXTRA_RESET_STATE);
++ table_list->table->file->ha_delete_all_rows();
++ free_io_cache(table_list->table);
++ filesort_free_buffers(table_list->table,1);
++ table_list->table->null_row= 0;
++ }
++ else
++ table_list->table->file->stats.records= 0;
++
++ if (table_list->schema_table->fill_table(thd, table_list,
++ tab->select_cond))
++ {
++ result= 1;
++ join->error= 1;
++ tab->read_record.file= table_list->table->file;
++ table_list->schema_table_state= executed_place;
++ break;
++ }
++ tab->read_record.file= table_list->table->file;
++ table_list->schema_table_state= executed_place;
++ }
++ }
++ thd->no_warnings_for_error= 0;
++ DBUG_RETURN(result);
++}
++
++struct run_hton_fill_schema_files_args
++{
++ TABLE_LIST *tables;
++ COND *cond;
++};
++
++static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin,
++ void *arg)
++{
++ struct run_hton_fill_schema_files_args *args=
++ (run_hton_fill_schema_files_args *) arg;
++ handlerton *hton= plugin_data(plugin, handlerton *);
++ if(hton->fill_files_table && hton->state == SHOW_OPTION_YES)
++ hton->fill_files_table(hton, thd, args->tables, args->cond);
++ return false;
++}
++
++int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond)
++{
++ DBUG_ENTER("fill_schema_files");
++
++ struct run_hton_fill_schema_files_args args;
++ args.tables= tables;
++ args.cond= cond;
++
++ plugin_foreach(thd, run_hton_fill_schema_files,
++ MYSQL_STORAGE_ENGINE_PLUGIN, &args);
++
++ DBUG_RETURN(0);
++}
++
++
++ST_FIELD_INFO schema_fields_info[]=
++{
++ {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
++ SKIP_OPEN_TABLE},
++ {"DEFAULT_CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ SKIP_OPEN_TABLE},
++ {"DEFAULT_COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ SKIP_OPEN_TABLE},
++ {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO tables_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
++ SKIP_OPEN_TABLE},
++ {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
++ {"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
++ {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
++ {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
++ {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
++ {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
++ {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
++ {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
++ {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
++ {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
++ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
++ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
++ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
++ {"TABLE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
++ OPEN_FRM_ONLY},
++ {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
++ {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
++ OPEN_FRM_ONLY},
++ {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO columns_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
++ OPEN_FRM_ONLY},
++ {"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
++ MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
++ {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
++ 1, "Default", OPEN_FRM_ONLY},
++ {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
++ {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
++ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
++ {"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
++ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
++ {"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
++ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
++ {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
++ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
++ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FRM_ONLY},
++ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
++ OPEN_FRM_ONLY},
++ {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
++ {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
++ {"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
++ {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
++ {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO charsets_fields_info[]=
++{
++ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
++ SKIP_OPEN_TABLE},
++ {"DEFAULT_COLLATE_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "Default collation", SKIP_OPEN_TABLE},
++ {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
++ SKIP_OPEN_TABLE},
++ {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO collation_fields_info[]=
++{
++ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Collation",
++ SKIP_OPEN_TABLE},
++ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
++ SKIP_OPEN_TABLE},
++ {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
++ SKIP_OPEN_TABLE},
++ {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
++ {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
++ {"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO engines_fields_info[]=
++{
++ {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE},
++ {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
++ {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
++ {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 1, "Transactions", SKIP_OPEN_TABLE},
++ {"XA", 3, MYSQL_TYPE_STRING, 0, 1, "XA", SKIP_OPEN_TABLE},
++ {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 1, "Savepoints", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO events_fields_info[]=
++{
++ {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
++ SKIP_OPEN_TABLE},
++ {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
++ SKIP_OPEN_TABLE},
++ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
++ {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
++ {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
++ {"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
++ {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
++ SKIP_OPEN_TABLE},
++ {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
++ SKIP_OPEN_TABLE},
++ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
++ {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
++ {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
++ {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
++ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "character_set_client", SKIP_OPEN_TABLE},
++ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "collation_connection", SKIP_OPEN_TABLE},
++ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "Database Collation", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++
++ST_FIELD_INFO coll_charset_app_fields_info[]=
++{
++ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ SKIP_OPEN_TABLE},
++ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO proc_fields_info[]=
++{
++ {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
++ SKIP_OPEN_TABLE},
++ {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
++ SKIP_OPEN_TABLE},
++ {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
++ {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ SKIP_OPEN_TABLE},
++ {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ SKIP_OPEN_TABLE},
++ {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type",
++ SKIP_OPEN_TABLE},
++ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE},
++ {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE},
++ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment",
++ SKIP_OPEN_TABLE},
++ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
++ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "character_set_client", SKIP_OPEN_TABLE},
++ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "collation_connection", SKIP_OPEN_TABLE},
++ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "Database Collation", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO stat_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
++ {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
++ {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
++ OPEN_FRM_ONLY},
++ {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
++ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
++ OPEN_FRM_ONLY},
++ {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
++ {"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
++ "Cardinality", OPEN_FULL_TABLE},
++ {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
++ {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
++ {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
++ {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
++ {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO view_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
++ {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO user_privileges_fields_info[]=
++{
++ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO schema_privileges_fields_info[]=
++{
++ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO table_privileges_fields_info[]=
++{
++ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO column_privileges_fields_info[]=
++{
++ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO table_constraints_fields_info[]=
++{
++ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO key_column_usage_fields_info[]=
++{
++ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
++ {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO table_names_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
++ SKIP_OPEN_TABLE},
++ {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
++ OPEN_FRM_ONLY},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO open_tables_fields_info[]=
++{
++ {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
++ SKIP_OPEN_TABLE},
++ {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
++ {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
++ {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO triggers_fields_info[]=
++{
++ {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger",
++ OPEN_FULL_TABLE},
++ {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE},
++ {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table",
++ OPEN_FULL_TABLE},
++ {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
++ {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement",
++ OPEN_FULL_TABLE},
++ {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE},
++ {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE},
++ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE},
++ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE},
++ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "character_set_client", OPEN_FULL_TABLE},
++ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "collation_connection", OPEN_FULL_TABLE},
++ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
++ "Database Collation", OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO partitions_fields_info[]=
++{
++ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
++ {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
++ {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
++ OPEN_FULL_TABLE},
++ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
++ OPEN_FULL_TABLE},
++ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
++ OPEN_FULL_TABLE},
++ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
++ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
++ OPEN_FULL_TABLE},
++ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
++ OPEN_FULL_TABLE},
++ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
++ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
++ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
++ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
++ {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO variables_fields_info[]=
++{
++ {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
++ SKIP_OPEN_TABLE},
++ {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO processlist_fields_info[]=
++{
++ {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
++ {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
++ {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
++ SKIP_OPEN_TABLE},
++ {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
++ {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
++ {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time", SKIP_OPEN_TABLE},
++ {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
++ {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
++ SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++ST_FIELD_INFO plugin_fields_info[]=
++{
++ {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
++ SKIP_OPEN_TABLE},
++ {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
++ {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
++ {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
++ SKIP_OPEN_TABLE},
++ {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++ST_FIELD_INFO files_fields_info[]=
++{
++ {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ SKIP_OPEN_TABLE},
++ {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ SKIP_OPEN_TABLE},
++ {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
++ {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
++ {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
++ {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
++ {"VERSION", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", SKIP_OPEN_TABLE},
++ {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
++ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
++ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
++ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
++ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
++ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
++ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
++ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
++ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
++ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
++ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
++ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
++ {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
++ {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++void init_fill_schema_files_row(TABLE* table)
++{
++ int i;
++ for(i=0; files_fields_info[i].field_name!=NULL; i++)
++ table->field[i]->set_null();
++
++ table->field[IS_FILES_STATUS]->set_notnull();
++ table->field[IS_FILES_STATUS]->store("NORMAL", 6, system_charset_info);
++}
++
++ST_FIELD_INFO referential_constraints_fields_info[]=
++{
++ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
++ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
++ OPEN_FULL_TABLE},
++ {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
++ MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
++ {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
++ {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
++ OPEN_FULL_TABLE},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
++};
++
++
++/*
++ Description of ST_FIELD_INFO in table.h
++
++ Make sure that the order of schema_tables and enum_schema_tables are the same.
++
++*/
++
++ST_SCHEMA_TABLE schema_tables[]=
++{
++ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
++ fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
++ {"COLLATIONS", collation_fields_info, create_schema_table,
++ fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
++ {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
++ create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
++ {"COLUMNS", columns_fields_info, create_schema_table,
++ get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
++ OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
++ {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
++ fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
++ {"ENGINES", engines_fields_info, create_schema_table,
++ fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
++#ifdef HAVE_EVENT_SCHEDULER
++ {"EVENTS", events_fields_info, create_schema_table,
++ Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
++#else
++ {"EVENTS", events_fields_info, create_schema_table,
++ 0, make_old_format, 0, -1, -1, 0, 0},
++#endif
++ {"FILES", files_fields_info, create_schema_table,
++ fill_schema_files, 0, 0, -1, -1, 0, 0},
++ {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
++ fill_status, make_old_format, 0, 0, -1, 0, 0},
++ {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
++ fill_variables, make_old_format, 0, 0, -1, 0, 0},
++ {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
++ get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
++ OPEN_TABLE_ONLY},
++ {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
++ fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
++ {"PARTITIONS", partitions_fields_info, create_schema_table,
++ get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY},
++ {"PLUGINS", plugin_fields_info, create_schema_table,
++ fill_plugins, make_old_format, 0, -1, -1, 0, 0},
++ {"PROCESSLIST", processlist_fields_info, create_schema_table,
++ fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
++ {"PROFILING", query_profile_statistics_info, create_schema_table,
++ fill_query_profile_statistics_info, make_profile_table_for_show,
++ NULL, -1, -1, false, 0},
++ {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
++ create_schema_table, get_all_tables, 0, get_referential_constraints_record,
++ 1, 9, 0, OPEN_TABLE_ONLY},
++ {"ROUTINES", proc_fields_info, create_schema_table,
++ fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
++ {"SCHEMATA", schema_fields_info, create_schema_table,
++ fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
++ {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
++ fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0},
++ {"SESSION_STATUS", variables_fields_info, create_schema_table,
++ fill_status, make_old_format, 0, 0, -1, 0, 0},
++ {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
++ fill_variables, make_old_format, 0, 0, -1, 0, 0},
++ {"STATISTICS", stat_fields_info, create_schema_table,
++ get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
++ OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
++ {"STATUS", variables_fields_info, create_schema_table, fill_status,
++ make_old_format, 0, 0, -1, 1, 0},
++ {"TABLES", tables_fields_info, create_schema_table,
++ get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
++ OPTIMIZE_I_S_TABLE},
++ {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
++ get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
++ {"TABLE_NAMES", table_names_fields_info, create_schema_table,
++ get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
++ {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
++ fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
++ {"TRIGGERS", triggers_fields_info, create_schema_table,
++ get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
++ OPEN_TABLE_ONLY},
++ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
++ fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
++ {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
++ make_old_format, 0, 0, -1, 1, 0},
++ {"VIEWS", view_fields_info, create_schema_table,
++ get_all_tables, 0, get_schema_views_record, 1, 2, 0,
++ OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
++ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
++};
++
++
++#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
++template class List_iterator_fast<char>;
++template class List<char>;
++#endif
++
++int initialize_schema_table(st_plugin_int *plugin)
++{
++ ST_SCHEMA_TABLE *schema_table;
++ DBUG_ENTER("initialize_schema_table");
++
++ if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
++ MYF(MY_WME | MY_ZEROFILL))))
++ DBUG_RETURN(1);
++ /* Historical Requirement */
++ plugin->data= schema_table; // shortcut for the future
++ if (plugin->plugin->init)
++ {
++ schema_table->create_table= create_schema_table;
++ schema_table->old_format= make_old_format;
++ schema_table->idx_field1= -1,
++ schema_table->idx_field2= -1;
++
++ /* Make the name available to the init() function. */
++ schema_table->table_name= plugin->name.str;
++
++ if (plugin->plugin->init(schema_table))
++ {
++ sql_print_error("Plugin '%s' init function returned error.",
++ plugin->name.str);
++ plugin->data= NULL;
++ my_free(schema_table, MYF(0));
++ DBUG_RETURN(1);
++ }
++
++ /* Make sure the plugin name is not set inside the init() function. */
++ schema_table->table_name= plugin->name.str;
++ }
++ DBUG_RETURN(0);
++}
++
++int finalize_schema_table(st_plugin_int *plugin)
++{
++ ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
++ DBUG_ENTER("finalize_schema_table");
++
++ if (schema_table)
++ {
++ if (plugin->plugin->deinit)
++ {
++ DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
++ if (plugin->plugin->deinit(NULL))
++ {
++ DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
++ plugin->name.str));
++ }
++ }
++ my_free(schema_table, MYF(0));
++ }
++ DBUG_RETURN(0);
++}
++
++
++/**
++ Output trigger information (SHOW CREATE TRIGGER) to the client.
++
++ @param thd Thread context.
++ @param triggers List of triggers for the table.
++ @param trigger_idx Index of the trigger to dump.
++
++ @return Operation status
++ @retval TRUE Error.
++ @retval FALSE Success.
++*/
++
++static bool show_create_trigger_impl(THD *thd,
++ Table_triggers_list *triggers,
++ int trigger_idx)
++{
++ int ret_code;
++
++ Protocol *p= thd->protocol;
++ List<Item> fields;
++
++ LEX_STRING trg_name;
++ ulonglong trg_sql_mode;
++ LEX_STRING trg_sql_mode_str;
++ LEX_STRING trg_sql_original_stmt;
++ LEX_STRING trg_client_cs_name;
++ LEX_STRING trg_connection_cl_name;
++ LEX_STRING trg_db_cl_name;
++
++ CHARSET_INFO *trg_client_cs;
++
++ /*
++ TODO: Check privileges here. This functionality will be added by
++ implementation of the following WL items:
++ - WL#2227: New privileges for new objects
++ - WL#3482: Protect SHOW CREATE PROCEDURE | FUNCTION | VIEW | TRIGGER
++ properly
++
++ SHOW TRIGGERS and I_S.TRIGGERS will be affected too.
++ */
++
++ /* Prepare trigger "object". */
++
++ triggers->get_trigger_info(thd,
++ trigger_idx,
++ &trg_name,
++ &trg_sql_mode,
++ &trg_sql_original_stmt,
++ &trg_client_cs_name,
++ &trg_connection_cl_name,
++ &trg_db_cl_name);
++
++ sys_var_thd_sql_mode::symbolic_mode_representation(thd,
++ trg_sql_mode,
++ &trg_sql_mode_str);
++
++ /* Resolve trigger client character set. */
++
++ if (resolve_charset(trg_client_cs_name.str, NULL, &trg_client_cs))
++ return TRUE;
++
++ /* Send header. */
++
++ fields.push_back(new Item_empty_string("Trigger", NAME_LEN));
++ fields.push_back(new Item_empty_string("sql_mode", trg_sql_mode_str.length));
++
++ {
++ /*
++ NOTE: SQL statement field must be not less than 1024 in order not to
++ confuse old clients.
++ */
++
++ Item_empty_string *stmt_fld=
++ new Item_empty_string("SQL Original Statement",
++ max(trg_sql_original_stmt.length, 1024));
++
++ stmt_fld->maybe_null= TRUE;
++
++ fields.push_back(stmt_fld);
++ }
++
++ fields.push_back(new Item_empty_string("character_set_client",
++ MY_CS_NAME_SIZE));
++
++ fields.push_back(new Item_empty_string("collation_connection",
++ MY_CS_NAME_SIZE));
++
++ fields.push_back(new Item_empty_string("Database Collation",
++ MY_CS_NAME_SIZE));
++
++ if (p->send_fields(&fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ return TRUE;
++
++ /* Send data. */
++
++ p->prepare_for_resend();
++
++ p->store(trg_name.str,
++ trg_name.length,
++ system_charset_info);
++
++ p->store(trg_sql_mode_str.str,
++ trg_sql_mode_str.length,
++ system_charset_info);
++
++ p->store(trg_sql_original_stmt.str,
++ trg_sql_original_stmt.length,
++ trg_client_cs);
++
++ p->store(trg_client_cs_name.str,
++ trg_client_cs_name.length,
++ system_charset_info);
++
++ p->store(trg_connection_cl_name.str,
++ trg_connection_cl_name.length,
++ system_charset_info);
++
++ p->store(trg_db_cl_name.str,
++ trg_db_cl_name.length,
++ system_charset_info);
++
++ ret_code= p->write();
++
++ if (!ret_code)
++ my_eof(thd);
++
++ return ret_code != 0;
++}
++
++
++/**
++ Read TRN and TRG files to obtain base table name for the specified
++ trigger name and construct TABE_LIST object for the base table.
++
++ @param thd Thread context.
++ @param trg_name Trigger name.
++
++ @return TABLE_LIST object corresponding to the base table.
++
++ TODO: This function is a copy&paste from add_table_to_list() and
++ sp_add_to_query_tables(). The problem is that in order to be compatible
++ with Stored Programs (Prepared Statements), we should not touch thd->lex.
++ The "source" functions also add created TABLE_LIST object to the
++ thd->lex->query_tables.
++
++ The plan to eliminate this copy&paste is to:
++
++ - get rid of sp_add_to_query_tables() and use Lex::add_table_to_list().
++ Only add_table_to_list() must be used to add tables from the parser
++ into Lex::query_tables list.
++
++ - do not update Lex::query_tables in add_table_to_list().
++*/
++
++static TABLE_LIST *get_trigger_table_impl(
++ THD *thd,
++ const sp_name *trg_name)
++{
++ char trn_path_buff[FN_REFLEN];
++
++ LEX_STRING trn_path= { trn_path_buff, 0 };
++ LEX_STRING tbl_name;
++
++ build_trn_path(thd, trg_name, &trn_path);
++
++ if (check_trn_exists(&trn_path))
++ {
++ my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
++ return NULL;
++ }
++
++ if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
++ return NULL;
++
++ /* We need to reset statement table list to be PS/SP friendly. */
++
++ TABLE_LIST *table;
++
++ if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
++ {
++ my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
++ return NULL;
++ }
++
++ table->db_length= trg_name->m_db.length;
++ table->db= thd->strmake(trg_name->m_db.str, trg_name->m_db.length);
++
++ table->table_name_length= tbl_name.length;
++ table->table_name= thd->strmake(tbl_name.str, tbl_name.length);
++
++ table->alias= thd->strmake(tbl_name.str, tbl_name.length);
++
++ table->lock_type= TL_IGNORE;
++ table->cacheable_table= 0;
++
++ return table;
++}
++
++/**
++ Read TRN and TRG files to obtain base table name for the specified
++ trigger name and construct TABE_LIST object for the base table. Acquire
++ LOCK_open when doing this.
++
++ @param thd Thread context.
++ @param trg_name Trigger name.
++
++ @return TABLE_LIST object corresponding to the base table.
++*/
++
++static TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
++{
++ /* Acquire LOCK_open (stop the server). */
++
++ pthread_mutex_lock(&LOCK_open);
++
++ /*
++ Load base table name from the TRN-file and create TABLE_LIST object.
++ */
++
++ TABLE_LIST *lst= get_trigger_table_impl(thd, trg_name);
++
++ /* Release LOCK_open (continue the server). */
++
++ pthread_mutex_unlock(&LOCK_open);
++
++ /* That's it. */
++
++ return lst;
++}
++
++
++/**
++ SHOW CREATE TRIGGER high-level implementation.
++
++ @param thd Thread context.
++ @param trg_name Trigger name.
++
++ @return Operation status
++ @retval TRUE Error.
++ @retval FALSE Success.
++*/
++
++bool show_create_trigger(THD *thd, const sp_name *trg_name)
++{
++ TABLE_LIST *lst= get_trigger_table(thd, trg_name);
++
++ if (!lst)
++ return TRUE;
++
++ if (check_table_access(thd, TRIGGER_ACL, lst, 1, TRUE))
++ {
++ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "TRIGGER");
++ return TRUE;
++ }
++
++ /*
++ Open the table by name in order to load Table_triggers_list object.
++
++ NOTE: there is race condition here -- the table can be dropped after
++ LOCK_open is released. It will be fixed later by introducing
++ acquire-shared-table-name-lock functionality.
++ */
++
++ uint num_tables; /* NOTE: unused, only to pass to open_tables(). */
++
++ if (open_tables(thd, &lst, &num_tables, 0))
++ {
++ my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0),
++ (const char *) trg_name->m_db.str,
++ (const char *) lst->table_name);
++
++ return TRUE;
++
++ /* Perform closing actions and return error status. */
++ }
++
++ Table_triggers_list *triggers= lst->table->triggers;
++
++ if (!triggers)
++ {
++ my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
++ return TRUE;
++ }
++
++ int trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name);
++
++ if (trigger_idx < 0)
++ {
++ my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
++ (const char *) trg_name->m_db.str,
++ (const char *) lst->table_name);
++
++ return TRUE;
++ }
++
++ return show_create_trigger_impl(thd, triggers, trigger_idx);
++
++ /*
++ NOTE: if show_create_trigger_impl() failed, that means we could not
++ send data to the client. In this case we simply raise the error
++ status and client connection will be closed.
++ */
++}
+diff -urN mysql-old/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql-old/sql/sql_string.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/sql_string.cc 2011-05-10 17:56:01.616682376 +0000
+@@ -695,7 +695,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -781,7 +781,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -798,7 +798,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -999,7 +999,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1185,7 +1185,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -urN mysql-old/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql-old/sql/sql_table.cc 2011-05-10 17:45:45.626682377 +0000
++++ mysql/sql/sql_table.cc 2011-05-10 17:56:01.620015709 +0000
+@@ -3274,7 +3274,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -urN mysql-old/sql/sql_table.cc.orig mysql/sql/sql_table.cc.orig
+--- mysql-old/sql/sql_table.cc.orig 1969-12-31 23:00:00.000000000 -0100
++++ mysql/sql/sql_table.cc.orig 2011-04-12 12:11:35.000000000 +0000
+@@ -0,0 +1,8126 @@
++/* Copyright 2000-2011, Oracle and/or its affiliates. All rights reserved.
++
++ This program is free software; you can redistribute it and/or modify
++ it under the terms of the GNU General Public License as published by
++ the Free Software Foundation; version 2 of the License.
++
++ This program is distributed in the hope that it will be useful,
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ GNU General Public License for more details.
++
++ You should have received a copy of the GNU General Public License
++ along with this program; if not, write to the Free Software
++ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ MA 02110-1301 USA */
++
++/* drop and alter of tables */
++
++#include "mysql_priv.h"
++#include <hash.h>
++#include <myisam.h>
++#include <my_dir.h>
++#include "sp_head.h"
++#include "sql_trigger.h"
++#include "sql_show.h"
++#include "debug_sync.h"
++
++#ifdef __WIN__
++#include <io.h>
++#endif
++
++int creating_table= 0; // How many mysql_create_table are running
++
++const char *primary_key_name="PRIMARY";
++
++static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
++static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
++static int copy_data_between_tables(TABLE *from,TABLE *to,
++ List<Create_field> &create, bool ignore,
++ uint order_num, ORDER *order,
++ ha_rows *copied,ha_rows *deleted,
++ enum enum_enable_or_disable keys_onoff,
++ bool error_if_not_empty);
++
++static bool prepare_blob_field(THD *thd, Create_field *sql_field);
++static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
++static int
++mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
++ Alter_info *alter_info,
++ bool tmp_table,
++ uint *db_options,
++ handler *file, KEY **key_info_buffer,
++ uint *key_count, int select_field_count);
++static bool
++mysql_prepare_alter_table(THD *thd, TABLE *table,
++ HA_CREATE_INFO *create_info,
++ Alter_info *alter_info);
++
++#ifndef DBUG_OFF
++
++/* Wait until we get a 'mysql_kill' signal */
++
++static void wait_for_kill_signal(THD *thd)
++{
++ while (thd->killed == 0)
++ sleep(1);
++ // Reset signal and continue as if nothing happend
++ thd->killed= THD::NOT_KILLED;
++}
++#endif
++
++
++/**
++ @brief Helper function for explain_filename
++ @param thd Thread handle
++ @param to_p Explained name in system_charset_info
++ @param end_p End of the to_p buffer
++ @param name Name to be converted
++ @param name_len Length of the name, in bytes
++*/
++static char* add_identifier(THD* thd, char *to_p, const char * end_p,
++ const char* name, uint name_len)
++{
++ uint res;
++ uint errors;
++ const char *conv_name;
++ char tmp_name[FN_REFLEN];
++ char conv_string[FN_REFLEN];
++ int quote;
++
++ DBUG_ENTER("add_identifier");
++ if (!name[name_len])
++ conv_name= name;
++ else
++ {
++ strnmov(tmp_name, name, name_len);
++ tmp_name[name_len]= 0;
++ conv_name= tmp_name;
++ }
++ res= strconvert(&my_charset_filename, conv_name, system_charset_info,
++ conv_string, FN_REFLEN, &errors);
++ if (!res || errors)
++ {
++ DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors));
++ conv_name= name;
++ }
++ else
++ {
++ DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string));
++ conv_name= conv_string;
++ }
++
++ quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"';
++
++ if (quote != EOF && (end_p - to_p > 2))
++ {
++ *(to_p++)= (char) quote;
++ while (*conv_name && (end_p - to_p - 1) > 0)
++ {
++ uint length= my_mbcharlen(system_charset_info, *conv_name);
++ if (!length)
++ length= 1;
++ if (length == 1 && *conv_name == (char) quote)
++ {
++ if ((end_p - to_p) < 3)
++ break;
++ *(to_p++)= (char) quote;
++ *(to_p++)= *(conv_name++);
++ }
++ else if (((long) length) < (end_p - to_p))
++ {
++ to_p= strnmov(to_p, conv_name, length);
++ conv_name+= length;
++ }
++ else
++ break; /* string already filled */
++ }
++ if (end_p > to_p) {
++ *(to_p++)= (char) quote;
++ if (end_p > to_p)
++ *to_p= 0; /* terminate by NUL, but do not include it in the count */
++ }
++ }
++ else
++ to_p= strnmov(to_p, conv_name, end_p - to_p);
++ DBUG_RETURN(to_p);
++}
++
++
++/**
++ @brief Explain a path name by split it to database, table etc.
++
++ @details Break down the path name to its logic parts
++ (database, table, partition, subpartition).
++ filename_to_tablename cannot be used on partitions, due to the #P# part.
++ There can be up to 6 '#', #P# for partition, #SP# for subpartition
++ and #TMP# or #REN# for temporary or renamed partitions.
++ This should be used when something should be presented to a user in a
++ diagnostic, error etc. when it would be useful to know what a particular
++ file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
++
++ @param thd Thread handle
++ @param from Path name in my_charset_filename
++ Null terminated in my_charset_filename, normalized
++ to use '/' as directory separation character.
++ @param to Explained name in system_charset_info
++ @param to_length Size of to buffer
++ @param explain_mode Requested output format.
++ EXPLAIN_ALL_VERBOSE ->
++ [Database `db`, ]Table `tbl`[,[ Temporary| Renamed]
++ Partition `p` [, Subpartition `sp`]]
++ EXPLAIN_PARTITIONS_VERBOSE -> `db`.`tbl`
++ [[ Temporary| Renamed] Partition `p`
++ [, Subpartition `sp`]]
++ EXPLAIN_PARTITIONS_AS_COMMENT -> `db`.`tbl` |*
++ [,[ Temporary| Renamed] Partition `p`
++ [, Subpartition `sp`]] *|
++ (| is really a /, and it is all in one line)
++
++ @retval Length of returned string
++*/
++
++uint explain_filename(THD* thd,
++ const char *from,
++ char *to,
++ uint to_length,
++ enum_explain_filename_mode explain_mode)
++{
++ uint res= 0;
++ char *to_p= to;
++ char *end_p= to_p + to_length;
++ const char *db_name= NULL;
++ int db_name_len= 0;
++ const char *table_name;
++ int table_name_len= 0;
++ const char *part_name= NULL;
++ int part_name_len= 0;
++ const char *subpart_name= NULL;
++ int subpart_name_len= 0;
++ enum enum_file_name_type {NORMAL, TEMP, RENAMED} name_type= NORMAL;
++ const char *tmp_p;
++ DBUG_ENTER("explain_filename");
++ DBUG_PRINT("enter", ("from '%s'", from));
++ tmp_p= from;
++ table_name= from;
++ /*
++ If '/' then take last directory part as database.
++ '/' is the directory separator, not FN_LIB_CHAR
++ */
++ while ((tmp_p= strchr(tmp_p, '/')))
++ {
++ db_name= table_name;
++ /* calculate the length */
++ db_name_len= tmp_p - db_name;
++ tmp_p++;
++ table_name= tmp_p;
++ }
++ tmp_p= table_name;
++ while (!res && (tmp_p= strchr(tmp_p, '#')))
++ {
++ tmp_p++;
++ switch (tmp_p[0]) {
++ case 'P':
++ case 'p':
++ if (tmp_p[1] == '#')
++ part_name= tmp_p + 2;
++ else
++ res= 1;
++ tmp_p+= 2;
++ break;
++ case 'S':
++ case 's':
++ if ((tmp_p[1] == 'P' || tmp_p[1] == 'p') && tmp_p[2] == '#')
++ {
++ part_name_len= tmp_p - part_name - 1;
++ subpart_name= tmp_p + 3;
++ }
++ else
++ res= 2;
++ tmp_p+= 3;
++ break;
++ case 'T':
++ case 't':
++ if ((tmp_p[1] == 'M' || tmp_p[1] == 'm') &&
++ (tmp_p[2] == 'P' || tmp_p[2] == 'p') &&
++ tmp_p[3] == '#' && !tmp_p[4])
++ name_type= TEMP;
++ else
++ res= 3;
++ tmp_p+= 4;
++ break;
++ case 'R':
++ case 'r':
++ if ((tmp_p[1] == 'E' || tmp_p[1] == 'e') &&
++ (tmp_p[2] == 'N' || tmp_p[2] == 'n') &&
++ tmp_p[3] == '#' && !tmp_p[4])
++ name_type= RENAMED;
++ else
++ res= 4;
++ tmp_p+= 4;
++ break;
++ default:
++ res= 5;
++ }
++ }
++ if (res)
++ {
++ /* Better to give something back if we fail parsing, than nothing at all */
++ DBUG_PRINT("info", ("Error in explain_filename: %u", res));
++ sql_print_warning("Invalid (old?) table or database name '%s'", from);
++ DBUG_RETURN(my_snprintf(to, to_length,
++ "<result %u when explaining filename '%s'>",
++ res, from));
++ }
++ if (part_name)
++ {
++ table_name_len= part_name - table_name - 3;
++ if (subpart_name)
++ subpart_name_len= strlen(subpart_name);
++ else
++ part_name_len= strlen(part_name);
++ if (name_type != NORMAL)
++ {
++ if (subpart_name)
++ subpart_name_len-= 5;
++ else
++ part_name_len-= 5;
++ }
++ }
++ else
++ table_name_len= strlen(table_name);
++ if (db_name)
++ {
++ if (explain_mode == EXPLAIN_ALL_VERBOSE)
++ {
++ to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
++ *(to_p++)= ' ';
++ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
++ to_p= strnmov(to_p, ", ", end_p - to_p);
++ }
++ else
++ {
++ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
++ to_p= strnmov(to_p, ".", end_p - to_p);
++ }
++ }
++ if (explain_mode == EXPLAIN_ALL_VERBOSE)
++ {
++ to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
++ *(to_p++)= ' ';
++ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
++ }
++ else
++ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
++ if (part_name)
++ {
++ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
++ to_p= strnmov(to_p, " /* ", end_p - to_p);
++ else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
++ to_p= strnmov(to_p, " ", end_p - to_p);
++ else
++ to_p= strnmov(to_p, ", ", end_p - to_p);
++ if (name_type != NORMAL)
++ {
++ if (name_type == TEMP)
++ to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
++ else
++ to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
++ to_p= strnmov(to_p, " ", end_p - to_p);
++ }
++ to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
++ *(to_p++)= ' ';
++ to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
++ if (subpart_name)
++ {
++ to_p= strnmov(to_p, ", ", end_p - to_p);
++ to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
++ *(to_p++)= ' ';
++ to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
++ }
++ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
++ to_p= strnmov(to_p, " */", end_p - to_p);
++ }
++ DBUG_PRINT("exit", ("to '%s'", to));
++ DBUG_RETURN(to_p - to);
++}
++
++
++/*
++ Translate a file name to a table name (WL #1324).
++
++ SYNOPSIS
++ filename_to_tablename()
++ from The file name in my_charset_filename.
++ to OUT The table name in system_charset_info.
++ to_length The size of the table name buffer.
++
++ RETURN
++ Table name length.
++*/
++
++uint filename_to_tablename(const char *from, char *to, uint to_length)
++{
++ uint errors;
++ size_t res;
++ DBUG_ENTER("filename_to_tablename");
++ DBUG_PRINT("enter", ("from '%s'", from));
++
++ if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
++ {
++ /* Temporary table name. */
++ res= (strnmov(to, from, to_length) - to);
++ }
++ else
++ {
++ res= strconvert(&my_charset_filename, from,
++ system_charset_info, to, to_length, &errors);
++ if (errors) // Old 5.0 name
++ {
++ res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) -
++ to);
++ sql_print_error("Invalid (old?) table or database name '%s'", from);
++ /*
++ TODO: add a stored procedure for fix table and database names,
++ and mention its name in error log.
++ */
++ }
++ }
++
++ DBUG_PRINT("exit", ("to '%s'", to));
++ DBUG_RETURN(res);
++}
++
++
++/**
++ Check if given string begins with "#mysql50#" prefix
++
++ @param name string to check cut
++
++ @retval
++ FALSE no prefix found
++ @retval
++ TRUE prefix found
++*/
++
++bool check_mysql50_prefix(const char *name)
++{
++ return (name[0] == '#' &&
++ !strncmp(name, MYSQL50_TABLE_NAME_PREFIX,
++ MYSQL50_TABLE_NAME_PREFIX_LENGTH));
++}
++
++
++/**
++ Check if given string begins with "#mysql50#" prefix, cut it if so.
++
++ @param from string to check and cut
++ @param to[out] buffer for result string
++ @param to_length its size
++
++ @retval
++ 0 no prefix found
++ @retval
++ non-0 result string length
++*/
++
++uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
++{
++ if (check_mysql50_prefix(from))
++ return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
++ to_length - 1) - to);
++ return 0;
++}
++
++
++/*
++ Translate a table name to a file name (WL #1324).
++
++ SYNOPSIS
++ tablename_to_filename()
++ from The table name in system_charset_info.
++ to OUT The file name in my_charset_filename.
++ to_length The size of the file name buffer.
++
++ RETURN
++ File name length.
++*/
++
++uint tablename_to_filename(const char *from, char *to, uint to_length)
++{
++ uint errors, length;
++ DBUG_ENTER("tablename_to_filename");
++ DBUG_PRINT("enter", ("from '%s'", from));
++
++ if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
++ {
++ /*
++ Check if the name supplied is a valid mysql 5.0 name and
++ make the name a zero length string if it's not.
++ Note that just returning zero length is not enough :
++ a lot of places don't check the return value and expect
++ a zero terminated string.
++ */
++ if (check_table_name(to, length, TRUE))
++ {
++ to[0]= 0;
++ length= 0;
++ }
++ DBUG_RETURN(length);
++ }
++ length= strconvert(system_charset_info, from,
++ &my_charset_filename, to, to_length, &errors);
++ if (check_if_legal_tablename(to) &&
++ length + 4 < to_length)
++ {
++ memcpy(to + length, "@@@", 4);
++ length+= 3;
++ }
++ DBUG_PRINT("exit", ("to '%s'", to));
++ DBUG_RETURN(length);
++}
++
++
++/*
++ Creates path to a file: mysql_data_dir/db/table.ext
++
++ SYNOPSIS
++ build_table_filename()
++ buff Where to write result in my_charset_filename.
++ This may be the same as table_name.
++ bufflen buff size
++ db Database name in system_charset_info.
++ table_name Table name in system_charset_info.
++ ext File extension.
++ flags FN_FROM_IS_TMP or FN_TO_IS_TMP or FN_IS_TMP
++ table_name is temporary, do not change.
++
++ NOTES
++
++ Uses database and table name, and extension to create
++ a file name in mysql_data_dir. Database and table
++ names are converted from system_charset_info into "fscs".
++ Unless flags indicate a temporary table name.
++ 'db' is always converted.
++ 'ext' is not converted.
++
++ The conversion suppression is required for ALTER TABLE. This
++ statement creates intermediate tables. These are regular
++ (non-temporary) tables with a temporary name. Their path names must
++ be derivable from the table name. So we cannot use
++ build_tmptable_filename() for them.
++
++ RETURN
++ path length
++*/
++
++uint build_table_filename(char *buff, size_t bufflen, const char *db,
++ const char *table_name, const char *ext, uint flags)
++{
++ char dbbuff[FN_REFLEN];
++ char tbbuff[FN_REFLEN];
++ DBUG_ENTER("build_table_filename");
++ DBUG_PRINT("enter", ("db: '%s' table_name: '%s' ext: '%s' flags: %x",
++ db, table_name, ext, flags));
++
++ if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
++ strnmov(tbbuff, table_name, sizeof(tbbuff));
++ else
++ VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
++
++ VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
++
++ char *end = buff + bufflen;
++ /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
++ char *pos = strnmov(buff, mysql_data_home, bufflen);
++ size_t rootdir_len= strlen(FN_ROOTDIR);
++ if (pos - rootdir_len >= buff &&
++ memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
++ pos= strnmov(pos, FN_ROOTDIR, end - pos);
++ pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
++#ifdef USE_SYMDIR
++ unpack_dirname(buff, buff);
++ pos= strend(buff);
++#endif
++ pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
++
++ DBUG_PRINT("exit", ("buff: '%s'", buff));
++ DBUG_RETURN(pos - buff);
++}
++
++
++/*
++ Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
++
++ SYNOPSIS
++ build_tmptable_filename()
++ thd The thread handle.
++ buff Where to write result in my_charset_filename.
++ bufflen buff size
++
++ NOTES
++
++ Uses current_pid, thread_id, and tmp_table counter to create
++ a file name in mysql_tmpdir.
++
++ RETURN
++ path length
++*/
++
++uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
++{
++ DBUG_ENTER("build_tmptable_filename");
++
++ char *p= strnmov(buff, mysql_tmpdir, bufflen);
++ my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
++ tmp_file_prefix, current_pid,
++ thd->thread_id, thd->tmp_table++, reg_ext);
++
++ if (lower_case_table_names)
++ {
++ /* Convert all except tmpdir to lower case */
++ my_casedn_str(files_charset_info, p);
++ }
++
++ size_t length= unpack_filename(buff, buff);
++ DBUG_PRINT("exit", ("buff: '%s'", buff));
++ DBUG_RETURN(length);
++}
++
++/*
++--------------------------------------------------------------------------
++
++ MODULE: DDL log
++ -----------------
++
++ This module is used to ensure that we can recover from crashes that occur
++ in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
++ We need to ensure that both t1 and t2 are dropped and not only t1 and
++ also that each table drop is entirely done and not "half-baked".
++
++ To support this we create log entries for each meta-data statement in the
++ ddl log while we are executing. These entries are dropped when the
++ operation is completed.
++
++ At recovery those entries that were not completed will be executed.
++
++ There is only one ddl log in the system and it is protected by a mutex
++ and there is a global struct that contains information about its current
++ state.
++
++ History:
++ First version written in 2006 by Mikael Ronstrom
++--------------------------------------------------------------------------
++*/
++
++
++struct st_global_ddl_log
++{
++ /*
++ We need to adjust buffer size to be able to handle downgrades/upgrades
++ where IO_SIZE has changed. We'll set the buffer size such that we can
++ handle that the buffer size was upto 4 times bigger in the version
++ that wrote the DDL log.
++ */
++ char file_entry_buf[4*IO_SIZE];
++ char file_name_str[FN_REFLEN];
++ char *file_name;
++ DDL_LOG_MEMORY_ENTRY *first_free;
++ DDL_LOG_MEMORY_ENTRY *first_used;
++ uint num_entries;
++ File file_id;
++ uint name_len;
++ uint io_size;
++ bool inited;
++ bool do_release;
++ bool recovery_phase;
++ st_global_ddl_log() : inited(false), do_release(false) {}
++};
++
++st_global_ddl_log global_ddl_log;
++
++pthread_mutex_t LOCK_gdl;
++
++#define DDL_LOG_ENTRY_TYPE_POS 0
++#define DDL_LOG_ACTION_TYPE_POS 1
++#define DDL_LOG_PHASE_POS 2
++#define DDL_LOG_NEXT_ENTRY_POS 4
++#define DDL_LOG_NAME_POS 8
++
++#define DDL_LOG_NUM_ENTRY_POS 0
++#define DDL_LOG_NAME_LEN_POS 4
++#define DDL_LOG_IO_SIZE_POS 8
++
++/*
++ Read one entry from ddl log file
++ SYNOPSIS
++ read_ddl_log_file_entry()
++ entry_no Entry number to read
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static bool read_ddl_log_file_entry(uint entry_no)
++{
++ bool error= FALSE;
++ File file_id= global_ddl_log.file_id;
++ uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
++ uint io_size= global_ddl_log.io_size;
++ DBUG_ENTER("read_ddl_log_file_entry");
++
++ if (my_pread(file_id, file_entry_buf, io_size, io_size * entry_no,
++ MYF(MY_WME)) != io_size)
++ error= TRUE;
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Write one entry from ddl log file
++ SYNOPSIS
++ write_ddl_log_file_entry()
++ entry_no Entry number to write
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static bool write_ddl_log_file_entry(uint entry_no)
++{
++ bool error= FALSE;
++ File file_id= global_ddl_log.file_id;
++ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
++ DBUG_ENTER("write_ddl_log_file_entry");
++
++ if (my_pwrite(file_id, (uchar*)file_entry_buf,
++ IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE)
++ error= TRUE;
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Write ddl log header
++ SYNOPSIS
++ write_ddl_log_header()
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static bool write_ddl_log_header()
++{
++ uint16 const_var;
++ bool error= FALSE;
++ DBUG_ENTER("write_ddl_log_header");
++
++ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
++ global_ddl_log.num_entries);
++ const_var= FN_LEN;
++ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
++ (ulong) const_var);
++ const_var= IO_SIZE;
++ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
++ (ulong) const_var);
++ if (write_ddl_log_file_entry(0UL))
++ {
++ sql_print_error("Error writing ddl log header");
++ DBUG_RETURN(TRUE);
++ }
++ VOID(sync_ddl_log());
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Create ddl log file name
++ SYNOPSIS
++ create_ddl_log_file_name()
++ file_name Filename setup
++ RETURN VALUES
++ NONE
++*/
++
++static inline void create_ddl_log_file_name(char *file_name)
++{
++ strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
++}
++
++
++/*
++ Read header of ddl log file
++ SYNOPSIS
++ read_ddl_log_header()
++ RETURN VALUES
++ > 0 Last entry in ddl log
++ 0 No entries in ddl log
++ DESCRIPTION
++ When we read the ddl log header we get information about maximum sizes
++ of names in the ddl log and we also get information about the number
++ of entries in the ddl log.
++*/
++
++static uint read_ddl_log_header()
++{
++ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
++ char file_name[FN_REFLEN];
++ uint entry_no;
++ bool successful_open= FALSE;
++ DBUG_ENTER("read_ddl_log_header");
++
++ create_ddl_log_file_name(file_name);
++ if ((global_ddl_log.file_id= my_open(file_name,
++ O_RDWR | O_BINARY, MYF(0))) >= 0)
++ {
++ if (read_ddl_log_file_entry(0UL))
++ {
++ /* Write message into error log */
++ sql_print_error("Failed to read ddl log file in recovery");
++ }
++ else
++ successful_open= TRUE;
++ }
++ if (successful_open)
++ {
++ entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
++ global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
++ global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
++ DBUG_ASSERT(global_ddl_log.io_size <=
++ sizeof(global_ddl_log.file_entry_buf));
++ }
++ else
++ {
++ entry_no= 0;
++ }
++ global_ddl_log.first_free= NULL;
++ global_ddl_log.first_used= NULL;
++ global_ddl_log.num_entries= 0;
++ VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
++ global_ddl_log.do_release= true;
++ DBUG_RETURN(entry_no);
++}
++
++
++/*
++ Read a ddl log entry
++ SYNOPSIS
++ read_ddl_log_entry()
++ read_entry Number of entry to read
++ out:entry_info Information from entry
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++ DESCRIPTION
++ Read a specified entry in the ddl log
++*/
++
++bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
++{
++ char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
++ uint inx;
++ uchar single_char;
++ DBUG_ENTER("read_ddl_log_entry");
++
++ if (read_ddl_log_file_entry(read_entry))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ ddl_log_entry->entry_pos= read_entry;
++ single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
++ ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
++ single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
++ ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
++ ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
++ ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
++ ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
++ inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
++ ddl_log_entry->from_name= &file_entry_buf[inx];
++ inx+= global_ddl_log.name_len;
++ ddl_log_entry->handler_name= &file_entry_buf[inx];
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ Initialise ddl log
++ SYNOPSIS
++ init_ddl_log()
++
++ DESCRIPTION
++ Write the header of the ddl log file and length of names. Also set
++ number of entries to zero.
++
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static bool init_ddl_log()
++{
++ char file_name[FN_REFLEN];
++ DBUG_ENTER("init_ddl_log");
++
++ if (global_ddl_log.inited)
++ goto end;
++
++ global_ddl_log.io_size= IO_SIZE;
++ global_ddl_log.name_len= FN_LEN;
++ create_ddl_log_file_name(file_name);
++ if ((global_ddl_log.file_id= my_create(file_name,
++ CREATE_MODE,
++ O_RDWR | O_TRUNC | O_BINARY,
++ MYF(MY_WME))) < 0)
++ {
++ /* Couldn't create ddl log file, this is serious error */
++ sql_print_error("Failed to open ddl log file");
++ DBUG_RETURN(TRUE);
++ }
++ global_ddl_log.inited= TRUE;
++ if (write_ddl_log_header())
++ {
++ VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
++ global_ddl_log.inited= FALSE;
++ DBUG_RETURN(TRUE);
++ }
++
++end:
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ Execute one action in a ddl log entry
++ SYNOPSIS
++ execute_ddl_log_action()
++ ddl_log_entry Information in action entry to execute
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
++{
++ bool frm_action= FALSE;
++ LEX_STRING handler_name;
++ handler *file= NULL;
++ MEM_ROOT mem_root;
++ int error= TRUE;
++ char to_path[FN_REFLEN];
++ char from_path[FN_REFLEN];
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ char *par_ext= (char*)".par";
++#endif
++ handlerton *hton;
++ DBUG_ENTER("execute_ddl_log_action");
++
++ if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
++ {
++ DBUG_RETURN(FALSE);
++ }
++ DBUG_PRINT("ddl_log",
++ ("execute type %c next %u name '%s' from_name '%s' handler '%s'",
++ ddl_log_entry->action_type,
++ ddl_log_entry->next_entry,
++ ddl_log_entry->name,
++ ddl_log_entry->from_name,
++ ddl_log_entry->handler_name));
++ handler_name.str= (char*)ddl_log_entry->handler_name;
++ handler_name.length= strlen(ddl_log_entry->handler_name);
++ init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
++ if (!strcmp(ddl_log_entry->handler_name, reg_ext))
++ frm_action= TRUE;
++ else
++ {
++ plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
++ if (!plugin)
++ {
++ my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
++ goto error;
++ }
++ hton= plugin_data(plugin, handlerton*);
++ file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
++ if (!file)
++ {
++ mem_alloc_error(sizeof(handler));
++ goto error;
++ }
++ }
++ switch (ddl_log_entry->action_type)
++ {
++ case DDL_LOG_REPLACE_ACTION:
++ case DDL_LOG_DELETE_ACTION:
++ {
++ if (ddl_log_entry->phase == 0)
++ {
++ if (frm_action)
++ {
++ strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
++ if ((error= my_delete(to_path, MYF(MY_WME))))
++ {
++ if (my_errno != ENOENT)
++ break;
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
++ VOID(my_delete(to_path, MYF(MY_WME)));
++#endif
++ }
++ else
++ {
++ if ((error= file->ha_delete_table(ddl_log_entry->name)))
++ {
++ if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
++ break;
++ }
++ }
++ if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
++ break;
++ VOID(sync_ddl_log());
++ error= FALSE;
++ if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
++ break;
++ }
++ DBUG_ASSERT(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
++ /*
++ Fall through and perform the rename action of the replace
++ action. We have already indicated the success of the delete
++ action in the log entry by stepping up the phase.
++ */
++ }
++ case DDL_LOG_RENAME_ACTION:
++ {
++ error= TRUE;
++ if (frm_action)
++ {
++ strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
++ strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
++ if (my_rename(from_path, to_path, MYF(MY_WME)))
++ break;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
++ strxmov(from_path, ddl_log_entry->from_name, par_ext, NullS);
++ VOID(my_rename(from_path, to_path, MYF(MY_WME)));
++#endif
++ }
++ else
++ {
++ if (file->ha_rename_table(ddl_log_entry->from_name,
++ ddl_log_entry->name))
++ break;
++ }
++ if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
++ break;
++ VOID(sync_ddl_log());
++ error= FALSE;
++ break;
++ }
++ default:
++ DBUG_ASSERT(0);
++ break;
++ }
++ delete file;
++error:
++ free_root(&mem_root, MYF(0));
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Get a free entry in the ddl log
++ SYNOPSIS
++ get_free_ddl_log_entry()
++ out:active_entry A ddl log memory entry returned
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
++ bool *write_header)
++{
++ DDL_LOG_MEMORY_ENTRY *used_entry;
++ DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
++ DBUG_ENTER("get_free_ddl_log_entry");
++
++ if (global_ddl_log.first_free == NULL)
++ {
++ if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
++ sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
++ {
++ sql_print_error("Failed to allocate memory for ddl log free list");
++ DBUG_RETURN(TRUE);
++ }
++ global_ddl_log.num_entries++;
++ used_entry->entry_pos= global_ddl_log.num_entries;
++ *write_header= TRUE;
++ }
++ else
++ {
++ used_entry= global_ddl_log.first_free;
++ global_ddl_log.first_free= used_entry->next_log_entry;
++ *write_header= FALSE;
++ }
++ /*
++ Move from free list to used list
++ */
++ used_entry->next_log_entry= first_used;
++ used_entry->prev_log_entry= NULL;
++ global_ddl_log.first_used= used_entry;
++ if (first_used)
++ first_used->prev_log_entry= used_entry;
++
++ *active_entry= used_entry;
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ External interface methods for the DDL log Module
++ ---------------------------------------------------
++*/
++
++/*
++ SYNOPSIS
++ write_ddl_log_entry()
++ ddl_log_entry Information about log entry
++ out:entry_written Entry information written into
++
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++
++ DESCRIPTION
++ A careful write of the ddl log is performed to ensure that we can
++ handle crashes occurring during CREATE and ALTER TABLE processing.
++*/
++
++bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
++ DDL_LOG_MEMORY_ENTRY **active_entry)
++{
++ bool error, write_header;
++ DBUG_ENTER("write_ddl_log_entry");
++
++ if (init_ddl_log())
++ {
++ DBUG_RETURN(TRUE);
++ }
++ global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
++ (char)DDL_LOG_ENTRY_CODE;
++ global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
++ (char)ddl_log_entry->action_type;
++ global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
++ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
++ ddl_log_entry->next_entry);
++ DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN);
++ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
++ ddl_log_entry->name, FN_LEN - 1);
++ if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
++ ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
++ {
++ DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN);
++ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
++ ddl_log_entry->from_name, FN_LEN - 1);
++ }
++ else
++ global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
++ DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN);
++ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
++ ddl_log_entry->handler_name, FN_LEN - 1);
++ if (get_free_ddl_log_entry(active_entry, &write_header))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ error= FALSE;
++ DBUG_PRINT("ddl_log",
++ ("write type %c next %u name '%s' from_name '%s' handler '%s'",
++ (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
++ ddl_log_entry->next_entry,
++ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
++ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
++ + FN_LEN],
++ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
++ + (2*FN_LEN)]));
++ if (write_ddl_log_file_entry((*active_entry)->entry_pos))
++ {
++ error= TRUE;
++ sql_print_error("Failed to write entry_no = %u",
++ (*active_entry)->entry_pos);
++ }
++ if (write_header && !error)
++ {
++ VOID(sync_ddl_log());
++ if (write_ddl_log_header())
++ error= TRUE;
++ }
++ if (error)
++ release_ddl_log_memory_entry(*active_entry);
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Write final entry in the ddl log
++ SYNOPSIS
++ write_execute_ddl_log_entry()
++ first_entry First entry in linked list of entries
++ to execute, if 0 = NULL it means that
++ the entry is removed and the entries
++ are put into the free list.
++ complete Flag indicating we are simply writing
++ info about that entry has been completed
++ in:out:active_entry Entry to execute, 0 = NULL if the entry
++ is written first time and needs to be
++ returned. In this case the entry written
++ is returned in this parameter
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++
++ DESCRIPTION
++ This is the last write in the ddl log. The previous log entries have
++ already been written but not yet synched to disk.
++ We write a couple of log entries that describes action to perform.
++ This entries are set-up in a linked list, however only when a first
++ execute entry is put as the first entry these will be executed.
++ This routine writes this first
++*/
++
++bool write_execute_ddl_log_entry(uint first_entry,
++ bool complete,
++ DDL_LOG_MEMORY_ENTRY **active_entry)
++{
++ bool write_header= FALSE;
++ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
++ DBUG_ENTER("write_execute_ddl_log_entry");
++
++ if (init_ddl_log())
++ {
++ DBUG_RETURN(TRUE);
++ }
++ if (!complete)
++ {
++ /*
++ We haven't synched the log entries yet, we synch them now before
++ writing the execute entry. If complete is true we haven't written
++ any log entries before, we are only here to write the execute
++ entry to indicate it is done.
++ */
++ VOID(sync_ddl_log());
++ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
++ }
++ else
++ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
++ file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
++ file_entry_buf[DDL_LOG_PHASE_POS]= 0;
++ int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
++ file_entry_buf[DDL_LOG_NAME_POS]= 0;
++ file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
++ file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
++ if (!(*active_entry))
++ {
++ if (get_free_ddl_log_entry(active_entry, &write_header))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ }
++ if (write_ddl_log_file_entry((*active_entry)->entry_pos))
++ {
++ sql_print_error("Error writing execute entry in ddl log");
++ release_ddl_log_memory_entry(*active_entry);
++ DBUG_RETURN(TRUE);
++ }
++ VOID(sync_ddl_log());
++ if (write_header)
++ {
++ if (write_ddl_log_header())
++ {
++ release_ddl_log_memory_entry(*active_entry);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ For complex rename operations we need to deactivate individual entries.
++ SYNOPSIS
++ deactivate_ddl_log_entry()
++ entry_no Entry position of record to change
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++ DESCRIPTION
++ During replace operations where we start with an existing table called
++ t1 and a replacement table called t1#temp or something else and where
++ we want to delete t1 and rename t1#temp to t1 this is not possible to
++ do in a safe manner unless the ddl log is informed of the phases in
++ the change.
++
++ Delete actions are 1-phase actions that can be ignored immediately after
++ being executed.
++ Rename actions from x to y is also a 1-phase action since there is no
++ interaction with any other handlers named x and y.
++ Replace action where drop y and x -> y happens needs to be a two-phase
++ action. Thus the first phase will drop y and the second phase will
++ rename x -> y.
++*/
++
++bool deactivate_ddl_log_entry(uint entry_no)
++{
++ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
++ DBUG_ENTER("deactivate_ddl_log_entry");
++
++ if (!read_ddl_log_file_entry(entry_no))
++ {
++ if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
++ {
++ if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
++ file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
++ (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
++ file_entry_buf[DDL_LOG_PHASE_POS] == 1))
++ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
++ else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
++ {
++ DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
++ file_entry_buf[DDL_LOG_PHASE_POS]= 1;
++ }
++ else
++ {
++ DBUG_ASSERT(0);
++ }
++ if (write_ddl_log_file_entry(entry_no))
++ {
++ sql_print_error("Error in deactivating log entry. Position = %u",
++ entry_no);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++ else
++ {
++ sql_print_error("Failed in reading entry before deactivating it");
++ DBUG_RETURN(TRUE);
++ }
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ Sync ddl log file
++ SYNOPSIS
++ sync_ddl_log()
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++bool sync_ddl_log()
++{
++ bool error= FALSE;
++ DBUG_ENTER("sync_ddl_log");
++
++ if ((!global_ddl_log.recovery_phase) &&
++ init_ddl_log())
++ {
++ DBUG_RETURN(TRUE);
++ }
++ if (my_sync(global_ddl_log.file_id, MYF(0)))
++ {
++ /* Write to error log */
++ sql_print_error("Failed to sync ddl log");
++ error= TRUE;
++ }
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Release a log memory entry
++ SYNOPSIS
++ release_ddl_log_memory_entry()
++ log_memory_entry Log memory entry to release
++ RETURN VALUES
++ NONE
++*/
++
++void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
++{
++ DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
++ DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
++ DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
++ DBUG_ENTER("release_ddl_log_memory_entry");
++
++ global_ddl_log.first_free= log_entry;
++ log_entry->next_log_entry= first_free;
++
++ if (prev_log_entry)
++ prev_log_entry->next_log_entry= next_log_entry;
++ else
++ global_ddl_log.first_used= next_log_entry;
++ if (next_log_entry)
++ next_log_entry->prev_log_entry= prev_log_entry;
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Execute one entry in the ddl log. Executing an entry means executing
++ a linked list of actions.
++ SYNOPSIS
++ execute_ddl_log_entry()
++ first_entry Reference to first action in entry
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++*/
++
++bool execute_ddl_log_entry(THD *thd, uint first_entry)
++{
++ DDL_LOG_ENTRY ddl_log_entry;
++ uint read_entry= first_entry;
++ DBUG_ENTER("execute_ddl_log_entry");
++
++ pthread_mutex_lock(&LOCK_gdl);
++ do
++ {
++ if (read_ddl_log_entry(read_entry, &ddl_log_entry))
++ {
++ /* Write to error log and continue with next log entry */
++ sql_print_error("Failed to read entry = %u from ddl log",
++ read_entry);
++ break;
++ }
++ DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
++ ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
++
++ if (execute_ddl_log_action(thd, &ddl_log_entry))
++ {
++ /* Write to error log and continue with next log entry */
++ sql_print_error("Failed to execute action for entry = %u from ddl log",
++ read_entry);
++ break;
++ }
++ read_entry= ddl_log_entry.next_entry;
++ } while (read_entry);
++ pthread_mutex_unlock(&LOCK_gdl);
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ Close the ddl log
++ SYNOPSIS
++ close_ddl_log()
++ RETURN VALUES
++ NONE
++*/
++
++static void close_ddl_log()
++{
++ DBUG_ENTER("close_ddl_log");
++ if (global_ddl_log.file_id >= 0)
++ {
++ VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
++ global_ddl_log.file_id= (File) -1;
++ }
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Execute the ddl log at recovery of MySQL Server
++ SYNOPSIS
++ execute_ddl_log_recovery()
++ RETURN VALUES
++ NONE
++*/
++
++void execute_ddl_log_recovery()
++{
++ uint num_entries, i;
++ THD *thd;
++ DDL_LOG_ENTRY ddl_log_entry;
++ char file_name[FN_REFLEN];
++ DBUG_ENTER("execute_ddl_log_recovery");
++
++ /*
++ Initialise global_ddl_log struct
++ */
++ bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
++ global_ddl_log.inited= FALSE;
++ global_ddl_log.recovery_phase= TRUE;
++ global_ddl_log.io_size= IO_SIZE;
++ global_ddl_log.file_id= (File) -1;
++
++ /*
++ To be able to run this from boot, we allocate a temporary THD
++ */
++ if (!(thd=new THD))
++ DBUG_VOID_RETURN;
++ thd->thread_stack= (char*) &thd;
++ thd->store_globals();
++
++ num_entries= read_ddl_log_header();
++ for (i= 1; i < num_entries + 1; i++)
++ {
++ if (read_ddl_log_entry(i, &ddl_log_entry))
++ {
++ sql_print_error("Failed to read entry no = %u from ddl log",
++ i);
++ continue;
++ }
++ if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
++ {
++ if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
++ {
++ /* Real unpleasant scenario but we continue anyways. */
++ continue;
++ }
++ }
++ }
++ close_ddl_log();
++ create_ddl_log_file_name(file_name);
++ VOID(my_delete(file_name, MYF(0)));
++ global_ddl_log.recovery_phase= FALSE;
++ delete thd;
++ /* Remember that we don't have a THD */
++ my_pthread_setspecific_ptr(THR_THD, 0);
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++ Release all memory allocated to the ddl log
++ SYNOPSIS
++ release_ddl_log()
++ RETURN VALUES
++ NONE
++*/
++
++void release_ddl_log()
++{
++ DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
++ DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
++ DBUG_ENTER("release_ddl_log");
++
++ if (!global_ddl_log.do_release)
++ DBUG_VOID_RETURN;
++
++ pthread_mutex_lock(&LOCK_gdl);
++ while (used_list)
++ {
++ DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
++ my_free(used_list, MYF(0));
++ used_list= tmp;
++ }
++ while (free_list)
++ {
++ DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
++ my_free(free_list, MYF(0));
++ free_list= tmp;
++ }
++ close_ddl_log();
++ global_ddl_log.inited= 0;
++ pthread_mutex_unlock(&LOCK_gdl);
++ VOID(pthread_mutex_destroy(&LOCK_gdl));
++ global_ddl_log.do_release= false;
++ DBUG_VOID_RETURN;
++}
++
++
++/*
++---------------------------------------------------------------------------
++
++ END MODULE DDL log
++ --------------------
++
++---------------------------------------------------------------------------
++*/
++
++
++/**
++ @brief construct a temporary shadow file name.
++
++ @details Make a shadow file name used by ALTER TABLE to construct the
++ modified table (with keeping the original). The modified table is then
++ moved back as original table. The name must start with the temp file
++ prefix so it gets filtered out by table files listing routines.
++
++ @param[out] buff buffer to receive the constructed name
++ @param bufflen size of buff
++ @param lpt alter table data structure
++
++ @retval path length
++*/
++
++uint build_table_shadow_filename(char *buff, size_t bufflen,
++ ALTER_PARTITION_PARAM_TYPE *lpt)
++{
++ char tmp_name[FN_REFLEN];
++ my_snprintf (tmp_name, sizeof (tmp_name), "%s-%s", tmp_file_prefix,
++ lpt->table_name);
++ return build_table_filename(buff, bufflen, lpt->db, tmp_name, "", FN_IS_TMP);
++}
++
++
++/*
++ SYNOPSIS
++ mysql_write_frm()
++ lpt Struct carrying many parameters needed for this
++ method
++ flags Flags as defined below
++ WFRM_INITIAL_WRITE If set we need to prepare table before
++ creating the frm file
++ WFRM_INSTALL_SHADOW If set we should install the new frm
++ WFRM_KEEP_SHARE If set we know that the share is to be
++ retained and thus we should ensure share
++ object is correct, if not set we don't
++ set the new partition syntax string since
++ we know the share object is destroyed.
++ WFRM_PACK_FRM If set we should pack the frm file and delete
++ the frm file
++
++ RETURN VALUES
++ TRUE Error
++ FALSE Success
++
++ DESCRIPTION
++ A support method that creates a new frm file and in this process it
++ regenerates the partition data. It works fine also for non-partitioned
++ tables since it only handles partitioned data if it exists.
++*/
++
++bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
++{
++ /*
++ Prepare table to prepare for writing a new frm file where the
++ partitions in add/drop state have temporarily changed their state
++ We set tmp_table to avoid get errors on naming of primary key index.
++ */
++ int error= 0;
++ char path[FN_REFLEN+1];
++ char shadow_path[FN_REFLEN+1];
++ char shadow_frm_name[FN_REFLEN+1];
++ char frm_name[FN_REFLEN+1];
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ char *part_syntax_buf;
++ uint syntax_len;
++#endif
++ DBUG_ENTER("mysql_write_frm");
++
++ /*
++ Build shadow frm file name
++ */
++ build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
++ strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
++ if (flags & WFRM_WRITE_SHADOW)
++ {
++ if (mysql_prepare_create_table(lpt->thd, lpt->create_info,
++ lpt->alter_info,
++ /*tmp_table*/ 1,
++ &lpt->db_options,
++ lpt->table->file,
++ &lpt->key_info_buffer,
++ &lpt->key_count,
++ /*select_field_count*/ 0))
++ {
++ DBUG_RETURN(TRUE);
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ {
++ partition_info *part_info= lpt->table->part_info;
++ if (part_info)
++ {
++ if (!(part_syntax_buf= generate_partition_syntax(part_info,
++ &syntax_len,
++ TRUE, TRUE)))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ part_info->part_info_string= part_syntax_buf;
++ part_info->part_info_len= syntax_len;
++ }
++ }
++#endif
++ /* Write shadow frm file */
++ lpt->create_info->table_options= lpt->db_options;
++ if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db,
++ lpt->table_name, lpt->create_info,
++ lpt->alter_info->create_list, lpt->key_count,
++ lpt->key_info_buffer, lpt->table->file)) ||
++ lpt->table->file->ha_create_handler_files(shadow_path, NULL,
++ CHF_CREATE_FLAG,
++ lpt->create_info))
++ {
++ my_delete(shadow_frm_name, MYF(0));
++ error= 1;
++ goto end;
++ }
++ }
++ if (flags & WFRM_PACK_FRM)
++ {
++ /*
++ We need to pack the frm file and after packing it we delete the
++ frm file to ensure it doesn't get used. This is only used for
++ handlers that have the main version of the frm file stored in the
++ handler.
++ */
++ uchar *data;
++ size_t length;
++ if (readfrm(shadow_path, &data, &length) ||
++ packfrm(data, length, &lpt->pack_frm_data, &lpt->pack_frm_len))
++ {
++ my_free(data, MYF(MY_ALLOW_ZERO_PTR));
++ my_free(lpt->pack_frm_data, MYF(MY_ALLOW_ZERO_PTR));
++ mem_alloc_error(length);
++ error= 1;
++ goto end;
++ }
++ error= my_delete(shadow_frm_name, MYF(MY_WME));
++ }
++ if (flags & WFRM_INSTALL_SHADOW)
++ {
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ partition_info *part_info= lpt->part_info;
++#endif
++ /*
++ Build frm file name
++ */
++ build_table_filename(path, sizeof(path) - 1, lpt->db,
++ lpt->table_name, "", 0);
++ strxmov(frm_name, path, reg_ext, NullS);
++ /*
++ When we are changing to use new frm file we need to ensure that we
++ don't collide with another thread in process to open the frm file.
++ We start by deleting the .frm file and possible .par file. Then we
++ write to the DDL log that we have completed the delete phase by
++ increasing the phase of the log entry. Next step is to rename the
++ new .frm file and the new .par file to the real name. After
++ completing this we write a new phase to the log entry that will
++ deactivate it.
++ */
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (my_delete(frm_name, MYF(MY_WME)) ||
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ lpt->table->file->ha_create_handler_files(path, shadow_path,
++ CHF_DELETE_FLAG, NULL) ||
++ deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
++ (sync_ddl_log(), FALSE) ||
++#endif
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) ||
++ lpt->table->file->ha_create_handler_files(path, shadow_path,
++ CHF_RENAME_FLAG, NULL))
++#else
++ my_rename(shadow_frm_name, frm_name, MYF(MY_WME)))
++#endif
++ {
++ error= 1;
++ goto err;
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (part_info && (flags & WFRM_KEEP_SHARE))
++ {
++ TABLE_SHARE *share= lpt->table->s;
++ char *tmp_part_syntax_str;
++ if (!(part_syntax_buf= generate_partition_syntax(part_info,
++ &syntax_len,
++ TRUE, TRUE)))
++ {
++ error= 1;
++ goto err;
++ }
++ if (share->partition_info_buffer_size < syntax_len + 1)
++ {
++ share->partition_info_buffer_size= syntax_len+1;
++ if (!(tmp_part_syntax_str= (char*) strmake_root(&share->mem_root,
++ part_syntax_buf,
++ syntax_len)))
++ {
++ error= 1;
++ goto err;
++ }
++ share->partition_info= tmp_part_syntax_str;
++ }
++ else
++ memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
++ share->partition_info_len= part_info->part_info_len= syntax_len;
++ part_info->part_info_string= part_syntax_buf;
++ }
++#endif
++
++err:
++ VOID(pthread_mutex_unlock(&LOCK_open));
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
++ part_info->frm_log_entry= NULL;
++ VOID(sync_ddl_log());
++#endif
++ }
++
++end:
++ DBUG_RETURN(error);
++}
++
++
++/*
++ SYNOPSIS
++ write_bin_log()
++ thd Thread object
++ clear_error is clear_error to be called
++ query Query to log
++ query_length Length of query
++
++ RETURN VALUES
++ NONE
++
++ DESCRIPTION
++ Write the binlog if open, routine used in multiple places in this
++ file
++*/
++
++int write_bin_log(THD *thd, bool clear_error,
++ char const *query, ulong query_length)
++{
++ int error= 0;
++ if (mysql_bin_log.is_open())
++ {
++ int errcode= 0;
++ if (clear_error)
++ thd->clear_error();
++ else
++ errcode= query_error_code(thd, TRUE);
++ error= thd->binlog_query(THD::STMT_QUERY_TYPE,
++ query, query_length, FALSE, FALSE, errcode);
++ }
++ return error;
++}
++
++
++/*
++ delete (drop) tables.
++
++ SYNOPSIS
++ mysql_rm_table()
++ thd Thread handle
++ tables List of tables to delete
++ if_exists If 1, don't give error if one table doesn't exists
++
++ NOTES
++ Will delete all tables that can be deleted and give a compact error
++ messages for tables that could not be deleted.
++ If a table is in use, we will wait for all users to free the table
++ before dropping it
++
++ Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
++
++ RETURN
++ FALSE OK. In this case ok packet is sent to user
++ TRUE Error
++
++*/
++
++bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
++ my_bool drop_temporary)
++{
++ bool error= FALSE, need_start_waiters= FALSE;
++ Drop_table_error_handler err_handler(thd->get_internal_handler());
++ DBUG_ENTER("mysql_rm_table");
++
++ /* mark for close and remove all cached entries */
++
++ if (!drop_temporary)
++ {
++ if ((error= wait_if_global_read_lock(thd, 0, 1)))
++ {
++ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name);
++ DBUG_RETURN(TRUE);
++ }
++ else
++ need_start_waiters= TRUE;
++ }
++
++ /*
++ Acquire LOCK_open after wait_if_global_read_lock(). If we would hold
++ LOCK_open during wait_if_global_read_lock(), other threads could not
++ close their tables. This would make a pretty deadlock.
++ */
++ thd->push_internal_handler(&err_handler);
++ error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
++ thd->pop_internal_handler();
++
++
++ if (need_start_waiters)
++ start_waiting_global_read_lock(thd);
++
++ if (error)
++ DBUG_RETURN(TRUE);
++ my_ok(thd);
++ DBUG_RETURN(FALSE);
++}
++
++/*
++ Execute the drop of a normal or temporary table
++
++ SYNOPSIS
++ mysql_rm_table_part2()
++ thd Thread handler
++ tables Tables to drop
++ if_exists If set, don't give an error if table doesn't exists.
++ In this case we give an warning of level 'NOTE'
++ drop_temporary Only drop temporary tables
++ drop_view Allow to delete VIEW .frm
++ dont_log_query Don't write query to log files. This will also not
++ generate warnings if the handler files doesn't exists
++
++ TODO:
++ When logging to the binary log, we should log
++ tmp_tables and transactional tables as separate statements if we
++ are in a transaction; This is needed to get these tables into the
++ cached binary log that is only written on COMMIT.
++
++ The current code only writes DROP statements that only uses temporary
++ tables to the cache binary log. This should be ok on most cases, but
++ not all.
++
++ RETURN
++ 0 ok
++ 1 Error
++ -1 Thread was killed
++*/
++
++int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
++ bool drop_temporary, bool drop_view,
++ bool dont_log_query)
++{
++ TABLE_LIST *table;
++ char path[FN_REFLEN + 1], *alias;
++ uint path_length;
++ String wrong_tables;
++ int error= 0;
++ int non_temp_tables_count= 0;
++ bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
++ String built_query;
++ String built_tmp_query;
++ DBUG_ENTER("mysql_rm_table_part2");
++
++ LINT_INIT(alias);
++ LINT_INIT(path_length);
++
++ if (thd->current_stmt_binlog_row_based && !dont_log_query)
++ {
++ built_query.set_charset(system_charset_info);
++ if (if_exists)
++ built_query.append("DROP TABLE IF EXISTS ");
++ else
++ built_query.append("DROP TABLE ");
++ }
++
++ mysql_ha_rm_tables(thd, tables, FALSE);
++
++ pthread_mutex_lock(&LOCK_open);
++
++ /* Disable drop of enabled log tables, must be done before name locking */
++ for (table= tables; table; table= table->next_local)
++ {
++ if (check_if_log_table(table->db_length, table->db,
++ table->table_name_length, table->table_name, 1))
++ {
++ my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP");
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(1);
++ }
++ }
++
++ if (!drop_temporary && lock_table_names_exclusively(thd, tables))
++ {
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(1);
++ }
++
++ for (table= tables; table; table= table->next_local)
++ {
++ char *db=table->db;
++ handlerton *table_type;
++ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
++
++ DBUG_PRINT("table", ("table_l: '%s'.'%s' table: 0x%lx s: 0x%lx",
++ table->db, table->table_name, (long) table->table,
++ table->table ? (long) table->table->s : (long) -1));
++
++ error= drop_temporary_table(thd, table);
++
++ switch (error) {
++ case 0:
++ // removed temporary table
++ tmp_table_deleted= 1;
++ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
++ thd->current_stmt_binlog_row_based)
++ {
++ if (built_tmp_query.is_empty())
++ {
++ built_tmp_query.set_charset(system_charset_info);
++ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
++ }
++
++ built_tmp_query.append("`");
++ if (thd->db == NULL || strcmp(db,thd->db) != 0)
++ {
++ built_tmp_query.append(db);
++ built_tmp_query.append("`.`");
++ }
++ built_tmp_query.append(table->table_name);
++ built_tmp_query.append("`,");
++ }
++
++ continue;
++ case -1:
++ DBUG_ASSERT(thd->in_sub_stmt);
++ error= 1;
++ goto err_with_placeholders;
++ default:
++ // temporary table not found
++ error= 0;
++ }
++
++ /*
++ If row-based replication is used and the table is not a
++ temporary table, we add the table name to the drop statement
++ being built. The string always end in a comma and the comma
++ will be chopped off before being written to the binary log.
++ */
++ if (!drop_temporary && thd->current_stmt_binlog_row_based && !dont_log_query)
++ {
++ non_temp_tables_count++;
++ /*
++ Don't write the database name if it is the current one (or if
++ thd->db is NULL).
++ */
++ built_query.append("`");
++ if (thd->db == NULL || strcmp(db,thd->db) != 0)
++ {
++ built_query.append(db);
++ built_query.append("`.`");
++ }
++
++ built_query.append(table->table_name);
++ built_query.append("`,");
++ }
++
++ if (!drop_temporary)
++ {
++ TABLE *locked_table;
++ abort_locked_tables(thd, db, table->table_name);
++ remove_table_from_cache(thd, db, table->table_name,
++ RTFC_WAIT_OTHER_THREAD_FLAG |
++ RTFC_CHECK_KILLED_FLAG);
++ /*
++ If the table was used in lock tables, remember it so that
++ unlock_table_names can free it
++ */
++ if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
++ table->table= locked_table;
++
++ if (thd->killed)
++ {
++ error= -1;
++ goto err_with_placeholders;
++ }
++ alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
++ /* remove .frm file and engine files */
++ path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
++ reg_ext,
++ table->internal_tmp_table ?
++ FN_IS_TMP : 0);
++ }
++ DEBUG_SYNC(thd, "rm_table_part2_before_delete_table");
++ if (drop_temporary ||
++ ((access(path, F_OK) &&
++ ha_create_table_from_engine(thd, db, alias)) ||
++ (!drop_view &&
++ mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
++ {
++ // Table was not found on disk and table can't be created from engine
++ if (if_exists)
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
++ table->table_name);
++ else
++ error= 1;
++ }
++ else
++ {
++ char *end;
++ /*
++ Cannot use the db_type from the table, since that might have changed
++ while waiting for the exclusive name lock. We are under LOCK_open,
++ so reading from the frm-file is safe.
++ */
++ if (frm_db_type == DB_TYPE_UNKNOWN)
++ {
++ mysql_frm_type(thd, path, &frm_db_type);
++ DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path));
++ }
++ table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
++ // Remove extension for delete
++ *(end= path + path_length - reg_ext_length)= '\0';
++ DBUG_PRINT("info", ("deleting table of type %d",
++ (table_type ? table_type->db_type : 0)));
++ error= ha_delete_table(thd, table_type, path, db, table->table_name,
++ !dont_log_query);
++
++ /* No error if non existent table and 'IF EXIST' clause or view */
++ if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
++ (if_exists || table_type == NULL))
++ {
++ error= 0;
++ thd->clear_error();
++ }
++ if (error == HA_ERR_ROW_IS_REFERENCED)
++ {
++ /* the table is referenced by a foreign key constraint */
++ foreign_key_error=1;
++ }
++ if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
++ {
++ int new_error;
++ /* Delete the table definition file */
++ strmov(end,reg_ext);
++ if (!(new_error=my_delete(path,MYF(MY_WME))))
++ {
++ some_tables_deleted=1;
++ new_error= Table_triggers_list::drop_all_triggers(thd, db,
++ table->table_name);
++ }
++ error|= new_error;
++ }
++ }
++ if (error)
++ {
++ if (wrong_tables.length())
++ wrong_tables.append(',');
++ wrong_tables.append(String(table->table_name,system_charset_info));
++ }
++ DBUG_PRINT("table", ("table: 0x%lx s: 0x%lx", (long) table->table,
++ table->table ? (long) table->table->s : (long) -1));
++ }
++ /*
++ It's safe to unlock LOCK_open: we have an exclusive lock
++ on the table name.
++ */
++ pthread_mutex_unlock(&LOCK_open);
++ DEBUG_SYNC(thd, "rm_table_part2_before_binlog");
++ thd->thread_specific_used|= tmp_table_deleted;
++ error= 0;
++ if (wrong_tables.length())
++ {
++ if (!foreign_key_error)
++ my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
++ wrong_tables.c_ptr());
++ else
++ my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
++ error= 1;
++ }
++
++ if (some_tables_deleted || tmp_table_deleted || !error)
++ {
++ query_cache_invalidate3(thd, tables, 0);
++ if (!dont_log_query)
++ {
++ if (!thd->current_stmt_binlog_row_based ||
++ (non_temp_tables_count > 0 && !tmp_table_deleted))
++ {
++ /*
++ In this case, we are either using statement-based
++ replication or using row-based replication but have only
++ deleted one or more non-temporary tables (and no temporary
++ tables). In this case, we can write the original query into
++ the binary log.
++ */
++ error |= write_bin_log(thd, !error, thd->query(), thd->query_length());
++ }
++ else if (thd->current_stmt_binlog_row_based &&
++ tmp_table_deleted)
++ {
++ if (non_temp_tables_count > 0)
++ {
++ /*
++ In this case we have deleted both temporary and
++ non-temporary tables, so:
++ - since we have deleted a non-temporary table we have to
++ binlog the statement, but
++ - since we have deleted a temporary table we cannot binlog
++ the statement (since the table may have not been created on the
++ slave - check "if" branch below, this might cause the slave to
++ stop).
++
++ Instead, we write a built statement, only containing the
++ non-temporary tables, to the binary log
++ */
++ built_query.chop(); // Chop of the last comma
++ built_query.append(" /* generated by server */");
++ error|= write_bin_log(thd, !error, built_query.ptr(), built_query.length());
++ }
++
++ /*
++ One needs to always log any temporary table drop, if:
++ 1. thread logging format is mixed mode; AND
++ 2. current statement logging format is set to row.
++ */
++ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED)
++ {
++ /*
++ In this case we have deleted some temporary tables but we are using
++ row based logging for the statement. However, thread uses mixed mode
++ format, thence we need to log the dropping as we cannot tell for
++ sure whether the create was logged as statement previously or not, ie,
++ before switching to row mode.
++ */
++ built_tmp_query.chop(); // Chop of the last comma
++ built_tmp_query.append(" /* generated by server */");
++ error|= write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
++ }
++ }
++
++ /*
++ The remaining cases are:
++ - no tables were deleted and
++ - only temporary tables were deleted and row-based
++ replication is used.
++ In both these cases, nothing should be written to the binary
++ log.
++ */
++ }
++ }
++ pthread_mutex_lock(&LOCK_open);
++err_with_placeholders:
++ unlock_table_names(thd, tables, (TABLE_LIST*) 0);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(error);
++}
++
++
++/*
++ Quickly remove a table.
++
++ SYNOPSIS
++ quick_rm_table()
++ base The handlerton handle.
++ db The database name.
++ table_name The table name.
++ flags flags for build_table_filename().
++
++ RETURN
++ 0 OK
++ != 0 Error
++*/
++
++bool quick_rm_table(handlerton *base,const char *db,
++ const char *table_name, uint flags)
++{
++ char path[FN_REFLEN + 1];
++ bool error= 0;
++ DBUG_ENTER("quick_rm_table");
++
++ uint path_length= build_table_filename(path, sizeof(path) - 1,
++ db, table_name, reg_ext, flags);
++ if (my_delete(path,MYF(0)))
++ error= 1; /* purecov: inspected */
++ path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
++ if (!(flags & FRM_ONLY))
++ error|= ha_delete_table(current_thd, base, path, db, table_name, 0);
++ DBUG_RETURN(error);
++}
++
++/*
++ Sort keys in the following order:
++ - PRIMARY KEY
++ - UNIQUE keys where all column are NOT NULL
++ - UNIQUE keys that don't contain partial segments
++ - Other UNIQUE keys
++ - Normal keys
++ - Fulltext keys
++
++ This will make checking for duplicated keys faster and ensure that
++ PRIMARY keys are prioritized.
++*/
++
++static int sort_keys(KEY *a, KEY *b)
++{
++ ulong a_flags= a->flags, b_flags= b->flags;
++
++ if (a_flags & HA_NOSAME)
++ {
++ if (!(b_flags & HA_NOSAME))
++ return -1;
++ if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
++ {
++ /* Sort NOT NULL keys before other keys */
++ return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
++ }
++ if (a->name == primary_key_name)
++ return -1;
++ if (b->name == primary_key_name)
++ return 1;
++ /* Sort keys don't containing partial segments before others */
++ if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
++ return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
++ }
++ else if (b_flags & HA_NOSAME)
++ return 1; // Prefer b
++
++ if ((a_flags ^ b_flags) & HA_FULLTEXT)
++ {
++ return (a_flags & HA_FULLTEXT) ? 1 : -1;
++ }
++ /*
++ Prefer original key order. usable_key_parts contains here
++ the original key position.
++ */
++ return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
++ (a->usable_key_parts > b->usable_key_parts) ? 1 :
++ 0);
++}
++
++/*
++ Check TYPELIB (set or enum) for duplicates
++
++ SYNOPSIS
++ check_duplicates_in_interval()
++ set_or_name "SET" or "ENUM" string for warning message
++ name name of the checked column
++ typelib list of values for the column
++ dup_val_count returns count of duplicate elements
++
++ DESCRIPTION
++ This function prints an warning for each value in list
++ which has some duplicates on its right
++
++ RETURN VALUES
++ 0 ok
++ 1 Error
++*/
++
++bool check_duplicates_in_interval(const char *set_or_name,
++ const char *name, TYPELIB *typelib,
++ CHARSET_INFO *cs, unsigned int *dup_val_count)
++{
++ TYPELIB tmp= *typelib;
++ const char **cur_value= typelib->type_names;
++ unsigned int *cur_length= typelib->type_lengths;
++ *dup_val_count= 0;
++
++ for ( ; tmp.count > 1; cur_value++, cur_length++)
++ {
++ tmp.type_names++;
++ tmp.type_lengths++;
++ tmp.count--;
++ if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
++ {
++ if ((current_thd->variables.sql_mode &
++ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
++ {
++ my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
++ name,*cur_value,set_or_name);
++ return 1;
++ }
++ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_DUPLICATED_VALUE_IN_TYPE,
++ ER(ER_DUPLICATED_VALUE_IN_TYPE),
++ name,*cur_value,set_or_name);
++ (*dup_val_count)++;
++ }
++ }
++ return 0;
++}
++
++
++/*
++ Check TYPELIB (set or enum) max and total lengths
++
++ SYNOPSIS
++ calculate_interval_lengths()
++ cs charset+collation pair of the interval
++ typelib list of values for the column
++ max_length length of the longest item
++ tot_length sum of the item lengths
++
++ DESCRIPTION
++ After this function call:
++ - ENUM uses max_length
++ - SET uses tot_length.
++
++ RETURN VALUES
++ void
++*/
++void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
++ uint32 *max_length, uint32 *tot_length)
++{
++ const char **pos;
++ uint *len;
++ *max_length= *tot_length= 0;
++ for (pos= interval->type_names, len= interval->type_lengths;
++ *pos ; pos++, len++)
++ {
++ size_t length= cs->cset->numchars(cs, *pos, *pos + *len);
++ *tot_length+= length;
++ set_if_bigger(*max_length, (uint32)length);
++ }
++}
++
++
++/*
++ Prepare a create_table instance for packing
++
++ SYNOPSIS
++ prepare_create_field()
++ sql_field field to prepare for packing
++ blob_columns count for BLOBs
++ timestamps count for timestamps
++ table_flags table flags
++
++ DESCRIPTION
++ This function prepares a Create_field instance.
++ Fields such as pack_flag are valid after this call.
++
++ RETURN VALUES
++ 0 ok
++ 1 Error
++*/
++
++int prepare_create_field(Create_field *sql_field,
++ uint *blob_columns,
++ int *timestamps, int *timestamps_with_niladic,
++ longlong table_flags)
++{
++ unsigned int dup_val_count;
++ DBUG_ENTER("prepare_field");
++
++ /*
++ This code came from mysql_prepare_create_table.
++ Indent preserved to make patching easier
++ */
++ DBUG_ASSERT(sql_field->charset);
++
++ switch (sql_field->sql_type) {
++ case MYSQL_TYPE_BLOB:
++ case MYSQL_TYPE_MEDIUM_BLOB:
++ case MYSQL_TYPE_TINY_BLOB:
++ case MYSQL_TYPE_LONG_BLOB:
++ sql_field->pack_flag=FIELDFLAG_BLOB |
++ pack_length_to_packflag(sql_field->pack_length -
++ portable_sizeof_char_ptr);
++ if (sql_field->charset->state & MY_CS_BINSORT)
++ sql_field->pack_flag|=FIELDFLAG_BINARY;
++ sql_field->length=8; // Unireg field length
++ sql_field->unireg_check=Field::BLOB_FIELD;
++ (*blob_columns)++;
++ break;
++ case MYSQL_TYPE_GEOMETRY:
++#ifdef HAVE_SPATIAL
++ if (!(table_flags & HA_CAN_GEOMETRY))
++ {
++ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
++ MYF(0), "GEOMETRY");
++ DBUG_RETURN(1);
++ }
++ sql_field->pack_flag=FIELDFLAG_GEOM |
++ pack_length_to_packflag(sql_field->pack_length -
++ portable_sizeof_char_ptr);
++ if (sql_field->charset->state & MY_CS_BINSORT)
++ sql_field->pack_flag|=FIELDFLAG_BINARY;
++ sql_field->length=8; // Unireg field length
++ sql_field->unireg_check=Field::BLOB_FIELD;
++ (*blob_columns)++;
++ break;
++#else
++ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
++ sym_group_geom.name, sym_group_geom.needed_define);
++ DBUG_RETURN(1);
++#endif /*HAVE_SPATIAL*/
++ case MYSQL_TYPE_VARCHAR:
++#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
++ if (table_flags & HA_NO_VARCHAR)
++ {
++ /* convert VARCHAR to CHAR because handler is not yet up to date */
++ sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
++ sql_field->pack_length= calc_pack_length(sql_field->sql_type,
++ (uint) sql_field->length);
++ if ((sql_field->length / sql_field->charset->mbmaxlen) >
++ MAX_FIELD_CHARLENGTH)
++ {
++ my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
++ MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
++ DBUG_RETURN(1);
++ }
++ }
++#endif
++ /* fall through */
++ case MYSQL_TYPE_STRING:
++ sql_field->pack_flag=0;
++ if (sql_field->charset->state & MY_CS_BINSORT)
++ sql_field->pack_flag|=FIELDFLAG_BINARY;
++ break;
++ case MYSQL_TYPE_ENUM:
++ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
++ FIELDFLAG_INTERVAL;
++ if (sql_field->charset->state & MY_CS_BINSORT)
++ sql_field->pack_flag|=FIELDFLAG_BINARY;
++ sql_field->unireg_check=Field::INTERVAL_FIELD;
++ if (check_duplicates_in_interval("ENUM",sql_field->field_name,
++ sql_field->interval,
++ sql_field->charset, &dup_val_count))
++ DBUG_RETURN(1);
++ break;
++ case MYSQL_TYPE_SET:
++ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
++ FIELDFLAG_BITFIELD;
++ if (sql_field->charset->state & MY_CS_BINSORT)
++ sql_field->pack_flag|=FIELDFLAG_BINARY;
++ sql_field->unireg_check=Field::BIT_FIELD;
++ if (check_duplicates_in_interval("SET",sql_field->field_name,
++ sql_field->interval,
++ sql_field->charset, &dup_val_count))
++ DBUG_RETURN(1);
++ /* Check that count of unique members is not more then 64 */
++ if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8)
++ {
++ my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
++ DBUG_RETURN(1);
++ }
++ break;
++ case MYSQL_TYPE_DATE: // Rest of string types
++ case MYSQL_TYPE_NEWDATE:
++ case MYSQL_TYPE_TIME:
++ case MYSQL_TYPE_DATETIME:
++ case MYSQL_TYPE_NULL:
++ sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
++ break;
++ case MYSQL_TYPE_BIT:
++ /*
++ We have sql_field->pack_flag already set here, see
++ mysql_prepare_create_table().
++ */
++ break;
++ case MYSQL_TYPE_NEWDECIMAL:
++ sql_field->pack_flag=(FIELDFLAG_NUMBER |
++ (sql_field->flags & UNSIGNED_FLAG ? 0 :
++ FIELDFLAG_DECIMAL) |
++ (sql_field->flags & ZEROFILL_FLAG ?
++ FIELDFLAG_ZEROFILL : 0) |
++ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
++ break;
++ case MYSQL_TYPE_TIMESTAMP:
++ /* We should replace old TIMESTAMP fields with their newer analogs */
++ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
++ {
++ if (!*timestamps)
++ {
++ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
++ (*timestamps_with_niladic)++;
++ }
++ else
++ sql_field->unireg_check= Field::NONE;
++ }
++ else if (sql_field->unireg_check != Field::NONE)
++ (*timestamps_with_niladic)++;
++
++ (*timestamps)++;
++ /* fall-through */
++ default:
++ sql_field->pack_flag=(FIELDFLAG_NUMBER |
++ (sql_field->flags & UNSIGNED_FLAG ? 0 :
++ FIELDFLAG_DECIMAL) |
++ (sql_field->flags & ZEROFILL_FLAG ?
++ FIELDFLAG_ZEROFILL : 0) |
++ f_settype((uint) sql_field->sql_type) |
++ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
++ break;
++ }
++ if (!(sql_field->flags & NOT_NULL_FLAG))
++ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
++ if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
++ sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
++ DBUG_RETURN(0);
++}
++
++/*
++ Preparation for table creation
++
++ SYNOPSIS
++ mysql_prepare_create_table()
++ thd Thread object.
++ create_info Create information (like MAX_ROWS).
++ alter_info List of columns and indexes to create
++ tmp_table If a temporary table is to be created.
++ db_options INOUT Table options (like HA_OPTION_PACK_RECORD).
++ file The handler for the new table.
++ key_info_buffer OUT An array of KEY structs for the indexes.
++ key_count OUT The number of elements in the array.
++ select_field_count The number of fields coming from a select table.
++
++ DESCRIPTION
++ Prepares the table and key structures for table creation.
++
++ NOTES
++ sets create_info->varchar if the table has a varchar
++
++ RETURN VALUES
++ FALSE OK
++ TRUE error
++*/
++
++static int
++mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
++ Alter_info *alter_info,
++ bool tmp_table,
++ uint *db_options,
++ handler *file, KEY **key_info_buffer,
++ uint *key_count, int select_field_count)
++{
++ const char *key_name;
++ Create_field *sql_field,*dup_field;
++ uint field,null_fields,blob_columns,max_key_length;
++ ulong record_offset= 0;
++ KEY *key_info;
++ KEY_PART_INFO *key_part_info;
++ int timestamps= 0, timestamps_with_niladic= 0;
++ int field_no,dup_no;
++ int select_field_pos,auto_increment=0;
++ List_iterator<Create_field> it(alter_info->create_list);
++ List_iterator<Create_field> it2(alter_info->create_list);
++ uint total_uneven_bit_length= 0;
++ DBUG_ENTER("mysql_prepare_create_table");
++
++ select_field_pos= alter_info->create_list.elements - select_field_count;
++ null_fields=blob_columns=0;
++ create_info->varchar= 0;
++ max_key_length= file->max_key_length();
++
++ for (field_no=0; (sql_field=it++) ; field_no++)
++ {
++ CHARSET_INFO *save_cs;
++
++ /*
++ Initialize length from its original value (number of characters),
++ which was set in the parser. This is necessary if we're
++ executing a prepared statement for the second time.
++ */
++ sql_field->length= sql_field->char_length;
++ if (!sql_field->charset)
++ sql_field->charset= create_info->default_table_charset;
++ /*
++ table_charset is set in ALTER TABLE if we want change character set
++ for all varchar/char columns.
++ But the table charset must not affect the BLOB fields, so don't
++ allow to change my_charset_bin to somethig else.
++ */
++ if (create_info->table_charset && sql_field->charset != &my_charset_bin)
++ sql_field->charset= create_info->table_charset;
++
++ save_cs= sql_field->charset;
++ if ((sql_field->flags & BINCMP_FLAG) &&
++ !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
++ MY_CS_BINSORT,MYF(0))))
++ {
++ char tmp[65];
++ strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
++ STRING_WITH_LEN("_bin"));
++ my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
++ DBUG_RETURN(TRUE);
++ }
++
++ /*
++ Convert the default value from client character
++ set into the column character set if necessary.
++ */
++ if (sql_field->def &&
++ save_cs != sql_field->def->collation.collation &&
++ (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
++ sql_field->sql_type == MYSQL_TYPE_STRING ||
++ sql_field->sql_type == MYSQL_TYPE_SET ||
++ sql_field->sql_type == MYSQL_TYPE_ENUM))
++ {
++ /*
++ Starting from 5.1 we work here with a copy of Create_field
++ created by the caller, not with the instance that was
++ originally created during parsing. It's OK to create
++ a temporary item and initialize with it a member of the
++ copy -- this item will be thrown away along with the copy
++ at the end of execution, and thus not introduce a dangling
++ pointer in the parsed tree of a prepared statement or a
++ stored procedure statement.
++ */
++ sql_field->def= sql_field->def->safe_charset_converter(save_cs);
++
++ if (sql_field->def == NULL)
++ {
++ /* Could not convert */
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++
++ if (sql_field->sql_type == MYSQL_TYPE_SET ||
++ sql_field->sql_type == MYSQL_TYPE_ENUM)
++ {
++ uint32 dummy;
++ CHARSET_INFO *cs= sql_field->charset;
++ TYPELIB *interval= sql_field->interval;
++
++ /*
++ Create typelib from interval_list, and if necessary
++ convert strings from client character set to the
++ column character set.
++ */
++ if (!interval)
++ {
++ /*
++ Create the typelib in runtime memory - we will free the
++ occupied memory at the same time when we free this
++ sql_field -- at the end of execution.
++ */
++ interval= sql_field->interval= typelib(thd->mem_root,
++ sql_field->interval_list);
++ List_iterator<String> int_it(sql_field->interval_list);
++ String conv, *tmp;
++ char comma_buf[2];
++ int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
++ (uchar*) comma_buf +
++ sizeof(comma_buf));
++ DBUG_ASSERT(comma_length > 0);
++ for (uint i= 0; (tmp= int_it++); i++)
++ {
++ size_t lengthsp;
++ if (String::needs_conversion(tmp->length(), tmp->charset(),
++ cs, &dummy))
++ {
++ uint cnv_errs;
++ conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
++ interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
++ conv.length());
++ interval->type_lengths[i]= conv.length();
++ }
++
++ // Strip trailing spaces.
++ lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
++ interval->type_lengths[i]);
++ interval->type_lengths[i]= lengthsp;
++ ((uchar *)interval->type_names[i])[lengthsp]= '\0';
++ if (sql_field->sql_type == MYSQL_TYPE_SET)
++ {
++ if (cs->coll->instr(cs, interval->type_names[i],
++ interval->type_lengths[i],
++ comma_buf, comma_length, NULL, 0))
++ {
++ my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++ sql_field->interval_list.empty(); // Don't need interval_list anymore
++ }
++
++ if (sql_field->sql_type == MYSQL_TYPE_SET)
++ {
++ uint32 field_length;
++ if (sql_field->def != NULL)
++ {
++ char *not_used;
++ uint not_used2;
++ bool not_found= 0;
++ String str, *def= sql_field->def->val_str(&str);
++ if (def == NULL) /* SQL "NULL" maps to NULL */
++ {
++ if ((sql_field->flags & NOT_NULL_FLAG) != 0)
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++
++ /* else, NULL is an allowed value */
++ (void) find_set(interval, NULL, 0,
++ cs, ¬_used, ¬_used2, ¬_found);
++ }
++ else /* not NULL */
++ {
++ (void) find_set(interval, def->ptr(), def->length(),
++ cs, ¬_used, ¬_used2, ¬_found);
++ }
++
++ if (not_found)
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ calculate_interval_lengths(cs, interval, &dummy, &field_length);
++ sql_field->length= field_length + (interval->count - 1);
++ }
++ else /* MYSQL_TYPE_ENUM */
++ {
++ uint32 field_length;
++ DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
++ if (sql_field->def != NULL)
++ {
++ String str, *def= sql_field->def->val_str(&str);
++ if (def == NULL) /* SQL "NULL" maps to NULL */
++ {
++ if ((sql_field->flags & NOT_NULL_FLAG) != 0)
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++
++ /* else, the defaults yield the correct length for NULLs. */
++ }
++ else /* not NULL */
++ {
++ def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
++ if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
++ {
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++ calculate_interval_lengths(cs, interval, &field_length, &dummy);
++ sql_field->length= field_length;
++ }
++ set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
++ }
++
++ if (sql_field->sql_type == MYSQL_TYPE_BIT)
++ {
++ sql_field->pack_flag= FIELDFLAG_NUMBER;
++ if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
++ total_uneven_bit_length+= sql_field->length & 7;
++ else
++ sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
++ }
++
++ sql_field->create_length_to_internal_length();
++ if (prepare_blob_field(thd, sql_field))
++ DBUG_RETURN(TRUE);
++
++ if (!(sql_field->flags & NOT_NULL_FLAG))
++ null_fields++;
++
++ if (check_column_name(sql_field->field_name))
++ {
++ my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++
++ /* Check if we have used the same field name before */
++ for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
++ {
++ if (my_strcasecmp(system_charset_info,
++ sql_field->field_name,
++ dup_field->field_name) == 0)
++ {
++ /*
++ If this was a CREATE ... SELECT statement, accept a field
++ redefinition if we are changing a field in the SELECT part
++ */
++ if (field_no < select_field_pos || dup_no >= select_field_pos)
++ {
++ my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ else
++ {
++ /* Field redefined */
++ sql_field->def= dup_field->def;
++ sql_field->sql_type= dup_field->sql_type;
++ sql_field->charset= (dup_field->charset ?
++ dup_field->charset :
++ create_info->default_table_charset);
++ sql_field->length= dup_field->char_length;
++ sql_field->pack_length= dup_field->pack_length;
++ sql_field->key_length= dup_field->key_length;
++ sql_field->decimals= dup_field->decimals;
++ sql_field->create_length_to_internal_length();
++ sql_field->unireg_check= dup_field->unireg_check;
++ /*
++ We're making one field from two, the result field will have
++ dup_field->flags as flags. If we've incremented null_fields
++ because of sql_field->flags, decrement it back.
++ */
++ if (!(sql_field->flags & NOT_NULL_FLAG))
++ null_fields--;
++ sql_field->flags= dup_field->flags;
++ sql_field->interval= dup_field->interval;
++ it2.remove(); // Remove first (create) definition
++ select_field_pos--;
++ break;
++ }
++ }
++ }
++ /* Don't pack rows in old tables if the user has requested this */
++ if ((sql_field->flags & BLOB_FLAG) ||
++ (sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
++ create_info->row_type != ROW_TYPE_FIXED))
++ (*db_options)|= HA_OPTION_PACK_RECORD;
++ it2.rewind();
++ }
++
++ /* record_offset will be increased with 'length-of-null-bits' later */
++ record_offset= 0;
++ null_fields+= total_uneven_bit_length;
++
++ it.rewind();
++ while ((sql_field=it++))
++ {
++ DBUG_ASSERT(sql_field->charset != 0);
++
++ if (prepare_create_field(sql_field, &blob_columns,
++ ×tamps, ×tamps_with_niladic,
++ file->ha_table_flags()))
++ DBUG_RETURN(TRUE);
++ if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
++ create_info->varchar= TRUE;
++ sql_field->offset= record_offset;
++ if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
++ auto_increment++;
++ record_offset+= sql_field->pack_length;
++ }
++ if (timestamps_with_niladic > 1)
++ {
++ my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
++ ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ if (auto_increment > 1)
++ {
++ my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ if (auto_increment &&
++ (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
++ {
++ my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
++ ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++ if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
++ {
++ my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
++ MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++ /* Create keys */
++
++ List_iterator<Key> key_iterator(alter_info->key_list);
++ List_iterator<Key> key_iterator2(alter_info->key_list);
++ uint key_parts=0, fk_key_count=0;
++ bool primary_key=0,unique_key=0;
++ Key *key, *key2;
++ uint tmp, key_number;
++ /* special marker for keys to be ignored */
++ static char ignore_key[1];
++
++ /* Calculate number of key segements */
++ *key_count= 0;
++
++ while ((key=key_iterator++))
++ {
++ DBUG_PRINT("info", ("key name: '%s' type: %d", key->name ? key->name :
++ "(none)" , key->type));
++ LEX_STRING key_name_str;
++ if (key->type == Key::FOREIGN_KEY)
++ {
++ fk_key_count++;
++ Foreign_key *fk_key= (Foreign_key*) key;
++ if (fk_key->ref_columns.elements &&
++ fk_key->ref_columns.elements != fk_key->columns.elements)
++ {
++ my_error(ER_WRONG_FK_DEF, MYF(0),
++ (fk_key->name ? fk_key->name : "foreign key without name"),
++ ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
++ DBUG_RETURN(TRUE);
++ }
++ continue;
++ }
++ (*key_count)++;
++ tmp=file->max_key_parts();
++ if (key->columns.elements > tmp)
++ {
++ my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
++ DBUG_RETURN(TRUE);
++ }
++ key_name_str.str= (char*) key->name;
++ key_name_str.length= key->name ? strlen(key->name) : 0;
++ if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN,
++ system_charset_info, 1))
++ {
++ my_error(ER_TOO_LONG_IDENT, MYF(0), key->name);
++ DBUG_RETURN(TRUE);
++ }
++ key_iterator2.rewind ();
++ if (key->type != Key::FOREIGN_KEY)
++ {
++ while ((key2 = key_iterator2++) != key)
++ {
++ /*
++ foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
++ 'generated', and a generated key is a prefix of the other key.
++ Then we do not need the generated shorter key.
++ */
++ if ((key2->type != Key::FOREIGN_KEY &&
++ key2->name != ignore_key &&
++ !foreign_key_prefix(key, key2)))
++ {
++ /* TODO: issue warning message */
++ /* mark that the generated key should be ignored */
++ if (!key2->generated ||
++ (key->generated && key->columns.elements <
++ key2->columns.elements))
++ key->name= ignore_key;
++ else
++ {
++ key2->name= ignore_key;
++ key_parts-= key2->columns.elements;
++ (*key_count)--;
++ }
++ break;
++ }
++ }
++ }
++ if (key->name != ignore_key)
++ key_parts+=key->columns.elements;
++ else
++ (*key_count)--;
++ if (key->name && !tmp_table && (key->type != Key::PRIMARY) &&
++ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
++ {
++ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ tmp=file->max_keys();
++ if (*key_count > tmp)
++ {
++ my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
++ DBUG_RETURN(TRUE);
++ }
++
++ (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
++ key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
++ if (!*key_info_buffer || ! key_part_info)
++ DBUG_RETURN(TRUE); // Out of memory
++
++ key_iterator.rewind();
++ key_number=0;
++ for (; (key=key_iterator++) ; key_number++)
++ {
++ uint key_length=0;
++ Key_part_spec *column;
++
++ if (key->name == ignore_key)
++ {
++ /* ignore redundant keys */
++ do
++ key=key_iterator++;
++ while (key && key->name == ignore_key);
++ if (!key)
++ break;
++ }
++
++ switch (key->type) {
++ case Key::MULTIPLE:
++ key_info->flags= 0;
++ break;
++ case Key::FULLTEXT:
++ key_info->flags= HA_FULLTEXT;
++ if ((key_info->parser_name= &key->key_create_info.parser_name)->str)
++ key_info->flags|= HA_USES_PARSER;
++ else
++ key_info->parser_name= 0;
++ break;
++ case Key::SPATIAL:
++#ifdef HAVE_SPATIAL
++ key_info->flags= HA_SPATIAL;
++ break;
++#else
++ my_error(ER_FEATURE_DISABLED, MYF(0),
++ sym_group_geom.name, sym_group_geom.needed_define);
++ DBUG_RETURN(TRUE);
++#endif
++ case Key::FOREIGN_KEY:
++ key_number--; // Skip this key
++ continue;
++ default:
++ key_info->flags = HA_NOSAME;
++ break;
++ }
++ if (key->generated)
++ key_info->flags|= HA_GENERATED_KEY;
++
++ key_info->key_parts=(uint8) key->columns.elements;
++ key_info->key_part=key_part_info;
++ key_info->usable_key_parts= key_number;
++ key_info->algorithm= key->key_create_info.algorithm;
++
++ if (key->type == Key::FULLTEXT)
++ {
++ if (!(file->ha_table_flags() & HA_CAN_FULLTEXT))
++ {
++ my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT),
++ MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ }
++ /*
++ Make SPATIAL to be RTREE by default
++ SPATIAL only on BLOB or at least BINARY, this
++ actually should be replaced by special GEOM type
++ in near future when new frm file is ready
++ checking for proper key parts number:
++ */
++
++ /* TODO: Add proper checks if handler supports key_type and algorithm */
++ if (key_info->flags & HA_SPATIAL)
++ {
++ if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS))
++ {
++ my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
++ MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ if (key_info->key_parts != 1)
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
++ DBUG_RETURN(TRUE);
++ }
++ }
++ else if (key_info->algorithm == HA_KEY_ALG_RTREE)
++ {
++#ifdef HAVE_RTREE_KEYS
++ if ((key_info->key_parts & 1) == 1)
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX");
++ DBUG_RETURN(TRUE);
++ }
++ /* TODO: To be deleted */
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX");
++ DBUG_RETURN(TRUE);
++#else
++ my_error(ER_FEATURE_DISABLED, MYF(0),
++ sym_group_rtree.name, sym_group_rtree.needed_define);
++ DBUG_RETURN(TRUE);
++#endif
++ }
++
++ /* Take block size from key part or table part */
++ /*
++ TODO: Add warning if block size changes. We can't do it here, as
++ this may depend on the size of the key
++ */
++ key_info->block_size= (key->key_create_info.block_size ?
++ key->key_create_info.block_size :
++ create_info->key_block_size);
++
++ if (key_info->block_size)
++ key_info->flags|= HA_USES_BLOCK_SIZE;
++
++ List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
++ CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
++ for (uint column_nr=0 ; (column=cols++) ; column_nr++)
++ {
++ uint length;
++ Key_part_spec *dup_column;
++
++ it.rewind();
++ field=0;
++ while ((sql_field=it++) &&
++ my_strcasecmp(system_charset_info,
++ column->field_name,
++ sql_field->field_name))
++ field++;
++ if (!sql_field)
++ {
++ my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ while ((dup_column= cols2++) != column)
++ {
++ if (!my_strcasecmp(system_charset_info,
++ column->field_name, dup_column->field_name))
++ {
++ my_printf_error(ER_DUP_FIELDNAME,
++ ER(ER_DUP_FIELDNAME),MYF(0),
++ column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ cols2.rewind();
++ if (key->type == Key::FULLTEXT)
++ {
++ if ((sql_field->sql_type != MYSQL_TYPE_STRING &&
++ sql_field->sql_type != MYSQL_TYPE_VARCHAR &&
++ !f_is_blob(sql_field->pack_flag)) ||
++ sql_field->charset == &my_charset_bin ||
++ sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
++ (ft_key_charset && sql_field->charset != ft_key_charset))
++ {
++ my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name);
++ DBUG_RETURN(-1);
++ }
++ ft_key_charset=sql_field->charset;
++ /*
++ for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
++ code anyway, and 0 (set to column width later) for char's. it has
++ to be correct col width for char's, as char data are not prefixed
++ with length (unlike blobs, where ft code takes data length from a
++ data prefix, ignoring column->length).
++ */
++ column->length=test(f_is_blob(sql_field->pack_flag));
++ }
++ else
++ {
++ column->length*= sql_field->charset->mbmaxlen;
++
++ if (key->type == Key::SPATIAL)
++ {
++ if (column->length)
++ {
++ my_error(ER_WRONG_SUB_KEY, MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++ if (!f_is_geom(sql_field->pack_flag))
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
++ DBUG_RETURN(TRUE);
++ }
++ }
++
++ if (f_is_blob(sql_field->pack_flag) ||
++ (f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
++ {
++ if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
++ {
++ my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
++ Field::GEOM_POINT)
++ column->length= 25;
++ if (!column->length)
++ {
++ my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++#ifdef HAVE_SPATIAL
++ if (key->type == Key::SPATIAL)
++ {
++ if (!column->length)
++ {
++ /*
++ 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
++ Lately we'll extend this code to support more dimensions
++ */
++ column->length= 4*sizeof(double);
++ }
++ }
++#endif
++ if (!(sql_field->flags & NOT_NULL_FLAG))
++ {
++ if (key->type == Key::PRIMARY)
++ {
++ /* Implicitly set primary key fields to NOT NULL for ISO conf. */
++ sql_field->flags|= NOT_NULL_FLAG;
++ sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
++ null_fields--;
++ }
++ else
++ {
++ key_info->flags|= HA_NULL_PART_KEY;
++ if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
++ {
++ my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ if (key->type == Key::SPATIAL)
++ {
++ my_message(ER_SPATIAL_CANT_HAVE_NULL,
++ ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++ if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
++ {
++ if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
++ auto_increment--; // Field is used
++ }
++ }
++
++ key_part_info->fieldnr= field;
++ key_part_info->offset= (uint16) sql_field->offset;
++ key_part_info->key_type=sql_field->pack_flag;
++ length= sql_field->key_length;
++
++ if (column->length)
++ {
++ if (f_is_blob(sql_field->pack_flag))
++ {
++ if ((length=column->length) > max_key_length ||
++ length > file->max_key_part_length())
++ {
++ length=min(max_key_length, file->max_key_part_length());
++ if (key->type == Key::MULTIPLE)
++ {
++ /* not a critical problem */
++ char warn_buff[MYSQL_ERRMSG_SIZE];
++ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
++ length);
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_TOO_LONG_KEY, warn_buff);
++ /* Align key length to multibyte char boundary */
++ length-= length % sql_field->charset->mbmaxlen;
++ }
++ else
++ {
++ my_error(ER_TOO_LONG_KEY,MYF(0),length);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++ else if (!f_is_geom(sql_field->pack_flag) &&
++ (column->length > length ||
++ !Field::type_can_have_key_part (sql_field->sql_type) ||
++ ((f_is_packed(sql_field->pack_flag) ||
++ ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
++ (key_info->flags & HA_NOSAME))) &&
++ column->length != length)))
++ {
++ my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
++ length=column->length;
++ }
++ else if (length == 0)
++ {
++ my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
++ {
++ length= file->max_key_part_length();
++ if (key->type == Key::MULTIPLE)
++ {
++ /* not a critical problem */
++ char warn_buff[MYSQL_ERRMSG_SIZE];
++ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
++ length);
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ ER_TOO_LONG_KEY, warn_buff);
++ /* Align key length to multibyte char boundary */
++ length-= length % sql_field->charset->mbmaxlen;
++ }
++ else
++ {
++ my_error(ER_TOO_LONG_KEY,MYF(0),length);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ key_part_info->length=(uint16) length;
++ /* Use packed keys for long strings on the first column */
++ if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
++ !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
++ (length >= KEY_DEFAULT_PACK_LENGTH &&
++ (sql_field->sql_type == MYSQL_TYPE_STRING ||
++ sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
++ sql_field->pack_flag & FIELDFLAG_BLOB)))
++ {
++ if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
++ sql_field->sql_type == MYSQL_TYPE_VARCHAR)
++ key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
++ else
++ key_info->flags|= HA_PACK_KEY;
++ }
++ /* Check if the key segment is partial, set the key flag accordingly */
++ if (length != sql_field->key_length)
++ key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
++
++ key_length+=length;
++ key_part_info++;
++
++ /* Create the key name based on the first column (if not given) */
++ if (column_nr == 0)
++ {
++ if (key->type == Key::PRIMARY)
++ {
++ if (primary_key)
++ {
++ my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
++ MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ key_name=primary_key_name;
++ primary_key=1;
++ }
++ else if (!(key_name = key->name))
++ key_name=make_unique_key_name(sql_field->field_name,
++ *key_info_buffer, key_info);
++ if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
++ {
++ my_error(ER_DUP_KEYNAME, MYF(0), key_name);
++ DBUG_RETURN(TRUE);
++ }
++ key_info->name=(char*) key_name;
++ }
++ }
++ if (!key_info->name || check_column_name(key_info->name))
++ {
++ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
++ DBUG_RETURN(TRUE);
++ }
++ if (!(key_info->flags & HA_NULL_PART_KEY))
++ unique_key=1;
++ key_info->key_length=(uint16) key_length;
++ if (key_length > max_key_length && key->type != Key::FULLTEXT)
++ {
++ my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
++ DBUG_RETURN(TRUE);
++ }
++ key_info++;
++ }
++ if (!unique_key && !primary_key &&
++ (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
++ {
++ my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ if (auto_increment > 0)
++ {
++ my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ /* Sort keys in optimized order */
++ my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
++ (qsort_cmp) sort_keys);
++ create_info->null_bits= null_fields;
++
++ /* Check fields. */
++ it.rewind();
++ while ((sql_field=it++))
++ {
++ Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
++
++ if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
++ !sql_field->def &&
++ sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
++ (sql_field->flags & NOT_NULL_FLAG) &&
++ (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
++ {
++ /*
++ An error should be reported if:
++ - NO_ZERO_DATE SQL mode is active;
++ - there is no explicit DEFAULT clause (default column value);
++ - this is a TIMESTAMP column;
++ - the column is not NULL;
++ - this is not the DEFAULT CURRENT_TIMESTAMP column.
++
++ In other words, an error should be reported if
++ - NO_ZERO_DATE SQL mode is active;
++ - the column definition is equivalent to
++ 'column_name TIMESTAMP DEFAULT 0'.
++ */
++
++ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
++ DBUG_RETURN(TRUE);
++ }
++ }
++
++ DBUG_RETURN(FALSE);
++}
++
++
++/*
++ Set table default charset, if not set
++
++ SYNOPSIS
++ set_table_default_charset()
++ create_info Table create information
++
++ DESCRIPTION
++ If the table character set was not given explicitely,
++ let's fetch the database default character set and
++ apply it to the table.
++*/
++
++static void set_table_default_charset(THD *thd,
++ HA_CREATE_INFO *create_info, char *db)
++{
++ /*
++ If the table character set was not given explicitly,
++ let's fetch the database default character set and
++ apply it to the table.
++ */
++ if (!create_info->default_table_charset)
++ {
++ HA_CREATE_INFO db_info;
++
++ load_db_opt_by_name(thd, db, &db_info);
++
++ create_info->default_table_charset= db_info.default_table_charset;
++ }
++}
++
++
++/*
++ Extend long VARCHAR fields to blob & prepare field if it's a blob
++
++ SYNOPSIS
++ prepare_blob_field()
++ sql_field Field to check
++
++ RETURN
++ 0 ok
++ 1 Error (sql_field can't be converted to blob)
++ In this case the error is given
++*/
++
++static bool prepare_blob_field(THD *thd, Create_field *sql_field)
++{
++ DBUG_ENTER("prepare_blob_field");
++
++ if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
++ !(sql_field->flags & BLOB_FLAG))
++ {
++ /* Convert long VARCHAR columns to TEXT or BLOB */
++ char warn_buff[MYSQL_ERRMSG_SIZE];
++
++ if (sql_field->def || (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
++ MODE_STRICT_ALL_TABLES)))
++ {
++ my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
++ MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
++ DBUG_RETURN(1);
++ }
++ sql_field->sql_type= MYSQL_TYPE_BLOB;
++ sql_field->flags|= BLOB_FLAG;
++ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_AUTO_CONVERT), sql_field->field_name,
++ (sql_field->charset == &my_charset_bin) ? "VARBINARY" : "VARCHAR",
++ (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT");
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
++ warn_buff);
++ }
++
++ if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
++ {
++ if (sql_field->sql_type == FIELD_TYPE_BLOB ||
++ sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
++ sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB)
++ {
++ /* The user has given a length to the blob column */
++ sql_field->sql_type= get_blob_type_from_length(sql_field->length);
++ sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
++ }
++ sql_field->length= 0;
++ }
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Preparation of Create_field for SP function return values.
++ Based on code used in the inner loop of mysql_prepare_create_table()
++ above.
++
++ SYNOPSIS
++ sp_prepare_create_field()
++ thd Thread object
++ sql_field Field to prepare
++
++ DESCRIPTION
++ Prepares the field structures for field creation.
++
++*/
++
++void sp_prepare_create_field(THD *thd, Create_field *sql_field)
++{
++ if (sql_field->sql_type == MYSQL_TYPE_SET ||
++ sql_field->sql_type == MYSQL_TYPE_ENUM)
++ {
++ uint32 field_length, dummy;
++ if (sql_field->sql_type == MYSQL_TYPE_SET)
++ {
++ calculate_interval_lengths(sql_field->charset,
++ sql_field->interval, &dummy,
++ &field_length);
++ sql_field->length= field_length +
++ (sql_field->interval->count - 1);
++ }
++ else /* MYSQL_TYPE_ENUM */
++ {
++ calculate_interval_lengths(sql_field->charset,
++ sql_field->interval,
++ &field_length, &dummy);
++ sql_field->length= field_length;
++ }
++ set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
++ }
++
++ if (sql_field->sql_type == MYSQL_TYPE_BIT)
++ {
++ sql_field->pack_flag= FIELDFLAG_NUMBER |
++ FIELDFLAG_TREAT_BIT_AS_CHAR;
++ }
++ sql_field->create_length_to_internal_length();
++ DBUG_ASSERT(sql_field->def == 0);
++ /* Can't go wrong as sql_field->def is not defined */
++ (void) prepare_blob_field(thd, sql_field);
++}
++
++
++/*
++ Write CREATE TABLE binlog
++
++ SYNOPSIS
++ write_create_table_bin_log()
++ thd Thread object
++ create_info Create information
++ internal_tmp_table Set to 1 if this is an internal temporary table
++
++ DESCRIPTION
++ This function only is called in mysql_create_table_no_lock and
++ mysql_create_table
++
++ RETURN VALUES
++ NONE
++ */
++static inline int write_create_table_bin_log(THD *thd,
++ const HA_CREATE_INFO *create_info,
++ bool internal_tmp_table)
++{
++ /*
++ Don't write statement if:
++ - It is an internal temporary table,
++ - Row-based logging is used and it we are creating a temporary table, or
++ - The binary log is not open.
++ Otherwise, the statement shall be binlogged.
++ */
++ if (!internal_tmp_table &&
++ (!thd->current_stmt_binlog_row_based ||
++ (thd->current_stmt_binlog_row_based &&
++ !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
++ return write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ return 0;
++}
++
++
++/*
++ Create a table
++
++ SYNOPSIS
++ mysql_create_table_no_lock()
++ thd Thread object
++ db Database
++ table_name Table name
++ create_info Create information (like MAX_ROWS)
++ fields List of fields to create
++ keys List of keys to create
++ internal_tmp_table Set to 1 if this is an internal temporary table
++ (From ALTER TABLE)
++ select_field_count
++
++ DESCRIPTION
++ If one creates a temporary table, this is automatically opened
++
++ Note that this function assumes that caller already have taken
++ name-lock on table being created or used some other way to ensure
++ that concurrent operations won't intervene. mysql_create_table()
++ is a wrapper that can be used for this.
++
++ no_log is needed for the case of CREATE ... SELECT,
++ as the logging will be done later in sql_insert.cc
++ select_field_count is also used for CREATE ... SELECT,
++ and must be zero for standard create of table.
++
++ RETURN VALUES
++ FALSE OK
++ TRUE error
++*/
++
++bool mysql_create_table_no_lock(THD *thd,
++ const char *db, const char *table_name,
++ HA_CREATE_INFO *create_info,
++ Alter_info *alter_info,
++ bool internal_tmp_table,
++ uint select_field_count)
++{
++ char path[FN_REFLEN + 1];
++ uint path_length;
++ const char *alias;
++ uint db_options, key_count;
++ KEY *key_info_buffer;
++ handler *file;
++ bool error= TRUE;
++ DBUG_ENTER("mysql_create_table_no_lock");
++ DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
++ db, table_name, internal_tmp_table));
++
++
++ /* Check for duplicate fields and check type of table to create */
++ if (!alter_info->create_list.elements)
++ {
++ my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
++ MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ if (check_engine(thd, table_name, create_info))
++ DBUG_RETURN(TRUE);
++ db_options= create_info->table_options;
++ if (create_info->row_type == ROW_TYPE_DYNAMIC)
++ db_options|=HA_OPTION_PACK_RECORD;
++ alias= table_case_name(create_info, table_name);
++ if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
++ create_info->db_type)))
++ {
++ mem_alloc_error(sizeof(handler));
++ DBUG_RETURN(TRUE);
++ }
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ partition_info *part_info= thd->work_part_info;
++
++ if (!part_info && create_info->db_type->partition_flags &&
++ (create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
++ {
++ /*
++ Table is not defined as a partitioned table but the engine handles
++ all tables as partitioned. The handler will set up the partition info
++ object with the default settings.
++ */
++ thd->work_part_info= part_info= new partition_info();
++ if (!part_info)
++ {
++ mem_alloc_error(sizeof(partition_info));
++ DBUG_RETURN(TRUE);
++ }
++ file->set_auto_partitions(part_info);
++ part_info->default_engine_type= create_info->db_type;
++ part_info->is_auto_partitioned= TRUE;
++ }
++ if (part_info)
++ {
++ /*
++ The table has been specified as a partitioned table.
++ If this is part of an ALTER TABLE the handler will be the partition
++ handler but we need to specify the default handler to use for
++ partitions also in the call to check_partition_info. We transport
++ this information in the default_db_type variable, it is either
++ DB_TYPE_DEFAULT or the engine set in the ALTER TABLE command.
++
++ Check that we don't use foreign keys in the table since it won't
++ work even with InnoDB beneath it.
++ */
++ List_iterator<Key> key_iterator(alter_info->key_list);
++ Key *key;
++ handlerton *part_engine_type= create_info->db_type;
++ char *part_syntax_buf;
++ uint syntax_len;
++ handlerton *engine_type;
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
++ {
++ my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
++ goto err;
++ }
++ while ((key= key_iterator++))
++ {
++ if (key->type == Key::FOREIGN_KEY &&
++ !part_info->is_auto_partitioned)
++ {
++ my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
++ goto err;
++ }
++ }
++ if ((part_engine_type == partition_hton) &&
++ part_info->default_engine_type)
++ {
++ /*
++ This only happens at ALTER TABLE.
++ default_engine_type was assigned from the engine set in the ALTER
++ TABLE command.
++ */
++ ;
++ }
++ else
++ {
++ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
++ {
++ part_info->default_engine_type= create_info->db_type;
++ }
++ else
++ {
++ if (part_info->default_engine_type == NULL)
++ {
++ part_info->default_engine_type= ha_checktype(thd,
++ DB_TYPE_DEFAULT, 0, 0);
++ }
++ }
++ }
++ DBUG_PRINT("info", ("db_type = %s create_info->db_type = %s",
++ ha_resolve_storage_engine_name(part_info->default_engine_type),
++ ha_resolve_storage_engine_name(create_info->db_type)));
++ if (part_info->check_partition_info(thd, &engine_type, file,
++ create_info, TRUE))
++ goto err;
++ part_info->default_engine_type= engine_type;
++
++ /*
++ We reverse the partitioning parser and generate a standard format
++ for syntax stored in frm file.
++ */
++ if (!(part_syntax_buf= generate_partition_syntax(part_info,
++ &syntax_len,
++ TRUE, TRUE)))
++ goto err;
++ part_info->part_info_string= part_syntax_buf;
++ part_info->part_info_len= syntax_len;
++ if ((!(engine_type->partition_flags &&
++ engine_type->partition_flags() & HA_CAN_PARTITION)) ||
++ create_info->db_type == partition_hton)
++ {
++ /*
++ The handler assigned to the table cannot handle partitioning.
++ Assign the partition handler as the handler of the table.
++ */
++ DBUG_PRINT("info", ("db_type: %s",
++ ha_resolve_storage_engine_name(create_info->db_type)));
++ delete file;
++ create_info->db_type= partition_hton;
++ if (!(file= get_ha_partition(part_info)))
++ {
++ DBUG_RETURN(TRUE);
++ }
++ /*
++ If we have default number of partitions or subpartitions we
++ might require to set-up the part_info object such that it
++ creates a proper .par file. The current part_info object is
++ only used to create the frm-file and .par-file.
++ */
++ if (part_info->use_default_no_partitions &&
++ part_info->no_parts &&
++ (int)part_info->no_parts !=
++ file->get_default_no_partitions(create_info))
++ {
++ uint i;
++ List_iterator<partition_element> part_it(part_info->partitions);
++ part_it++;
++ DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
++ for (i= 1; i < part_info->partitions.elements; i++)
++ (part_it++)->part_state= PART_TO_BE_DROPPED;
++ }
++ else if (part_info->is_sub_partitioned() &&
++ part_info->use_default_no_subpartitions &&
++ part_info->no_subparts &&
++ (int)part_info->no_subparts !=
++ file->get_default_no_partitions(create_info))
++ {
++ DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
++ part_info->no_subparts= file->get_default_no_partitions(create_info);
++ }
++ }
++ else if (create_info->db_type != engine_type)
++ {
++ /*
++ We come here when we don't use a partitioned handler.
++ Since we use a partitioned table it must be "native partitioned".
++ We have switched engine from defaults, most likely only specified
++ engines in partition clauses.
++ */
++ delete file;
++ if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
++ engine_type)))
++ {
++ mem_alloc_error(sizeof(handler));
++ DBUG_RETURN(TRUE);
++ }
++ }
++ }
++#endif
++
++ set_table_default_charset(thd, create_info, (char*) db);
++
++ if (mysql_prepare_create_table(thd, create_info, alter_info,
++ internal_tmp_table,
++ &db_options, file,
++ &key_info_buffer, &key_count,
++ select_field_count))
++ goto err;
++
++ /* Check if table exists */
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
++ {
++ path_length= build_tmptable_filename(thd, path, sizeof(path));
++ create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
++ }
++ else
++ {
++ path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext,
++ internal_tmp_table ? FN_IS_TMP : 0);
++ }
++
++ /* Check if table already exists */
++ if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
++ find_temporary_table(thd, db, table_name))
++ {
++ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ {
++ create_info->table_existed= 1; // Mark that table existed
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
++ alias);
++ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
++ goto err;
++ }
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
++ goto err;
++ }
++
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ if (!access(path,F_OK))
++ {
++ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ goto warn;
++ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
++ goto unlock_and_end;
++ }
++ /*
++ We don't assert here, but check the result, because the table could be
++ in the table definition cache and in the same time the .frm could be
++ missing from the disk, in case of manual intervention which deletes
++ the .frm file. The user has to use FLUSH TABLES; to clear the cache.
++ Then she could create the table. This case is pretty obscure and
++ therefore we don't introduce a new error message only for it.
++ */
++ if (get_cached_table_share(db, table_name))
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
++ goto unlock_and_end;
++ }
++ }
++
++ /*
++ Check that table with given name does not already
++ exist in any storage engine. In such a case it should
++ be discovered and the error ER_TABLE_EXISTS_ERROR be returned
++ unless user specified CREATE TABLE IF EXISTS
++ The LOCK_open mutex has been locked to make sure no
++ one else is attempting to discover the table. Since
++ it's not on disk as a frm file, no one could be using it!
++ */
++ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ bool create_if_not_exists =
++ create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
++ int retcode = ha_table_exists_in_engine(thd, db, table_name);
++ DBUG_PRINT("info", ("exists_in_engine: %u",retcode));
++ switch (retcode)
++ {
++ case HA_ERR_NO_SUCH_TABLE:
++ /* Normal case, no table exists. we can go and create it */
++ break;
++ case HA_ERR_TABLE_EXIST:
++ DBUG_PRINT("info", ("Table existed in handler"));
++
++ if (create_if_not_exists)
++ goto warn;
++ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
++ goto unlock_and_end;
++ break;
++ default:
++ DBUG_PRINT("info", ("error: %u from storage engine", retcode));
++ my_error(retcode, MYF(0),table_name);
++ goto unlock_and_end;
++ }
++ }
++
++ thd_proc_info(thd, "creating table");
++ create_info->table_existed= 0; // Mark that table is created
++
++#ifdef HAVE_READLINK
++ if (test_if_data_home_dir(create_info->data_file_name))
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
++ goto unlock_and_end;
++ }
++ if (test_if_data_home_dir(create_info->index_file_name))
++ {
++ my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
++ goto unlock_and_end;
++ }
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (check_partition_dirs(thd->lex->part_info))
++ {
++ goto unlock_and_end;
++ }
++#endif /* WITH_PARTITION_STORAGE_ENGINE */
++
++ if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
++#endif /* HAVE_READLINK */
++ {
++ if (create_info->data_file_name)
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
++ "DATA DIRECTORY");
++ if (create_info->index_file_name)
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
++ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
++ "INDEX DIRECTORY");
++ create_info->data_file_name= create_info->index_file_name= 0;
++ }
++ create_info->table_options=db_options;
++
++ path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
++ if (rea_create_table(thd, path, db, table_name,
++ create_info, alter_info->create_list,
++ key_count, key_info_buffer, file))
++ goto unlock_and_end;
++
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
++ {
++ /* Open table and put in temporary table list */
++ if (!(open_temporary_table(thd, path, db, table_name, 1)))
++ {
++ (void) rm_temporary_table(create_info->db_type, path);
++ goto unlock_and_end;
++ }
++ thd->thread_specific_used= TRUE;
++ }
++
++ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
++unlock_and_end:
++ VOID(pthread_mutex_unlock(&LOCK_open));
++
++err:
++ thd_proc_info(thd, "After create");
++ delete file;
++ DBUG_RETURN(error);
++
++warn:
++ error= FALSE;
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
++ alias);
++ create_info->table_existed= 1; // Mark that table existed
++ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
++ goto unlock_and_end;
++}
++
++
++/*
++ Database and name-locking aware wrapper for mysql_create_table_no_lock(),
++*/
++
++bool mysql_create_table(THD *thd, const char *db, const char *table_name,
++ HA_CREATE_INFO *create_info,
++ Alter_info *alter_info,
++ bool internal_tmp_table,
++ uint select_field_count)
++{
++ TABLE *name_lock= 0;
++ bool result;
++ DBUG_ENTER("mysql_create_table");
++
++ /* Wait for any database locks */
++ pthread_mutex_lock(&LOCK_lock_db);
++ while (!thd->killed &&
++ hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
++ {
++ wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
++ pthread_mutex_lock(&LOCK_lock_db);
++ }
++
++ if (thd->killed)
++ {
++ pthread_mutex_unlock(&LOCK_lock_db);
++ DBUG_RETURN(TRUE);
++ }
++ creating_table++;
++ pthread_mutex_unlock(&LOCK_lock_db);
++
++ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
++ {
++ result= TRUE;
++ goto unlock;
++ }
++ if (!name_lock)
++ {
++ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ {
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
++ table_name);
++ create_info->table_existed= 1;
++ result= FALSE;
++ write_create_table_bin_log(thd, create_info, internal_tmp_table);
++ }
++ else
++ {
++ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
++ result= TRUE;
++ }
++ goto unlock;
++ }
++ }
++
++ result= mysql_create_table_no_lock(thd, db, table_name, create_info,
++ alter_info,
++ internal_tmp_table,
++ select_field_count);
++
++unlock:
++ if (name_lock)
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlink_open_table(thd, name_lock, FALSE);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ pthread_mutex_lock(&LOCK_lock_db);
++ if (!--creating_table && creating_database)
++ pthread_cond_signal(&COND_refresh);
++ pthread_mutex_unlock(&LOCK_lock_db);
++ DBUG_RETURN(result);
++}
++
++
++/*
++** Give the key name after the first field with an optional '_#' after
++**/
++
++static bool
++check_if_keyname_exists(const char *name, KEY *start, KEY *end)
++{
++ for (KEY *key=start ; key != end ; key++)
++ if (!my_strcasecmp(system_charset_info,name,key->name))
++ return 1;
++ return 0;
++}
++
++
++static char *
++make_unique_key_name(const char *field_name,KEY *start,KEY *end)
++{
++ char buff[MAX_FIELD_NAME],*buff_end;
++
++ if (!check_if_keyname_exists(field_name,start,end) &&
++ my_strcasecmp(system_charset_info,field_name,primary_key_name))
++ return (char*) field_name; // Use fieldname
++ buff_end=strmake(buff,field_name, sizeof(buff)-4);
++
++ /*
++ Only 3 chars + '\0' left, so need to limit to 2 digit
++ This is ok as we can't have more than 100 keys anyway
++ */
++ for (uint i=2 ; i< 100; i++)
++ {
++ *buff_end= '_';
++ int10_to_str(i, buff_end+1, 10);
++ if (!check_if_keyname_exists(buff,start,end))
++ return sql_strdup(buff);
++ }
++ return (char*) "not_specified"; // Should never happen
++}
++
++
++/****************************************************************************
++** Alter a table definition
++****************************************************************************/
++
++
++/*
++ Rename a table.
++
++ SYNOPSIS
++ mysql_rename_table()
++ base The handlerton handle.
++ old_db The old database name.
++ old_name The old table name.
++ new_db The new database name.
++ new_name The new table name.
++ flags flags for build_table_filename().
++ FN_FROM_IS_TMP old_name is temporary.
++ FN_TO_IS_TMP new_name is temporary.
++ NO_FRM_RENAME Don't rename the FRM file
++ but only the table in the storage engine.
++
++ RETURN
++ FALSE OK
++ TRUE Error
++*/
++
++bool
++mysql_rename_table(handlerton *base, const char *old_db,
++ const char *old_name, const char *new_db,
++ const char *new_name, uint flags)
++{
++ THD *thd= current_thd;
++ char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
++ lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1];
++ char *from_base= from, *to_base= to;
++ char tmp_name[NAME_LEN+1];
++ handler *file;
++ int error=0;
++ DBUG_ENTER("mysql_rename_table");
++ DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
++ old_db, old_name, new_db, new_name));
++
++ file= (base == NULL ? 0 :
++ get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
++
++ build_table_filename(from, sizeof(from) - 1, old_db, old_name, "",
++ flags & FN_FROM_IS_TMP);
++ build_table_filename(to, sizeof(to) - 1, new_db, new_name, "",
++ flags & FN_TO_IS_TMP);
++
++ /*
++ If lower_case_table_names == 2 (case-preserving but case-insensitive
++ file system) and the storage is not HA_FILE_BASED, we need to provide
++ a lowercase file name, but we leave the .frm in mixed case.
++ */
++ if (lower_case_table_names == 2 && file &&
++ !(file->ha_table_flags() & HA_FILE_BASED))
++ {
++ strmov(tmp_name, old_name);
++ my_casedn_str(files_charset_info, tmp_name);
++ build_table_filename(lc_from, sizeof(lc_from) - 1, old_db, tmp_name, "",
++ flags & FN_FROM_IS_TMP);
++ from_base= lc_from;
++
++ strmov(tmp_name, new_name);
++ my_casedn_str(files_charset_info, tmp_name);
++ build_table_filename(lc_to, sizeof(lc_to) - 1, new_db, tmp_name, "",
++ flags & FN_TO_IS_TMP);
++ to_base= lc_to;
++ }
++
++ if (!file || !(error=file->ha_rename_table(from_base, to_base)))
++ {
++ if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
++ {
++ error=my_errno;
++ /* Restore old file name */
++ if (file)
++ file->ha_rename_table(to_base, from_base);
++ }
++ }
++ delete file;
++ if (error == HA_ERR_WRONG_COMMAND)
++ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
++ else if (error)
++ my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
++ DBUG_RETURN(error != 0);
++}
++
++
++/*
++ Force all other threads to stop using the table
++
++ SYNOPSIS
++ wait_while_table_is_used()
++ thd Thread handler
++ table Table to remove from cache
++ function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
++ HA_EXTRA_FORCE_REOPEN if table is not be used
++ HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
++ NOTES
++ When returning, the table will be unusable for other threads until
++ the table is closed.
++
++ PREREQUISITES
++ Lock on LOCK_open
++ Win32 clients must also have a WRITE LOCK on the table !
++*/
++
++void wait_while_table_is_used(THD *thd, TABLE *table,
++ enum ha_extra_function function)
++{
++ DBUG_ENTER("wait_while_table_is_used");
++ DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
++ table->s->table_name.str, (ulong) table->s,
++ table->db_stat, table->s->version));
++
++ safe_mutex_assert_owner(&LOCK_open);
++
++ VOID(table->file->extra(function));
++ /* Mark all tables that are in use as 'old' */
++ mysql_lock_abort(thd, table, TRUE); /* end threads waiting on lock */
++
++ /* Wait until all there are no other threads that has this table open */
++ remove_table_from_cache(thd, table->s->db.str,
++ table->s->table_name.str,
++ RTFC_WAIT_OTHER_THREAD_FLAG);
++ DBUG_VOID_RETURN;
++}
++
++/*
++ Close a cached table
++
++ SYNOPSIS
++ close_cached_table()
++ thd Thread handler
++ table Table to remove from cache
++
++ NOTES
++ Function ends by signaling threads waiting for the table to try to
++ reopen the table.
++
++ PREREQUISITES
++ Lock on LOCK_open
++ Win32 clients must also have a WRITE LOCK on the table !
++*/
++
++void close_cached_table(THD *thd, TABLE *table)
++{
++ DBUG_ENTER("close_cached_table");
++
++ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
++ /* Close lock if this is not got with LOCK TABLES */
++ if (thd->lock)
++ {
++ mysql_unlock_tables(thd, thd->lock);
++ thd->lock=0; // Start locked threads
++ }
++ /* Close all copies of 'table'. This also frees all LOCK TABLES lock */
++ unlink_open_table(thd, table, TRUE);
++
++ /* When lock on LOCK_open is freed other threads can continue */
++ broadcast_refresh();
++ DBUG_VOID_RETURN;
++}
++
++static int send_check_errmsg(THD *thd, TABLE_LIST* table,
++ const char* operator_name, const char* errmsg)
++
++{
++ Protocol *protocol= thd->protocol;
++ protocol->prepare_for_resend();
++ protocol->store(table->alias, system_charset_info);
++ protocol->store((char*) operator_name, system_charset_info);
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ protocol->store(errmsg, system_charset_info);
++ thd->clear_error();
++ if (protocol->write())
++ return -1;
++ return 1;
++}
++
++
++static int prepare_for_restore(THD* thd, TABLE_LIST* table,
++ HA_CHECK_OPT *check_opt)
++{
++ DBUG_ENTER("prepare_for_restore");
++
++ if (table->table) // do not overwrite existing tables on restore
++ {
++ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
++ "table exists, will not overwrite on restore"
++ ));
++ }
++ else
++ {
++ char* backup_dir= thd->lex->backup_dir;
++ char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1], uname[FN_REFLEN];
++ char* table_name= table->table_name;
++ char* db= table->db;
++
++ VOID(tablename_to_filename(table->table_name, uname, sizeof(uname) - 1));
++
++ if (fn_format_relative_to_data_home(src_path, uname, backup_dir, reg_ext))
++ DBUG_RETURN(-1); // protect buffer overflow
++
++ build_table_filename(dst_path, sizeof(dst_path) - 1,
++ db, table_name, reg_ext, 0);
++
++ if (lock_and_wait_for_table_name(thd,table))
++ DBUG_RETURN(-1);
++
++ if (my_copy(src_path, dst_path, MYF(MY_WME)))
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlock_table_name(thd, table);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
++ "Failed copying .frm file"));
++ }
++ if (mysql_truncate(thd, table, 1))
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlock_table_name(thd, table);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
++ "Failed generating table from .frm file"));
++ }
++ }
++
++ /*
++ Now we should be able to open the partially restored table
++ to finish the restore in the handler later on
++ */
++ pthread_mutex_lock(&LOCK_open);
++ if (reopen_name_locked_table(thd, table, TRUE))
++ {
++ unlock_table_name(thd, table);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
++ "Failed to open partially restored table"));
++ }
++ /* A MERGE table must not come here. */
++ DBUG_ASSERT(!table->table || !table->table->child_l);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(0);
++}
++
++
++static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
++ HA_CHECK_OPT *check_opt)
++{
++ int error= 0;
++ TABLE tmp_table, *table;
++ TABLE_SHARE *share;
++ char from[FN_REFLEN],tmp[FN_REFLEN+32];
++ const char **ext;
++ MY_STAT stat_info;
++ DBUG_ENTER("prepare_for_repair");
++
++ if (!(check_opt->sql_flags & TT_USEFRM))
++ DBUG_RETURN(0);
++
++ if (!(table= table_list->table)) /* if open_ltable failed */
++ {
++ char key[MAX_DBKEY_LENGTH];
++ uint key_length;
++
++ key_length= create_table_def_key(thd, key, table_list, 0);
++ pthread_mutex_lock(&LOCK_open);
++ if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
++ &error))))
++ {
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(0); // Can't open frm file
++ }
++
++ if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
++ {
++ release_table_share(share, RELEASE_NORMAL);
++ pthread_mutex_unlock(&LOCK_open);
++ DBUG_RETURN(0); // Out of memory
++ }
++ table= &tmp_table;
++ pthread_mutex_unlock(&LOCK_open);
++ }
++
++ /*
++ REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
++ */
++ if (table->s->tmp_table)
++ {
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Cannot repair temporary table from .frm file");
++ goto end;
++ }
++
++ /*
++ User gave us USE_FRM which means that the header in the index file is
++ trashed.
++ In this case we will try to fix the table the following way:
++ - Rename the data file to a temporary name
++ - Truncate the table
++ - Replace the new data file with the old one
++ - Run a normal repair using the new index file and the old data file
++ */
++
++ if (table->s->frm_version != FRM_VER_TRUE_VARCHAR)
++ {
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Failed repairing incompatible .frm file");
++ goto end;
++ }
++
++ /*
++ Check if this is a table type that stores index and data separately,
++ like ISAM or MyISAM. We assume fixed order of engine file name
++ extentions array. First element of engine file name extentions array
++ is meta/index file extention. Second element - data file extention.
++ */
++ ext= table->file->bas_ext();
++ if (!ext[0] || !ext[1])
++ goto end; // No data file
++
++ // Name of data file
++ strxmov(from, table->s->normalized_path.str, ext[1], NullS);
++ if (!my_stat(from, &stat_info, MYF(0)))
++ goto end; // Can't use USE_FRM flag
++
++ my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
++ from, current_pid, thd->thread_id);
++
++ /* If we could open the table, close it */
++ if (table_list->table)
++ {
++ pthread_mutex_lock(&LOCK_open);
++ close_cached_table(thd, table);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ if (lock_and_wait_for_table_name(thd,table_list))
++ {
++ error= -1;
++ goto end;
++ }
++ if (my_rename(from, tmp, MYF(MY_WME)))
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlock_table_name(thd, table_list);
++ pthread_mutex_unlock(&LOCK_open);
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Failed renaming data file");
++ goto end;
++ }
++ if (mysql_truncate(thd, table_list, 1))
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlock_table_name(thd, table_list);
++ pthread_mutex_unlock(&LOCK_open);
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Failed generating table from .frm file");
++ goto end;
++ }
++ if (my_rename(tmp, from, MYF(MY_WME)))
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlock_table_name(thd, table_list);
++ pthread_mutex_unlock(&LOCK_open);
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Failed restoring .MYD file");
++ goto end;
++ }
++
++ /*
++ Now we should be able to open the partially repaired table
++ to finish the repair in the handler later on.
++ */
++ pthread_mutex_lock(&LOCK_open);
++ if (reopen_name_locked_table(thd, table_list, TRUE))
++ {
++ unlock_table_name(thd, table_list);
++ pthread_mutex_unlock(&LOCK_open);
++ error= send_check_errmsg(thd, table_list, "repair",
++ "Failed to open partially repaired table");
++ goto end;
++ }
++ pthread_mutex_unlock(&LOCK_open);
++
++end:
++ if (table == &tmp_table)
++ {
++ pthread_mutex_lock(&LOCK_open);
++ closefrm(table, 1); // Free allocated memory
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ DBUG_RETURN(error);
++}
++
++
++
++/*
++ RETURN VALUES
++ FALSE Message sent to net (admin operation went ok)
++ TRUE Message should be sent by caller
++ (admin operation or network communication failed)
++*/
++static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
++ HA_CHECK_OPT* check_opt,
++ const char *operator_name,
++ thr_lock_type lock_type,
++ bool open_for_modify,
++ bool no_warnings_for_error,
++ uint extra_open_options,
++ int (*prepare_func)(THD *, TABLE_LIST *,
++ HA_CHECK_OPT *),
++ int (handler::*operator_func)(THD *,
++ HA_CHECK_OPT *),
++ int (view_operator_func)(THD *, TABLE_LIST*))
++{
++ TABLE_LIST *table;
++ SELECT_LEX *select= &thd->lex->select_lex;
++ List<Item> field_list;
++ Item *item;
++ Protocol *protocol= thd->protocol;
++ LEX *lex= thd->lex;
++ int result_code;
++ DBUG_ENTER("mysql_admin_table");
++
++ if (end_active_trans(thd))
++ DBUG_RETURN(1);
++ field_list.push_back(item = new Item_empty_string("Table", NAME_CHAR_LEN*2));
++ item->maybe_null = 1;
++ field_list.push_back(item = new Item_empty_string("Op", 10));
++ item->maybe_null = 1;
++ field_list.push_back(item = new Item_empty_string("Msg_type", 10));
++ item->maybe_null = 1;
++ field_list.push_back(item = new Item_empty_string("Msg_text", 255));
++ item->maybe_null = 1;
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ mysql_ha_rm_tables(thd, tables, FALSE);
++
++ for (table= tables; table; table= table->next_local)
++ {
++ char table_name[NAME_LEN*2+2];
++ char* db = table->db;
++ bool fatal_error=0;
++
++ DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
++ DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
++ strxmov(table_name, db, ".", table->table_name, NullS);
++ thd->open_options|= extra_open_options;
++ table->lock_type= lock_type;
++ /* open only one table from local list of command */
++ {
++ TABLE_LIST *save_next_global, *save_next_local;
++ save_next_global= table->next_global;
++ table->next_global= 0;
++ save_next_local= table->next_local;
++ table->next_local= 0;
++ select->table_list.first= table;
++ /*
++ Time zone tables and SP tables can be add to lex->query_tables list,
++ so it have to be prepared.
++ TODO: Investigate if we can put extra tables into argument instead of
++ using lex->query_tables
++ */
++ lex->query_tables= table;
++ lex->query_tables_last= &table->next_global;
++ lex->query_tables_own_last= 0;
++ thd->no_warnings_for_error= no_warnings_for_error;
++ if (view_operator_func == NULL)
++ table->required_type=FRMTYPE_TABLE;
++
++ open_and_lock_tables(thd, table);
++ thd->no_warnings_for_error= 0;
++ table->next_global= save_next_global;
++ table->next_local= save_next_local;
++ thd->open_options&= ~extra_open_options;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (table->table)
++ {
++ /*
++ Set up which partitions that should be processed
++ if ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION ..
++ */
++ Alter_info *alter_info= &lex->alter_info;
++
++ if (alter_info->flags & ALTER_ADMIN_PARTITION)
++ {
++ if (!table->table->part_info)
++ {
++ my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++ uint no_parts_found;
++ uint no_parts_opt= alter_info->partition_names.elements;
++ no_parts_found= set_part_state(alter_info, table->table->part_info,
++ PART_CHANGED);
++ if (no_parts_found != no_parts_opt &&
++ (!(alter_info->flags & ALTER_ALL_PARTITION)))
++ {
++ char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
++ size_t length;
++ DBUG_PRINT("admin", ("sending non existent partition error"));
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ length= my_snprintf(buff, sizeof(buff),
++ ER(ER_DROP_PARTITION_NON_EXISTENT),
++ table_name);
++ protocol->store(buff, length, system_charset_info);
++ if(protocol->write())
++ goto err;
++ my_eof(thd);
++ goto err;
++ }
++ }
++ }
++#endif
++ }
++ DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
++
++ if (prepare_func)
++ {
++ DBUG_PRINT("admin", ("calling prepare_func"));
++ switch ((*prepare_func)(thd, table, check_opt)) {
++ case 1: // error, message written to net
++ ha_autocommit_or_rollback(thd, 1);
++ end_trans(thd, ROLLBACK);
++ close_thread_tables(thd);
++ DBUG_PRINT("admin", ("simple error, admin next table"));
++ continue;
++ case -1: // error, message could be written to net
++ /* purecov: begin inspected */
++ DBUG_PRINT("admin", ("severe error, stop"));
++ goto err;
++ /* purecov: end */
++ default: // should be 0 otherwise
++ DBUG_PRINT("admin", ("prepare_func succeeded"));
++ ;
++ }
++ }
++
++ /*
++ CHECK TABLE command is only command where VIEW allowed here and this
++ command use only temporary teble method for VIEWs resolving => there
++ can't be VIEW tree substitition of join view => if opening table
++ succeed then table->table will have real TABLE pointer as value (in
++ case of join view substitution table->table can be 0, but here it is
++ impossible)
++ */
++ if (!table->table)
++ {
++ DBUG_PRINT("admin", ("open table failed"));
++ if (!thd->warn_list.elements)
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
++ /* if it was a view will check md5 sum */
++ if (table->view &&
++ view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
++ if (thd->main_da.is_error() &&
++ (thd->main_da.sql_errno() == ER_NO_SUCH_TABLE ||
++ thd->main_da.sql_errno() == ER_FILE_NOT_FOUND))
++ /* A missing table is just issued as a failed command */
++ result_code= HA_ADMIN_FAILED;
++ else
++ /* Default failure code is corrupt table */
++ result_code= HA_ADMIN_CORRUPT;
++ goto send_result;
++ }
++
++ if (table->view)
++ {
++ DBUG_PRINT("admin", ("calling view_operator_func"));
++ result_code= (*view_operator_func)(thd, table);
++ goto send_result;
++ }
++
++ if (table->schema_table)
++ {
++ result_code= HA_ADMIN_NOT_IMPLEMENTED;
++ goto send_result;
++ }
++
++ if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
++ {
++ /* purecov: begin inspected */
++ char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
++ size_t length;
++ DBUG_PRINT("admin", ("sending error message"));
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
++ table_name);
++ protocol->store(buff, length, system_charset_info);
++ ha_autocommit_or_rollback(thd, 0);
++ end_trans(thd, COMMIT);
++ close_thread_tables(thd);
++ lex->reset_query_tables_list(FALSE);
++ table->table=0; // For query cache
++ if (protocol->write())
++ goto err;
++ thd->main_da.reset_diagnostics_area();
++ continue;
++ /* purecov: end */
++ }
++
++ /* Close all instances of the table to allow repair to rename files */
++ if (lock_type == TL_WRITE && table->table->s->version)
++ {
++ DBUG_PRINT("admin", ("removing table from cache"));
++ pthread_mutex_lock(&LOCK_open);
++ const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
++ "Waiting to get writelock");
++ mysql_lock_abort(thd,table->table, TRUE);
++ remove_table_from_cache(thd, table->table->s->db.str,
++ table->table->s->table_name.str,
++ RTFC_WAIT_OTHER_THREAD_FLAG |
++ RTFC_CHECK_KILLED_FLAG);
++ thd->exit_cond(old_message);
++ DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
++ if (thd->killed)
++ goto err;
++ /* Flush entries in the query cache involving this table. */
++ query_cache_invalidate3(thd, table->table, 0);
++ open_for_modify= 0;
++ }
++
++ if (table->table->s->crashed && operator_func == &handler::ha_check)
++ {
++ /* purecov: begin inspected */
++ DBUG_PRINT("admin", ("sending crashed warning"));
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++ protocol->store(STRING_WITH_LEN("warning"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Table is marked as crashed"),
++ system_charset_info);
++ if (protocol->write())
++ goto err;
++ /* purecov: end */
++ }
++
++ if (operator_func == &handler::ha_repair &&
++ !(check_opt->sql_flags & TT_USEFRM))
++ {
++ if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
++ (table->table->file->ha_check_for_upgrade(check_opt) ==
++ HA_ADMIN_NEEDS_ALTER))
++ {
++ DBUG_PRINT("admin", ("recreating table"));
++ ha_autocommit_or_rollback(thd, 1);
++ close_thread_tables(thd);
++ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
++ result_code= mysql_recreate_table(thd, table);
++ reenable_binlog(thd);
++ /*
++ mysql_recreate_table() can push OK or ERROR.
++ Clear 'OK' status. If there is an error, keep it:
++ we will store the error message in a result set row
++ and then clear.
++ */
++ if (thd->main_da.is_ok())
++ thd->main_da.reset_diagnostics_area();
++ goto send_result;
++ }
++ }
++
++ DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
++ result_code = (table->table->file->*operator_func)(thd, check_opt);
++ DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
++
++send_result:
++
++ lex->cleanup_after_one_table_open();
++ thd->clear_error(); // these errors shouldn't get client
++ {
++ List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
++ MYSQL_ERROR *err;
++ while ((err= it++))
++ {
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store((char*) operator_name, system_charset_info);
++ protocol->store(warning_level_names[err->level].str,
++ warning_level_names[err->level].length,
++ system_charset_info);
++ protocol->store(err->msg, system_charset_info);
++ if (protocol->write())
++ goto err;
++ }
++ mysql_reset_errors(thd, true);
++ }
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++
++send_result_message:
++
++ DBUG_PRINT("info", ("result_code: %d", result_code));
++ switch (result_code) {
++ case HA_ADMIN_NOT_IMPLEMENTED:
++ {
++ char buf[MYSQL_ERRMSG_SIZE];
++ size_t length=my_snprintf(buf, sizeof(buf),
++ ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
++ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
++ protocol->store(buf, length, system_charset_info);
++ }
++ break;
++
++ case HA_ADMIN_NOT_BASE_TABLE:
++ {
++ char buf[MYSQL_ERRMSG_SIZE];
++ size_t length= my_snprintf(buf, sizeof(buf),
++ ER(ER_BAD_TABLE_ERROR), table_name);
++ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
++ protocol->store(buf, length, system_charset_info);
++ }
++ break;
++
++ case HA_ADMIN_OK:
++ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
++ break;
++
++ case HA_ADMIN_FAILED:
++ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Operation failed"),
++ system_charset_info);
++ break;
++
++ case HA_ADMIN_REJECT:
++ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Operation need committed state"),
++ system_charset_info);
++ open_for_modify= FALSE;
++ break;
++
++ case HA_ADMIN_ALREADY_DONE:
++ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Table is already up to date"),
++ system_charset_info);
++ break;
++
++ case HA_ADMIN_CORRUPT:
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Corrupt"), system_charset_info);
++ fatal_error=1;
++ break;
++
++ case HA_ADMIN_INVALID:
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ protocol->store(STRING_WITH_LEN("Invalid argument"),
++ system_charset_info);
++ break;
++
++ case HA_ADMIN_TRY_ALTER:
++ {
++ /*
++ This is currently used only by InnoDB. ha_innobase::optimize() answers
++ "try with alter", so here we close the table, do an ALTER TABLE,
++ reopen the table and do ha_innobase::analyze() on it.
++ We have to end the row, so analyze could return more rows.
++ */
++ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
++ protocol->store(STRING_WITH_LEN(
++ "Table does not support optimize, doing recreate + analyze instead"),
++ system_charset_info);
++ if (protocol->write())
++ goto err;
++ ha_autocommit_or_rollback(thd, 0);
++ close_thread_tables(thd);
++ DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
++ TABLE_LIST *save_next_local= table->next_local,
++ *save_next_global= table->next_global;
++ table->next_local= table->next_global= 0;
++ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
++ result_code= mysql_recreate_table(thd, table);
++ reenable_binlog(thd);
++ /*
++ mysql_recreate_table() can push OK or ERROR.
++ Clear 'OK' status. If there is an error, keep it:
++ we will store the error message in a result set row
++ and then clear.
++ */
++ if (thd->main_da.is_ok())
++ thd->main_da.reset_diagnostics_area();
++ ha_autocommit_or_rollback(thd, 0);
++ close_thread_tables(thd);
++ if (!result_code) // recreation went ok
++ {
++ if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
++ ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
++ result_code= 0; // analyze went ok
++ }
++ /* Start a new row for the final status row */
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++ if (result_code) // either mysql_recreate_table or analyze failed
++ {
++ DBUG_ASSERT(thd->is_error());
++ if (thd->is_error())
++ {
++ const char *err_msg= thd->main_da.message();
++ if (!thd->vio_ok())
++ {
++ sql_print_error("%s", err_msg);
++ }
++ else
++ {
++ /* Hijack the row already in-progress. */
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ protocol->store(err_msg, system_charset_info);
++ if (protocol->write())
++ goto err;
++ /* Start off another row for HA_ADMIN_FAILED */
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++ protocol->store(operator_name, system_charset_info);
++ }
++ thd->clear_error();
++ }
++ }
++ result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
++ table->next_local= save_next_local;
++ table->next_global= save_next_global;
++ goto send_result_message;
++ }
++ case HA_ADMIN_WRONG_CHECKSUM:
++ {
++ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
++ protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
++ system_charset_info);
++ break;
++ }
++
++ case HA_ADMIN_NEEDS_UPGRADE:
++ case HA_ADMIN_NEEDS_ALTER:
++ {
++ char buf[MYSQL_ERRMSG_SIZE];
++ size_t length;
++
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
++ table->table_name);
++ protocol->store(buf, length, system_charset_info);
++ fatal_error=1;
++ break;
++ }
++
++ default: // Probably HA_ADMIN_INTERNAL_ERROR
++ {
++ char buf[MYSQL_ERRMSG_SIZE];
++ size_t length=my_snprintf(buf, sizeof(buf),
++ "Unknown - internal error %d during operation",
++ result_code);
++ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
++ protocol->store(buf, length, system_charset_info);
++ fatal_error=1;
++ break;
++ }
++ }
++ if (table->table)
++ {
++ if (fatal_error)
++ table->table->s->version=0; // Force close of table
++ else if (open_for_modify)
++ {
++ if (table->table->s->tmp_table)
++ table->table->file->info(HA_STATUS_CONST);
++ else
++ {
++ pthread_mutex_lock(&LOCK_open);
++ remove_table_from_cache(thd, table->table->s->db.str,
++ table->table->s->table_name.str, RTFC_NO_FLAG);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ /* May be something modified consequently we have to invalidate cache */
++ query_cache_invalidate3(thd, table->table, 0);
++ }
++ }
++ ha_autocommit_or_rollback(thd, 0);
++ end_trans(thd, COMMIT);
++ close_thread_tables(thd);
++ table->table=0; // For query cache
++ if (protocol->write())
++ goto err;
++ }
++
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++
++err:
++ ha_autocommit_or_rollback(thd, 1);
++ end_trans(thd, ROLLBACK);
++ close_thread_tables(thd); // Shouldn't be needed
++ if (table)
++ table->table=0;
++ DBUG_RETURN(TRUE);
++}
++
++
++bool mysql_backup_table(THD* thd, TABLE_LIST* table_list)
++{
++ DBUG_ENTER("mysql_backup_table");
++ WARN_DEPRECATED(thd, "6.0", "BACKUP TABLE",
++ "MySQL Administrator (mysqldump, mysql)");
++ DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
++ "backup", TL_READ, 0, 0, 0, 0,
++ &handler::ha_backup, 0));
++}
++
++
++bool mysql_restore_table(THD* thd, TABLE_LIST* table_list)
++{
++ DBUG_ENTER("mysql_restore_table");
++ WARN_DEPRECATED(thd, "6.0", "RESTORE TABLE",
++ "MySQL Administrator (mysqldump, mysql)");
++ DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
++ "restore", TL_WRITE, 1, 1, 0,
++ &prepare_for_restore,
++ &handler::ha_restore, 0));
++}
++
++
++bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
++{
++ DBUG_ENTER("mysql_repair_table");
++ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
++ "repair", TL_WRITE, 1,
++ test(check_opt->sql_flags & TT_USEFRM),
++ HA_OPEN_FOR_REPAIR,
++ &prepare_for_repair,
++ &handler::ha_repair, 0));
++}
++
++
++bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
++{
++ DBUG_ENTER("mysql_optimize_table");
++ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
++ "optimize", TL_WRITE, 1,0,0,0,
++ &handler::ha_optimize, 0));
++}
++
++
++/*
++ Assigned specified indexes for a table into key cache
++
++ SYNOPSIS
++ mysql_assign_to_keycache()
++ thd Thread object
++ tables Table list (one table only)
++
++ RETURN VALUES
++ FALSE ok
++ TRUE error
++*/
++
++bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
++ LEX_STRING *key_cache_name)
++{
++ HA_CHECK_OPT check_opt;
++ KEY_CACHE *key_cache;
++ DBUG_ENTER("mysql_assign_to_keycache");
++
++ check_opt.init();
++ pthread_mutex_lock(&LOCK_global_system_variables);
++ if (!(key_cache= get_key_cache(key_cache_name)))
++ {
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
++ DBUG_RETURN(TRUE);
++ }
++ pthread_mutex_unlock(&LOCK_global_system_variables);
++ check_opt.key_cache= key_cache;
++ DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
++ "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
++ 0, 0, &handler::assign_to_keycache, 0));
++}
++
++
++/*
++ Reassign all tables assigned to a key cache to another key cache
++
++ SYNOPSIS
++ reassign_keycache_tables()
++ thd Thread object
++ src_cache Reference to the key cache to clean up
++ dest_cache New key cache
++
++ NOTES
++ This is called when one sets a key cache size to zero, in which
++ case we have to move the tables associated to this key cache to
++ the "default" one.
++
++ One has to ensure that one never calls this function while
++ some other thread is changing the key cache. This is assured by
++ the caller setting src_cache->in_init before calling this function.
++
++ We don't delete the old key cache as there may still be pointers pointing
++ to it for a while after this function returns.
++
++ RETURN VALUES
++ 0 ok
++*/
++
++int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
++ KEY_CACHE *dst_cache)
++{
++ DBUG_ENTER("reassign_keycache_tables");
++
++ DBUG_ASSERT(src_cache != dst_cache);
++ DBUG_ASSERT(src_cache->in_init);
++ src_cache->param_buff_size= 0; // Free key cache
++ ha_resize_key_cache(src_cache);
++ ha_change_key_cache(src_cache, dst_cache);
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Preload specified indexes for a table into key cache
++
++ SYNOPSIS
++ mysql_preload_keys()
++ thd Thread object
++ tables Table list (one table only)
++
++ RETURN VALUES
++ FALSE ok
++ TRUE error
++*/
++
++bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
++{
++ DBUG_ENTER("mysql_preload_keys");
++ /*
++ We cannot allow concurrent inserts. The storage engine reads
++ directly from the index file, bypassing the cache. It could read
++ outdated information if parallel inserts into cache blocks happen.
++ */
++ DBUG_RETURN(mysql_admin_table(thd, tables, 0,
++ "preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
++ &handler::preload_keys, 0));
++}
++
++
++
++/**
++ @brief Create frm file based on I_S table
++
++ @param[in] thd thread handler
++ @param[in] schema_table I_S table
++ @param[in] dst_path path where frm should be created
++ @param[in] create_info Create info
++
++ @return Operation status
++ @retval 0 success
++ @retval 1 error
++*/
++
++
++bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
++ char *dst_path, HA_CREATE_INFO *create_info)
++{
++ HA_CREATE_INFO local_create_info;
++ Alter_info alter_info;
++ bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
++ uint keys= schema_table->table->s->keys;
++ uint db_options= 0;
++ DBUG_ENTER("mysql_create_like_schema_frm");
++
++ bzero((char*) &local_create_info, sizeof(local_create_info));
++ local_create_info.db_type= schema_table->table->s->db_type();
++ local_create_info.row_type= schema_table->table->s->row_type;
++ local_create_info.default_table_charset=default_charset_info;
++ alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
++ schema_table->table->use_all_columns();
++ if (mysql_prepare_alter_table(thd, schema_table->table,
++ &local_create_info, &alter_info))
++ DBUG_RETURN(1);
++ if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
++ tmp_table, &db_options,
++ schema_table->table->file,
++ &schema_table->table->s->key_info, &keys, 0))
++ DBUG_RETURN(1);
++ local_create_info.max_rows= 0;
++ if (mysql_create_frm(thd, dst_path, NullS, NullS,
++ &local_create_info, alter_info.create_list,
++ keys, schema_table->table->s->key_info,
++ schema_table->table->file))
++ DBUG_RETURN(1);
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Create a table identical to the specified table
++
++ SYNOPSIS
++ mysql_create_like_table()
++ thd Thread object
++ table Table list element for target table
++ src_table Table list element for source table
++ create_info Create info
++
++ RETURN VALUES
++ FALSE OK
++ TRUE error
++*/
++
++bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
++ HA_CREATE_INFO *create_info)
++{
++ TABLE *name_lock= 0;
++ char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1];
++ uint dst_path_length;
++ char *db= table->db;
++ char *table_name= table->table_name;
++ int err;
++ bool res= TRUE;
++ uint not_used;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ char tmp_path[FN_REFLEN];
++#endif
++ char ts_name[FN_LEN + 1];
++ myf flags= MY_DONT_OVERWRITE_FILE;
++ DBUG_ENTER("mysql_create_like_table");
++
++
++ /*
++ By opening source table we guarantee that it exists and no concurrent
++ DDL operation will mess with it. Later we also take an exclusive
++ name-lock on target table name, which makes copying of .frm file,
++ call to ha_create_table() and binlogging atomic against concurrent DML
++ and DDL operations on target table. Thus by holding both these "locks"
++ we ensure that our statement is properly isolated from all concurrent
++ operations which matter.
++ */
++ if (open_tables(thd, &src_table, ¬_used, 0))
++ DBUG_RETURN(TRUE);
++
++ /*
++ For bug#25875, Newly created table through CREATE TABLE .. LIKE
++ has no ndb_dd attributes;
++ Add something to get possible tablespace info from src table,
++ it can get valid tablespace name only for disk-base ndb table
++ */
++ if ((src_table->table->file->get_tablespace_name(thd, ts_name, FN_LEN)))
++ {
++ create_info->tablespace= ts_name;
++ create_info->storage_media= HA_SM_DISK;
++ }
++
++ strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
++
++ DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
++
++ /*
++ Check that destination tables does not exist. Note that its name
++ was already checked when it was added to the table list.
++ */
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
++ {
++ if (src_table->table->file->ht == partition_hton)
++ {
++ my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
++ goto err;
++ }
++ if (find_temporary_table(thd, db, table_name))
++ goto table_exists;
++ dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
++ create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
++ }
++ else
++ {
++ if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
++ goto err;
++ if (!name_lock)
++ goto table_exists;
++ dst_path_length= build_table_filename(dst_path, sizeof(dst_path) - 1,
++ db, table_name, reg_ext, 0);
++ if (!access(dst_path, F_OK))
++ goto table_exists;
++ }
++
++ DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
++
++ if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
++ flags|= MY_SYNC;
++
++ /*
++ Create a new table by copying from source table
++ and sync the new table if the flag MY_SYNC is set
++
++ Altough exclusive name-lock on target table protects us from concurrent
++ DML and DDL operations on it we still want to wrap .FRM creation and call
++ to ha_create_table() in critical section protected by LOCK_open in order
++ to provide minimal atomicity against operations which disregard name-locks,
++ like I_S implementation, for example. This is a temporary and should not
++ be copied. Instead we should fix our code to always honor name-locks.
++
++ Also some engines (e.g. NDB cluster) require that LOCK_open should be held
++ during the call to ha_create_table(). See bug #28614 for more info.
++ */
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (src_table->schema_table)
++ {
++ if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ goto err;
++ }
++ }
++ else if (my_copy(src_path, dst_path, flags))
++ {
++ if (my_errno == ENOENT)
++ my_error(ER_BAD_DB_ERROR,MYF(0),db);
++ else
++ my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ goto err;
++ }
++
++ /*
++ As mysql_truncate don't work on a new table at this stage of
++ creation, instead create the table directly (for both normal
++ and temporary tables).
++ */
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ /*
++ For partitioned tables we need to copy the .par file as well since
++ it is used in open_table_def to even be able to create a new handler.
++ */
++ if (src_table->table->file->ht == partition_hton)
++ {
++ fn_format(tmp_path, dst_path, reg_ext, ".par", MYF(MY_REPLACE_EXT));
++ strmov(dst_path, tmp_path);
++ fn_format(tmp_path, src_path, reg_ext, ".par", MYF(MY_REPLACE_EXT));
++ strmov(src_path, tmp_path);
++ my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE));
++ }
++#endif
++
++ DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
++
++ dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
++ if (thd->variables.keep_files_on_create)
++ create_info->options|= HA_CREATE_KEEP_FILES;
++ err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
++ {
++ if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
++ {
++ (void) rm_temporary_table(create_info->db_type,
++ dst_path); /* purecov: inspected */
++ goto err; /* purecov: inspected */
++ }
++ thd->thread_specific_used= TRUE;
++ }
++ else if (err)
++ {
++ (void) quick_rm_table(create_info->db_type, db,
++ table_name, 0); /* purecov: inspected */
++ goto err; /* purecov: inspected */
++ }
++
++goto binlog;
++
++table_exists:
++ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
++ {
++ char warn_buff[MYSQL_ERRMSG_SIZE];
++ my_snprintf(warn_buff, sizeof(warn_buff),
++ ER(ER_TABLE_EXISTS_ERROR), table_name);
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_TABLE_EXISTS_ERROR,warn_buff);
++ }
++ else
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
++ goto err;
++ }
++
++binlog:
++ DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
++
++ /*
++ We have to write the query before we unlock the tables.
++ */
++ if (thd->current_stmt_binlog_row_based)
++ {
++ /*
++ Since temporary tables are not replicated under row-based
++ replication, CREATE TABLE ... LIKE ... needs special
++ treatement. We have four cases to consider, according to the
++ following decision table:
++
++ ==== ========= ========= ==============================
++ Case Target Source Write to binary log
++ ==== ========= ========= ==============================
++ 1 normal normal Original statement
++ 2 normal temporary Generated statement
++ 3 temporary normal Nothing
++ 4 temporary temporary Nothing
++ ==== ========= ========= ==============================
++ */
++ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
++ {
++ if (src_table->table->s->tmp_table) // Case 2
++ {
++ char buf[2048];
++ String query(buf, sizeof(buf), system_charset_info);
++ query.length(0); // Have to zero it since constructor doesn't
++
++ /*
++ Here we open the destination table, on which we already have
++ name-lock. This is needed for store_create_info() to work.
++ The table will be closed by unlink_open_table() at the end
++ of this function.
++ */
++ table->table= name_lock;
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (reopen_name_locked_table(thd, table, FALSE))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ goto err;
++ }
++ VOID(pthread_mutex_unlock(&LOCK_open));
++
++ /*
++ The condition avoids a crash as described in BUG#48506. Other
++ binlogging problems related to CREATE TABLE IF NOT EXISTS LIKE
++ when the existing object is a view will be solved by BUG 47442.
++ */
++ if (!table->view)
++ {
++ IF_DBUG(int result=)
++ store_create_info(thd, table, &query,
++ create_info, FALSE /* show_database */);
++
++ DBUG_ASSERT(result == 0); // store_create_info() always return 0
++ if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
++ goto err;
++ }
++ }
++ else // Case 1
++ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
++ goto err;
++ }
++ /*
++ Case 3 and 4 does nothing under RBR
++ */
++ }
++ else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
++ goto err;
++
++ res= FALSE;
++
++err:
++ if (name_lock)
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlink_open_table(thd, name_lock, FALSE);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ DBUG_RETURN(res);
++}
++
++
++bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
++{
++ thr_lock_type lock_type = TL_READ_NO_INSERT;
++
++ DBUG_ENTER("mysql_analyze_table");
++ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
++ "analyze", lock_type, 1, 0, 0, 0,
++ &handler::ha_analyze, 0));
++}
++
++
++bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
++{
++ thr_lock_type lock_type = TL_READ_NO_INSERT;
++
++ DBUG_ENTER("mysql_check_table");
++ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
++ "check", lock_type,
++ 0, 0, HA_OPEN_FOR_REPAIR, 0,
++ &handler::ha_check, &view_checksum));
++}
++
++
++/* table_list should contain just one table */
++static int
++mysql_discard_or_import_tablespace(THD *thd,
++ TABLE_LIST *table_list,
++ enum tablespace_op_type tablespace_op)
++{
++ TABLE *table;
++ my_bool discard;
++ int error;
++ DBUG_ENTER("mysql_discard_or_import_tablespace");
++
++ /*
++ Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
++ ALTER TABLE
++ */
++
++ thd_proc_info(thd, "discard_or_import_tablespace");
++
++ discard= test(tablespace_op == DISCARD_TABLESPACE);
++
++ /*
++ We set this flag so that ha_innobase::open and ::external_lock() do
++ not complain when we lock the table
++ */
++ thd->tablespace_op= TRUE;
++ if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
++ {
++ thd->tablespace_op=FALSE;
++ DBUG_RETURN(-1);
++ }
++
++ error= table->file->ha_discard_or_import_tablespace(discard);
++
++ thd_proc_info(thd, "end");
++
++ if (error)
++ goto err;
++
++ /*
++ The 0 in the call below means 'not in a transaction', which means
++ immediate invalidation; that is probably what we wish here
++ */
++ query_cache_invalidate3(thd, table_list, 0);
++
++ /* The ALTER TABLE is always in its own transaction */
++ error = ha_autocommit_or_rollback(thd, 0);
++ if (end_active_trans(thd))
++ error=1;
++ if (error)
++ goto err;
++ error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
++
++err:
++ ha_autocommit_or_rollback(thd, error);
++ thd->tablespace_op=FALSE;
++
++ if (error == 0)
++ {
++ my_ok(thd);
++ DBUG_RETURN(0);
++ }
++
++ table->file->print_error(error, MYF(0));
++
++ DBUG_RETURN(-1);
++}
++
++/**
++ @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
++
++ @details Checks if any index is being modified (present as both DROP INDEX
++ and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling
++ online ALTER TABLE.
++
++ @param table The table being altered
++ @param alter_info The ALTER TABLE structure
++ @return presence of index being altered
++ @retval FALSE No such index
++ @retval TRUE Have at least 1 index modified
++*/
++
++static bool
++is_index_maintenance_unique (TABLE *table, Alter_info *alter_info)
++{
++ List_iterator<Key> key_it(alter_info->key_list);
++ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
++ Key *key;
++
++ while ((key= key_it++))
++ {
++ if (key->name)
++ {
++ Alter_drop *drop;
++
++ drop_it.rewind();
++ while ((drop= drop_it++))
++ {
++ if (drop->type == Alter_drop::KEY &&
++ !my_strcasecmp(system_charset_info, key->name, drop->name))
++ return TRUE;
++ }
++ }
++ }
++ return FALSE;
++}
++
++
++/*
++ SYNOPSIS
++ compare_tables()
++ table The original table.
++ alter_info Alter options, fields and keys for the new
++ table.
++ create_info Create options for the new table.
++ order_num Number of order list elements.
++ need_copy_table OUT Result of the comparison. Undefined if error.
++ Otherwise is one of:
++ ALTER_TABLE_METADATA_ONLY No copy needed
++ ALTER_TABLE_DATA_CHANGED Data changes,
++ copy needed
++ ALTER_TABLE_INDEX_CHANGED Index changes,
++ copy might be needed
++ key_info_buffer OUT An array of KEY structs for new indexes
++ index_drop_buffer OUT An array of offsets into table->key_info.
++ index_drop_count OUT The number of elements in the array.
++ index_add_buffer OUT An array of offsets into key_info_buffer.
++ index_add_count OUT The number of elements in the array.
++ candidate_key_count OUT The number of candidate keys in original table.
++
++ DESCRIPTION
++ 'table' (first argument) contains information of the original
++ table, which includes all corresponding parts that the new
++ table has in arguments create_list, key_list and create_info.
++
++ By comparing the changes between the original and new table
++ we can determine how much it has changed after ALTER TABLE
++ and whether we need to make a copy of the table, or just change
++ the .frm file.
++
++ If there are no data changes, but index changes, 'index_drop_buffer'
++ and/or 'index_add_buffer' are populated with offsets into
++ table->key_info or key_info_buffer respectively for the indexes
++ that need to be dropped and/or (re-)created.
++
++ RETURN VALUES
++ TRUE error
++ FALSE success
++*/
++
++static
++bool
++compare_tables(TABLE *table,
++ Alter_info *alter_info,
++ HA_CREATE_INFO *create_info,
++ uint order_num,
++ enum_alter_table_change_level *need_copy_table,
++ KEY **key_info_buffer,
++ uint **index_drop_buffer, uint *index_drop_count,
++ uint **index_add_buffer, uint *index_add_count,
++ uint *candidate_key_count)
++{
++ Field **f_ptr, *field;
++ uint changes= 0, tmp;
++ uint key_count;
++ List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
++ Create_field *new_field, *tmp_new_field;
++ KEY_PART_INFO *key_part;
++ KEY_PART_INFO *end;
++ THD *thd= table->in_use;
++ /*
++ Remember if the new definition has new VARCHAR column;
++ create_info->varchar will be reset in mysql_prepare_create_table.
++ */
++ bool varchar= create_info->varchar;
++ bool not_nullable= true;
++ DBUG_ENTER("compare_tables");
++
++ /*
++ Create a copy of alter_info.
++ To compare the new and old table definitions, we need to "prepare"
++ the new definition - transform it from parser output to a format
++ that describes the final table layout (all column defaults are
++ initialized, duplicate columns are removed). This is done by
++ mysql_prepare_create_table. Unfortunately,
++ mysql_prepare_create_table performs its transformations
++ "in-place", that is, modifies the argument. Since we would
++ like to keep compare_tables() idempotent (not altering any
++ of the arguments) we create a copy of alter_info here and
++ pass it to mysql_prepare_create_table, then use the result
++ to evaluate possibility of fast ALTER TABLE, and then
++ destroy the copy.
++ */
++ Alter_info tmp_alter_info(*alter_info, thd->mem_root);
++ uint db_options= 0; /* not used */
++
++ /* Create the prepared information. */
++ if (mysql_prepare_create_table(thd, create_info,
++ &tmp_alter_info,
++ (table->s->tmp_table != NO_TMP_TABLE),
++ &db_options,
++ table->file, key_info_buffer,
++ &key_count, 0))
++ DBUG_RETURN(1);
++ /* Allocate result buffers. */
++ if (! (*index_drop_buffer=
++ (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
++ ! (*index_add_buffer=
++ (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
++ DBUG_RETURN(1);
++
++ /*
++ Some very basic checks. If number of fields changes, or the
++ handler, we need to run full ALTER TABLE. In the future
++ new fields can be added and old dropped without copy, but
++ not yet.
++
++ Test also that engine was not given during ALTER TABLE, or
++ we are force to run regular alter table (copy).
++ E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
++
++ For the following ones we also want to run regular alter table:
++ ALTER TABLE tbl_name ORDER BY ..
++ ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
++
++ At the moment we can't handle altering temporary tables without a copy.
++ We also test if OPTIMIZE TABLE was given and was mapped to alter table.
++ In that case we always do full copy.
++
++ There was a bug prior to mysql-4.0.25. Number of null fields was
++ calculated incorrectly. As a result frm and data files gets out of
++ sync after fast alter table. There is no way to determine by which
++ mysql version (in 4.0 and 4.1 branches) table was created, thus we
++ disable fast alter table for all tables created by mysql versions
++ prior to 5.0 branch.
++ See BUG#6236.
++ */
++ if (table->s->fields != alter_info->create_list.elements ||
++ table->s->db_type() != create_info->db_type ||
++ table->s->tmp_table ||
++ create_info->used_fields & HA_CREATE_USED_ENGINE ||
++ create_info->used_fields & HA_CREATE_USED_CHARSET ||
++ create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
++ (table->s->row_type != create_info->row_type) ||
++ create_info->used_fields & HA_CREATE_USED_PACK_KEYS ||
++ create_info->used_fields & HA_CREATE_USED_MAX_ROWS ||
++ (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
++ order_num ||
++ !table->s->mysql_version ||
++ (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
++ {
++ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
++ DBUG_RETURN(0);
++ }
++
++ /*
++ Use transformed info to evaluate possibility of fast ALTER TABLE
++ but use the preserved field to persist modifications.
++ */
++ new_field_it.init(alter_info->create_list);
++ tmp_new_field_it.init(tmp_alter_info.create_list);
++
++ /*
++ Go through fields and check if the original ones are compatible
++ with new table.
++ */
++ for (f_ptr= table->field, new_field= new_field_it++,
++ tmp_new_field= tmp_new_field_it++;
++ (field= *f_ptr);
++ f_ptr++, new_field= new_field_it++,
++ tmp_new_field= tmp_new_field_it++)
++ {
++ /* Make sure we have at least the default charset in use. */
++ if (!new_field->charset)
++ new_field->charset= create_info->default_table_charset;
++
++ /* Check that NULL behavior is same for old and new fields */
++ if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
++ (uint) (field->flags & NOT_NULL_FLAG))
++ {
++ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
++ DBUG_RETURN(0);
++ }
++
++ /* Don't pack rows in old tables if the user has requested this. */
++ if (create_info->row_type == ROW_TYPE_DYNAMIC ||
++ (tmp_new_field->flags & BLOB_FLAG) ||
++ (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
++ create_info->row_type != ROW_TYPE_FIXED))
++ create_info->table_options|= HA_OPTION_PACK_RECORD;
++
++ /* Check if field was renamed */
++ field->flags&= ~FIELD_IS_RENAMED;
++ if (my_strcasecmp(system_charset_info,
++ field->field_name,
++ tmp_new_field->field_name))
++ field->flags|= FIELD_IS_RENAMED;
++
++ /* Evaluate changes bitmap and send to check_if_incompatible_data() */
++ if (!(tmp= field->is_equal(tmp_new_field)))
++ {
++ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
++ DBUG_RETURN(0);
++ }
++ // Clear indexed marker
++ field->flags&= ~FIELD_IN_ADD_INDEX;
++ changes|= tmp;
++ }
++
++ /*
++ Go through keys and check if the original ones are compatible
++ with new table.
++ */
++ KEY *table_key;
++ KEY *table_key_end= table->key_info + table->s->keys;
++ KEY *new_key;
++ KEY *new_key_end= *key_info_buffer + key_count;
++
++ DBUG_PRINT("info", ("index count old: %d new: %d",
++ table->s->keys, key_count));
++ /*
++ Step through all keys of the old table and search matching new keys.
++ */
++ *index_drop_count= 0;
++ *index_add_count= 0;
++ *candidate_key_count= 0;
++ for (table_key= table->key_info; table_key < table_key_end; table_key++)
++ {
++ KEY_PART_INFO *table_part;
++ KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
++ KEY_PART_INFO *new_part;
++
++ /*
++ Check if key is a candidate key, i.e. a unique index with no index
++ fields nullable, then key is either already primary key or could
++ be promoted to primary key if the original primary key is dropped.
++ Count all candidate keys.
++ */
++ not_nullable= true;
++ for (table_part= table_key->key_part;
++ table_part < table_part_end;
++ table_part++)
++ {
++ not_nullable= not_nullable && (! table_part->field->maybe_null());
++ }
++ if ((table_key->flags & HA_NOSAME) && not_nullable)
++ (*candidate_key_count)++;
++
++ /* Search a new key with the same name. */
++ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
++ {
++ if (! strcmp(table_key->name, new_key->name))
++ break;
++ }
++ if (new_key >= new_key_end)
++ {
++ /* Key not found. Add the offset of the key to the drop buffer. */
++ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
++ DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
++ continue;
++ }
++
++ /* Check that the key types are compatible between old and new tables. */
++ if ((table_key->algorithm != new_key->algorithm) ||
++ ((table_key->flags & HA_KEYFLAG_MASK) !=
++ (new_key->flags & HA_KEYFLAG_MASK)) ||
++ (table_key->key_parts != new_key->key_parts))
++ goto index_changed;
++
++ /*
++ Check that the key parts remain compatible between the old and
++ new tables.
++ */
++ for (table_part= table_key->key_part, new_part= new_key->key_part;
++ table_part < table_part_end;
++ table_part++, new_part++)
++ {
++ /*
++ Key definition has changed if we are using a different field or
++ if the used key part length is different. We know that the fields
++ did not change. Comparing field numbers is sufficient.
++ */
++ if ((table_part->length != new_part->length) ||
++ (table_part->fieldnr - 1 != new_part->fieldnr))
++ goto index_changed;
++ }
++ continue;
++
++ index_changed:
++ /* Key modified. Add the offset of the key to both buffers. */
++ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
++ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
++ key_part= new_key->key_part;
++ end= key_part + new_key->key_parts;
++ for(; key_part != end; key_part++)
++ {
++ // Mark field to be part of new key
++ field= table->field[key_part->fieldnr];
++ field->flags|= FIELD_IN_ADD_INDEX;
++ }
++ DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
++ }
++ /*end of for (; table_key < table_key_end;) */
++
++ /*
++ Step through all keys of the new table and find matching old keys.
++ */
++ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
++ {
++ /* Search an old key with the same name. */
++ for (table_key= table->key_info; table_key < table_key_end; table_key++)
++ {
++ if (! strcmp(table_key->name, new_key->name))
++ break;
++ }
++ if (table_key >= table_key_end)
++ {
++ /* Key not found. Add the offset of the key to the add buffer. */
++ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
++ key_part= new_key->key_part;
++ end= key_part + new_key->key_parts;
++ for(; key_part != end; key_part++)
++ {
++ // Mark field to be part of new key
++ field= table->field[key_part->fieldnr];
++ field->flags|= FIELD_IN_ADD_INDEX;
++ }
++ DBUG_PRINT("info", ("index added: '%s'", new_key->name));
++ }
++ }
++
++ /* Check if changes are compatible with current handler without a copy */
++ if (table->file->check_if_incompatible_data(create_info, changes))
++ {
++ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
++ DBUG_RETURN(0);
++ }
++
++ if (*index_drop_count || *index_add_count)
++ {
++ *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
++ DBUG_RETURN(0);
++ }
++
++ *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
++ DBUG_RETURN(0);
++}
++
++
++/*
++ Manages enabling/disabling of indexes for ALTER TABLE
++
++ SYNOPSIS
++ alter_table_manage_keys()
++ table Target table
++ indexes_were_disabled Whether the indexes of the from table
++ were disabled
++ keys_onoff ENABLE | DISABLE | LEAVE_AS_IS
++
++ RETURN VALUES
++ FALSE OK
++ TRUE Error
++*/
++
++static
++bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
++ enum enum_enable_or_disable keys_onoff)
++{
++ int error= 0;
++ DBUG_ENTER("alter_table_manage_keys");
++ DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
++ table, indexes_were_disabled, keys_onoff));
++
++ switch (keys_onoff) {
++ case ENABLE:
++ error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
++ break;
++ case LEAVE_AS_IS:
++ if (!indexes_were_disabled)
++ break;
++ /* fall-through: disabled indexes */
++ case DISABLE:
++ error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
++ }
++
++ if (error == HA_ERR_WRONG_COMMAND)
++ {
++ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
++ table->s->table_name.str);
++ error= 0;
++ } else if (error)
++ table->file->print_error(error, MYF(0));
++
++ DBUG_RETURN(error);
++}
++
++
++/**
++ Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
++
++ This function transforms parse output of ALTER TABLE - lists of
++ columns and keys to add, drop or modify into, essentially,
++ CREATE TABLE definition - a list of columns and keys of the new
++ table. While doing so, it also performs some (bug not all)
++ semantic checks.
++
++ This function is invoked when we know that we're going to
++ perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
++ is not possible, perhaps because the ALTER statement contains
++ instructions that require change in table data, not only in
++ table definition or indexes.
++
++ @param[in,out] thd thread handle. Used as a memory pool
++ and source of environment information.
++ @param[in] table the source table, open and locked
++ Used as an interface to the storage engine
++ to acquire additional information about
++ the original table.
++ @param[in,out] create_info A blob with CREATE/ALTER TABLE
++ parameters
++ @param[in,out] alter_info Another blob with ALTER/CREATE parameters.
++ Originally create_info was used only in
++ CREATE TABLE and alter_info only in ALTER TABLE.
++ But since ALTER might end-up doing CREATE,
++ this distinction is gone and we just carry
++ around two structures.
++
++ @return
++ Fills various create_info members based on information retrieved
++ from the storage engine.
++ Sets create_info->varchar if the table has a VARCHAR column.
++ Prepares alter_info->create_list and alter_info->key_list with
++ columns and keys of the new table.
++ @retval TRUE error, out of memory or a semantical error in ALTER
++ TABLE instructions
++ @retval FALSE success
++*/
++
++static bool
++mysql_prepare_alter_table(THD *thd, TABLE *table,
++ HA_CREATE_INFO *create_info,
++ Alter_info *alter_info)
++{
++ /* New column definitions are added here */
++ List<Create_field> new_create_list;
++ /* New key definitions are added here */
++ List<Key> new_key_list;
++ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
++ List_iterator<Create_field> def_it(alter_info->create_list);
++ List_iterator<Alter_column> alter_it(alter_info->alter_list);
++ List_iterator<Key> key_it(alter_info->key_list);
++ List_iterator<Create_field> find_it(new_create_list);
++ List_iterator<Create_field> field_it(new_create_list);
++ List<Key_part_spec> key_parts;
++ uint db_create_options= (table->s->db_create_options
++ & ~(HA_OPTION_PACK_RECORD));
++ uint used_fields= create_info->used_fields;
++ KEY *key_info=table->key_info;
++ bool rc= TRUE;
++
++ DBUG_ENTER("mysql_prepare_alter_table");
++
++ create_info->varchar= FALSE;
++ /* Let new create options override the old ones */
++ if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
++ create_info->min_rows= table->s->min_rows;
++ if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
++ create_info->max_rows= table->s->max_rows;
++ if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
++ create_info->avg_row_length= table->s->avg_row_length;
++ if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
++ create_info->default_table_charset= table->s->table_charset;
++ if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
++ {
++ /* Table has an autoincrement, copy value to new table */
++ table->file->info(HA_STATUS_AUTO);
++ create_info->auto_increment_value= table->file->stats.auto_increment_value;
++ }
++ if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
++ create_info->key_block_size= table->s->key_block_size;
++
++ if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY)
++ {
++ char *tablespace= static_cast<char *>(thd->alloc(FN_LEN + 1));
++ /*
++ Regular alter table of disk stored table (no tablespace/storage change)
++ Copy tablespace name
++ */
++ if (tablespace &&
++ (table->file->get_tablespace_name(thd, tablespace, FN_LEN)))
++ create_info->tablespace= tablespace;
++ }
++ restore_record(table, s->default_values); // Empty record for DEFAULT
++ Create_field *def;
++
++ /*
++ First collect all fields from table which isn't in drop_list
++ */
++ Field **f_ptr,*field;
++ for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
++ {
++ if (field->type() == MYSQL_TYPE_STRING)
++ create_info->varchar= TRUE;
++ /* Check if field should be dropped */
++ Alter_drop *drop;
++ drop_it.rewind();
++ while ((drop=drop_it++))
++ {
++ if (drop->type == Alter_drop::COLUMN &&
++ !my_strcasecmp(system_charset_info,field->field_name, drop->name))
++ {
++ /* Reset auto_increment value if it was dropped */
++ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
++ !(used_fields & HA_CREATE_USED_AUTO))
++ {
++ create_info->auto_increment_value=0;
++ create_info->used_fields|=HA_CREATE_USED_AUTO;
++ }
++ break;
++ }
++ }
++ if (drop)
++ {
++ drop_it.remove();
++ continue;
++ }
++ /* Check if field is changed */
++ def_it.rewind();
++ while ((def=def_it++))
++ {
++ if (def->change &&
++ !my_strcasecmp(system_charset_info,field->field_name, def->change))
++ break;
++ }
++ if (def)
++ { // Field is changed
++ def->field=field;
++ if (!def->after)
++ {
++ new_create_list.push_back(def);
++ def_it.remove();
++ }
++ }
++ else
++ {
++ /*
++ This field was not dropped and not changed, add it to the list
++ for the new table.
++ */
++ def= new Create_field(field, field);
++ new_create_list.push_back(def);
++ alter_it.rewind(); // Change default if ALTER
++ Alter_column *alter;
++ while ((alter=alter_it++))
++ {
++ if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
++ break;
++ }
++ if (alter)
++ {
++ if (def->sql_type == MYSQL_TYPE_BLOB)
++ {
++ my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
++ goto err;
++ }
++ if ((def->def=alter->def)) // Use new default
++ def->flags&= ~NO_DEFAULT_VALUE_FLAG;
++ else
++ def->flags|= NO_DEFAULT_VALUE_FLAG;
++ alter_it.remove();
++ }
++ }
++ }
++ def_it.rewind();
++ while ((def=def_it++)) // Add new columns
++ {
++ if (def->change && ! def->field)
++ {
++ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
++ goto err;
++ }
++ /*
++ Check that the DATE/DATETIME not null field we are going to add is
++ either has a default value or the '0000-00-00' is allowed by the
++ set sql mode.
++ If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
++ flag to allow ALTER TABLE only if the table to be altered is empty.
++ */
++ if ((def->sql_type == MYSQL_TYPE_DATE ||
++ def->sql_type == MYSQL_TYPE_NEWDATE ||
++ def->sql_type == MYSQL_TYPE_DATETIME) &&
++ !alter_info->datetime_field &&
++ !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
++ thd->variables.sql_mode & MODE_NO_ZERO_DATE)
++ {
++ alter_info->datetime_field= def;
++ alter_info->error_if_not_empty= TRUE;
++ }
++ if (!def->after)
++ new_create_list.push_back(def);
++ else if (def->after == first_keyword)
++ new_create_list.push_front(def);
++ else
++ {
++ Create_field *find;
++ find_it.rewind();
++ while ((find=find_it++)) // Add new columns
++ {
++ if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
++ break;
++ }
++ if (!find)
++ {
++ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
++ goto err;
++ }
++ find_it.after(def); // Put element after this
++ alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
++ }
++ }
++ if (alter_info->alter_list.elements)
++ {
++ my_error(ER_BAD_FIELD_ERROR, MYF(0),
++ alter_info->alter_list.head()->name, table->s->table_name.str);
++ goto err;
++ }
++ if (!new_create_list.elements)
++ {
++ my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
++ MYF(0));
++ goto err;
++ }
++
++ /*
++ Collect all keys which isn't in drop list. Add only those
++ for which some fields exists.
++ */
++
++ for (uint i=0 ; i < table->s->keys ; i++,key_info++)
++ {
++ char *key_name= key_info->name;
++ Alter_drop *drop;
++ drop_it.rewind();
++ while ((drop=drop_it++))
++ {
++ if (drop->type == Alter_drop::KEY &&
++ !my_strcasecmp(system_charset_info,key_name, drop->name))
++ break;
++ }
++ if (drop)
++ {
++ drop_it.remove();
++ continue;
++ }
++
++ KEY_PART_INFO *key_part= key_info->key_part;
++ key_parts.empty();
++ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
++ {
++ if (!key_part->field)
++ continue; // Wrong field (from UNIREG)
++ const char *key_part_name=key_part->field->field_name;
++ Create_field *cfield;
++ field_it.rewind();
++ while ((cfield=field_it++))
++ {
++ if (cfield->change)
++ {
++ if (!my_strcasecmp(system_charset_info, key_part_name,
++ cfield->change))
++ break;
++ }
++ else if (!my_strcasecmp(system_charset_info,
++ key_part_name, cfield->field_name))
++ break;
++ }
++ if (!cfield)
++ continue; // Field is removed
++ uint key_part_length=key_part->length;
++ if (cfield->field) // Not new field
++ {
++ /*
++ If the field can't have only a part used in a key according to its
++ new type, or should not be used partially according to its
++ previous type, or the field length is less than the key part
++ length, unset the key part length.
++
++ We also unset the key part length if it is the same as the
++ old field's length, so the whole new field will be used.
++
++ BLOBs may have cfield->length == 0, which is why we test it before
++ checking whether cfield->length < key_part_length (in chars).
++ */
++ if (!Field::type_can_have_key_part(cfield->field->type()) ||
++ !Field::type_can_have_key_part(cfield->sql_type) ||
++ /* spatial keys can't have sub-key length */
++ (key_info->flags & HA_SPATIAL) ||
++ (cfield->field->field_length == key_part_length &&
++ !f_is_blob(key_part->key_type)) ||
++ (cfield->length && (cfield->length < key_part_length /
++ key_part->field->charset()->mbmaxlen)))
++ key_part_length= 0; // Use whole field
++ }
++ key_part_length /= key_part->field->charset()->mbmaxlen;
++ key_parts.push_back(new Key_part_spec(cfield->field_name,
++ key_part_length));
++ }
++ if (key_parts.elements)
++ {
++ KEY_CREATE_INFO key_create_info;
++ Key *key;
++ enum Key::Keytype key_type;
++ bzero((char*) &key_create_info, sizeof(key_create_info));
++
++ key_create_info.algorithm= key_info->algorithm;
++ if (key_info->flags & HA_USES_BLOCK_SIZE)
++ key_create_info.block_size= key_info->block_size;
++ if (key_info->flags & HA_USES_PARSER)
++ key_create_info.parser_name= *plugin_name(key_info->parser);
++
++ if (key_info->flags & HA_SPATIAL)
++ key_type= Key::SPATIAL;
++ else if (key_info->flags & HA_NOSAME)
++ {
++ if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
++ key_type= Key::PRIMARY;
++ else
++ key_type= Key::UNIQUE;
++ }
++ else if (key_info->flags & HA_FULLTEXT)
++ key_type= Key::FULLTEXT;
++ else
++ key_type= Key::MULTIPLE;
++
++ key= new Key(key_type, key_name,
++ &key_create_info,
++ test(key_info->flags & HA_GENERATED_KEY),
++ key_parts);
++ new_key_list.push_back(key);
++ }
++ }
++ {
++ Key *key;
++ while ((key=key_it++)) // Add new keys
++ {
++ if (key->type != Key::FOREIGN_KEY)
++ new_key_list.push_back(key);
++ if (key->name &&
++ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
++ {
++ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
++ goto err;
++ }
++ }
++ }
++
++ if (alter_info->drop_list.elements)
++ {
++ my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
++ alter_info->drop_list.head()->name);
++ goto err;
++ }
++ if (alter_info->alter_list.elements)
++ {
++ my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
++ alter_info->alter_list.head()->name);
++ goto err;
++ }
++
++ if (!create_info->comment.str)
++ {
++ create_info->comment.str= table->s->comment.str;
++ create_info->comment.length= table->s->comment.length;
++ }
++
++ table->file->update_create_info(create_info);
++ if ((create_info->table_options &
++ (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
++ (used_fields & HA_CREATE_USED_PACK_KEYS))
++ db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
++ if (create_info->table_options &
++ (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
++ db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
++ if (create_info->table_options &
++ (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
++ db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
++ HA_OPTION_NO_DELAY_KEY_WRITE);
++ create_info->table_options|= db_create_options;
++
++ if (table->s->tmp_table)
++ create_info->options|=HA_LEX_CREATE_TMP_TABLE;
++
++ rc= FALSE;
++ alter_info->create_list.swap(new_create_list);
++ alter_info->key_list.swap(new_key_list);
++err:
++ DBUG_RETURN(rc);
++}
++
++
++/*
++ Alter table
++
++ SYNOPSIS
++ mysql_alter_table()
++ thd Thread handle
++ new_db If there is a RENAME clause
++ new_name If there is a RENAME clause
++ create_info Information from the parsing phase about new
++ table properties.
++ table_list The table to change.
++ alter_info Lists of fields, keys to be changed, added
++ or dropped.
++ order_num How many ORDER BY fields has been specified.
++ order List of fields to ORDER BY.
++ ignore Whether we have ALTER IGNORE TABLE
++
++ DESCRIPTION
++ This is a veery long function and is everything but the kitchen sink :)
++ It is used to alter a table and not only by ALTER TABLE but also
++ CREATE|DROP INDEX are mapped on this function.
++
++ When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
++ or both, then this function short cuts its operation by renaming
++ the table and/or enabling/disabling the keys. In this case, the FRM is
++ not changed, directly by mysql_alter_table. However, if there is a
++ RENAME + change of a field, or an index, the short cut is not used.
++ See how `create_list` is used to generate the new FRM regarding the
++ structure of the fields. The same is done for the indices of the table.
++
++ Important is the fact, that this function tries to do as little work as
++ possible, by finding out whether a intermediate table is needed to copy
++ data into and when finishing the altering to use it as the original table.
++ For this reason the function compare_tables() is called, which decides
++ based on all kind of data how similar are the new and the original
++ tables.
++
++ RETURN VALUES
++ FALSE OK
++ TRUE Error
++*/
++
++bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
++ HA_CREATE_INFO *create_info,
++ TABLE_LIST *table_list,
++ Alter_info *alter_info,
++ uint order_num, ORDER *order, bool ignore)
++{
++ TABLE *table, *new_table= 0, *name_lock= 0;
++ int error= 0;
++ char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1];
++ char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
++ char index_file[FN_REFLEN], data_file[FN_REFLEN];
++ char path[FN_REFLEN + 1];
++ char reg_path[FN_REFLEN+1];
++ ha_rows copied,deleted;
++ handlerton *old_db_type, *new_db_type, *save_old_db_type;
++ legacy_db_type table_type;
++ frm_type_enum frm_type;
++ enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ uint fast_alter_partition= 0;
++ bool partition_changed= FALSE;
++#endif
++ bool need_lock_for_indexes= TRUE;
++ KEY *key_info_buffer;
++ uint index_drop_count= 0;
++ uint *index_drop_buffer= NULL;
++ uint index_add_count= 0;
++ uint *index_add_buffer= NULL;
++ uint candidate_key_count= 0;
++ bool no_pk;
++ DBUG_ENTER("mysql_alter_table");
++
++ /*
++ Check if we attempt to alter mysql.slow_log or
++ mysql.general_log table and return an error if
++ it is the case.
++ TODO: this design is obsolete and will be removed.
++ */
++ if (table_list && table_list->db && table_list->table_name)
++ {
++ int table_kind= 0;
++
++ table_kind= check_if_log_table(table_list->db_length, table_list->db,
++ table_list->table_name_length,
++ table_list->table_name, 0);
++
++ if (table_kind)
++ {
++ /* Disable alter of enabled log tables */
++ if (logger.is_log_table_enabled(table_kind))
++ {
++ my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
++ DBUG_RETURN(TRUE);
++ }
++
++ /* Disable alter of log tables to unsupported engine */
++ if ((create_info->used_fields & HA_CREATE_USED_ENGINE) &&
++ (!create_info->db_type || /* unknown engine */
++ !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
++ {
++ my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (alter_info->flags & ALTER_PARTITION)
++ {
++ my_error(ER_WRONG_USAGE, MYF(0), "PARTITION", "log table");
++ DBUG_RETURN(TRUE);
++ }
++#endif
++ }
++ }
++
++ /*
++ Assign variables table_name, new_name, db, new_db, path, reg_path
++ to simplify further comparisions: we want to see if it's a RENAME
++ later just by comparing the pointers, avoiding the need for strcmp.
++ */
++ thd_proc_info(thd, "init");
++ table_name=table_list->table_name;
++ alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
++ db=table_list->db;
++ if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
++ new_db= db;
++ build_table_filename(reg_path, sizeof(reg_path) - 1, db, table_name, reg_ext, 0);
++ build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0);
++
++ mysql_ha_rm_tables(thd, table_list, FALSE);
++
++ /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
++ if (alter_info->tablespace_op != NO_TABLESPACE_OP)
++ /* Conditionally writes to binlog. */
++ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
++ alter_info->tablespace_op));
++ strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
++ "/", table_name, reg_ext, NullS);
++ (void) unpack_filename(new_name_buff, new_name_buff);
++ /*
++ If this is just a rename of a view, short cut to the
++ following scenario: 1) lock LOCK_open 2) do a RENAME
++ 2) unlock LOCK_open.
++ This is a copy-paste added to make sure
++ ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
++ as an independent branch in mysql_execute_command. The need
++ for a copy-paste arose because the main code flow of ALTER TABLE
++ ... RENAME tries to use open_ltable, which does not work for views
++ (open_ltable was never modified to merge table lists of child tables
++ into the main table list, like open_tables does).
++ This code is wrong and will be removed, please do not copy.
++ */
++ frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
++ /* Rename a view */
++ /* Sic: there is a race here */
++ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME))
++ {
++ /*
++ The following branch handles "ALTER VIEW v1 /no arguments/;"
++ This feature is not documented one.
++ However, before "OPTIMIZE TABLE t1;" was implemented,
++ ALTER TABLE with no alter_specifications was used to force-rebuild
++ the table. That's why this grammar is allowed. That's why we ignore
++ it for views. So just do nothing in such a case.
++ */
++ if (!new_name)
++ {
++ my_ok(thd);
++ DBUG_RETURN(FALSE);
++ }
++
++ /*
++ Avoid problems with a rename on a table that we have locked or
++ if the user is trying to to do this in a transcation context
++ */
++
++ if (thd->locked_tables || thd->active_transaction())
++ {
++ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
++ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++ if (wait_if_global_read_lock(thd,0,1))
++ DBUG_RETURN(TRUE);
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (lock_table_names(thd, table_list))
++ {
++ error= 1;
++ goto view_err;
++ }
++
++ if (!do_rename(thd, table_list, new_db, new_name, new_name, 1))
++ {
++ if (mysql_bin_log.is_open())
++ {
++ thd->clear_error();
++ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
++ 0, FALSE, 0);
++ if ((error= mysql_bin_log.write(&qinfo)))
++ goto view_err_unlock;
++ }
++ my_ok(thd);
++ }
++
++view_err_unlock:
++ unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
++
++view_err:
++ pthread_mutex_unlock(&LOCK_open);
++ start_waiting_global_read_lock(thd);
++ DBUG_RETURN(error);
++ }
++
++ if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
++ DBUG_RETURN(TRUE);
++ table->use_all_columns();
++
++ /*
++ Prohibit changing of the UNION list of a non-temporary MERGE table
++ under LOCK tables. It would be quite difficult to reuse a shrinked
++ set of tables from the old table or to open a new TABLE object for
++ an extended list and verify that they belong to locked tables.
++ */
++ if (thd->locked_tables &&
++ (create_info->used_fields & HA_CREATE_USED_UNION) &&
++ (table->s->tmp_table == NO_TMP_TABLE))
++ {
++ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
++ DBUG_RETURN(TRUE);
++ }
++
++ /* Check that we are not trying to rename to an existing table */
++ if (new_name)
++ {
++ DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
++ strmov(new_name_buff,new_name);
++ strmov(new_alias= new_alias_buff, new_name);
++ if (lower_case_table_names)
++ {
++ if (lower_case_table_names != 2)
++ {
++ my_casedn_str(files_charset_info, new_name_buff);
++ new_alias= new_name; // Create lower case table name
++ }
++ my_casedn_str(files_charset_info, new_name);
++ }
++ if (new_db == db &&
++ !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
++ {
++ /*
++ Source and destination table names are equal: make later check
++ easier.
++ */
++ new_alias= new_name= table_name;
++ }
++ else
++ {
++ if (table->s->tmp_table != NO_TMP_TABLE)
++ {
++ if (find_temporary_table(thd,new_db,new_name_buff))
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
++ DBUG_RETURN(TRUE);
++ }
++ }
++ else
++ {
++ if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
++ DBUG_RETURN(TRUE);
++ if (!name_lock)
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
++ DBUG_RETURN(TRUE);
++ }
++
++ build_table_filename(new_name_buff, sizeof(new_name_buff) - 1,
++ new_db, new_name_buff, reg_ext, 0);
++ if (!access(new_name_buff, F_OK))
++ {
++ /* Table will be closed in do_command() */
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
++ goto err;
++ }
++ }
++ }
++ }
++ else
++ {
++ new_alias= (lower_case_table_names == 2) ? alias : table_name;
++ new_name= table_name;
++ }
++
++ old_db_type= table->s->db_type();
++ if (!create_info->db_type)
++ {
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (table->part_info &&
++ create_info->used_fields & HA_CREATE_USED_ENGINE)
++ {
++ /*
++ This case happens when the user specified
++ ENGINE = x where x is a non-existing storage engine
++ We set create_info->db_type to default_engine_type
++ to ensure we don't change underlying engine type
++ due to a erroneously given engine name.
++ */
++ create_info->db_type= table->part_info->default_engine_type;
++ }
++ else
++#endif
++ create_info->db_type= old_db_type;
++ }
++
++ if (check_engine(thd, new_name, create_info))
++ goto err;
++ new_db_type= create_info->db_type;
++
++ if ((new_db_type != old_db_type ||
++ alter_info->flags & ALTER_PARTITION) &&
++ !table->file->can_switch_engines())
++ {
++ my_error(ER_ROW_IS_REFERENCED, MYF(0));
++ goto err;
++ }
++
++ /*
++ If this is an ALTER TABLE and no explicit row type specified reuse
++ the table's row type.
++ Note : this is the same as if the row type was specified explicitly.
++ */
++ if (create_info->row_type == ROW_TYPE_NOT_USED)
++ {
++ /* ALTER TABLE without explicit row type */
++ create_info->row_type= table->s->row_type;
++ }
++ else
++ {
++ /* ALTER TABLE with specific row type */
++ create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
++ }
++
++ DBUG_PRINT("info", ("old type: %s new type: %s",
++ ha_resolve_storage_engine_name(old_db_type),
++ ha_resolve_storage_engine_name(new_db_type)));
++ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
++ ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
++ {
++ DBUG_PRINT("info", ("doesn't support alter"));
++ my_error(ER_ILLEGAL_HA, MYF(0), table_name);
++ goto err;
++ }
++
++ thd_proc_info(thd, "setup");
++ if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
++ !table->s->tmp_table) // no need to touch frm
++ {
++ switch (alter_info->keys_onoff) {
++ case LEAVE_AS_IS:
++ break;
++ case ENABLE:
++ /*
++ wait_while_table_is_used() ensures that table being altered is
++ opened only by this thread and that TABLE::TABLE_SHARE::version
++ of TABLE object corresponding to this table is 0.
++ The latter guarantees that no DML statement will open this table
++ until ALTER TABLE finishes (i.e. until close_thread_tables())
++ while the fact that the table is still open gives us protection
++ from concurrent DDL statements.
++ */
++ VOID(pthread_mutex_lock(&LOCK_open));
++ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
++ error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
++ /* COND_refresh will be signaled in close_thread_tables() */
++ break;
++ case DISABLE:
++ VOID(pthread_mutex_lock(&LOCK_open));
++ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
++ /* COND_refresh will be signaled in close_thread_tables() */
++ break;
++ default:
++ DBUG_ASSERT(FALSE);
++ error= 0;
++ break;
++ }
++ if (error == HA_ERR_WRONG_COMMAND)
++ {
++ error= 0;
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
++ table->alias);
++ }
++
++ /*
++ Unlike to the above case close_cached_table() below will remove ALL
++ instances of TABLE from table cache (it will also remove table lock
++ held by this thread). So to make actual table renaming and writing
++ to binlog atomic we have to put them into the same critical section
++ protected by LOCK_open mutex. This also removes gap for races between
++ access() and mysql_rename_table() calls.
++ */
++
++ if (!error && (new_name != table_name || new_db != db))
++ {
++ thd_proc_info(thd, "rename");
++
++ /*
++ Workaround InnoDB ending the transaction when the table instance
++ is unlocked/closed (close_cached_table below), otherwise the trx
++ state will differ between the server and storage engine layers.
++ */
++ ha_autocommit_or_rollback(thd, 0);
++
++ VOID(pthread_mutex_lock(&LOCK_open));
++ /*
++ Then do a 'simple' rename of the table. First we need to close all
++ instances of 'source' table.
++ */
++ close_cached_table(thd, table);
++ /*
++ Then, we want check once again that target table does not exist.
++ Actually the order of these two steps does not matter since
++ earlier we took name-lock on the target table, so we do them
++ in this particular order only to be consistent with 5.0, in which
++ we don't take this name-lock and where this order really matters.
++ TODO: Investigate if we need this access() check at all.
++ */
++ if (!access(new_name_buff,F_OK))
++ {
++ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
++ error= -1;
++ }
++ else
++ {
++ *fn_ext(new_name)=0;
++ if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
++ error= -1;
++ else if (Table_triggers_list::change_table_name(thd, db, table_name,
++ new_db, new_alias))
++ {
++ VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
++ table_name, 0));
++ error= -1;
++ }
++ }
++ }
++ else
++ VOID(pthread_mutex_lock(&LOCK_open));
++
++ if (error == HA_ERR_WRONG_COMMAND)
++ {
++ error= 0;
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
++ table->alias);
++ }
++
++ if (!error)
++ {
++ error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
++ if (!error)
++ my_ok(thd);
++ }
++ else if (error > 0)
++ {
++ table->file->print_error(error, MYF(0));
++ error= -1;
++ }
++ if (name_lock)
++ unlink_open_table(thd, name_lock, FALSE);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ table_list->table= NULL; // For query cache
++ query_cache_invalidate3(thd, table_list, 0);
++ DBUG_RETURN(error);
++ }
++
++ /* We have to do full alter table. */
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
++ &partition_changed, &fast_alter_partition))
++ goto err;
++#endif
++ /*
++ If the old table had partitions and we are doing ALTER TABLE ...
++ engine= <new_engine>, the new table must preserve the original
++ partitioning. That means that the new engine is still the
++ partitioning engine, not the engine specified in the parser.
++ This is discovered in prep_alter_part_table, which in such case
++ updates create_info->db_type.
++ Now we need to update the stack copy of create_info->db_type,
++ as otherwise we won't be able to correctly move the files of the
++ temporary table to the result table files.
++ */
++ new_db_type= create_info->db_type;
++
++ if (is_index_maintenance_unique (table, alter_info))
++ need_copy_table= ALTER_TABLE_DATA_CHANGED;
++
++ if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
++ goto err;
++
++ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
++ need_copy_table= alter_info->change_level;
++
++ set_table_default_charset(thd, create_info, db);
++
++ if (thd->variables.old_alter_table
++ || (table->s->db_type() != create_info->db_type)
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ || partition_changed
++#endif
++ )
++ need_copy_table= ALTER_TABLE_DATA_CHANGED;
++ else
++ {
++ enum_alter_table_change_level need_copy_table_res;
++ /* Check how much the tables differ. */
++ if (compare_tables(table, alter_info,
++ create_info, order_num,
++ &need_copy_table_res,
++ &key_info_buffer,
++ &index_drop_buffer, &index_drop_count,
++ &index_add_buffer, &index_add_count,
++ &candidate_key_count))
++ goto err;
++
++ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
++ if (need_copy_table_res != ALTER_TABLE_METADATA_ONLY)
++ goto err; });
++ DBUG_EXECUTE_IF("alter_table_only_index_change", {
++ if (need_copy_table_res != ALTER_TABLE_INDEX_CHANGED)
++ goto err; });
++
++ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
++ need_copy_table= need_copy_table_res;
++ }
++
++ /*
++ If there are index changes only, try to do them online. "Index
++ changes only" means also that the handler for the table does not
++ change. The table is open and locked. The handler can be accessed.
++ */
++ if (need_copy_table == ALTER_TABLE_INDEX_CHANGED)
++ {
++ int pk_changed= 0;
++ ulong alter_flags= 0;
++ ulong needed_online_flags= 0;
++ ulong needed_fast_flags= 0;
++ KEY *key;
++ uint *idx_p;
++ uint *idx_end_p;
++
++ alter_flags= table->file->alter_table_flags(alter_info->flags);
++ DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
++ /* Check dropped indexes. */
++ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
++ idx_p < idx_end_p;
++ idx_p++)
++ {
++ key= table->key_info + *idx_p;
++ DBUG_PRINT("info", ("index dropped: '%s'", key->name));
++ if (key->flags & HA_NOSAME)
++ {
++ /*
++ Unique key. Check for "PRIMARY".
++ or if dropping last unique key
++ */
++ if ((uint) (key - table->key_info) == table->s->primary_key)
++ {
++ DBUG_PRINT("info", ("Dropping primary key"));
++ /* Primary key. */
++ needed_online_flags|= HA_ONLINE_DROP_PK_INDEX;
++ needed_fast_flags|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
++ pk_changed++;
++ candidate_key_count--;
++ }
++ else
++ {
++ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
++ bool is_candidate_key= true;
++
++ /* Non-primary unique key. */
++ needed_online_flags|= HA_ONLINE_DROP_UNIQUE_INDEX;
++ needed_fast_flags|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
++
++ /*
++ Check if all fields in key are declared
++ NOT NULL and adjust candidate_key_count
++ */
++ for (KEY_PART_INFO *key_part= key->key_part;
++ key_part < part_end;
++ key_part++)
++ is_candidate_key=
++ (is_candidate_key &&
++ (! table->field[key_part->fieldnr-1]->maybe_null()));
++ if (is_candidate_key)
++ candidate_key_count--;
++ }
++ }
++ else
++ {
++ /* Non-unique key. */
++ needed_online_flags|= HA_ONLINE_DROP_INDEX;
++ needed_fast_flags|= HA_ONLINE_DROP_INDEX_NO_WRITES;
++ }
++ }
++ no_pk= ((table->s->primary_key == MAX_KEY) ||
++ (needed_online_flags & HA_ONLINE_DROP_PK_INDEX));
++ /* Check added indexes. */
++ for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
++ idx_p < idx_end_p;
++ idx_p++)
++ {
++ key= key_info_buffer + *idx_p;
++ DBUG_PRINT("info", ("index added: '%s'", key->name));
++ if (key->flags & HA_NOSAME)
++ {
++ /* Unique key */
++
++ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
++ bool is_candidate_key= true;
++
++ /*
++ Check if all fields in key are declared
++ NOT NULL
++ */
++ for (KEY_PART_INFO *key_part= key->key_part;
++ key_part < part_end;
++ key_part++)
++ is_candidate_key=
++ (is_candidate_key &&
++ (! table->field[key_part->fieldnr]->maybe_null()));
++
++ /*
++ Check for "PRIMARY"
++ or if adding first unique key
++ defined on non-nullable fields
++ */
++
++ if ((!my_strcasecmp(system_charset_info,
++ key->name, primary_key_name)) ||
++ (no_pk && candidate_key_count == 0 && is_candidate_key))
++ {
++ DBUG_PRINT("info", ("Adding primary key"));
++ /* Primary key. */
++ needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
++ needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
++ pk_changed++;
++ no_pk= false;
++ }
++ else
++ {
++ /* Non-primary unique key. */
++ needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
++ needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
++ }
++ }
++ else
++ {
++ /* Non-unique key. */
++ needed_online_flags|= HA_ONLINE_ADD_INDEX;
++ needed_fast_flags|= HA_ONLINE_ADD_INDEX_NO_WRITES;
++ }
++ }
++
++ if ((candidate_key_count > 0) &&
++ (needed_online_flags & HA_ONLINE_DROP_PK_INDEX))
++ {
++ /*
++ Dropped primary key when there is some other unique
++ not null key that should be converted to primary key
++ */
++ needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
++ needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
++ pk_changed= 2;
++ }
++
++ DBUG_PRINT("info", ("needed_online_flags: 0x%lx, needed_fast_flags: 0x%lx",
++ needed_online_flags, needed_fast_flags));
++ /*
++ Online or fast add/drop index is possible only if
++ the primary key is not added and dropped in the same statement.
++ Otherwise we have to recreate the table.
++ need_copy_table is no-zero at this place.
++ */
++ if ( pk_changed < 2 )
++ {
++ if ((alter_flags & needed_online_flags) == needed_online_flags)
++ {
++ /* All required online flags are present. */
++ need_copy_table= ALTER_TABLE_METADATA_ONLY;
++ need_lock_for_indexes= FALSE;
++ }
++ else if ((alter_flags & needed_fast_flags) == needed_fast_flags)
++ {
++ /* All required fast flags are present. */
++ need_copy_table= ALTER_TABLE_METADATA_ONLY;
++ }
++ }
++ DBUG_PRINT("info", ("need_copy_table: %u need_lock: %d",
++ need_copy_table, need_lock_for_indexes));
++ }
++
++ /*
++ better have a negative test here, instead of positive, like
++ alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|...
++ so that ALTER TABLE won't break when somebody will add new flag
++ */
++ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
++ create_info->frm_only= 1;
++
++#ifdef WITH_PARTITION_STORAGE_ENGINE
++ if (fast_alter_partition)
++ {
++ DBUG_ASSERT(!name_lock);
++ DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
++ create_info, table_list,
++ db, table_name,
++ fast_alter_partition));
++ }
++#endif
++
++ my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
++ current_pid, thd->thread_id);
++ /* Safety fix for innodb */
++ if (lower_case_table_names)
++ my_casedn_str(files_charset_info, tmp_name);
++
++ /*
++ Handling of symlinked tables:
++ If no rename:
++ Create new data file and index file on the same disk as the
++ old data and index files.
++ Copy data.
++ Rename new data file over old data file and new index file over
++ old index file.
++ Symlinks are not changed.
++
++ If rename:
++ Create new data file and index file on the same disk as the
++ old data and index files. Create also symlinks to point at
++ the new tables.
++ Copy data.
++ At end, rename intermediate tables, and symlinks to intermediate
++ table, to final table name.
++ Remove old table and old symlinks
++
++ If rename is made to another database:
++ Create new tables in new database.
++ Copy data.
++ Remove old table and symlinks.
++ */
++ if (!strcmp(db, new_db)) // Ignore symlink if db changed
++ {
++ if (create_info->index_file_name)
++ {
++ /* Fix index_file_name to have 'tmp_name' as basename */
++ strmov(index_file, tmp_name);
++ create_info->index_file_name=fn_same(index_file,
++ create_info->index_file_name,
++ 1);
++ }
++ if (create_info->data_file_name)
++ {
++ /* Fix data_file_name to have 'tmp_name' as basename */
++ strmov(data_file, tmp_name);
++ create_info->data_file_name=fn_same(data_file,
++ create_info->data_file_name,
++ 1);
++ }
++ }
++ else
++ create_info->data_file_name=create_info->index_file_name=0;
++
++ DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
++ /*
++ Create a table with a temporary name.
++ With create_info->frm_only == 1 this creates a .frm file only.
++ We don't log the statement, it will be logged later.
++ */
++ tmp_disable_binlog(thd);
++ error= mysql_create_table_no_lock(thd, new_db, tmp_name,
++ create_info,
++ alter_info,
++ 1, 0);
++ reenable_binlog(thd);
++ if (error)
++ goto err;
++
++ /* Open the table if we need to copy the data. */
++ DBUG_PRINT("info", ("need_copy_table: %u", need_copy_table));
++ if (need_copy_table != ALTER_TABLE_METADATA_ONLY)
++ {
++ if (table->s->tmp_table)
++ {
++ TABLE_LIST tbl;
++ bzero((void*) &tbl, sizeof(tbl));
++ tbl.db= new_db;
++ tbl.table_name= tbl.alias= tmp_name;
++ /* Table is in thd->temporary_tables */
++ new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
++ MYSQL_LOCK_IGNORE_FLUSH);
++ }
++ else
++ {
++ char path[FN_REFLEN + 1];
++ /* table is a normal table: Create temporary table in same directory */
++ build_table_filename(path, sizeof(path) - 1, new_db, tmp_name, "",
++ FN_IS_TMP);
++ /* Open our intermediate table */
++ new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
++ }
++ if (!new_table)
++ goto err1;
++ /*
++ Note: In case of MERGE table, we do not attach children. We do not
++ copy data for MERGE tables. Only the children have data.
++ */
++ }
++
++ /* Copy the data if necessary. */
++ thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
++ thd->cuted_fields=0L;
++ copied=deleted=0;
++ /*
++ We do not copy data for MERGE tables. Only the children have data.
++ MERGE tables have HA_NO_COPY_ON_ALTER set.
++ */
++ if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
++ {
++ /* We don't want update TIMESTAMP fields during ALTER TABLE. */
++ new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
++ new_table->next_number_field=new_table->found_next_number_field;
++ thd_proc_info(thd, "copy to tmp table");
++ error= copy_data_between_tables(table, new_table,
++ alter_info->create_list, ignore,
++ order_num, order, &copied, &deleted,
++ alter_info->keys_onoff,
++ alter_info->error_if_not_empty);
++ }
++ else
++ {
++ VOID(pthread_mutex_lock(&LOCK_open));
++ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ thd_proc_info(thd, "manage keys");
++ alter_table_manage_keys(table, table->file->indexes_are_disabled(),
++ alter_info->keys_onoff);
++ error= ha_autocommit_or_rollback(thd, 0);
++ if (end_active_trans(thd))
++ error= 1;
++ }
++ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
++
++ /* If we did not need to copy, we might still need to add/drop indexes. */
++ if (! new_table)
++ {
++ uint *key_numbers;
++ uint *keyno_p;
++ KEY *key_info;
++ KEY *key;
++ uint *idx_p;
++ uint *idx_end_p;
++ KEY_PART_INFO *key_part;
++ KEY_PART_INFO *part_end;
++ DBUG_PRINT("info", ("No new_table, checking add/drop index"));
++
++ table->file->ha_prepare_for_alter();
++ if (index_add_count)
++ {
++ /* The add_index() method takes an array of KEY structs. */
++ key_info= (KEY*) thd->alloc(sizeof(KEY) * index_add_count);
++ key= key_info;
++ for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
++ idx_p < idx_end_p;
++ idx_p++, key++)
++ {
++ /* Copy the KEY struct. */
++ *key= key_info_buffer[*idx_p];
++ /* Fix the key parts. */
++ part_end= key->key_part + key->key_parts;
++ for (key_part= key->key_part; key_part < part_end; key_part++)
++ key_part->field= table->field[key_part->fieldnr];
++ }
++ /* Add the indexes. */
++ if ((error= table->file->add_index(table, key_info, index_add_count)))
++ {
++ /*
++ Exchange the key_info for the error message. If we exchange
++ key number by key name in the message later, we need correct info.
++ */
++ KEY *save_key_info= table->key_info;
++ table->key_info= key_info;
++ table->file->print_error(error, MYF(0));
++ table->key_info= save_key_info;
++ goto err1;
++ }
++ }
++ /*end of if (index_add_count)*/
++
++ if (index_drop_count)
++ {
++ /* The prepare_drop_index() method takes an array of key numbers. */
++ key_numbers= (uint*) thd->alloc(sizeof(uint) * index_drop_count);
++ keyno_p= key_numbers;
++ /* Get the number of each key. */
++ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
++ idx_p < idx_end_p;
++ idx_p++, keyno_p++)
++ *keyno_p= *idx_p;
++ /*
++ Tell the handler to prepare for drop indexes.
++ This re-numbers the indexes to get rid of gaps.
++ */
++ if ((error= table->file->prepare_drop_index(table, key_numbers,
++ index_drop_count)))
++ {
++ table->file->print_error(error, MYF(0));
++ goto err1;
++ }
++
++ /* Tell the handler to finally drop the indexes. */
++ if ((error= table->file->final_drop_index(table)))
++ {
++ table->file->print_error(error, MYF(0));
++ goto err1;
++ }
++ }
++ /*end of if (index_drop_count)*/
++
++ /*
++ The final .frm file is already created as a temporary file
++ and will be renamed to the original table name later.
++ */
++
++ /* Need to commit before a table is unlocked (NDB requirement). */
++ DBUG_PRINT("info", ("Committing before unlocking table"));
++ if (ha_autocommit_or_rollback(thd, 0) || end_active_trans(thd))
++ goto err1;
++ }
++ /*end of if (! new_table) for add/drop index*/
++
++ if (table->s->tmp_table != NO_TMP_TABLE)
++ {
++ /* We changed a temporary table */
++ if (error)
++ goto err1;
++ /* Close lock if this is a transactional table */
++ if (thd->lock)
++ {
++ mysql_unlock_tables(thd, thd->lock);
++ thd->lock=0;
++ }
++ /*
++ If LOCK TABLES list is not empty and contains this table,
++ unlock the table and remove the table from this list.
++ */
++ mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
++ /* Remove link to old table and rename the new one */
++ close_temporary_table(thd, table, 1, 1);
++ /* Should pass the 'new_name' as we store table name in the cache */
++ if (rename_temporary_table(thd, new_table, new_db, new_name))
++ goto err1;
++ /* We don't replicate alter table statement on temporary tables */
++ if (!thd->current_stmt_binlog_row_based &&
++ write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
++ DBUG_RETURN(TRUE);
++ goto end_temporary;
++ }
++
++ if (new_table)
++ {
++ /*
++ Close the intermediate table that will be the new table.
++ Note that MERGE tables do not have their children attached here.
++ */
++ intern_close_table(new_table);
++ my_free(new_table,MYF(0));
++ }
++ DEBUG_SYNC(thd, "alter_table_before_rename_result_table");
++ VOID(pthread_mutex_lock(&LOCK_open));
++ if (error)
++ {
++ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ goto err;
++ }
++
++ /*
++ Data is copied. Now we:
++ 1) Wait until all other threads close old version of table.
++ 2) Close instances of table open by this thread and replace them
++ with exclusive name-locks.
++ 3) Rename the old table to a temp name, rename the new one to the
++ old name.
++ 4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
++ we reopen new version of table.
++ 5) Write statement to the binary log.
++ 6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
++ remove name-locks from list of open tables and table cache.
++ 7) If we are not not under LOCK TABLES we rely on close_thread_tables()
++ call to remove name-locks from table cache and list of open table.
++ */
++
++ thd_proc_info(thd, "rename result table");
++ my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
++ current_pid, thd->thread_id);
++ if (lower_case_table_names)
++ my_casedn_str(files_charset_info, old_name);
++
++ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
++ close_data_files_and_morph_locks(thd, db, table_name);
++
++ error=0;
++ save_old_db_type= old_db_type;
++
++ /*
++ This leads to the storage engine (SE) not being notified for renames in
++ mysql_rename_table(), because we just juggle with the FRM and nothing
++ more. If we have an intermediate table, then we notify the SE that
++ it should become the actual table. Later, we will recycle the old table.
++ However, in case of ALTER TABLE RENAME there might be no intermediate
++ table. This is when the old and new tables are compatible, according to
++ compare_table(). Then, we need one additional call to
++ mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
++ actual rename in the SE and the FRM is not touched. Note that, if the
++ table is renamed and the SE is also changed, then an intermediate table
++ is created and the additional call will not take place.
++ */
++ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
++ {
++ DBUG_ASSERT(new_db_type == old_db_type);
++ /* This type cannot happen in regular ALTER. */
++ new_db_type= old_db_type= NULL;
++ }
++ if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
++ FN_TO_IS_TMP))
++ {
++ error=1;
++ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
++ }
++ else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
++ new_alias, FN_FROM_IS_TMP) ||
++ ((new_name != table_name || new_db != db) && // we also do rename
++ (need_copy_table != ALTER_TABLE_METADATA_ONLY ||
++ mysql_rename_table(save_old_db_type, db, table_name, new_db,
++ new_alias, NO_FRM_RENAME)) &&
++ Table_triggers_list::change_table_name(thd, db, table_name,
++ new_db, new_alias)))
++ {
++ /* Try to get everything back. */
++ error=1;
++ VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
++ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
++ VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
++ FN_FROM_IS_TMP));
++ }
++
++ if (error)
++ {
++ /* This shouldn't happen. But let us play it safe. */
++ goto err_with_placeholders;
++ }
++
++ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
++ {
++ /*
++ Now we have to inform handler that new .FRM file is in place.
++ To do this we need to obtain a handler object for it.
++ NO need to tamper with MERGE tables. The real open is done later.
++ */
++ TABLE *t_table;
++ if (new_name != table_name || new_db != db)
++ {
++ table_list->alias= new_name;
++ table_list->table_name= new_name;
++ table_list->table_name_length= strlen(new_name);
++ table_list->db= new_db;
++ table_list->db_length= strlen(new_db);
++ table_list->table= name_lock;
++ if (reopen_name_locked_table(thd, table_list, FALSE))
++ goto err_with_placeholders;
++ t_table= table_list->table;
++ }
++ else
++ {
++ if (reopen_table(table))
++ goto err_with_placeholders;
++ t_table= table;
++ }
++ /* Tell the handler that a new frm file is in place. */
++ if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG,
++ create_info))
++ goto err_with_placeholders;
++ if (thd->locked_tables && new_name == table_name && new_db == db)
++ {
++ /*
++ We are going to reopen table down on the road, so we have to restore
++ state of the TABLE object which we used for obtaining of handler
++ object to make it suitable for reopening.
++ */
++ DBUG_ASSERT(t_table == table);
++ table->open_placeholder= 1;
++ close_handle_and_leave_table_as_lock(table);
++ }
++ }
++
++ VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
++
++ if (thd->locked_tables && new_name == table_name && new_db == db)
++ {
++ thd->in_lock_tables= 1;
++ error= reopen_tables(thd, 1, 1);
++ thd->in_lock_tables= 0;
++ if (error)
++ goto err_with_placeholders;
++ }
++ VOID(pthread_mutex_unlock(&LOCK_open));
++
++ thd_proc_info(thd, "end");
++
++ DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
++ DEBUG_SYNC(thd, "alter_table_before_main_binlog");
++
++ ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
++ thd->query(), thd->query_length(),
++ db, table_name);
++
++ DBUG_ASSERT(!(mysql_bin_log.is_open() &&
++ thd->current_stmt_binlog_row_based &&
++ (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
++ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
++ DBUG_RETURN(TRUE);
++
++ if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
++ {
++ /*
++ For the alter table to be properly flushed to the logs, we
++ have to open the new table. If not, we get a problem on server
++ shutdown. But we do not need to attach MERGE children.
++ */
++ char path[FN_REFLEN];
++ TABLE *t_table;
++ build_table_filename(path + 1, sizeof(path) - 1, new_db, table_name, "", 0);
++ t_table= open_temporary_table(thd, path, new_db, tmp_name, 0);
++ if (t_table)
++ {
++ intern_close_table(t_table);
++ my_free(t_table, MYF(0));
++ }
++ else
++ sql_print_warning("Could not open table %s.%s after rename\n",
++ new_db,table_name);
++ ha_flush_logs(old_db_type);
++ }
++ table_list->table=0; // For query cache
++ query_cache_invalidate3(thd, table_list, 0);
++
++ if (thd->locked_tables && (new_name != table_name || new_db != db))
++ {
++ /*
++ If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
++ to remove placeholders for the old table and for the target table
++ from the list of open tables and table cache. If we are not under
++ LOCK TABLES we can rely on close_thread_tables() doing this job.
++ */
++ pthread_mutex_lock(&LOCK_open);
++ unlink_open_table(thd, table, FALSE);
++ unlink_open_table(thd, name_lock, FALSE);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++
++end_temporary:
++ my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
++ (ulong) (copied + deleted), (ulong) deleted,
++ (ulong) thd->cuted_fields);
++ my_ok(thd, copied + deleted, 0L, tmp_name);
++ thd->some_tables_deleted=0;
++ DBUG_RETURN(FALSE);
++
++err1:
++ if (new_table)
++ {
++ /* close_temporary_table() frees the new_table pointer. */
++ close_temporary_table(thd, new_table, 1, 1);
++ }
++ else
++ VOID(quick_rm_table(new_db_type, new_db, tmp_name,
++ create_info->frm_only
++ ? FN_IS_TMP | FRM_ONLY
++ : FN_IS_TMP));
++
++err:
++ /*
++ No default value was provided for a DATE/DATETIME field, the
++ current sql_mode doesn't allow the '0000-00-00' value and
++ the table to be altered isn't empty.
++ Report error here.
++ */
++ if (alter_info->error_if_not_empty && thd->row_count)
++ {
++ const char *f_val= 0;
++ enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
++ switch (alter_info->datetime_field->sql_type)
++ {
++ case MYSQL_TYPE_DATE:
++ case MYSQL_TYPE_NEWDATE:
++ f_val= "0000-00-00";
++ t_type= MYSQL_TIMESTAMP_DATE;
++ break;
++ case MYSQL_TYPE_DATETIME:
++ f_val= "0000-00-00 00:00:00";
++ t_type= MYSQL_TIMESTAMP_DATETIME;
++ break;
++ default:
++ /* Shouldn't get here. */
++ DBUG_ASSERT(0);
++ }
++ bool save_abort_on_warning= thd->abort_on_warning;
++ thd->abort_on_warning= TRUE;
++ make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
++ f_val, strlength(f_val), t_type,
++ alter_info->datetime_field->field_name);
++ thd->abort_on_warning= save_abort_on_warning;
++ }
++ if (name_lock)
++ {
++ pthread_mutex_lock(&LOCK_open);
++ unlink_open_table(thd, name_lock, FALSE);
++ pthread_mutex_unlock(&LOCK_open);
++ }
++ DBUG_RETURN(TRUE);
++
++err_with_placeholders:
++ /*
++ An error happened while we were holding exclusive name-lock on table
++ being altered. To be safe under LOCK TABLES we should remove placeholders
++ from list of open tables list and table cache.
++ */
++ unlink_open_table(thd, table, FALSE);
++ if (name_lock)
++ unlink_open_table(thd, name_lock, FALSE);
++ VOID(pthread_mutex_unlock(&LOCK_open));
++ DBUG_RETURN(TRUE);
++}
++/* mysql_alter_table */
++
++static int
++copy_data_between_tables(TABLE *from,TABLE *to,
++ List<Create_field> &create,
++ bool ignore,
++ uint order_num, ORDER *order,
++ ha_rows *copied,
++ ha_rows *deleted,
++ enum enum_enable_or_disable keys_onoff,
++ bool error_if_not_empty)
++{
++ int error;
++ Copy_field *copy,*copy_end;
++ ulong found_count,delete_count;
++ THD *thd= current_thd;
++ uint length= 0;
++ SORT_FIELD *sortorder;
++ READ_RECORD info;
++ TABLE_LIST tables;
++ List<Item> fields;
++ List<Item> all_fields;
++ ha_rows examined_rows;
++ bool auto_increment_field_copied= 0;
++ ulong save_sql_mode;
++ ulonglong prev_insert_id;
++ DBUG_ENTER("copy_data_between_tables");
++
++ /*
++ Turn off recovery logging since rollback of an alter table is to
++ delete the new table so there is no need to log the changes to it.
++
++ This needs to be done before external_lock
++ */
++ error= ha_enable_transaction(thd, FALSE);
++ if (error)
++ DBUG_RETURN(-1);
++
++ if (!(copy= new Copy_field[to->s->fields]))
++ DBUG_RETURN(-1); /* purecov: inspected */
++
++ if (to->file->ha_external_lock(thd, F_WRLCK))
++ DBUG_RETURN(-1);
++
++ /* We need external lock before we can disable/enable keys */
++ alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
++
++ /* We can abort alter table for any table type */
++ thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
++ (MODE_STRICT_TRANS_TABLES |
++ MODE_STRICT_ALL_TABLES));
++
++ from->file->info(HA_STATUS_VARIABLE);
++ to->file->ha_start_bulk_insert(from->file->stats.records);
++
++ save_sql_mode= thd->variables.sql_mode;
++
++ List_iterator<Create_field> it(create);
++ Create_field *def;
++ copy_end=copy;
++ for (Field **ptr=to->field ; *ptr ; ptr++)
++ {
++ def=it++;
++ if (def->field)
++ {
++ if (*ptr == to->next_number_field)
++ {
++ auto_increment_field_copied= TRUE;
++ /*
++ If we are going to copy contents of one auto_increment column to
++ another auto_increment column it is sensible to preserve zeroes.
++ This condition also covers case when we are don't actually alter
++ auto_increment column.
++ */
++ if (def->field == from->found_next_number_field)
++ thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
++ }
++ (copy_end++)->set(*ptr,def->field,0);
++ }
++
++ }
++
++ found_count=delete_count=0;
++
++ if (order)
++ {
++ if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
++ {
++ char warn_buff[MYSQL_ERRMSG_SIZE];
++ my_snprintf(warn_buff, sizeof(warn_buff),
++ "ORDER BY ignored as there is a user-defined clustered index"
++ " in the table '%-.192s'", from->s->table_name.str);
++ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
++ warn_buff);
++ }
++ else
++ {
++ from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
++ MYF(MY_FAE | MY_ZEROFILL));
++ bzero((char *) &tables, sizeof(tables));
++ tables.table= from;
++ tables.alias= tables.table_name= from->s->table_name.str;
++ tables.db= from->s->db.str;
++ error= 1;
++
++ if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
++ setup_order(thd, thd->lex->select_lex.ref_pointer_array,
++ &tables, fields, all_fields, order) ||
++ !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
++ (from->sort.found_records= filesort(thd, from, sortorder, length,
++ (SQL_SELECT *) 0, HA_POS_ERROR,
++ 1, &examined_rows)) ==
++ HA_POS_ERROR)
++ goto err;
++ }
++ };
++
++ /* Tell handler that we have values for all columns in the to table */
++ to->use_all_columns();
++ init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
++ if (ignore)
++ to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
++ thd->row_count= 0;
++ restore_record(to, s->default_values); // Create empty record
++ while (!(error=info.read_record(&info)))
++ {
++ if (thd->killed)
++ {
++ thd->send_kill_message();
++ error= 1;
++ break;
++ }
++ thd->row_count++;
++ /* Return error if source table isn't empty. */
++ if (error_if_not_empty)
++ {
++ error= 1;
++ break;
++ }
++ if (to->next_number_field)
++ {
++ if (auto_increment_field_copied)
++ to->auto_increment_field_not_null= TRUE;
++ else
++ to->next_number_field->reset();
++ }
++
++ for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
++ {
++ copy_ptr->do_copy(copy_ptr);
++ }
++ prev_insert_id= to->file->next_insert_id;
++ error=to->file->ha_write_row(to->record[0]);
++ to->auto_increment_field_not_null= FALSE;
++ if (error)
++ {
++ if (!ignore ||
++ to->file->is_fatal_error(error, HA_CHECK_DUP))
++ {
++ if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
++ {
++ uint key_nr= to->file->get_dup_key(error);
++ if ((int) key_nr >= 0)
++ {
++ const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
++ if (key_nr == 0 &&
++ (to->key_info[0].key_part[0].field->flags &
++ AUTO_INCREMENT_FLAG))
++ err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
++ to->file->print_keydup_error(key_nr, err_msg);
++ break;
++ }
++ }
++
++ to->file->print_error(error,MYF(0));
++ break;
++ }
++ to->file->restore_auto_increment(prev_insert_id);
++ delete_count++;
++ }
++ else
++ found_count++;
++ }
++ end_read_record(&info);
++ free_io_cache(from);
++ delete [] copy; // This is never 0
++
++ if (to->file->ha_end_bulk_insert() && error <= 0)
++ {
++ to->file->print_error(my_errno,MYF(0));
++ error=1;
++ }
++ to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
++
++ if (ha_enable_transaction(thd, TRUE))
++ {
++ error= 1;
++ goto err;
++ }
++
++ /*
++ Ensure that the new table is saved properly to disk so that we
++ can do a rename
++ */
++ if (ha_autocommit_or_rollback(thd, 0))
++ error=1;
++ if (end_active_trans(thd))
++ error=1;
++
++ err:
++ thd->variables.sql_mode= save_sql_mode;
++ thd->abort_on_warning= 0;
++ free_io_cache(from);
++ *copied= found_count;
++ *deleted=delete_count;
++ to->file->ha_release_auto_increment();
++ if (to->file->ha_external_lock(thd,F_UNLCK))
++ error=1;
++ DBUG_RETURN(error > 0 ? -1 : 0);
++}
++
++
++/*
++ Recreates tables by calling mysql_alter_table().
++
++ SYNOPSIS
++ mysql_recreate_table()
++ thd Thread handler
++ tables Tables to recreate
++
++ RETURN
++ Like mysql_alter_table().
++*/
++bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
++{
++ HA_CREATE_INFO create_info;
++ Alter_info alter_info;
++
++ DBUG_ENTER("mysql_recreate_table");
++ DBUG_ASSERT(!table_list->next_global);
++ /*
++ table_list->table has been closed and freed. Do not reference
++ uninitialized data. open_tables() could fail.
++ */
++ table_list->table= NULL;
++
++ bzero((char*) &create_info, sizeof(create_info));
++ create_info.row_type=ROW_TYPE_NOT_USED;
++ create_info.default_table_charset=default_charset_info;
++ /* Force alter table to recreate table */
++ alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
++ DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
++ table_list, &alter_info, 0,
++ (ORDER *) 0, 0));
++}
++
++
++bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
++ HA_CHECK_OPT *check_opt)
++{
++ TABLE_LIST *table;
++ List<Item> field_list;
++ Item *item;
++ Protocol *protocol= thd->protocol;
++ DBUG_ENTER("mysql_checksum_table");
++
++ field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
++ item->maybe_null= 1;
++ field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
++ MY_INT64_NUM_DECIMAL_DIGITS));
++ item->maybe_null= 1;
++ if (protocol->send_fields(&field_list,
++ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
++ DBUG_RETURN(TRUE);
++
++ /* Open one table after the other to keep lock time as short as possible. */
++ for (table= tables; table; table= table->next_local)
++ {
++ char table_name[NAME_LEN*2+2];
++ TABLE *t;
++
++ strxmov(table_name, table->db ,".", table->table_name, NullS);
++
++ t= table->table= open_n_lock_single_table(thd, table, TL_READ);
++ thd->clear_error(); // these errors shouldn't get client
++
++ protocol->prepare_for_resend();
++ protocol->store(table_name, system_charset_info);
++
++ if (!t)
++ {
++ /* Table didn't exist */
++ protocol->store_null();
++ thd->clear_error();
++ }
++ else
++ {
++ if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
++ !(check_opt->flags & T_EXTEND))
++ protocol->store((ulonglong)t->file->checksum());
++ else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
++ (check_opt->flags & T_QUICK))
++ protocol->store_null();
++ else
++ {
++ /* calculating table's checksum */
++ ha_checksum crc= 0;
++ uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
++
++ t->use_all_columns();
++
++ if (t->file->ha_rnd_init(1))
++ protocol->store_null();
++ else
++ {
++ for (;;)
++ {
++ if (thd->killed)
++ {
++ /*
++ we've been killed; let handler clean up, and remove the
++ partial current row from the recordset (embedded lib)
++ */
++ t->file->ha_rnd_end();
++ thd->protocol->remove_last_row();
++ goto err;
++ }
++ ha_checksum row_crc= 0;
++ int error= t->file->rnd_next(t->record[0]);
++ if (unlikely(error))
++ {
++ if (error == HA_ERR_RECORD_DELETED)
++ continue;
++ break;
++ }
++ if (t->s->null_bytes)
++ {
++ /* fix undefined null bits */
++ t->record[0][t->s->null_bytes-1] |= null_mask;
++ if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
++ t->record[0][0] |= 1;
++
++ row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
++ }
++
++ for (uint i= 0; i < t->s->fields; i++ )
++ {
++ Field *f= t->field[i];
++
++ /*
++ BLOB and VARCHAR have pointers in their field, we must convert
++ to string; GEOMETRY is implemented on top of BLOB.
++ BIT may store its data among NULL bits, convert as well.
++ */
++ switch (f->type()) {
++ case MYSQL_TYPE_BLOB:
++ case MYSQL_TYPE_VARCHAR:
++ case MYSQL_TYPE_GEOMETRY:
++ case MYSQL_TYPE_BIT:
++ {
++ String tmp;
++ f->val_str(&tmp);
++ row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
++ tmp.length());
++ break;
++ }
++ default:
++ row_crc= my_checksum(row_crc, f->ptr, f->pack_length());
++ break;
++ }
++ }
++
++ crc+= row_crc;
++ }
++ protocol->store((ulonglong)crc);
++ t->file->ha_rnd_end();
++ }
++ }
++ thd->clear_error();
++ close_thread_tables(thd);
++ table->table=0; // For query cache
++ }
++ if (protocol->write())
++ goto err;
++ }
++
++ my_eof(thd);
++ DBUG_RETURN(FALSE);
++
++ err:
++ close_thread_tables(thd); // Shouldn't be needed
++ if (table)
++ table->table=0;
++ DBUG_RETURN(TRUE);
++}
++
++static bool check_engine(THD *thd, const char *table_name,
++ HA_CREATE_INFO *create_info)
++{
++ handlerton **new_engine= &create_info->db_type;
++ handlerton *req_engine= *new_engine;
++ bool no_substitution=
++ test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION);
++ if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
++ no_substitution, 1)))
++ return TRUE;
++
++ if (req_engine && req_engine != *new_engine)
++ {
++ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
++ ER_WARN_USING_OTHER_HANDLER,
++ ER(ER_WARN_USING_OTHER_HANDLER),
++ ha_resolve_storage_engine_name(*new_engine),
++ table_name);
++ }
++ if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
++ ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
++ {
++ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
++ {
++ my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
++ ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
++ *new_engine= 0;
++ return TRUE;
++ }
++ *new_engine= myisam_hton;
++ }
++ return FALSE;
++}
+diff -urN mysql-old/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql-old/sql/sql_yacc.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/sql_yacc.cc 2011-05-10 17:56:01.630015710 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -urN mysql-old/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql-old/sql/sql_yacc.yy 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/sql_yacc.yy 2011-05-10 17:56:01.650015709 +0000
+@@ -1805,7 +1805,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1815,7 +1815,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -urN mysql-old/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql-old/sql/thr_malloc.cc 2011-05-10 17:45:45.633349043 +0000
++++ mysql/sql/thr_malloc.cc 2011-05-10 17:56:01.656682376 +0000
+@@ -130,7 +130,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -urN mysql-old/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql-old/sql/tztime.cc 2011-05-10 17:45:45.636682376 +0000
++++ mysql/sql/tztime.cc 2011-05-10 17:56:01.656682376 +0000
+@@ -167,7 +167,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -396,7 +396,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1823,7 +1823,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -urN mysql-old/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql-old/sql/unireg.cc 2011-05-10 17:45:45.630015710 +0000
++++ mysql/sql/unireg.cc 2011-05-10 17:56:01.660015710 +0000
+@@ -496,7 +496,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -715,7 +715,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -urN mysql-old/sql-common/client.c mysql/sql-common/client.c
+--- mysql-old/sql-common/client.c 2011-05-10 17:45:45.710015710 +0000
++++ mysql/sql-common/client.c 2011-05-10 17:56:01.660015710 +0000
+@@ -728,7 +728,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2102,7 +2102,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -urN mysql-old/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql-old/sql-common/my_time.c 2011-05-10 17:45:45.710015710 +0000
++++ mysql/sql-common/my_time.c 2011-05-10 17:56:01.660015710 +0000
+@@ -249,7 +249,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -urN mysql-old/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql-old/storage/csv/ha_tina.cc 2011-05-10 17:45:45.693349043 +0000
++++ mysql/storage/csv/ha_tina.cc 2011-05-10 17:56:01.663349044 +0000
+@@ -1193,7 +1193,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1429,7 +1429,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -urN mysql-old/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql-old/storage/federated/ha_federated.cc 2011-05-10 17:45:45.690015710 +0000
++++ mysql/storage/federated/ha_federated.cc 2011-05-10 17:56:01.663349044 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -urN mysql-old/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql-old/storage/heap/hp_create.c 2011-05-10 17:45:45.690015710 +0000
++++ mysql/storage/heap/hp_create.c 2011-05-10 17:56:01.666682377 +0000
+@@ -229,7 +229,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -urN mysql-old/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql-old/storage/heap/hp_test2.c 2011-05-10 17:45:45.690015710 +0000
++++ mysql/storage/heap/hp_test2.c 2011-05-10 17:56:01.723349044 +0000
+@@ -136,7 +136,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -217,7 +217,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -urN mysql-old/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql-old/storage/myisam/ha_myisam.cc 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2011-05-10 17:56:01.723349044 +0000
+@@ -1527,7 +1527,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -urN mysql-old/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql-old/storage/myisam/mi_cache.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_cache.c 2011-05-10 17:56:01.723349044 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -urN mysql-old/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql-old/storage/myisam/mi_check.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_check.c 2011-05-10 17:56:01.726682377 +0000
+@@ -2173,7 +2173,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2329,7 +2329,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2782,7 +2782,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -4331,7 +4331,7 @@
+
+ VOID(mi_close(*org_info));
+ bzero((char*) &create_info,sizeof(create_info));
+- create_info.max_rows=max(max_records,share.base.records);
++ create_info.max_rows=MYSQL_MAX(max_records,share.base.records);
+ create_info.reloc_rows=share.base.reloc;
+ create_info.old_options=(share.options |
+ (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
+diff -urN mysql-old/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql-old/storage/myisam/mi_create.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_create.c 2011-05-10 17:56:01.726682377 +0000
+@@ -437,8 +437,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -527,7 +527,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -565,7 +565,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -urN mysql-old/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql-old/storage/myisam/mi_dynrec.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2011-05-10 17:56:01.730015710 +0000
+@@ -880,7 +880,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -urN mysql-old/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql-old/storage/myisam/mi_extra.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_extra.c 2011-05-10 17:56:01.730015710 +0000
+@@ -99,7 +99,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -urN mysql-old/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql-old/storage/myisam/mi_open.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_open.c 2011-05-10 17:56:01.730015710 +0000
+@@ -328,7 +328,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -501,7 +501,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -714,10 +714,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -urN mysql-old/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql-old/storage/myisam/mi_packrec.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_packrec.c 2011-05-10 17:56:01.733349043 +0000
+@@ -684,7 +684,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1399,7 +1399,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -urN mysql-old/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql-old/storage/myisam/mi_test1.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_test1.c 2011-05-10 17:56:01.733349043 +0000
+@@ -436,7 +436,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -urN mysql-old/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql-old/storage/myisam/mi_test2.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/mi_test2.c 2011-05-10 17:56:01.733349043 +0000
+@@ -601,7 +601,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -urN mysql-old/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql-old/storage/myisam/myisamlog.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/myisamlog.c 2011-05-10 17:56:01.733349043 +0000
+@@ -90,7 +90,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -urN mysql-old/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql-old/storage/myisam/myisampack.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/myisampack.c 2011-05-10 17:56:01.736682376 +0000
+@@ -1239,7 +1239,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3001,7 +3001,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -urN mysql-old/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql-old/storage/myisam/rt_mbr.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/rt_mbr.c 2011-05-10 17:56:01.736682376 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -urN mysql-old/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql-old/storage/myisam/sort.c 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisam/sort.c 2011-05-10 17:56:01.736682376 +0000
+@@ -129,7 +129,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -346,7 +346,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -820,7 +820,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -841,7 +841,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -urN mysql-old/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql-old/storage/myisammrg/ha_myisammrg.cc 2011-05-10 17:45:45.670015709 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2011-05-10 17:56:01.740015709 +0000
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -urN mysql-old/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-old/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-05-10 17:45:45.666682376 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-05-10 17:56:01.740015709 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -urN mysql-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-05-10 17:45:45.656682377 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-05-10 17:56:01.740015709 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -urN mysql-old/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-old/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-05-10 17:45:45.653349044 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-05-10 17:56:01.740015709 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -urN mysql-old/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-old/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-05-10 17:45:45.650015710 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-05-10 17:56:01.743349042 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -urN mysql-old/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql-old/storage/ndb/test/src/getarg.c 2011-05-10 17:45:45.650015710 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2011-05-10 17:56:01.743349042 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -urN mysql-old/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql-old/strings/ctype-big5.c 2011-05-10 17:45:45.706682376 +0000
++++ mysql/strings/ctype-big5.c 2011-05-10 17:56:01.743349042 +0000
+@@ -253,7 +253,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -266,7 +266,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -urN mysql-old/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql-old/strings/ctype-bin.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-bin.c 2011-05-10 17:56:01.750015710 +0000
+@@ -80,7 +80,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -131,7 +131,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -175,7 +175,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -404,7 +404,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -417,7 +417,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-old/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql-old/strings/ctype-gbk.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-gbk.c 2011-05-10 17:56:01.753349044 +0000
+@@ -2616,7 +2616,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2627,7 +2627,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -urN mysql-old/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql-old/strings/ctype-mb.c 2011-05-10 17:45:45.706682376 +0000
++++ mysql/strings/ctype-mb.c 2011-05-10 17:56:01.760015710 +0000
+@@ -368,7 +368,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -412,7 +412,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -451,7 +451,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-old/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql-old/strings/ctype-simple.c 2011-05-10 17:45:45.706682376 +0000
++++ mysql/strings/ctype-simple.c 2011-05-10 17:56:01.760015710 +0000
+@@ -159,7 +159,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -873,7 +873,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -927,7 +927,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1158,7 +1158,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -urN mysql-old/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql-old/strings/ctype-tis620.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-tis620.c 2011-05-10 17:56:01.760015710 +0000
+@@ -581,7 +581,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -638,7 +638,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -urN mysql-old/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql-old/strings/ctype-uca.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-uca.c 2011-05-10 17:56:01.763349043 +0000
+@@ -7567,7 +7567,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -urN mysql-old/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql-old/strings/ctype-ucs2.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-ucs2.c 2011-05-10 17:56:01.773349042 +0000
+@@ -279,7 +279,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1331,7 +1331,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1425,7 +1425,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1472,7 +1472,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-old/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql-old/strings/ctype-utf8.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/ctype-utf8.c 2011-05-10 17:56:01.776682376 +0000
+@@ -1937,7 +1937,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -urN mysql-old/strings/decimal.c mysql/strings/decimal.c
+--- mysql-old/strings/decimal.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/decimal.c 2011-05-10 17:56:01.780015710 +0000
+@@ -403,7 +403,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -426,7 +426,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1517,8 +1517,8 @@
+
+ if (to != from || intg1>intg0)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg1+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg1+MYSQL_MAX(frac1, frac0);
+
+ while (buf0 < p0)
+ *(--p1) = *(--p0);
+@@ -1529,7 +1529,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1631,7 +1631,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1650,7 +1650,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1699,11 +1699,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1718,7 +1718,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1743,7 +1743,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1772,14 +1772,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... max(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1800,7 +1800,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1875,7 +1875,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1910,7 +1910,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2173,11 +2173,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2301,7 +2301,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2339,7 +2339,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -urN mysql-old/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql-old/strings/my_vsnprintf.c 2011-05-10 17:45:45.703349042 +0000
++++ mysql/strings/my_vsnprintf.c 2011-05-10 17:56:01.846682377 +0000
+@@ -141,7 +141,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -urN mysql-old/strings/str2int.c mysql/strings/str2int.c
+--- mysql-old/strings/str2int.c 2011-05-10 17:45:45.706682376 +0000
++++ mysql/strings/str2int.c 2011-05-10 17:56:01.846682377 +0000
+@@ -82,7 +82,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -urN mysql-old/tests/mysql_client_test.c mysql/tests/mysql_client_test.c
+--- mysql-old/tests/mysql_client_test.c 2011-05-10 17:45:45.620015710 +0000
++++ mysql/tests/mysql_client_test.c 2011-05-10 17:56:01.850015711 +0000
+@@ -610,7 +610,7 @@
+ return row_count;
+ }
+
+- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
++ field_count= MYSQL_MIN(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+diff -urN mysql-old/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql-old/vio/viosocket.c 2011-05-10 17:45:45.640015709 +0000
++++ mysql/vio/viosocket.c 2011-05-10 17:56:01.856682377 +0000
+@@ -69,7 +69,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-06-16 2:20 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-06-16 2:20 UTC (permalink / raw
To: gentoo-commits
commit: 38951023312766989c75acc00565ac5217c6c66c
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 16 02:11:01 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Jun 16 02:11:01 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=38951023
Extend 02040 patch for mysql-5.5.10 to the mysql-5.6 series as this has yet to be fixed upstream.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index a65a9c9..9e2c2a7 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -296,7 +296,7 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.5.10.patch
-@ver 5.05.10.00 to 5.05.99.99
+@ver 5.05.10.00 to 5.06.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-07-15 11:17 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-07-15 11:17 UTC (permalink / raw
To: gentoo-commits
commit: 85ae3597dbb44d07e9556751c10ef464633f237b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 15 11:15:27 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Fri Jul 15 11:15:27 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=85ae3597
Update 07110_all_mysql_gcc-4.2 patch for mysql-5.1.58.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.58.patch | 3838 ++++++++++++++++++++++++++++++++++
2 files changed, 3845 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 9e2c2a7..62b1372 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -529,7 +529,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.57.patch
-@ver 5.01.57.00 to 5.01.99.99
+@ver 5.01.57.00 to 5.01.57.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.58.patch
+@ver 5.01.58.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.58.patch b/07110_all_mysql_gcc-4.2_5.1.58.patch
new file mode 100644
index 0000000..37dc3e9
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.58.patch
@@ -0,0 +1,3838 @@
+diff -urN mysql-5.1.58-old/client/mysqlbinlog.cc mysql-5.1.58/client/mysqlbinlog.cc
+--- mysql-5.1.58-old/client/mysqlbinlog.cc 2011-07-15 02:20:33.710015973 +0000
++++ mysql-5.1.58/client/mysqlbinlog.cc 2011-07-15 10:45:58.896682639 +0000
+@@ -1954,7 +1954,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -urN mysql-5.1.58-old/client/mysql.cc mysql-5.1.58/client/mysql.cc
+--- mysql-5.1.58-old/client/mysql.cc 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/client/mysql.cc 2011-07-15 10:45:58.896682639 +0000
+@@ -3336,9 +3336,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3358,7 +3358,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -urN mysql-5.1.58-old/client/mysqldump.c mysql-5.1.58/client/mysqldump.c
+--- mysql-5.1.58-old/client/mysqldump.c 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/client/mysqldump.c 2011-07-15 10:49:00.153349307 +0000
+@@ -830,7 +830,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4523,7 +4523,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -urN mysql-5.1.58-old/client/mysqltest.cc mysql-5.1.58/client/mysqltest.cc
+--- mysql-5.1.58-old/client/mysqltest.cc 2011-07-15 02:20:33.710015973 +0000
++++ mysql-5.1.58/client/mysqltest.cc 2011-07-15 10:45:58.900015973 +0000
+@@ -5654,9 +5654,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -urN mysql-5.1.58-old/client/mysql_upgrade.c mysql-5.1.58/client/mysql_upgrade.c
+--- mysql-5.1.58-old/client/mysql_upgrade.c 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/client/mysql_upgrade.c 2011-07-15 10:49:00.123349307 +0000
+@@ -528,7 +528,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -urN mysql-5.1.58-old/client/sql_string.cc mysql-5.1.58/client/sql_string.cc
+--- mysql-5.1.58-old/client/sql_string.cc 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/client/sql_string.cc 2011-07-15 10:45:58.903349307 +0000
+@@ -660,7 +660,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -746,7 +746,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -763,7 +763,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -urN mysql-5.1.58-old/dbug/dbug.c mysql-5.1.58/dbug/dbug.c
+--- mysql-5.1.58-old/dbug/dbug.c 2011-07-15 02:20:33.670015973 +0000
++++ mysql-5.1.58/dbug/dbug.c 2011-07-15 10:48:59.536682640 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -urN mysql-5.1.58-old/extra/yassl/src/ssl.cpp mysql-5.1.58/extra/yassl/src/ssl.cpp
+--- mysql-5.1.58-old/extra/yassl/src/ssl.cpp 2011-07-15 02:20:33.666682640 +0000
++++ mysql-5.1.58/extra/yassl/src/ssl.cpp 2011-07-15 10:45:58.903349307 +0000
+@@ -38,6 +38,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -113,7 +114,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/include/pwdbased.hpp mysql-5.1.58/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-5.1.58-old/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-15 02:20:33.663349307 +0000
++++ mysql-5.1.58/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-15 10:45:58.903349307 +0000
+@@ -67,7 +67,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/src/dh.cpp mysql-5.1.58/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-5.1.58-old/extra/yassl/taocrypt/src/dh.cpp 2011-07-15 02:20:33.663349307 +0000
++++ mysql-5.1.58/extra/yassl/taocrypt/src/dh.cpp 2011-07-15 10:45:58.903349307 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -urN mysql-5.1.58-old/libmysql/libmysql.c mysql-5.1.58/libmysql/libmysql.c
+--- mysql-5.1.58-old/libmysql/libmysql.c 2011-07-15 02:20:33.566682641 +0000
++++ mysql-5.1.58/libmysql/libmysql.c 2011-07-15 10:48:57.350015973 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -urN mysql-5.1.58-old/libmysqld/lib_sql.cc mysql-5.1.58/libmysqld/lib_sql.cc
+--- mysql-5.1.58-old/libmysqld/lib_sql.cc 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/libmysqld/lib_sql.cc 2011-07-15 10:45:58.906682641 +0000
+@@ -848,7 +848,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -urN mysql-5.1.58-old/mysys/array.c mysql-5.1.58/mysys/array.c
+--- mysql-5.1.58-old/mysys/array.c 2011-07-15 02:20:33.740015973 +0000
++++ mysql-5.1.58/mysys/array.c 2011-07-15 10:49:00.450015973 +0000
+@@ -47,7 +47,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -341,7 +341,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -urN mysql-5.1.58-old/mysys/default.c mysql-5.1.58/mysys/default.c
+--- mysql-5.1.58-old/mysys/default.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/default.c 2011-07-15 10:49:00.556682640 +0000
+@@ -793,7 +793,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -urN mysql-5.1.58-old/mysys/mf_format.c mysql-5.1.58/mysys/mf_format.c
+--- mysql-5.1.58-old/mysys/mf_format.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/mf_format.c 2011-07-15 10:49:00.596682639 +0000
+@@ -83,7 +83,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -urN mysql-5.1.58-old/mysys/mf_iocache.c mysql-5.1.58/mysys/mf_iocache.c
+--- mysql-5.1.58-old/mysys/mf_iocache.c 2011-07-15 02:20:33.740015973 +0000
++++ mysql-5.1.58/mysys/mf_iocache.c 2011-07-15 10:49:00.520015974 +0000
+@@ -1097,7 +1097,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1256,7 +1256,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1365,7 +1365,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1399,7 +1399,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -urN mysql-5.1.58-old/mysys/my_alloc.c mysql-5.1.58/mysys/my_alloc.c
+--- mysql-5.1.58-old/mysys/my_alloc.c 2011-07-15 02:20:33.740015973 +0000
++++ mysql-5.1.58/mysys/my_alloc.c 2011-07-15 10:49:00.510015973 +0000
+@@ -212,7 +212,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -urN mysql-5.1.58-old/mysys/my_bitmap.c mysql-5.1.58/mysys/my_bitmap.c
+--- mysql-5.1.58-old/mysys/my_bitmap.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_bitmap.c 2011-07-15 10:49:00.586682640 +0000
+@@ -423,7 +423,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -urN mysql-5.1.58-old/mysys/my_compare.c mysql-5.1.58/mysys/my_compare.c
+--- mysql-5.1.58-old/mysys/my_compare.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_compare.c 2011-07-15 10:49:00.570015973 +0000
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -urN mysql-5.1.58-old/mysys/my_compress.c mysql-5.1.58/mysys/my_compress.c
+--- mysql-5.1.58-old/mysys/my_compress.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_compress.c 2011-07-15 10:49:00.630015973 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -urN mysql-5.1.58-old/mysys/my_conio.c mysql-5.1.58/mysys/my_conio.c
+--- mysql-5.1.58-old/mysys/my_conio.c 2011-07-15 02:20:33.740015973 +0000
++++ mysql-5.1.58/mysys/my_conio.c 2011-07-15 10:49:00.526682640 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -urN mysql-5.1.58-old/mysys/my_file.c mysql-5.1.58/mysys/my_file.c
+--- mysql-5.1.58-old/mysys/my_file.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_file.c 2011-07-15 10:49:00.600015973 +0000
+@@ -75,7 +75,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -97,7 +97,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -107,9 +107,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -urN mysql-5.1.58-old/mysys/my_getopt.c mysql-5.1.58/mysys/my_getopt.c
+--- mysql-5.1.58-old/mysys/my_getopt.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_getopt.c 2011-07-15 10:49:00.626682639 +0000
+@@ -983,7 +983,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -urN mysql-5.1.58-old/mysys/my_static.h mysql-5.1.58/mysys/my_static.h
+--- mysql-5.1.58-old/mysys/my_static.h 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/my_static.h 2011-07-15 10:49:00.563349306 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -urN mysql-5.1.58-old/mysys/safemalloc.c mysql-5.1.58/mysys/safemalloc.c
+--- mysql-5.1.58-old/mysys/safemalloc.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/safemalloc.c 2011-07-15 10:49:00.583349307 +0000
+@@ -248,7 +248,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -urN mysql-5.1.58-old/mysys/stacktrace.c mysql-5.1.58/mysys/stacktrace.c
+--- mysql-5.1.58-old/mysys/stacktrace.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/mysys/stacktrace.c 2011-07-15 10:49:00.603349307 +0000
+@@ -96,7 +96,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -324,7 +324,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) &
+ ~(ulong) 0xFFFF);
+diff -urN mysql-5.1.58-old/server-tools/instance-manager/buffer.cc mysql-5.1.58/server-tools/instance-manager/buffer.cc
+--- mysql-5.1.58-old/server-tools/instance-manager/buffer.cc 2011-07-15 02:20:33.706682639 +0000
++++ mysql-5.1.58/server-tools/instance-manager/buffer.cc 2011-07-15 10:45:58.910015974 +0000
+@@ -83,8 +83,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -urN mysql-5.1.58-old/server-tools/instance-manager/listener.cc mysql-5.1.58/server-tools/instance-manager/listener.cc
+--- mysql-5.1.58-old/server-tools/instance-manager/listener.cc 2011-07-15 02:20:33.703349306 +0000
++++ mysql-5.1.58/server-tools/instance-manager/listener.cc 2011-07-15 10:45:58.910015974 +0000
+@@ -103,7 +103,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -urN mysql-5.1.58-old/sql/debug_sync.cc mysql-5.1.58/sql/debug_sync.cc
+--- mysql-5.1.58-old/sql/debug_sync.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/debug_sync.cc 2011-07-15 10:45:58.910015974 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -urN mysql-5.1.58-old/sql/field.cc mysql-5.1.58/sql/field.cc
+--- mysql-5.1.58-old/sql/field.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/field.cc 2011-07-15 10:45:58.913349307 +0000
+@@ -53,7 +53,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2071,7 +2071,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2079,7 +2079,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2504,7 +2504,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2520,7 +2520,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3090,7 +3090,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3302,7 +3302,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3519,7 +3519,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3738,7 +3738,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3979,7 +3979,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4202,7 +4202,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6441,13 +6441,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6455,7 +6455,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6713,7 +6713,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7707,7 +7707,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7867,7 +7867,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8063,7 +8063,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9110,7 +9110,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9196,7 +9196,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9324,7 +9324,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9781,7 +9781,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -urN mysql-5.1.58-old/sql/filesort.cc mysql-5.1.58/sql/filesort.cc
+--- mysql-5.1.58-old/sql/filesort.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/filesort.cc 2011-07-15 10:45:58.913349307 +0000
+@@ -193,7 +193,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -215,12 +215,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+ if ((table_sort.sort_keys=
+ (uchar **) make_char_array((char **) table_sort.sort_keys,
+ param.keys, param.rec_length, MYF(0))))
+@@ -1117,7 +1117,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1380,7 +1380,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -urN mysql-5.1.58-old/sql/ha_ndbcluster.cc mysql-5.1.58/sql/ha_ndbcluster.cc
+--- mysql-5.1.58-old/sql/ha_ndbcluster.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/ha_ndbcluster.cc 2011-07-15 10:45:58.913349307 +0000
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -urN mysql-5.1.58-old/sql/handler.h mysql-5.1.58/sql/handler.h
+--- mysql-5.1.58-old/sql/handler.h 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/handler.h 2011-07-15 10:48:59.960015973 +0000
+@@ -1606,15 +1606,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -urN mysql-5.1.58-old/sql/ha_partition.cc mysql-5.1.58/sql/ha_partition.cc
+--- mysql-5.1.58-old/sql/ha_partition.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/ha_partition.cc 2011-07-15 10:45:58.916682640 +0000
+@@ -6131,7 +6131,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -urN mysql-5.1.58-old/sql/item_buff.cc mysql-5.1.58/sql/item_buff.cc
+--- mysql-5.1.58-old/sql/item_buff.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/item_buff.cc 2011-07-15 10:45:58.916682640 +0000
+@@ -59,7 +59,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -69,7 +69,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -urN mysql-5.1.58-old/sql/item.cc mysql-5.1.58/sql/item.cc
+--- mysql-5.1.58-old/sql/item.cc 2011-07-15 02:20:33.683349307 +0000
++++ mysql-5.1.58/sql/item.cc 2011-07-15 10:45:58.920015973 +0000
+@@ -74,7 +74,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -442,9 +442,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -750,7 +750,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5414,7 +5414,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5469,7 +5469,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7559,14 +7559,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7597,7 +7597,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7619,7 +7619,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7637,7 +7637,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -urN mysql-5.1.58-old/sql/item_cmpfunc.cc mysql-5.1.58/sql/item_cmpfunc.cc
+--- mysql-5.1.58-old/sql/item_cmpfunc.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/item_cmpfunc.cc 2011-07-15 10:45:58.920015973 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -urN mysql-5.1.58-old/sql/item_func.cc mysql-5.1.58/sql/item_func.cc
+--- mysql-5.1.58-old/sql/item_func.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/item_func.cc 2011-07-15 10:45:58.923349306 +0000
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -urN mysql-5.1.58-old/sql/item_func.h mysql-5.1.58/sql/item_func.h
+--- mysql-5.1.58-old/sql/item_func.h 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/item_func.h 2011-07-15 10:48:59.923349307 +0000
+@@ -420,7 +420,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -urN mysql-5.1.58-old/sql/item_strfunc.cc mysql-5.1.58/sql/item_strfunc.cc
+--- mysql-5.1.58-old/sql/item_strfunc.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/item_strfunc.cc 2011-07-15 10:45:58.923349306 +0000
+@@ -387,7 +387,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -748,7 +748,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1249,7 +1249,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1269,7 +1269,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1960,7 +1960,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3112,11 +3112,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3580,7 +3580,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -urN mysql-5.1.58-old/sql/item_strfunc.h mysql-5.1.58/sql/item_strfunc.h
+--- mysql-5.1.58-old/sql/item_strfunc.h 2011-07-15 02:20:33.680015973 +0000
++++ mysql-5.1.58/sql/item_strfunc.h 2011-07-15 10:48:59.833349307 +0000
+@@ -707,7 +707,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -urN mysql-5.1.58-old/sql/item_sum.cc mysql-5.1.58/sql/item_sum.cc
+--- mysql-5.1.58-old/sql/item_sum.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/item_sum.cc 2011-07-15 10:45:58.923349306 +0000
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -urN mysql-5.1.58-old/sql/item_timefunc.cc mysql-5.1.58/sql/item_timefunc.cc
+--- mysql-5.1.58-old/sql/item_timefunc.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/item_timefunc.cc 2011-07-15 10:45:58.926682639 +0000
+@@ -308,14 +308,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -324,7 +324,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -341,15 +341,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -360,14 +360,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -375,7 +375,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -427,7 +427,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -439,7 +439,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -451,7 +451,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -596,7 +596,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1828,7 +1828,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -urN mysql-5.1.58-old/sql/key.cc mysql-5.1.58/sql/key.cc
+--- mysql-5.1.58-old/sql/key.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/key.cc 2011-07-15 10:45:58.926682639 +0000
+@@ -125,13 +125,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -215,7 +215,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -224,7 +224,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -285,7 +285,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -351,7 +351,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -urN mysql-5.1.58-old/sql/log.cc mysql-5.1.58/sql/log.cc
+--- mysql-5.1.58-old/sql/log.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/log.cc 2011-07-15 10:45:58.926682639 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2429,7 +2429,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5237,7 +5237,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -urN mysql-5.1.58-old/sql/log_event.cc mysql-5.1.58/sql/log_event.cc
+--- mysql-5.1.58-old/sql/log_event.cc 2011-07-15 02:20:33.683349307 +0000
++++ mysql-5.1.58/sql/log_event.cc 2011-07-15 10:45:58.930015973 +0000
+@@ -1075,7 +1075,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2671,7 +2671,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5588,7 +5588,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7315,7 +7315,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -urN mysql-5.1.58-old/sql/log_event_old.cc mysql-5.1.58/sql/log_event_old.cc
+--- mysql-5.1.58-old/sql/log_event_old.cc 2011-07-15 02:20:33.683349307 +0000
++++ mysql-5.1.58/sql/log_event_old.cc 2011-07-15 10:45:58.930015973 +0000
+@@ -1420,7 +1420,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -urN mysql-5.1.58-old/sql/mysqld.cc mysql-5.1.58/sql/mysqld.cc
+--- mysql-5.1.58-old/sql/mysqld.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/mysqld.cc 2011-07-15 10:45:58.933349307 +0000
+@@ -3394,7 +3394,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3406,15 +3406,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -5096,7 +5096,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -urN mysql-5.1.58-old/sql/net_serv.cc mysql-5.1.58/sql/net_serv.cc
+--- mysql-5.1.58-old/sql/net_serv.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/net_serv.cc 2011-07-15 10:45:58.933349307 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -urN mysql-5.1.58-old/sql/opt_range.cc mysql-5.1.58/sql/opt_range.cc
+--- mysql-5.1.58-old/sql/opt_range.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/opt_range.cc 2011-07-15 10:45:58.936682641 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -urN mysql-5.1.58-old/sql/opt_range.h mysql-5.1.58/sql/opt_range.h
+--- mysql-5.1.58-old/sql/opt_range.h 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/opt_range.h 2011-07-15 10:48:59.926682640 +0000
+@@ -83,7 +83,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -121,7 +121,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -urN mysql-5.1.58-old/sql/protocol.cc mysql-5.1.58/sql/protocol.cc
+--- mysql-5.1.58-old/sql/protocol.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/protocol.cc 2011-07-15 10:45:58.936682641 +0000
+@@ -167,7 +167,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -262,7 +262,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -urN mysql-5.1.58-old/sql/rpl_record.cc mysql-5.1.58/sql/rpl_record.cc
+--- mysql-5.1.58-old/sql/rpl_record.cc 2011-07-15 02:20:33.696682640 +0000
++++ mysql-5.1.58/sql/rpl_record.cc 2011-07-15 10:45:58.936682641 +0000
+@@ -285,7 +285,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -urN mysql-5.1.58-old/sql/rpl_rli.cc mysql-5.1.58/sql/rpl_rli.cc
+--- mysql-5.1.58-old/sql/rpl_rli.cc 2011-07-15 02:20:33.696682640 +0000
++++ mysql-5.1.58/sql/rpl_rli.cc 2011-07-15 10:45:58.936682641 +0000
+@@ -686,7 +686,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -696,7 +696,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -urN mysql-5.1.58-old/sql/rpl_utility.cc mysql-5.1.58/sql/rpl_utility.cc
+--- mysql-5.1.58-old/sql/rpl_utility.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/rpl_utility.cc 2011-07-15 10:45:58.936682641 +0000
+@@ -180,7 +180,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -urN mysql-5.1.58-old/sql/rpl_utility.h mysql-5.1.58/sql/rpl_utility.h
+--- mysql-5.1.58-old/sql/rpl_utility.h 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/rpl_utility.h 2011-07-15 10:48:59.950015974 +0000
+@@ -295,7 +295,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -urN mysql-5.1.58-old/sql/set_var.cc mysql-5.1.58/sql/set_var.cc
+--- mysql-5.1.58-old/sql/set_var.cc 2011-07-15 02:20:33.683349307 +0000
++++ mysql-5.1.58/sql/set_var.cc 2011-07-15 10:45:58.940015974 +0000
+@@ -1845,7 +1845,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4030,7 +4030,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -urN mysql-5.1.58-old/sql/slave.cc mysql-5.1.58/sql/slave.cc
+--- mysql-5.1.58-old/sql/slave.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/slave.cc 2011-07-15 10:45:58.940015974 +0000
+@@ -1737,7 +1737,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2354,7 +2354,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4050,7 +4050,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -urN mysql-5.1.58-old/sql/spatial.h mysql-5.1.58/sql/spatial.h
+--- mysql-5.1.58-old/sql/spatial.h 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/spatial.h 2011-07-15 10:48:59.790015973 +0000
+@@ -180,8 +180,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -urN mysql-5.1.58-old/sql/sp_head.cc mysql-5.1.58/sql/sp_head.cc
+--- mysql-5.1.58-old/sql/sp_head.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/sp_head.cc 2011-07-15 10:45:58.940015974 +0000
+@@ -2454,7 +2454,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2655,7 +2655,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -urN mysql-5.1.58-old/sql/sql_acl.cc mysql-5.1.58/sql/sql_acl.cc
+--- mysql-5.1.58-old/sql/sql_acl.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/sql_acl.cc 2011-07-15 10:45:58.943349307 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -urN mysql-5.1.58-old/sql/sql_analyse.cc mysql-5.1.58/sql/sql_analyse.cc
+--- mysql-5.1.58-old/sql/sql_analyse.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/sql_analyse.cc 2011-07-15 10:45:58.943349307 +0000
+@@ -280,16 +280,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1043,7 +1043,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1068,7 +1068,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1185,7 +1185,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -urN mysql-5.1.58-old/sql/sql_cache.cc mysql-5.1.58/sql/sql_cache.cc
+--- mysql-5.1.58-old/sql/sql_cache.cc 2011-07-15 02:20:33.680015973 +0000
++++ mysql-5.1.58/sql/sql_cache.cc 2011-07-15 10:45:58.943349307 +0000
+@@ -1004,7 +1004,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2425,7 +2425,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2480,7 +2480,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2508,7 +2508,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2596,8 +2596,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2629,7 +2629,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2638,7 +2638,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3061,7 +3061,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -urN mysql-5.1.58-old/sql/sql_class.cc mysql-5.1.58/sql/sql_class.cc
+--- mysql-5.1.58-old/sql/sql_class.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/sql_class.cc 2011-07-15 10:45:58.943349307 +0000
+@@ -415,7 +415,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -430,7 +430,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2100,7 +2100,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -urN mysql-5.1.58-old/sql/sql_client.cc mysql-5.1.58/sql/sql_client.cc
+--- mysql-5.1.58-old/sql/sql_client.cc 2011-07-15 02:20:33.696682640 +0000
++++ mysql-5.1.58/sql/sql_client.cc 2011-07-15 10:45:58.946682640 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -urN mysql-5.1.58-old/sql/sql_connect.cc mysql-5.1.58/sql/sql_connect.cc
+--- mysql-5.1.58-old/sql/sql_connect.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/sql_connect.cc 2011-07-15 10:45:58.946682640 +0000
+@@ -843,7 +843,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -urN mysql-5.1.58-old/sql/sql_parse.cc mysql-5.1.58/sql/sql_parse.cc
+--- mysql-5.1.58-old/sql/sql_parse.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/sql_parse.cc 2011-07-15 10:45:58.946682640 +0000
+@@ -5721,7 +5721,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7225,7 +7225,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -urN mysql-5.1.58-old/sql/sql_partition.cc mysql-5.1.58/sql/sql_partition.cc
+--- mysql-5.1.58-old/sql/sql_partition.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/sql_partition.cc 2011-07-15 10:45:58.950015973 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -urN mysql-5.1.58-old/sql/sql_plugin.cc mysql-5.1.58/sql/sql_plugin.cc
+--- mysql-5.1.58-old/sql/sql_plugin.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/sql_plugin.cc 2011-07-15 10:45:58.950015973 +0000
+@@ -510,7 +510,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2129,7 +2129,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -urN mysql-5.1.58-old/sql/sql_prepare.cc mysql-5.1.58/sql/sql_prepare.cc
+--- mysql-5.1.58-old/sql/sql_prepare.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/sql_prepare.cc 2011-07-15 10:45:58.953349306 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -urN mysql-5.1.58-old/sql/sql_profile.cc mysql-5.1.58/sql/sql_profile.cc
+--- mysql-5.1.58-old/sql/sql_profile.cc 2011-07-15 02:20:33.683349307 +0000
++++ mysql-5.1.58/sql/sql_profile.cc 2011-07-15 10:45:58.953349306 +0000
+@@ -252,7 +252,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -urN mysql-5.1.58-old/sql/sql_repl.cc mysql-5.1.58/sql/sql_repl.cc
+--- mysql-5.1.58-old/sql/sql_repl.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/sql_repl.cc 2011-07-15 10:45:58.953349306 +0000
+@@ -1297,12 +1297,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1474,7 +1474,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1745,14 +1745,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1761,7 +1761,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -urN mysql-5.1.58-old/sql/sql_select.cc mysql-5.1.58/sql/sql_select.cc
+--- mysql-5.1.58-old/sql/sql_select.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/sql_select.cc 2011-07-15 10:45:58.956682639 +0000
+@@ -3006,7 +3006,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3942,7 +3942,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3965,7 +3965,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4128,7 +4128,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4448,7 +4448,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4615,7 +4615,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5565,7 +5565,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10481,7 +10481,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13693,7 +13693,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13705,7 +13705,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14403,7 +14403,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14525,7 +14525,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -urN mysql-5.1.58-old/sql/sql_show.cc mysql-5.1.58/sql/sql_show.cc
+--- mysql-5.1.58-old/sql/sql_show.cc 2011-07-15 02:20:33.686682641 +0000
++++ mysql-5.1.58/sql/sql_show.cc 2011-07-15 10:45:58.960015973 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1871,7 +1871,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2002,7 +2002,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3267,7 +3267,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7084,7 +7084,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -urN mysql-5.1.58-old/sql/sql_string.cc mysql-5.1.58/sql/sql_string.cc
+--- mysql-5.1.58-old/sql/sql_string.cc 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/sql_string.cc 2011-07-15 10:45:58.960015973 +0000
+@@ -695,7 +695,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -781,7 +781,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -798,7 +798,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -999,7 +999,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1185,7 +1185,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -urN mysql-5.1.58-old/sql/sql_table.cc mysql-5.1.58/sql/sql_table.cc
+--- mysql-5.1.58-old/sql/sql_table.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/sql_table.cc 2011-07-15 10:45:58.960015973 +0000
+@@ -3275,7 +3275,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -urN mysql-5.1.58-old/sql/sql_yacc.cc mysql-5.1.58/sql/sql_yacc.cc
+--- mysql-5.1.58-old/sql/sql_yacc.cc 2011-07-15 02:20:33.700015973 +0000
++++ mysql-5.1.58/sql/sql_yacc.cc 2011-07-15 10:45:58.970015974 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -urN mysql-5.1.58-old/sql/sql_yacc.yy mysql-5.1.58/sql/sql_yacc.yy
+--- mysql-5.1.58-old/sql/sql_yacc.yy 2011-07-15 02:20:33.693349307 +0000
++++ mysql-5.1.58/sql/sql_yacc.yy 2011-07-15 10:45:58.973349307 +0000
+@@ -1805,7 +1805,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1815,7 +1815,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -urN mysql-5.1.58-old/sql/thr_malloc.cc mysql-5.1.58/sql/thr_malloc.cc
+--- mysql-5.1.58-old/sql/thr_malloc.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/thr_malloc.cc 2011-07-15 10:45:58.973349307 +0000
+@@ -130,7 +130,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -urN mysql-5.1.58-old/sql/tztime.cc mysql-5.1.58/sql/tztime.cc
+--- mysql-5.1.58-old/sql/tztime.cc 2011-07-15 02:20:33.676682639 +0000
++++ mysql-5.1.58/sql/tztime.cc 2011-07-15 10:45:58.973349307 +0000
+@@ -167,7 +167,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -396,7 +396,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1823,7 +1823,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -urN mysql-5.1.58-old/sql/unireg.cc mysql-5.1.58/sql/unireg.cc
+--- mysql-5.1.58-old/sql/unireg.cc 2011-07-15 02:20:33.690015974 +0000
++++ mysql-5.1.58/sql/unireg.cc 2011-07-15 10:45:58.973349307 +0000
+@@ -496,7 +496,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -716,7 +716,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -urN mysql-5.1.58-old/sql-common/client.c mysql-5.1.58/sql-common/client.c
+--- mysql-5.1.58-old/sql-common/client.c 2011-07-15 02:20:33.716682641 +0000
++++ mysql-5.1.58/sql-common/client.c 2011-07-15 10:49:00.413349306 +0000
+@@ -728,7 +728,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2102,7 +2102,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -urN mysql-5.1.58-old/sql-common/my_time.c mysql-5.1.58/sql-common/my_time.c
+--- mysql-5.1.58-old/sql-common/my_time.c 2011-07-15 02:20:33.720015974 +0000
++++ mysql-5.1.58/sql-common/my_time.c 2011-07-15 10:49:00.423349307 +0000
+@@ -249,7 +249,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -urN mysql-5.1.58-old/storage/csv/ha_tina.cc mysql-5.1.58/storage/csv/ha_tina.cc
+--- mysql-5.1.58-old/storage/csv/ha_tina.cc 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/csv/ha_tina.cc 2011-07-15 10:45:58.976682640 +0000
+@@ -1193,7 +1193,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1429,7 +1429,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -urN mysql-5.1.58-old/storage/example/ha_example.h mysql-5.1.58/storage/example/ha_example.h
+--- mysql-5.1.58-old/storage/example/ha_example.h 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/example/ha_example.h 2011-07-15 10:48:57.970015974 +0000
+@@ -110,14 +110,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -128,7 +128,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -139,7 +139,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -urN mysql-5.1.58-old/storage/federated/ha_federated.cc mysql-5.1.58/storage/federated/ha_federated.cc
+--- mysql-5.1.58-old/storage/federated/ha_federated.cc 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/federated/ha_federated.cc 2011-07-15 10:45:58.976682640 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -urN mysql-5.1.58-old/storage/heap/hp_create.c mysql-5.1.58/storage/heap/hp_create.c
+--- mysql-5.1.58-old/storage/heap/hp_create.c 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/heap/hp_create.c 2011-07-15 10:48:57.983349306 +0000
+@@ -229,7 +229,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -urN mysql-5.1.58-old/storage/heap/hp_test2.c mysql-5.1.58/storage/heap/hp_test2.c
+--- mysql-5.1.58-old/storage/heap/hp_test2.c 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/heap/hp_test2.c 2011-07-15 10:48:58.006682640 +0000
+@@ -136,7 +136,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -217,7 +217,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -urN mysql-5.1.58-old/storage/innobase/include/ut0byte.h mysql-5.1.58/storage/innobase/include/ut0byte.h
+--- mysql-5.1.58-old/storage/innobase/include/ut0byte.h 2011-07-15 02:20:33.570015974 +0000
++++ mysql-5.1.58/storage/innobase/include/ut0byte.h 2011-07-15 10:48:57.576682641 +0000
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -urN mysql-5.1.58-old/storage/innodb_plugin/dict/dict0dict.c mysql-5.1.58/storage/innodb_plugin/dict/dict0dict.c
+--- mysql-5.1.58-old/storage/innodb_plugin/dict/dict0dict.c 2011-07-15 02:20:33.636682640 +0000
++++ mysql-5.1.58/storage/innodb_plugin/dict/dict0dict.c 2011-07-15 10:48:58.506682641 +0000
+@@ -4858,7 +4858,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4868,7 +4868,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -urN mysql-5.1.58-old/storage/innodb_plugin/include/dict0dict.h mysql-5.1.58/storage/innodb_plugin/include/dict0dict.h
+--- mysql-5.1.58-old/storage/innodb_plugin/include/dict0dict.h 2011-07-15 02:20:33.643349306 +0000
++++ mysql-5.1.58/storage/innodb_plugin/include/dict0dict.h 2011-07-15 10:48:58.683349307 +0000
+@@ -1123,7 +1123,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -urN mysql-5.1.58-old/storage/myisam/ft_boolean_search.c mysql-5.1.58/storage/myisam/ft_boolean_search.c
+--- mysql-5.1.58-old/storage/myisam/ft_boolean_search.c 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/myisam/ft_boolean_search.c 2011-07-15 10:48:58.020015973 +0000
+@@ -46,9 +46,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -urN mysql-5.1.58-old/storage/myisam/ha_myisam.cc mysql-5.1.58/storage/myisam/ha_myisam.cc
+--- mysql-5.1.58-old/storage/myisam/ha_myisam.cc 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/ha_myisam.cc 2011-07-15 10:45:58.976682640 +0000
+@@ -1528,7 +1528,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -urN mysql-5.1.58-old/storage/myisam/mi_cache.c mysql-5.1.58/storage/myisam/mi_cache.c
+--- mysql-5.1.58-old/storage/myisam/mi_cache.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_cache.c 2011-07-15 10:48:58.080015973 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -urN mysql-5.1.58-old/storage/myisam/mi_check.c mysql-5.1.58/storage/myisam/mi_check.c
+--- mysql-5.1.58-old/storage/myisam/mi_check.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_check.c 2011-07-15 10:48:58.186682640 +0000
+@@ -2173,7 +2173,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2329,7 +2329,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2418,7 +2418,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAXparam->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2782,7 +2782,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3980,7 +3980,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAXval_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+@@ -4331,7 +4331,7 @@
+
+ VOID(mi_close(*org_info));
+ bzero((char*) &create_info,sizeof(create_info));
+- create_info.max_rows=max(max_records,share.base.records);
++ create_info.max_rows=MYSQL_MAX(max_records,share.base.records);
+ create_info.reloc_rows=share.base.reloc;
+ create_info.old_options=(share.options |
+ (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
+diff -urN mysql-5.1.58-old/storage/myisam/mi_create.c mysql-5.1.58/storage/myisam/mi_create.c
+--- mysql-5.1.58-old/storage/myisam/mi_create.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_create.c 2011-07-15 10:48:58.100015973 +0000
+@@ -437,8 +437,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -527,7 +527,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -565,7 +565,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -urN mysql-5.1.58-old/storage/myisam/mi_dynrec.c mysql-5.1.58/storage/myisam/mi_dynrec.c
+--- mysql-5.1.58-old/storage/myisam/mi_dynrec.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_dynrec.c 2011-07-15 10:48:58.116682641 +0000
+@@ -880,7 +880,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -urN mysql-5.1.58-old/storage/myisam/mi_extra.c mysql-5.1.58/storage/myisam/mi_extra.c
+--- mysql-5.1.58-old/storage/myisam/mi_extra.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_extra.c 2011-07-15 10:48:58.153349307 +0000
+@@ -99,7 +99,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -urN mysql-5.1.58-old/storage/myisam/mi_open.c mysql-5.1.58/storage/myisam/mi_open.c
+--- mysql-5.1.58-old/storage/myisam/mi_open.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_open.c 2011-07-15 10:48:58.196682639 +0000
+@@ -328,7 +328,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -501,7 +501,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -714,10 +714,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -urN mysql-5.1.58-old/storage/myisam/mi_packrec.c mysql-5.1.58/storage/myisam/mi_packrec.c
+--- mysql-5.1.58-old/storage/myisam/mi_packrec.c 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/myisam/mi_packrec.c 2011-07-15 10:48:58.040015973 +0000
+@@ -684,7 +684,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1399,7 +1399,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -urN mysql-5.1.58-old/storage/myisam/mi_test1.c mysql-5.1.58/storage/myisam/mi_test1.c
+--- mysql-5.1.58-old/storage/myisam/mi_test1.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/mi_test1.c 2011-07-15 10:48:58.106682639 +0000
+@@ -436,7 +436,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -urN mysql-5.1.58-old/storage/myisam/mi_test2.c mysql-5.1.58/storage/myisam/mi_test2.c
+--- mysql-5.1.58-old/storage/myisam/mi_test2.c 2011-07-15 02:20:33.583349306 +0000
++++ mysql-5.1.58/storage/myisam/mi_test2.c 2011-07-15 10:48:58.053349307 +0000
+@@ -601,7 +601,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -urN mysql-5.1.58-old/storage/myisam/myisamlog.c mysql-5.1.58/storage/myisam/myisamlog.c
+--- mysql-5.1.58-old/storage/myisam/myisamlog.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/myisamlog.c 2011-07-15 10:48:58.143349307 +0000
+@@ -90,7 +90,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -urN mysql-5.1.58-old/storage/myisam/myisampack.c mysql-5.1.58/storage/myisam/myisampack.c
+--- mysql-5.1.58-old/storage/myisam/myisampack.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/myisampack.c 2011-07-15 10:48:58.130015973 +0000
+@@ -1239,7 +1239,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3001,7 +3001,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -urN mysql-5.1.58-old/storage/myisam/rt_mbr.c mysql-5.1.58/storage/myisam/rt_mbr.c
+--- mysql-5.1.58-old/storage/myisam/rt_mbr.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/rt_mbr.c 2011-07-15 10:48:58.190015973 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -urN mysql-5.1.58-old/storage/myisam/sort.c mysql-5.1.58/storage/myisam/sort.c
+--- mysql-5.1.58-old/storage/myisam/sort.c 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisam/sort.c 2011-07-15 10:48:58.160015973 +0000
+@@ -129,7 +129,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -346,7 +346,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -820,7 +820,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -841,7 +841,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -urN mysql-5.1.58-old/storage/myisammrg/ha_myisammrg.cc mysql-5.1.58/storage/myisammrg/ha_myisammrg.cc
+--- mysql-5.1.58-old/storage/myisammrg/ha_myisammrg.cc 2011-07-15 02:20:33.586682639 +0000
++++ mysql-5.1.58/storage/myisammrg/ha_myisammrg.cc 2011-07-15 10:45:58.983349306 +0000
+@@ -964,7 +964,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -urN mysql-5.1.58-old/storage/ndb/src/common/portlib/NdbTCP.cpp mysql-5.1.58/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-5.1.58-old/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-15 02:20:33.610015973 +0000
++++ mysql-5.1.58/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-15 10:45:58.983349306 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -urN mysql-5.1.58-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql-5.1.58/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-5.1.58-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-15 02:20:33.600015974 +0000
++++ mysql-5.1.58/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-15 10:45:58.983349306 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -urN mysql-5.1.58-old/storage/ndb/src/ndbapi/NdbBlob.cpp mysql-5.1.58/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-5.1.58-old/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-15 02:20:33.606682640 +0000
++++ mysql-5.1.58/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-15 10:45:58.983349306 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -urN mysql-5.1.58-old/storage/ndb/test/ndbapi/testIndexStat.cpp mysql-5.1.58/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-5.1.58-old/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-15 02:20:33.620015973 +0000
++++ mysql-5.1.58/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-15 10:45:58.986682639 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -urN mysql-5.1.58-old/storage/ndb/test/src/getarg.c mysql-5.1.58/storage/ndb/test/src/getarg.c
+--- mysql-5.1.58-old/storage/ndb/test/src/getarg.c 2011-07-15 02:20:33.616682639 +0000
++++ mysql-5.1.58/storage/ndb/test/src/getarg.c 2011-07-15 10:48:58.276682640 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -urN mysql-5.1.58-old/strings/ctype-big5.c mysql-5.1.58/strings/ctype-big5.c
+--- mysql-5.1.58-old/strings/ctype-big5.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/ctype-big5.c 2011-07-15 10:48:59.236682640 +0000
+@@ -253,7 +253,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -266,7 +266,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -urN mysql-5.1.58-old/strings/ctype-bin.c mysql-5.1.58/strings/ctype-bin.c
+--- mysql-5.1.58-old/strings/ctype-bin.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/ctype-bin.c 2011-07-15 10:48:59.206682640 +0000
+@@ -80,7 +80,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -131,7 +131,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -175,7 +175,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -404,7 +404,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -417,7 +417,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-5.1.58-old/strings/ctype-gbk.c mysql-5.1.58/strings/ctype-gbk.c
+--- mysql-5.1.58-old/strings/ctype-gbk.c 2011-07-15 02:20:33.660015974 +0000
++++ mysql-5.1.58/strings/ctype-gbk.c 2011-07-15 10:48:59.453349306 +0000
+@@ -2616,7 +2616,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2627,7 +2627,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -urN mysql-5.1.58-old/strings/ctype-mb.c mysql-5.1.58/strings/ctype-mb.c
+--- mysql-5.1.58-old/strings/ctype-mb.c 2011-07-15 02:20:33.653349307 +0000
++++ mysql-5.1.58/strings/ctype-mb.c 2011-07-15 10:48:59.066682639 +0000
+@@ -368,7 +368,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -412,7 +412,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -451,7 +451,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-5.1.58-old/strings/ctype-simple.c mysql-5.1.58/strings/ctype-simple.c
+--- mysql-5.1.58-old/strings/ctype-simple.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/ctype-simple.c 2011-07-15 10:48:59.283349307 +0000
+@@ -159,7 +159,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -873,7 +873,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -927,7 +927,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1158,7 +1158,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -urN mysql-5.1.58-old/strings/ctype-tis620.c mysql-5.1.58/strings/ctype-tis620.c
+--- mysql-5.1.58-old/strings/ctype-tis620.c 2011-07-15 02:20:33.660015974 +0000
++++ mysql-5.1.58/strings/ctype-tis620.c 2011-07-15 10:48:59.356682640 +0000
+@@ -581,7 +581,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -638,7 +638,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -urN mysql-5.1.58-old/strings/ctype-uca.c mysql-5.1.58/strings/ctype-uca.c
+--- mysql-5.1.58-old/strings/ctype-uca.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/ctype-uca.c 2011-07-15 10:48:59.273349306 +0000
+@@ -7567,7 +7567,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -urN mysql-5.1.58-old/strings/ctype-ucs2.c mysql-5.1.58/strings/ctype-ucs2.c
+--- mysql-5.1.58-old/strings/ctype-ucs2.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/ctype-ucs2.c 2011-07-15 10:48:59.203349307 +0000
+@@ -279,7 +279,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1331,7 +1331,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1425,7 +1425,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1472,7 +1472,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -urN mysql-5.1.58-old/strings/ctype-utf8.c mysql-5.1.58/strings/ctype-utf8.c
+--- mysql-5.1.58-old/strings/ctype-utf8.c 2011-07-15 02:20:33.660015974 +0000
++++ mysql-5.1.58/strings/ctype-utf8.c 2011-07-15 10:48:59.370015973 +0000
+@@ -1937,7 +1937,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -urN mysql-5.1.58-old/strings/decimal.c mysql-5.1.58/strings/decimal.c
+--- mysql-5.1.58-old/strings/decimal.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/decimal.c 2011-07-15 10:48:59.196682641 +0000
+@@ -404,7 +404,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -427,7 +427,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1518,8 +1518,8 @@
+
+ if (to != from || intg1>intg0)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg1+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg1+MYSQL_MAX(frac1, frac0);
+
+ while (buf0 < p0)
+ *(--p1) = *(--p0);
+@@ -1530,7 +1530,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1632,7 +1632,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1651,7 +1651,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1700,11 +1700,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1719,7 +1719,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1744,7 +1744,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1755,7 +1755,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1773,14 +1773,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1801,7 +1801,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1876,7 +1876,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1887,7 +1887,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1911,7 +1911,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2174,11 +2174,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2302,7 +2302,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2340,7 +2340,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -urN mysql-5.1.58-old/strings/my_vsnprintf.c mysql-5.1.58/strings/my_vsnprintf.c
+--- mysql-5.1.58-old/strings/my_vsnprintf.c 2011-07-15 02:20:33.656682641 +0000
++++ mysql-5.1.58/strings/my_vsnprintf.c 2011-07-15 10:48:59.156682639 +0000
+@@ -141,7 +141,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -urN mysql-5.1.58-old/strings/str2int.c mysql-5.1.58/strings/str2int.c
+--- mysql-5.1.58-old/strings/str2int.c 2011-07-15 02:20:33.653349307 +0000
++++ mysql-5.1.58/strings/str2int.c 2011-07-15 10:48:59.116682640 +0000
+@@ -82,7 +82,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -urN mysql-5.1.58-old/tests/mysql_client_test.c mysql-5.1.58/tests/mysql_client_test.c
+--- mysql-5.1.58-old/tests/mysql_client_test.c 2011-07-15 02:20:33.713349307 +0000
++++ mysql-5.1.58/tests/mysql_client_test.c 2011-07-15 10:49:00.340015974 +0000
+@@ -610,7 +610,7 @@
+ return row_count;
+ }
+
+- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
++ field_count= MYSQL_MIN(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+diff -urN mysql-5.1.58-old/vio/viosocket.c mysql-5.1.58/vio/viosocket.c
+--- mysql-5.1.58-old/vio/viosocket.c 2011-07-15 02:20:33.743349307 +0000
++++ mysql-5.1.58/vio/viosocket.c 2011-07-15 10:49:00.653349306 +0000
+@@ -71,7 +71,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-07-21 2:20 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-07-21 2:20 UTC (permalink / raw
To: gentoo-commits
commit: 31ef12e00217866d1ebb472145c4d691acc61b00
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 02:20:16 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 02:20:16 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=31ef12e0
Update 07110_all_mysql_gcc-4.2_5.1.58.patch.
---
07110_all_mysql_gcc-4.2_5.1.58.patch | 777 +++++++++++++++++-----------------
1 files changed, 399 insertions(+), 378 deletions(-)
diff --git a/07110_all_mysql_gcc-4.2_5.1.58.patch b/07110_all_mysql_gcc-4.2_5.1.58.patch
index 37dc3e9..659728c 100644
--- a/07110_all_mysql_gcc-4.2_5.1.58.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.58.patch
@@ -1,6 +1,11 @@
-diff -urN mysql-5.1.58-old/client/mysqlbinlog.cc mysql-5.1.58/client/mysqlbinlog.cc
---- mysql-5.1.58-old/client/mysqlbinlog.cc 2011-07-15 02:20:33.710015973 +0000
-+++ mysql-5.1.58/client/mysqlbinlog.cc 2011-07-15 10:45:58.896682639 +0000
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -urN mysql-orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql-orig/client/mysqlbinlog.cc 2011-07-21 02:15:51.904095298 +0000
++++ mysql/client/mysqlbinlog.cc 2011-07-21 02:16:28.801095322 +0000
@@ -1954,7 +1954,7 @@
my_off_t length,tmp;
for (length= start_position_mot ; length > 0 ; length-=tmp)
@@ -10,9 +15,9 @@ diff -urN mysql-5.1.58-old/client/mysqlbinlog.cc mysql-5.1.58/client/mysqlbinlog
if (my_b_read(file, buff, (uint) tmp))
{
error("Failed reading from file.");
-diff -urN mysql-5.1.58-old/client/mysql.cc mysql-5.1.58/client/mysql.cc
---- mysql-5.1.58-old/client/mysql.cc 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/client/mysql.cc 2011-07-15 10:45:58.896682639 +0000
+diff -urN mysql-orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql-orig/client/mysql.cc 2011-07-21 02:15:51.903095298 +0000
++++ mysql/client/mysql.cc 2011-07-21 02:16:28.803095322 +0000
@@ -3336,9 +3336,9 @@
{
uint length= column_names ? field->name_length : 0;
@@ -34,9 +39,9 @@ diff -urN mysql-5.1.58-old/client/mysql.cc mysql-5.1.58/client/mysql.cc
MAX_COLUMN_LENGTH),
field->name);
num_flag[off]= IS_NUM(field->type);
-diff -urN mysql-5.1.58-old/client/mysqldump.c mysql-5.1.58/client/mysqldump.c
---- mysql-5.1.58-old/client/mysqldump.c 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/client/mysqldump.c 2011-07-15 10:49:00.153349307 +0000
+diff -urN mysql-orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql-orig/client/mysqldump.c 2011-07-21 02:15:51.904095298 +0000
++++ mysql/client/mysqldump.c 2011-07-21 02:16:28.806095322 +0000
@@ -830,7 +830,7 @@
&err_ptr, &err_len);
if (err_len)
@@ -55,9 +60,9 @@ diff -urN mysql-5.1.58-old/client/mysqldump.c mysql-5.1.58/client/mysqldump.c
find= find_type(buff, lib, var_len);
if (!find)
{
-diff -urN mysql-5.1.58-old/client/mysqltest.cc mysql-5.1.58/client/mysqltest.cc
---- mysql-5.1.58-old/client/mysqltest.cc 2011-07-15 02:20:33.710015973 +0000
-+++ mysql-5.1.58/client/mysqltest.cc 2011-07-15 10:45:58.900015973 +0000
+diff -urN mysql-orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql-orig/client/mysqltest.cc 2011-07-21 02:15:51.903095298 +0000
++++ mysql/client/mysqltest.cc 2011-07-21 02:16:28.810095322 +0000
@@ -5654,9 +5654,9 @@
}
else if ((c == '{' &&
@@ -70,9 +75,9 @@ diff -urN mysql-5.1.58-old/client/mysqltest.cc mysql-5.1.58/client/mysqltest.cc
{
/* Only if and while commands can be terminated by { */
*p++= c;
-diff -urN mysql-5.1.58-old/client/mysql_upgrade.c mysql-5.1.58/client/mysql_upgrade.c
---- mysql-5.1.58-old/client/mysql_upgrade.c 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/client/mysql_upgrade.c 2011-07-15 10:49:00.123349307 +0000
+diff -urN mysql-orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql-orig/client/mysql_upgrade.c 2011-07-21 02:15:51.903095298 +0000
++++ mysql/client/mysql_upgrade.c 2011-07-21 02:16:28.814095322 +0000
@@ -528,7 +528,7 @@
if ((value_end= strchr(value_start, '\n')) == NULL)
return 1; /* Unexpected result */
@@ -82,9 +87,9 @@ diff -urN mysql-5.1.58-old/client/mysql_upgrade.c mysql-5.1.58/client/mysql_upgr
return 0;
}
-diff -urN mysql-5.1.58-old/client/sql_string.cc mysql-5.1.58/client/sql_string.cc
---- mysql-5.1.58-old/client/sql_string.cc 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/client/sql_string.cc 2011-07-15 10:45:58.903349307 +0000
+diff -urN mysql-orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql-orig/client/sql_string.cc 2011-07-21 02:15:51.904095298 +0000
++++ mysql/client/sql_string.cc 2011-07-21 02:16:28.815095322 +0000
@@ -660,7 +660,7 @@
{
if (Alloced_length < str_length + space_needed)
@@ -112,9 +117,9 @@ diff -urN mysql-5.1.58-old/client/sql_string.cc mysql-5.1.58/client/sql_string.c
memcpy(to->Ptr,from->Ptr,to->str_length);
to->str_charset=from->str_charset;
return to;
-diff -urN mysql-5.1.58-old/dbug/dbug.c mysql-5.1.58/dbug/dbug.c
---- mysql-5.1.58-old/dbug/dbug.c 2011-07-15 02:20:33.670015973 +0000
-+++ mysql-5.1.58/dbug/dbug.c 2011-07-15 10:48:59.536682640 +0000
+diff -urN mysql-orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql-orig/dbug/dbug.c 2011-07-21 02:15:51.908095298 +0000
++++ mysql/dbug/dbug.c 2011-07-21 02:16:28.816095322 +0000
@@ -1205,7 +1205,7 @@
if (TRACING)
{
@@ -133,9 +138,9 @@ diff -urN mysql-5.1.58-old/dbug/dbug.c mysql-5.1.58/dbug/dbug.c
for (count= 0; count < indent ; count++)
{
if ((count % INDENT) == 0)
-diff -urN mysql-5.1.58-old/extra/yassl/src/ssl.cpp mysql-5.1.58/extra/yassl/src/ssl.cpp
---- mysql-5.1.58-old/extra/yassl/src/ssl.cpp 2011-07-15 02:20:33.666682640 +0000
-+++ mysql-5.1.58/extra/yassl/src/ssl.cpp 2011-07-15 10:45:58.903349307 +0000
+diff -urN mysql-orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql-orig/extra/yassl/src/ssl.cpp 2011-07-21 02:15:52.091095298 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2011-07-21 02:16:28.818095322 +0000
@@ -38,6 +38,7 @@
#include "file.hpp" // for TaoCrypt Source
#include "coding.hpp" // HexDecoder
@@ -153,9 +158,9 @@ diff -urN mysql-5.1.58-old/extra/yassl/src/ssl.cpp mysql-5.1.58/extra/yassl/src/
source.size()));
EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
passwordSz, 1, key, iv);
-diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/include/pwdbased.hpp mysql-5.1.58/extra/yassl/taocrypt/include/pwdbased.hpp
---- mysql-5.1.58-old/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-15 02:20:33.663349307 +0000
-+++ mysql-5.1.58/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-15 10:45:58.903349307 +0000
+diff -urN mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-21 02:15:52.089095298 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2011-07-21 02:16:28.818095322 +0000
@@ -67,7 +67,7 @@
}
hmac.Final(buffer.get_buffer());
@@ -165,9 +170,9 @@ diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/include/pwdbased.hpp mysql-5.1.5
memcpy(derived, buffer.get_buffer(), segmentLen);
for (j = 1; j < iterations; j++) {
-diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/src/dh.cpp mysql-5.1.58/extra/yassl/taocrypt/src/dh.cpp
---- mysql-5.1.58-old/extra/yassl/taocrypt/src/dh.cpp 2011-07-15 02:20:33.663349307 +0000
-+++ mysql-5.1.58/extra/yassl/taocrypt/src/dh.cpp 2011-07-15 10:45:58.903349307 +0000
+diff -urN mysql-orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-orig/extra/yassl/taocrypt/src/dh.cpp 2011-07-21 02:15:52.090095298 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2011-07-21 02:16:28.818095322 +0000
@@ -23,6 +23,7 @@
#include "runtime.hpp"
#include "dh.hpp"
@@ -185,9 +190,25 @@ diff -urN mysql-5.1.58-old/extra/yassl/taocrypt/src/dh.cpp mysql-5.1.58/extra/ya
Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
x.Encode(priv, p_.ByteCount());
}
-diff -urN mysql-5.1.58-old/libmysql/libmysql.c mysql-5.1.58/libmysql/libmysql.c
---- mysql-5.1.58-old/libmysql/libmysql.c 2011-07-15 02:20:33.566682641 +0000
-+++ mysql-5.1.58/libmysql/libmysql.c 2011-07-15 10:48:57.350015973 +0000
+diff -urN mysql-orig/include/my_global.h mysql/include/my_global.h
+--- mysql-orig/include/my_global.h 2011-07-21 02:15:51.905095298 +0000
++++ mysql/include/my_global.h 2011-07-21 02:17:54.425095383 +0000
+@@ -584,10 +584,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -urN mysql-orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql-orig/libmysql/libmysql.c 2011-07-21 02:15:52.076095298 +0000
++++ mysql/libmysql/libmysql.c 2011-07-21 02:16:28.821095322 +0000
@@ -1572,7 +1572,7 @@
my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
@@ -236,9 +257,9 @@ diff -urN mysql-5.1.58-old/libmysql/libmysql.c mysql-5.1.58/libmysql/libmysql.c
memcpy(param->buffer, (char *)*row, copy_length);
/* Add an end null if there is room in the buffer */
if (copy_length != param->buffer_length)
-diff -urN mysql-5.1.58-old/libmysqld/lib_sql.cc mysql-5.1.58/libmysqld/lib_sql.cc
---- mysql-5.1.58-old/libmysqld/lib_sql.cc 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/libmysqld/lib_sql.cc 2011-07-15 10:45:58.906682641 +0000
+diff -urN mysql-orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql-orig/libmysqld/lib_sql.cc 2011-07-21 02:15:51.924095298 +0000
++++ mysql/libmysqld/lib_sql.cc 2011-07-21 02:16:28.822095322 +0000
@@ -848,7 +848,7 @@
is cleared between substatements, and mysqltest gets confused
*/
@@ -248,9 +269,9 @@ diff -urN mysql-5.1.58-old/libmysqld/lib_sql.cc mysql-5.1.58/libmysqld/lib_sql.c
return FALSE;
}
-diff -urN mysql-5.1.58-old/mysys/array.c mysql-5.1.58/mysys/array.c
---- mysql-5.1.58-old/mysys/array.c 2011-07-15 02:20:33.740015973 +0000
-+++ mysql-5.1.58/mysys/array.c 2011-07-15 10:49:00.450015973 +0000
+diff -urN mysql-orig/mysys/array.c mysql/mysys/array.c
+--- mysql-orig/mysys/array.c 2011-07-21 02:15:51.940095298 +0000
++++ mysql/mysys/array.c 2011-07-21 02:16:28.823095322 +0000
@@ -47,7 +47,7 @@
DBUG_ENTER("init_dynamic_array");
if (!alloc_increment)
@@ -269,9 +290,9 @@ diff -urN mysql-5.1.58-old/mysys/array.c mysql-5.1.58/mysys/array.c
/*
Do nothing if we are using a static buffer
-diff -urN mysql-5.1.58-old/mysys/default.c mysql-5.1.58/mysys/default.c
---- mysql-5.1.58-old/mysys/default.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/default.c 2011-07-15 10:49:00.556682640 +0000
+diff -urN mysql-orig/mysys/default.c mysql/mysys/default.c
+--- mysql-orig/mysys/default.c 2011-07-21 02:15:51.942095298 +0000
++++ mysql/mysys/default.c 2011-07-21 02:16:28.823095322 +0000
@@ -793,7 +793,7 @@
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
end[0]=0;
@@ -281,9 +302,9 @@ diff -urN mysql-5.1.58-old/mysys/default.c mysql-5.1.58/mysys/default.c
/* signal that a new group is found */
opt_handler(handler_ctx, curr_gr, NULL);
-diff -urN mysql-5.1.58-old/mysys/mf_format.c mysql-5.1.58/mysys/mf_format.c
---- mysql-5.1.58-old/mysys/mf_format.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/mf_format.c 2011-07-15 10:49:00.596682639 +0000
+diff -urN mysql-orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql-orig/mysys/mf_format.c 2011-07-21 02:15:51.942095298 +0000
++++ mysql/mysys/mf_format.c 2011-07-21 02:16:28.824095322 +0000
@@ -83,7 +83,7 @@
tmp_length= strlength(startpos);
DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
@@ -293,9 +314,9 @@ diff -urN mysql-5.1.58-old/mysys/mf_format.c mysql-5.1.58/mysys/mf_format.c
}
else
{
-diff -urN mysql-5.1.58-old/mysys/mf_iocache.c mysql-5.1.58/mysys/mf_iocache.c
---- mysql-5.1.58-old/mysys/mf_iocache.c 2011-07-15 02:20:33.740015973 +0000
-+++ mysql-5.1.58/mysys/mf_iocache.c 2011-07-15 10:49:00.520015974 +0000
+diff -urN mysql-orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql-orig/mysys/mf_iocache.c 2011-07-21 02:15:51.941095298 +0000
++++ mysql/mysys/mf_iocache.c 2011-07-21 02:16:28.825095322 +0000
@@ -1097,7 +1097,7 @@
*/
while (write_length)
@@ -332,9 +353,9 @@ diff -urN mysql-5.1.58-old/mysys/mf_iocache.c mysql-5.1.58/mysys/mf_iocache.c
memcpy(Buffer,info->request_pos,(size_t) use_length);
info->read_pos=info->request_pos+Count;
info->read_end=info->request_pos+read_length;
-diff -urN mysql-5.1.58-old/mysys/my_alloc.c mysql-5.1.58/mysys/my_alloc.c
---- mysql-5.1.58-old/mysys/my_alloc.c 2011-07-15 02:20:33.740015973 +0000
-+++ mysql-5.1.58/mysys/my_alloc.c 2011-07-15 10:49:00.510015973 +0000
+diff -urN mysql-orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql-orig/mysys/my_alloc.c 2011-07-21 02:15:51.941095298 +0000
++++ mysql/mysys/my_alloc.c 2011-07-21 02:16:28.826095322 +0000
@@ -212,7 +212,7 @@
{ /* Time to alloc new block */
block_size= mem_root->block_size * (mem_root->block_num >> 2);
@@ -344,9 +365,9 @@ diff -urN mysql-5.1.58-old/mysys/my_alloc.c mysql-5.1.58/mysys/my_alloc.c
if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
{
-diff -urN mysql-5.1.58-old/mysys/my_bitmap.c mysql-5.1.58/mysys/my_bitmap.c
---- mysql-5.1.58-old/mysys/my_bitmap.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_bitmap.c 2011-07-15 10:49:00.586682640 +0000
+diff -urN mysql-orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql-orig/mysys/my_bitmap.c 2011-07-21 02:15:51.942095298 +0000
++++ mysql/mysys/my_bitmap.c 2011-07-21 02:16:28.826095322 +0000
@@ -423,7 +423,7 @@
DBUG_ASSERT(map->bitmap && map2->bitmap);
@@ -356,9 +377,9 @@ diff -urN mysql-5.1.58-old/mysys/my_bitmap.c mysql-5.1.58/mysys/my_bitmap.c
for (; to < end; to++, from++)
*to &= *from;
-diff -urN mysql-5.1.58-old/mysys/my_compare.c mysql-5.1.58/mysys/my_compare.c
---- mysql-5.1.58-old/mysys/my_compare.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_compare.c 2011-07-15 10:49:00.570015973 +0000
+diff -urN mysql-orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql-orig/mysys/my_compare.c 2011-07-21 02:15:51.942095298 +0000
++++ mysql/mysys/my_compare.c 2011-07-21 02:16:28.827095322 +0000
@@ -30,7 +30,7 @@
static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
my_bool part_key, my_bool skip_end_space)
@@ -377,9 +398,9 @@ diff -urN mysql-5.1.58-old/mysys/my_compare.c mysql-5.1.58/mysys/my_compare.c
next_key_length=key_length-keyseg->length;
switch ((enum ha_base_keytype) keyseg->type) {
-diff -urN mysql-5.1.58-old/mysys/my_compress.c mysql-5.1.58/mysys/my_compress.c
---- mysql-5.1.58-old/mysys/my_compress.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_compress.c 2011-07-15 10:49:00.630015973 +0000
+diff -urN mysql-orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql-orig/mysys/my_compress.c 2011-07-21 02:15:51.943095298 +0000
++++ mysql/mysys/my_compress.c 2011-07-21 02:16:28.827095322 +0000
@@ -244,7 +244,7 @@
if (ver != 1)
@@ -389,9 +410,9 @@ diff -urN mysql-5.1.58-old/mysys/my_compress.c mysql-5.1.58/mysys/my_compress.c
DBUG_RETURN(2);
memcpy(data, pack_data + BLOB_HEADER, complen);
-diff -urN mysql-5.1.58-old/mysys/my_conio.c mysql-5.1.58/mysys/my_conio.c
---- mysql-5.1.58-old/mysys/my_conio.c 2011-07-15 02:20:33.740015973 +0000
-+++ mysql-5.1.58/mysys/my_conio.c 2011-07-15 10:49:00.526682640 +0000
+diff -urN mysql-orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql-orig/mysys/my_conio.c 2011-07-21 02:15:51.941095298 +0000
++++ mysql/mysys/my_conio.c 2011-07-21 02:16:28.829095322 +0000
@@ -165,13 +165,13 @@
though it is known it should not be more than 64K
so we cut 64K and try first size of screen buffer
@@ -409,9 +430,9 @@ diff -urN mysql-5.1.58-old/mysys/my_conio.c mysql-5.1.58/mysys/my_conio.c
if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
NULL))
{
-diff -urN mysql-5.1.58-old/mysys/my_file.c mysql-5.1.58/mysys/my_file.c
---- mysql-5.1.58-old/mysys/my_file.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_file.c 2011-07-15 10:49:00.600015973 +0000
+diff -urN mysql-orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql-orig/mysys/my_file.c 2011-07-21 02:15:51.940095298 +0000
++++ mysql/mysys/my_file.c 2011-07-21 02:16:28.829095322 +0000
@@ -75,7 +75,7 @@
static uint set_max_open_files(uint max_file_limit)
{
@@ -442,9 +463,9 @@ diff -urN mysql-5.1.58-old/mysys/my_file.c mysql-5.1.58/mysys/my_file.c
my_free_open_file_info(); /* Free if already allocated */
my_file_info= tmp;
my_file_limit= files;
-diff -urN mysql-5.1.58-old/mysys/my_getopt.c mysql-5.1.58/mysys/my_getopt.c
---- mysql-5.1.58-old/mysys/my_getopt.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_getopt.c 2011-07-15 10:49:00.626682639 +0000
+diff -urN mysql-orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql-orig/mysys/my_getopt.c 2011-07-21 02:15:51.943095298 +0000
++++ mysql/mysys/my_getopt.c 2011-07-21 02:16:28.830095322 +0000
@@ -983,7 +983,7 @@
}
if (optp->max_value && num > (double) optp->max_value)
@@ -454,9 +475,9 @@ diff -urN mysql-5.1.58-old/mysys/my_getopt.c mysql-5.1.58/mysys/my_getopt.c
}
/*
-diff -urN mysql-5.1.58-old/mysys/my_static.h mysql-5.1.58/mysys/my_static.h
---- mysql-5.1.58-old/mysys/my_static.h 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/my_static.h 2011-07-15 10:49:00.563349306 +0000
+diff -urN mysql-orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql-orig/mysys/my_static.h 2011-07-21 02:15:51.941095298 +0000
++++ mysql/mysys/my_static.h 2011-07-21 02:16:28.830095322 +0000
@@ -22,7 +22,7 @@
#include <signal.h>
@@ -466,9 +487,9 @@ diff -urN mysql-5.1.58-old/mysys/my_static.h mysql-5.1.58/mysys/my_static.h
#define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
#define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
-diff -urN mysql-5.1.58-old/mysys/safemalloc.c mysql-5.1.58/mysys/safemalloc.c
---- mysql-5.1.58-old/mysys/safemalloc.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/safemalloc.c 2011-07-15 10:49:00.583349307 +0000
+diff -urN mysql-orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql-orig/mysys/safemalloc.c 2011-07-21 02:15:51.941095298 +0000
++++ mysql/mysys/safemalloc.c 2011-07-21 02:16:28.831095322 +0000
@@ -248,7 +248,7 @@
if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
@@ -478,9 +499,9 @@ diff -urN mysql-5.1.58-old/mysys/safemalloc.c mysql-5.1.58/mysys/safemalloc.c
memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
_myfree(ptr, filename, lineno, 0); /* Free not needed area */
}
-diff -urN mysql-5.1.58-old/mysys/stacktrace.c mysql-5.1.58/mysys/stacktrace.c
---- mysql-5.1.58-old/mysys/stacktrace.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/mysys/stacktrace.c 2011-07-15 10:49:00.603349307 +0000
+diff -urN mysql-orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql-orig/mysys/stacktrace.c 2011-07-21 02:15:51.943095298 +0000
++++ mysql/mysys/stacktrace.c 2011-07-21 02:16:28.831095322 +0000
@@ -96,7 +96,7 @@
/* Read up to the maximum number of bytes. */
while (total)
@@ -499,9 +520,9 @@ diff -urN mysql-5.1.58-old/mysys/stacktrace.c mysql-5.1.58/mysys/stacktrace.c
/* Assume that the stack starts at the previous even 65K */
stack_bottom= (uchar*) (((ulong) &fp + tmp) &
~(ulong) 0xFFFF);
-diff -urN mysql-5.1.58-old/server-tools/instance-manager/buffer.cc mysql-5.1.58/server-tools/instance-manager/buffer.cc
---- mysql-5.1.58-old/server-tools/instance-manager/buffer.cc 2011-07-15 02:20:33.706682639 +0000
-+++ mysql-5.1.58/server-tools/instance-manager/buffer.cc 2011-07-15 10:45:58.910015974 +0000
+diff -urN mysql-orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql-orig/server-tools/instance-manager/buffer.cc 2011-07-21 02:15:51.929095298 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2011-07-21 02:16:28.832095322 +0000
@@ -83,8 +83,8 @@
if (position + len_arg >= buffer_size)
{
@@ -513,9 +534,9 @@ diff -urN mysql-5.1.58-old/server-tools/instance-manager/buffer.cc mysql-5.1.58/
position + len_arg)), MYF(0));
if (!(buffer))
goto err;
-diff -urN mysql-5.1.58-old/server-tools/instance-manager/listener.cc mysql-5.1.58/server-tools/instance-manager/listener.cc
---- mysql-5.1.58-old/server-tools/instance-manager/listener.cc 2011-07-15 02:20:33.703349306 +0000
-+++ mysql-5.1.58/server-tools/instance-manager/listener.cc 2011-07-15 10:45:58.910015974 +0000
+diff -urN mysql-orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql-orig/server-tools/instance-manager/listener.cc 2011-07-21 02:15:51.927095298 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2011-07-21 02:16:28.832095322 +0000
@@ -103,7 +103,7 @@
/* II. Listen sockets and spawn childs */
@@ -525,9 +546,9 @@ diff -urN mysql-5.1.58-old/server-tools/instance-manager/listener.cc mysql-5.1.5
n++;
timeval tv;
-diff -urN mysql-5.1.58-old/sql/debug_sync.cc mysql-5.1.58/sql/debug_sync.cc
---- mysql-5.1.58-old/sql/debug_sync.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/debug_sync.cc 2011-07-15 10:45:58.910015974 +0000
+diff -urN mysql-orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql-orig/sql/debug_sync.cc 2011-07-21 02:15:51.955095298 +0000
++++ mysql/sql/debug_sync.cc 2011-07-21 02:16:28.834095322 +0000
@@ -1036,7 +1036,7 @@
DBUG_ASSERT(action);
DBUG_ASSERT(ds_control);
@@ -537,9 +558,9 @@ diff -urN mysql-5.1.58-old/sql/debug_sync.cc mysql-5.1.58/sql/debug_sync.cc
if (!action->activation_count)
{
debug_sync_remove_action(ds_control, action);
-diff -urN mysql-5.1.58-old/sql/field.cc mysql-5.1.58/sql/field.cc
---- mysql-5.1.58-old/sql/field.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/field.cc 2011-07-15 10:45:58.913349307 +0000
+diff -urN mysql-orig/sql/field.cc mysql/sql/field.cc
+--- mysql-orig/sql/field.cc 2011-07-21 02:15:51.956095298 +0000
++++ mysql/sql/field.cc 2011-07-21 02:16:28.838095322 +0000
@@ -53,7 +53,7 @@
#define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
#define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
@@ -736,9 +757,9 @@ diff -urN mysql-5.1.58-old/sql/field.cc mysql-5.1.58/sql/field.cc
}
flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
/*
-diff -urN mysql-5.1.58-old/sql/filesort.cc mysql-5.1.58/sql/filesort.cc
---- mysql-5.1.58-old/sql/filesort.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/filesort.cc 2011-07-15 10:45:58.913349307 +0000
+diff -urN mysql-orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql-orig/sql/filesort.cc 2011-07-21 02:15:51.950095298 +0000
++++ mysql/sql/filesort.cc 2011-07-21 02:16:28.841095322 +0000
@@ -193,7 +193,7 @@
#ifdef CAN_TRUST_RANGE
if (select && select->quick && select->quick->records > 0L)
@@ -781,9 +802,9 @@ diff -urN mysql-5.1.58-old/sql/filesort.cc mysql-5.1.58/sql/filesort.cc
lastbuff->file_pos= to_start_filepos;
err:
delete_queue(&queue);
-diff -urN mysql-5.1.58-old/sql/ha_ndbcluster.cc mysql-5.1.58/sql/ha_ndbcluster.cc
---- mysql-5.1.58-old/sql/ha_ndbcluster.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/ha_ndbcluster.cc 2011-07-15 10:45:58.913349307 +0000
+diff -urN mysql-orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql-orig/sql/ha_ndbcluster.cc 2011-07-21 02:15:51.962095298 +0000
++++ mysql/sql/ha_ndbcluster.cc 2011-07-21 02:16:28.845095322 +0000
@@ -799,7 +799,7 @@
DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
@@ -793,9 +814,9 @@ diff -urN mysql-5.1.58-old/sql/ha_ndbcluster.cc mysql-5.1.58/sql/ha_ndbcluster.c
if (set_blob_value)
*set_blob_value= TRUE;
-diff -urN mysql-5.1.58-old/sql/handler.h mysql-5.1.58/sql/handler.h
---- mysql-5.1.58-old/sql/handler.h 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/handler.h 2011-07-15 10:48:59.960015973 +0000
+diff -urN mysql-orig/sql/handler.h mysql/sql/handler.h
+--- mysql-orig/sql/handler.h 2011-07-21 02:15:51.955095298 +0000
++++ mysql/sql/handler.h 2011-07-21 02:16:28.847095322 +0000
@@ -1606,15 +1606,15 @@
{ return (HA_ERR_WRONG_COMMAND); }
@@ -817,9 +838,9 @@ diff -urN mysql-5.1.58-old/sql/handler.h mysql-5.1.58/sql/handler.h
virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
virtual uint max_supported_keys() const { return 0; }
-diff -urN mysql-5.1.58-old/sql/ha_partition.cc mysql-5.1.58/sql/ha_partition.cc
---- mysql-5.1.58-old/sql/ha_partition.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/ha_partition.cc 2011-07-15 10:45:58.916682640 +0000
+diff -urN mysql-orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql-orig/sql/ha_partition.cc 2011-07-21 02:15:51.953095298 +0000
++++ mysql/sql/ha_partition.cc 2011-07-21 02:16:28.850095322 +0000
@@ -6131,7 +6131,7 @@
{
*first= bitmap_get_first_set(&(m_part_info->used_partitions));
@@ -829,9 +850,9 @@ diff -urN mysql-5.1.58-old/sql/ha_partition.cc mysql-5.1.58/sql/ha_partition.cc
}
-diff -urN mysql-5.1.58-old/sql/item_buff.cc mysql-5.1.58/sql/item_buff.cc
---- mysql-5.1.58-old/sql/item_buff.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/item_buff.cc 2011-07-15 10:45:58.916682640 +0000
+diff -urN mysql-orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql-orig/sql/item_buff.cc 2011-07-21 02:15:51.951095298 +0000
++++ mysql/sql/item_buff.cc 2011-07-21 02:16:28.852095322 +0000
@@ -59,7 +59,7 @@
Cached_item_str::Cached_item_str(THD *thd, Item *arg)
@@ -850,9 +871,9 @@ diff -urN mysql-5.1.58-old/sql/item_buff.cc mysql-5.1.58/sql/item_buff.cc
if (null_value != item->null_value)
{
if ((null_value= item->null_value))
-diff -urN mysql-5.1.58-old/sql/item.cc mysql-5.1.58/sql/item.cc
---- mysql-5.1.58-old/sql/item.cc 2011-07-15 02:20:33.683349307 +0000
-+++ mysql-5.1.58/sql/item.cc 2011-07-15 10:45:58.920015973 +0000
+diff -urN mysql-orig/sql/item.cc mysql/sql/item.cc
+--- mysql-orig/sql/item.cc 2011-07-21 02:15:51.961095298 +0000
++++ mysql/sql/item.cc 2011-07-21 02:16:28.854095322 +0000
@@ -74,7 +74,7 @@
Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
{
@@ -947,9 +968,9 @@ diff -urN mysql-5.1.58-old/sql/item.cc mysql-5.1.58/sql/item.cc
};
maybe_null|= item->maybe_null;
get_full_info(item);
-diff -urN mysql-5.1.58-old/sql/item_cmpfunc.cc mysql-5.1.58/sql/item_cmpfunc.cc
---- mysql-5.1.58-old/sql/item_cmpfunc.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/item_cmpfunc.cc 2011-07-15 10:45:58.920015973 +0000
+diff -urN mysql-orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql-orig/sql/item_cmpfunc.cc 2011-07-21 02:15:51.954095298 +0000
++++ mysql/sql/item_cmpfunc.cc 2011-07-21 02:16:28.857095322 +0000
@@ -628,7 +628,7 @@
{
if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
@@ -1100,9 +1121,9 @@ diff -urN mysql-5.1.58-old/sql/item_cmpfunc.cc mysql-5.1.58/sql/item_cmpfunc.cc
u = 0;
}
j+= shift;
-diff -urN mysql-5.1.58-old/sql/item_func.cc mysql-5.1.58/sql/item_func.cc
---- mysql-5.1.58-old/sql/item_func.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/item_func.cc 2011-07-15 10:45:58.923349306 +0000
+diff -urN mysql-orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql-orig/sql/item_func.cc 2011-07-21 02:15:51.957095298 +0000
++++ mysql/sql/item_func.cc 2011-07-21 02:16:28.860095322 +0000
@@ -549,7 +549,7 @@
set_if_bigger(max_int_part, args[i]->decimal_int_part());
set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
@@ -1236,9 +1257,9 @@ diff -urN mysql-5.1.58-old/sql/item_func.cc mysql-5.1.58/sql/item_func.cc
}
initialized=1;
if (error)
-diff -urN mysql-5.1.58-old/sql/item_func.h mysql-5.1.58/sql/item_func.h
---- mysql-5.1.58-old/sql/item_func.h 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/item_func.h 2011-07-15 10:48:59.923349307 +0000
+diff -urN mysql-orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql-orig/sql/item_func.h 2011-07-21 02:15:51.954095298 +0000
++++ mysql/sql/item_func.h 2011-07-21 02:16:28.861095322 +0000
@@ -420,7 +420,7 @@
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
@@ -1248,9 +1269,9 @@ diff -urN mysql-5.1.58-old/sql/item_func.h mysql-5.1.58/sql/item_func.h
unsigned_flag=1;
}
longlong val_int();
-diff -urN mysql-5.1.58-old/sql/item_strfunc.cc mysql-5.1.58/sql/item_strfunc.cc
---- mysql-5.1.58-old/sql/item_strfunc.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/item_strfunc.cc 2011-07-15 10:45:58.923349306 +0000
+diff -urN mysql-orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql-orig/sql/item_strfunc.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/item_strfunc.cc 2011-07-21 02:16:28.863095322 +0000
@@ -387,7 +387,7 @@
}
else
@@ -1319,9 +1340,9 @@ diff -urN mysql-5.1.58-old/sql/item_strfunc.cc mysql-5.1.58/sql/item_strfunc.cc
tv-= delta;
nanoseq-= delta;
}
-diff -urN mysql-5.1.58-old/sql/item_strfunc.h mysql-5.1.58/sql/item_strfunc.h
---- mysql-5.1.58-old/sql/item_strfunc.h 2011-07-15 02:20:33.680015973 +0000
-+++ mysql-5.1.58/sql/item_strfunc.h 2011-07-15 10:48:59.833349307 +0000
+diff -urN mysql-orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql-orig/sql/item_strfunc.h 2011-07-21 02:15:51.951095298 +0000
++++ mysql/sql/item_strfunc.h 2011-07-21 02:16:28.864095322 +0000
@@ -707,7 +707,7 @@
collation.set(args[0]->collation);
ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
@@ -1331,9 +1352,9 @@ diff -urN mysql-5.1.58-old/sql/item_strfunc.h mysql-5.1.58/sql/item_strfunc.h
}
};
-diff -urN mysql-5.1.58-old/sql/item_sum.cc mysql-5.1.58/sql/item_sum.cc
---- mysql-5.1.58-old/sql/item_sum.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/item_sum.cc 2011-07-15 10:45:58.923349306 +0000
+diff -urN mysql-orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql-orig/sql/item_sum.cc 2011-07-21 02:15:51.955095298 +0000
++++ mysql/sql/item_sum.cc 2011-07-21 02:16:28.865095322 +0000
@@ -1139,7 +1139,7 @@
AVG() will divide val by count. We need to reserve digits
after decimal point as the result can be fractional.
@@ -1388,9 +1409,9 @@ diff -urN mysql-5.1.58-old/sql/item_sum.cc mysql-5.1.58/sql/item_sum.cc
thd->variables.sortbuff_size/16), 0,
tree_key_length,
group_concat_key_cmp_with_order , 0, NULL, (void*) this);
-diff -urN mysql-5.1.58-old/sql/item_timefunc.cc mysql-5.1.58/sql/item_timefunc.cc
---- mysql-5.1.58-old/sql/item_timefunc.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/item_timefunc.cc 2011-07-15 10:45:58.926682639 +0000
+diff -urN mysql-orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql-orig/sql/item_timefunc.cc 2011-07-21 02:15:51.961095298 +0000
++++ mysql/sql/item_timefunc.cc 2011-07-21 02:16:28.867095322 +0000
@@ -308,14 +308,14 @@
switch (*++ptr) {
/* Year */
@@ -1507,9 +1528,9 @@ diff -urN mysql-5.1.58-old/sql/item_timefunc.cc mysql-5.1.58/sql/item_timefunc.c
collation.collation->mbmaxlen;
set_if_smaller(max_length,MAX_BLOB_WIDTH);
}
-diff -urN mysql-5.1.58-old/sql/key.cc mysql-5.1.58/sql/key.cc
---- mysql-5.1.58-old/sql/key.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/key.cc 2011-07-15 10:45:58.926682639 +0000
+diff -urN mysql-orig/sql/key.cc mysql/sql/key.cc
+--- mysql-orig/sql/key.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/key.cc 2011-07-21 02:16:28.868095322 +0000
@@ -125,13 +125,13 @@
key_part->key_part_flag & HA_VAR_LENGTH_PART)
{
@@ -1562,9 +1583,9 @@ diff -urN mysql-5.1.58-old/sql/key.cc mysql-5.1.58/sql/key.cc
to->append(tmp);
}
else
-diff -urN mysql-5.1.58-old/sql/log.cc mysql-5.1.58/sql/log.cc
---- mysql-5.1.58-old/sql/log.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/log.cc 2011-07-15 10:45:58.926682639 +0000
+diff -urN mysql-orig/sql/log.cc mysql/sql/log.cc
+--- mysql-orig/sql/log.cc 2011-07-21 02:15:51.950095298 +0000
++++ mysql/sql/log.cc 2011-07-21 02:16:28.870095322 +0000
@@ -597,11 +597,11 @@
t.neg= 0;
@@ -1597,9 +1618,9 @@ diff -urN mysql-5.1.58-old/sql/log.cc mysql-5.1.58/sql/log.cc
setup_windows_event_source();
if ((event= RegisterEventSource(NULL,"MySQL")))
-diff -urN mysql-5.1.58-old/sql/log_event.cc mysql-5.1.58/sql/log_event.cc
---- mysql-5.1.58-old/sql/log_event.cc 2011-07-15 02:20:33.683349307 +0000
-+++ mysql-5.1.58/sql/log_event.cc 2011-07-15 10:45:58.930015973 +0000
+diff -urN mysql-orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql-orig/sql/log_event.cc 2011-07-21 02:15:51.955095298 +0000
++++ mysql/sql/log_event.cc 2011-07-21 02:16:28.873095322 +0000
@@ -1075,7 +1075,7 @@
of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
"minimal" over the set {MySQL >=4.0}).
@@ -1636,9 +1657,9 @@ diff -urN mysql-5.1.58-old/sql/log_event.cc mysql-5.1.58/sql/log_event.cc
#endif
DBUG_ASSERT(m_rows_buf <= m_rows_cur);
-diff -urN mysql-5.1.58-old/sql/log_event_old.cc mysql-5.1.58/sql/log_event_old.cc
---- mysql-5.1.58-old/sql/log_event_old.cc 2011-07-15 02:20:33.683349307 +0000
-+++ mysql-5.1.58/sql/log_event_old.cc 2011-07-15 10:45:58.930015973 +0000
+diff -urN mysql-orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql-orig/sql/log_event_old.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/log_event_old.cc 2011-07-21 02:16:28.876095322 +0000
@@ -1420,7 +1420,7 @@
trigger false warnings.
*/
@@ -1648,9 +1669,9 @@ diff -urN mysql-5.1.58-old/sql/log_event_old.cc mysql-5.1.58/sql/log_event_old.c
#endif
DBUG_ASSERT(m_rows_buf <= m_rows_cur);
-diff -urN mysql-5.1.58-old/sql/mysqld.cc mysql-5.1.58/sql/mysqld.cc
---- mysql-5.1.58-old/sql/mysqld.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/mysqld.cc 2011-07-15 10:45:58.933349307 +0000
+diff -urN mysql-orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql-orig/sql/mysqld.cc 2011-07-21 02:15:51.952095298 +0000
++++ mysql/sql/mysqld.cc 2011-07-21 02:16:28.880095322 +0000
@@ -3394,7 +3394,7 @@
can't get max_connections*5 but still got no less than was
requested (value of wanted_files).
@@ -1688,9 +1709,9 @@ diff -urN mysql-5.1.58-old/sql/mysqld.cc mysql-5.1.58/sql/mysqld.cc
fd_set readFDs,clientFDs;
THD *thd;
struct sockaddr_in cAddr;
-diff -urN mysql-5.1.58-old/sql/net_serv.cc mysql-5.1.58/sql/net_serv.cc
---- mysql-5.1.58-old/sql/net_serv.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/net_serv.cc 2011-07-15 10:45:58.933349307 +0000
+diff -urN mysql-orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql-orig/sql/net_serv.cc 2011-07-21 02:15:51.953095298 +0000
++++ mysql/sql/net_serv.cc 2011-07-21 02:16:28.883095322 +0000
@@ -755,7 +755,7 @@
{
while (remain > 0)
@@ -1709,9 +1730,9 @@ diff -urN mysql-5.1.58-old/sql/net_serv.cc mysql-5.1.58/sql/net_serv.cc
/* The necessary size of net->buff */
if (helping >= net->max_packet)
{
-diff -urN mysql-5.1.58-old/sql/opt_range.cc mysql-5.1.58/sql/opt_range.cc
---- mysql-5.1.58-old/sql/opt_range.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/opt_range.cc 2011-07-15 10:45:58.936682641 +0000
+diff -urN mysql-orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql-orig/sql/opt_range.cc 2011-07-21 02:15:51.956095298 +0000
++++ mysql/sql/opt_range.cc 2011-07-21 02:16:28.886095322 +0000
@@ -2347,7 +2347,7 @@
group_trp= get_best_group_min_max(¶m, tree);
if (group_trp)
@@ -1812,9 +1833,9 @@ diff -urN mysql-5.1.58-old/sql/opt_range.cc mysql-5.1.58/sql/opt_range.cc
}
else
io_cost= (keys_per_group > keys_per_block) ?
-diff -urN mysql-5.1.58-old/sql/opt_range.h mysql-5.1.58/sql/opt_range.h
---- mysql-5.1.58-old/sql/opt_range.h 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/opt_range.h 2011-07-15 10:48:59.926682640 +0000
+diff -urN mysql-orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql-orig/sql/opt_range.h 2011-07-21 02:15:51.950095298 +0000
++++ mysql/sql/opt_range.h 2011-07-21 02:16:28.889095322 +0000
@@ -83,7 +83,7 @@
void make_min_endpoint(key_range *kr, uint prefix_length,
key_part_map keypart_map) {
@@ -1833,9 +1854,9 @@ diff -urN mysql-5.1.58-old/sql/opt_range.h mysql-5.1.58/sql/opt_range.h
kr->keypart_map&= keypart_map;
}
-diff -urN mysql-5.1.58-old/sql/protocol.cc mysql-5.1.58/sql/protocol.cc
---- mysql-5.1.58-old/sql/protocol.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/protocol.cc 2011-07-15 10:45:58.936682641 +0000
+diff -urN mysql-orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql-orig/sql/protocol.cc 2011-07-21 02:15:51.960095298 +0000
++++ mysql/sql/protocol.cc 2011-07-21 02:16:28.890095322 +0000
@@ -167,7 +167,7 @@
pos+=2;
@@ -1854,9 +1875,9 @@ diff -urN mysql-5.1.58-old/sql/protocol.cc mysql-5.1.58/sql/protocol.cc
buff[0]= 254;
int2store(buff+1, tmp);
/*
-diff -urN mysql-5.1.58-old/sql/rpl_record.cc mysql-5.1.58/sql/rpl_record.cc
---- mysql-5.1.58-old/sql/rpl_record.cc 2011-07-15 02:20:33.696682640 +0000
-+++ mysql-5.1.58/sql/rpl_record.cc 2011-07-15 10:45:58.936682641 +0000
+diff -urN mysql-orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql-orig/sql/rpl_record.cc 2011-07-21 02:15:51.954095298 +0000
++++ mysql/sql/rpl_record.cc 2011-07-21 02:16:28.890095322 +0000
@@ -285,7 +285,7 @@
/*
throw away master's extra fields
@@ -1866,9 +1887,9 @@ diff -urN mysql-5.1.58-old/sql/rpl_record.cc mysql-5.1.58/sql/rpl_record.cc
for (; i < max_cols; i++)
{
if (bitmap_is_set(cols, i))
-diff -urN mysql-5.1.58-old/sql/rpl_rli.cc mysql-5.1.58/sql/rpl_rli.cc
---- mysql-5.1.58-old/sql/rpl_rli.cc 2011-07-15 02:20:33.696682640 +0000
-+++ mysql-5.1.58/sql/rpl_rli.cc 2011-07-15 10:45:58.936682641 +0000
+diff -urN mysql-orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql-orig/sql/rpl_rli.cc 2011-07-21 02:15:51.960095298 +0000
++++ mysql/sql/rpl_rli.cc 2011-07-21 02:16:28.891095322 +0000
@@ -686,7 +686,7 @@
ulong log_name_extension;
char log_name_tmp[FN_REFLEN]; //make a char[] from String
@@ -1887,9 +1908,9 @@ diff -urN mysql-5.1.58-old/sql/rpl_rli.cc mysql-5.1.58/sql/rpl_rli.cc
/* p points to '.' */
log_name_extension= strtoul(++p, &p_end, 10);
/*
-diff -urN mysql-5.1.58-old/sql/rpl_utility.cc mysql-5.1.58/sql/rpl_utility.cc
---- mysql-5.1.58-old/sql/rpl_utility.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/rpl_utility.cc 2011-07-15 10:45:58.936682641 +0000
+diff -urN mysql-orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql-orig/sql/rpl_utility.cc 2011-07-21 02:15:51.951095298 +0000
++++ mysql/sql/rpl_utility.cc 2011-07-21 02:16:28.892095322 +0000
@@ -180,7 +180,7 @@
/*
We only check the initial columns for the tables.
@@ -1899,9 +1920,9 @@ diff -urN mysql-5.1.58-old/sql/rpl_utility.cc mysql-5.1.58/sql/rpl_utility.cc
int error= 0;
Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
-diff -urN mysql-5.1.58-old/sql/rpl_utility.h mysql-5.1.58/sql/rpl_utility.h
---- mysql-5.1.58-old/sql/rpl_utility.h 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/rpl_utility.h 2011-07-15 10:48:59.950015974 +0000
+diff -urN mysql-orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql-orig/sql/rpl_utility.h 2011-07-21 02:15:51.951095298 +0000
++++ mysql/sql/rpl_utility.h 2011-07-21 02:16:28.892095322 +0000
@@ -295,7 +295,7 @@
do { \
char buf[256]; \
@@ -1911,9 +1932,9 @@ diff -urN mysql-5.1.58-old/sql/rpl_utility.h mysql-5.1.58/sql/rpl_utility.h
buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
buf[i] = '\0'; \
DBUG_PRINT((N), ((FRM), buf)); \
-diff -urN mysql-5.1.58-old/sql/set_var.cc mysql-5.1.58/sql/set_var.cc
---- mysql-5.1.58-old/sql/set_var.cc 2011-07-15 02:20:33.683349307 +0000
-+++ mysql-5.1.58/sql/set_var.cc 2011-07-15 10:45:58.940015974 +0000
+diff -urN mysql-orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql-orig/sql/set_var.cc 2011-07-21 02:15:51.952095298 +0000
++++ mysql/sql/set_var.cc 2011-07-21 02:16:28.894095322 +0000
@@ -1845,7 +1845,7 @@
¬_used));
if (error_len)
@@ -1932,9 +1953,9 @@ diff -urN mysql-5.1.58-old/sql/set_var.cc mysql-5.1.58/sql/set_var.cc
goto err;
}
return FALSE;
-diff -urN mysql-5.1.58-old/sql/slave.cc mysql-5.1.58/sql/slave.cc
---- mysql-5.1.58-old/sql/slave.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/slave.cc 2011-07-15 10:45:58.940015974 +0000
+diff -urN mysql-orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql-orig/sql/slave.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/slave.cc 2011-07-21 02:16:28.896095322 +0000
@@ -1737,7 +1737,7 @@
special marker to say "consider we have caught up".
*/
@@ -1962,9 +1983,9 @@ diff -urN mysql-5.1.58-old/sql/slave.cc mysql-5.1.58/sql/slave.cc
my_b_seek(cur_log,rli->event_relay_log_pos);
DBUG_RETURN(cur_log);
}
-diff -urN mysql-5.1.58-old/sql/spatial.h mysql-5.1.58/sql/spatial.h
---- mysql-5.1.58-old/sql/spatial.h 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/spatial.h 2011-07-15 10:48:59.790015973 +0000
+diff -urN mysql-orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql-orig/sql/spatial.h 2011-07-21 02:15:51.949095298 +0000
++++ mysql/sql/spatial.h 2011-07-21 02:16:28.929095322 +0000
@@ -180,8 +180,8 @@
if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
return 0;
@@ -1976,9 +1997,9 @@ diff -urN mysql-5.1.58-old/sql/spatial.h mysql-5.1.58/sql/spatial.h
return (d == intersection.dimension());
}
-diff -urN mysql-5.1.58-old/sql/sp_head.cc mysql-5.1.58/sql/sp_head.cc
---- mysql-5.1.58-old/sql/sp_head.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/sp_head.cc 2011-07-15 10:45:58.940015974 +0000
+diff -urN mysql-orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql-orig/sql/sp_head.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/sp_head.cc 2011-07-21 02:16:28.932095322 +0000
@@ -2454,7 +2454,7 @@
Item_empty_string *stmt_fld=
@@ -1997,9 +2018,9 @@ diff -urN mysql-5.1.58-old/sql/sp_head.cc mysql-5.1.58/sql/sp_head.cc
if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
DBUG_RETURN(1);
-diff -urN mysql-5.1.58-old/sql/sql_acl.cc mysql-5.1.58/sql/sql_acl.cc
---- mysql-5.1.58-old/sql/sql_acl.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/sql_acl.cc 2011-07-15 10:45:58.943349307 +0000
+diff -urN mysql-orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql-orig/sql/sql_acl.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/sql_acl.cc 2011-07-21 02:16:28.935095322 +0000
@@ -824,7 +824,7 @@
chars= 128; // Marker that chars existed
}
@@ -2009,9 +2030,9 @@ diff -urN mysql-5.1.58-old/sql/sql_acl.cc mysql-5.1.58/sql/sql_acl.cc
}
va_end(args);
return sort;
-diff -urN mysql-5.1.58-old/sql/sql_analyse.cc mysql-5.1.58/sql/sql_analyse.cc
---- mysql-5.1.58-old/sql/sql_analyse.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/sql_analyse.cc 2011-07-15 10:45:58.943349307 +0000
+diff -urN mysql-orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql-orig/sql/sql_analyse.cc 2011-07-21 02:15:51.955095298 +0000
++++ mysql/sql/sql_analyse.cc 2011-07-21 02:16:28.937095322 +0000
@@ -280,16 +280,16 @@
{
if (((longlong) info->ullval) < 0)
@@ -2060,9 +2081,9 @@ diff -urN mysql-5.1.58-old/sql/sql_analyse.cc mysql-5.1.58/sql/sql_analyse.cc
for (uint i = 0; i < array_elements(func_items); i++)
field_list.push_back(func_items[i]);
-diff -urN mysql-5.1.58-old/sql/sql_cache.cc mysql-5.1.58/sql/sql_cache.cc
---- mysql-5.1.58-old/sql/sql_cache.cc 2011-07-15 02:20:33.680015973 +0000
-+++ mysql-5.1.58/sql/sql_cache.cc 2011-07-15 10:45:58.943349307 +0000
+diff -urN mysql-orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql-orig/sql/sql_cache.cc 2011-07-21 02:15:51.953095298 +0000
++++ mysql/sql/sql_cache.cc 2011-07-21 02:16:28.938095322 +0000
@@ -1004,7 +1004,7 @@
}
last_result_block= header->result()->prev;
@@ -2137,9 +2158,9 @@ diff -urN mysql-5.1.58-old/sql/sql_cache.cc mysql-5.1.58/sql/sql_cache.cc
{
DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
query_cache_size, query_cache_limit));
-diff -urN mysql-5.1.58-old/sql/sql_class.cc mysql-5.1.58/sql/sql_class.cc
---- mysql-5.1.58-old/sql/sql_class.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/sql_class.cc 2011-07-15 10:45:58.943349307 +0000
+diff -urN mysql-orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql-orig/sql/sql_class.cc 2011-07-21 02:15:51.962095298 +0000
++++ mysql/sql/sql_class.cc 2011-07-21 02:16:28.941095322 +0000
@@ -415,7 +415,7 @@
if (max_query_len < 1)
len= thd->query_length();
@@ -2167,9 +2188,9 @@ diff -urN mysql-5.1.58-old/sql/sql_class.cc mysql-5.1.58/sql/sql_class.cc
else
used_length=res->length();
if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
-diff -urN mysql-5.1.58-old/sql/sql_client.cc mysql-5.1.58/sql/sql_client.cc
---- mysql-5.1.58-old/sql/sql_client.cc 2011-07-15 02:20:33.696682640 +0000
-+++ mysql-5.1.58/sql/sql_client.cc 2011-07-15 10:45:58.946682640 +0000
+diff -urN mysql-orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql-orig/sql/sql_client.cc 2011-07-21 02:15:51.956095298 +0000
++++ mysql/sql/sql_client.cc 2011-07-21 02:16:28.942095322 +0000
@@ -34,7 +34,7 @@
(uint)global_system_variables.net_write_timeout);
@@ -2179,9 +2200,9 @@ diff -urN mysql-5.1.58-old/sql/sql_client.cc mysql-5.1.58/sql/sql_client.cc
global_system_variables.max_allowed_packet);
#endif
}
-diff -urN mysql-5.1.58-old/sql/sql_connect.cc mysql-5.1.58/sql/sql_connect.cc
---- mysql-5.1.58-old/sql/sql_connect.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/sql_connect.cc 2011-07-15 10:45:58.946682640 +0000
+diff -urN mysql-orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql-orig/sql/sql_connect.cc 2011-07-21 02:15:51.950095298 +0000
++++ mysql/sql/sql_connect.cc 2011-07-21 02:16:28.943095322 +0000
@@ -843,7 +843,7 @@
if (thd->main_security_ctx.host)
{
@@ -2191,9 +2212,9 @@ diff -urN mysql-5.1.58-old/sql/sql_connect.cc mysql-5.1.58/sql/sql_connect.cc
HOSTNAME_LENGTH)]= 0;
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
}
-diff -urN mysql-5.1.58-old/sql/sql_parse.cc mysql-5.1.58/sql/sql_parse.cc
---- mysql-5.1.58-old/sql/sql_parse.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/sql_parse.cc 2011-07-15 10:45:58.946682640 +0000
+diff -urN mysql-orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql-orig/sql/sql_parse.cc 2011-07-21 02:15:51.954095298 +0000
++++ mysql/sql/sql_parse.cc 2011-07-21 02:16:28.946095322 +0000
@@ -5721,7 +5721,7 @@
return 1;
}
@@ -2212,9 +2233,9 @@ diff -urN mysql-5.1.58-old/sql/sql_parse.cc mysql-5.1.58/sql/sql_parse.cc
my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
return 1;
}
-diff -urN mysql-5.1.58-old/sql/sql_partition.cc mysql-5.1.58/sql/sql_partition.cc
---- mysql-5.1.58-old/sql/sql_partition.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/sql_partition.cc 2011-07-15 10:45:58.950015973 +0000
+diff -urN mysql-orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql-orig/sql/sql_partition.cc 2011-07-21 02:15:51.956095298 +0000
++++ mysql/sql/sql_partition.cc 2011-07-21 02:16:28.951095322 +0000
@@ -4592,7 +4592,7 @@
*/
start_part= 0;
@@ -2224,9 +2245,9 @@ diff -urN mysql-5.1.58-old/sql/sql_partition.cc mysql-5.1.58/sql/sql_partition.c
}
else if (new_total_partitions <= upper_2n)
{
-diff -urN mysql-5.1.58-old/sql/sql_plugin.cc mysql-5.1.58/sql/sql_plugin.cc
---- mysql-5.1.58-old/sql/sql_plugin.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/sql_plugin.cc 2011-07-15 10:45:58.950015973 +0000
+diff -urN mysql-orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql-orig/sql/sql_plugin.cc 2011-07-21 02:15:51.957095298 +0000
++++ mysql/sql/sql_plugin.cc 2011-07-21 02:16:28.953095322 +0000
@@ -510,7 +510,7 @@
for (i=0;
(old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
@@ -2245,9 +2266,9 @@ diff -urN mysql-5.1.58-old/sql/sql_plugin.cc mysql-5.1.58/sql/sql_plugin.cc
strvalue= buff;
goto err;
}
-diff -urN mysql-5.1.58-old/sql/sql_prepare.cc mysql-5.1.58/sql/sql_prepare.cc
---- mysql-5.1.58-old/sql/sql_prepare.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/sql_prepare.cc 2011-07-15 10:45:58.953349306 +0000
+diff -urN mysql-orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql-orig/sql/sql_prepare.cc 2011-07-21 02:15:51.949095298 +0000
++++ mysql/sql/sql_prepare.cc 2011-07-21 02:16:28.956095322 +0000
@@ -249,7 +249,7 @@
int2store(buff+5, columns);
int2store(buff+7, stmt->param_count);
@@ -2257,9 +2278,9 @@ diff -urN mysql-5.1.58-old/sql/sql_prepare.cc mysql-5.1.58/sql/sql_prepare.cc
int2store(buff+10, tmp);
/*
-diff -urN mysql-5.1.58-old/sql/sql_profile.cc mysql-5.1.58/sql/sql_profile.cc
---- mysql-5.1.58-old/sql/sql_profile.cc 2011-07-15 02:20:33.683349307 +0000
-+++ mysql-5.1.58/sql/sql_profile.cc 2011-07-15 10:45:58.953349306 +0000
+diff -urN mysql-orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql-orig/sql/sql_profile.cc 2011-07-21 02:15:51.951095298 +0000
++++ mysql/sql/sql_profile.cc 2011-07-21 02:16:28.957095322 +0000
@@ -252,7 +252,7 @@
uint query_length_arg)
{
@@ -2269,9 +2290,9 @@ diff -urN mysql-5.1.58-old/sql/sql_profile.cc mysql-5.1.58/sql/sql_profile.cc
DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
if (query_source_arg != NULL)
-diff -urN mysql-5.1.58-old/sql/sql_repl.cc mysql-5.1.58/sql/sql_repl.cc
---- mysql-5.1.58-old/sql/sql_repl.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/sql_repl.cc 2011-07-15 10:45:58.953349306 +0000
+diff -urN mysql-orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql-orig/sql/sql_repl.cc 2011-07-21 02:15:51.957095298 +0000
++++ mysql/sql/sql_repl.cc 2011-07-21 02:16:28.958095322 +0000
@@ -1297,12 +1297,12 @@
{
/*
@@ -2323,9 +2344,9 @@ diff -urN mysql-5.1.58-old/sql/sql_repl.cc mysql-5.1.58/sql/sql_repl.cc
lf_info->log_delayed);
if (mysql_bin_log.write(&b))
DBUG_RETURN(1);
-diff -urN mysql-5.1.58-old/sql/sql_select.cc mysql-5.1.58/sql/sql_select.cc
---- mysql-5.1.58-old/sql/sql_select.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/sql_select.cc 2011-07-15 10:45:58.956682639 +0000
+diff -urN mysql-orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql-orig/sql/sql_select.cc 2011-07-21 02:15:51.945095298 +0000
++++ mysql/sql/sql_select.cc 2011-07-21 02:16:28.965095322 +0000
@@ -3006,7 +3006,7 @@
This is can't be to high as otherwise we are likely to use
table scan.
@@ -2434,9 +2455,9 @@ diff -urN mysql-5.1.58-old/sql/sql_select.cc mysql-5.1.58/sql/sql_select.cc
if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
cache->end=cache->buff+size;
-diff -urN mysql-5.1.58-old/sql/sql_show.cc mysql-5.1.58/sql/sql_show.cc
---- mysql-5.1.58-old/sql/sql_show.cc 2011-07-15 02:20:33.686682641 +0000
-+++ mysql-5.1.58/sql/sql_show.cc 2011-07-15 10:45:58.960015973 +0000
+diff -urN mysql-orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql-orig/sql/sql_show.cc 2011-07-21 02:15:51.944095298 +0000
++++ mysql/sql/sql_show.cc 2011-07-21 02:16:28.971095322 +0000
@@ -753,7 +753,7 @@
{
field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
@@ -2491,9 +2512,9 @@ diff -urN mysql-5.1.58-old/sql/sql_show.cc mysql-5.1.58/sql/sql_show.cc
stmt_fld->maybe_null= TRUE;
-diff -urN mysql-5.1.58-old/sql/sql_string.cc mysql-5.1.58/sql/sql_string.cc
---- mysql-5.1.58-old/sql/sql_string.cc 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/sql_string.cc 2011-07-15 10:45:58.960015973 +0000
+diff -urN mysql-orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql-orig/sql/sql_string.cc 2011-07-21 02:15:51.962095298 +0000
++++ mysql/sql/sql_string.cc 2011-07-21 02:16:28.973095322 +0000
@@ -695,7 +695,7 @@
{
if (Alloced_length < str_length + space_needed)
@@ -2539,9 +2560,9 @@ diff -urN mysql-5.1.58-old/sql/sql_string.cc mysql-5.1.58/sql/sql_string.cc
char *dots= to; // last safe place to append '...'
if (!f || t == t_end)
-diff -urN mysql-5.1.58-old/sql/sql_table.cc mysql-5.1.58/sql/sql_table.cc
---- mysql-5.1.58-old/sql/sql_table.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/sql_table.cc 2011-07-15 10:45:58.960015973 +0000
+diff -urN mysql-orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql-orig/sql/sql_table.cc 2011-07-21 02:15:51.956095298 +0000
++++ mysql/sql/sql_table.cc 2011-07-21 02:16:28.976095322 +0000
@@ -3275,7 +3275,7 @@
if ((length=column->length) > max_key_length ||
length > file->max_key_part_length())
@@ -2551,9 +2572,9 @@ diff -urN mysql-5.1.58-old/sql/sql_table.cc mysql-5.1.58/sql/sql_table.cc
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
-diff -urN mysql-5.1.58-old/sql/sql_yacc.cc mysql-5.1.58/sql/sql_yacc.cc
---- mysql-5.1.58-old/sql/sql_yacc.cc 2011-07-15 02:20:33.700015973 +0000
-+++ mysql-5.1.58/sql/sql_yacc.cc 2011-07-15 10:45:58.970015974 +0000
+diff -urN mysql-orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql-orig/sql/sql_yacc.cc 2011-07-21 02:15:51.958095298 +0000
++++ mysql/sql/sql_yacc.cc 2011-07-21 02:16:28.990095322 +0000
@@ -16217,7 +16217,7 @@
from 0" (4 in fact), unspecified means "don't change the position
(keep the preceding value)").
@@ -2572,9 +2593,9 @@ diff -urN mysql-5.1.58-old/sql/sql_yacc.cc mysql-5.1.58/sql/sql_yacc.cc
}
break;
-diff -urN mysql-5.1.58-old/sql/sql_yacc.yy mysql-5.1.58/sql/sql_yacc.yy
---- mysql-5.1.58-old/sql/sql_yacc.yy 2011-07-15 02:20:33.693349307 +0000
-+++ mysql-5.1.58/sql/sql_yacc.yy 2011-07-15 10:45:58.973349307 +0000
+diff -urN mysql-orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql-orig/sql/sql_yacc.yy 2011-07-21 02:15:51.950095298 +0000
++++ mysql/sql/sql_yacc.yy 2011-07-21 02:16:29.003095322 +0000
@@ -1805,7 +1805,7 @@
from 0" (4 in fact), unspecified means "don't change the position
(keep the preceding value)").
@@ -2593,9 +2614,9 @@ diff -urN mysql-5.1.58-old/sql/sql_yacc.yy mysql-5.1.58/sql/sql_yacc.yy
}
;
-diff -urN mysql-5.1.58-old/sql/thr_malloc.cc mysql-5.1.58/sql/thr_malloc.cc
---- mysql-5.1.58-old/sql/thr_malloc.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/thr_malloc.cc 2011-07-15 10:45:58.973349307 +0000
+diff -urN mysql-orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql-orig/sql/thr_malloc.cc 2011-07-21 02:15:51.959095298 +0000
++++ mysql/sql/thr_malloc.cc 2011-07-21 02:16:29.006095322 +0000
@@ -130,7 +130,7 @@
if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
{
@@ -2605,9 +2626,9 @@ diff -urN mysql-5.1.58-old/sql/thr_malloc.cc mysql-5.1.58/sql/thr_malloc.cc
memcpy(pos, str, new_length);
}
else
-diff -urN mysql-5.1.58-old/sql/tztime.cc mysql-5.1.58/sql/tztime.cc
---- mysql-5.1.58-old/sql/tztime.cc 2011-07-15 02:20:33.676682639 +0000
-+++ mysql-5.1.58/sql/tztime.cc 2011-07-15 10:45:58.973349307 +0000
+diff -urN mysql-orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql-orig/sql/tztime.cc 2011-07-21 02:15:51.960095298 +0000
++++ mysql/sql/tztime.cc 2011-07-21 02:16:29.007095322 +0000
@@ -167,7 +167,7 @@
uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
@@ -2635,9 +2656,9 @@ diff -urN mysql-5.1.58-old/sql/tztime.cc mysql-5.1.58/sql/tztime.cc
#endif
/*
Used as a temporary tz_info until we decide that we actually want to
-diff -urN mysql-5.1.58-old/sql/unireg.cc mysql-5.1.58/sql/unireg.cc
---- mysql-5.1.58-old/sql/unireg.cc 2011-07-15 02:20:33.690015974 +0000
-+++ mysql-5.1.58/sql/unireg.cc 2011-07-15 10:45:58.973349307 +0000
+diff -urN mysql-orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql-orig/sql/unireg.cc 2011-07-21 02:15:51.954095298 +0000
++++ mysql/sql/unireg.cc 2011-07-21 02:16:29.008095322 +0000
@@ -496,7 +496,7 @@
}
cfield->row=(uint8) row;
@@ -2656,9 +2677,9 @@ diff -urN mysql-5.1.58-old/sql/unireg.cc mysql-5.1.58/sql/unireg.cc
if (info_length+(ulong) create_fields.elements*FCOMP+288+
n_length+int_length+com_length > 65535L || int_count > 255)
{
-diff -urN mysql-5.1.58-old/sql-common/client.c mysql-5.1.58/sql-common/client.c
---- mysql-5.1.58-old/sql-common/client.c 2011-07-15 02:20:33.716682641 +0000
-+++ mysql-5.1.58/sql-common/client.c 2011-07-15 10:49:00.413349306 +0000
+diff -urN mysql-orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql-orig/sql-common/client.c 2011-07-21 02:15:51.926095298 +0000
++++ mysql/sql-common/client.c 2011-07-21 02:16:29.009095322 +0000
@@ -728,7 +728,7 @@
}
@@ -2677,9 +2698,9 @@ diff -urN mysql-5.1.58-old/sql-common/client.c mysql-5.1.58/sql-common/client.c
DBUG_PRINT("info",("Trying %s...",
(my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
status= my_connect(sock, (struct sockaddr *) &sock_addr,
-diff -urN mysql-5.1.58-old/sql-common/my_time.c mysql-5.1.58/sql-common/my_time.c
---- mysql-5.1.58-old/sql-common/my_time.c 2011-07-15 02:20:33.720015974 +0000
-+++ mysql-5.1.58/sql-common/my_time.c 2011-07-15 10:49:00.423349307 +0000
+diff -urN mysql-orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql-orig/sql-common/my_time.c 2011-07-21 02:15:51.926095298 +0000
++++ mysql/sql-common/my_time.c 2011-07-21 02:16:29.011095322 +0000
@@ -249,7 +249,7 @@
2003-03-03 20:00:20 AM
20:00:20.000000 AM 03-03-2000
@@ -2689,9 +2710,9 @@ diff -urN mysql-5.1.58-old/sql-common/my_time.c mysql-5.1.58/sql-common/my_time.
set_if_bigger(i, (uint) format_position[2]);
allow_space= ((1 << i) | (1 << format_position[6]));
allow_space&= (1 | 2 | 4 | 8);
-diff -urN mysql-5.1.58-old/storage/csv/ha_tina.cc mysql-5.1.58/storage/csv/ha_tina.cc
---- mysql-5.1.58-old/storage/csv/ha_tina.cc 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/csv/ha_tina.cc 2011-07-15 10:45:58.976682640 +0000
+diff -urN mysql-orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql-orig/storage/csv/ha_tina.cc 2011-07-21 02:15:52.017095298 +0000
++++ mysql/storage/csv/ha_tina.cc 2011-07-21 02:16:29.011095322 +0000
@@ -1193,7 +1193,7 @@
if (closest_hole == chain_ptr) /* no more chains */
*end_pos= file_buff->end();
@@ -2710,9 +2731,9 @@ diff -urN mysql-5.1.58-old/storage/csv/ha_tina.cc mysql-5.1.58/storage/csv/ha_ti
if ((write_end - write_begin) &&
(my_write(repair_file, (uchar*)file_buff->ptr(),
(size_t) (write_end - write_begin), MYF_RW)))
-diff -urN mysql-5.1.58-old/storage/example/ha_example.h mysql-5.1.58/storage/example/ha_example.h
---- mysql-5.1.58-old/storage/example/ha_example.h 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/example/ha_example.h 2011-07-15 10:48:57.970015974 +0000
+diff -urN mysql-orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql-orig/storage/example/ha_example.h 2011-07-21 02:15:52.016095298 +0000
++++ mysql/storage/example/ha_example.h 2011-07-21 02:16:29.012095322 +0000
@@ -110,14 +110,14 @@
max_supported_key_parts(), uint max_supported_key_length()
to make sure that the storage engine can handle the data it is about to
@@ -2748,9 +2769,9 @@ diff -urN mysql-5.1.58-old/storage/example/ha_example.h mysql-5.1.58/storage/exa
@details
There is no need to implement ..._key_... methods if your engine doesn't
-diff -urN mysql-5.1.58-old/storage/federated/ha_federated.cc mysql-5.1.58/storage/federated/ha_federated.cc
---- mysql-5.1.58-old/storage/federated/ha_federated.cc 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/federated/ha_federated.cc 2011-07-15 10:45:58.976682640 +0000
+diff -urN mysql-orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql-orig/storage/federated/ha_federated.cc 2011-07-21 02:15:52.075095298 +0000
++++ mysql/storage/federated/ha_federated.cc 2011-07-21 02:16:29.014095322 +0000
@@ -546,7 +546,7 @@
size_t buf_len;
DBUG_ENTER("ha_federated parse_url_error");
@@ -2769,9 +2790,9 @@ diff -urN mysql-5.1.58-old/storage/federated/ha_federated.cc mysql-5.1.58/storag
needs_quotes= field->str_needs_quotes();
DBUG_DUMP("key, start of loop", ptr, length);
-diff -urN mysql-5.1.58-old/storage/heap/hp_create.c mysql-5.1.58/storage/heap/hp_create.c
---- mysql-5.1.58-old/storage/heap/hp_create.c 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/heap/hp_create.c 2011-07-15 10:48:57.983349306 +0000
+diff -urN mysql-orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql-orig/storage/heap/hp_create.c 2011-07-21 02:15:52.018095298 +0000
++++ mysql/storage/heap/hp_create.c 2011-07-21 02:16:29.015095322 +0000
@@ -229,7 +229,7 @@
{
uint i,recbuffer,records_in_block;
@@ -2781,9 +2802,9 @@ diff -urN mysql-5.1.58-old/storage/heap/hp_create.c mysql-5.1.58/storage/heap/hp
if (!max_records)
max_records= 1000; /* As good as quess as anything */
recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
-diff -urN mysql-5.1.58-old/storage/heap/hp_test2.c mysql-5.1.58/storage/heap/hp_test2.c
---- mysql-5.1.58-old/storage/heap/hp_test2.c 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/heap/hp_test2.c 2011-07-15 10:48:58.006682640 +0000
+diff -urN mysql-orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql-orig/storage/heap/hp_test2.c 2011-07-21 02:15:52.017095298 +0000
++++ mysql/storage/heap/hp_test2.c 2011-07-21 02:16:29.015095322 +0000
@@ -136,7 +136,7 @@
for (i=0 ; i < recant ; i++)
@@ -2802,9 +2823,9 @@ diff -urN mysql-5.1.58-old/storage/heap/hp_test2.c mysql-5.1.58/storage/heap/hp_
make_record(record2, n1, n2, n3, "XXX", update);
if (rnd(2) == 1)
{
-diff -urN mysql-5.1.58-old/storage/innobase/include/ut0byte.h mysql-5.1.58/storage/innobase/include/ut0byte.h
---- mysql-5.1.58-old/storage/innobase/include/ut0byte.h 2011-07-15 02:20:33.570015974 +0000
-+++ mysql-5.1.58/storage/innobase/include/ut0byte.h 2011-07-15 10:48:57.576682641 +0000
+diff -urN mysql-orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql-orig/storage/innobase/include/ut0byte.h 2011-07-21 02:15:52.008095298 +0000
++++ mysql/storage/innobase/include/ut0byte.h 2011-07-21 02:16:29.016095322 +0000
@@ -87,7 +87,7 @@
dulint
ut_dulint_get_max(
@@ -2823,9 +2844,9 @@ diff -urN mysql-5.1.58-old/storage/innobase/include/ut0byte.h mysql-5.1.58/stora
dulint a, /* in: dulint */
dulint b); /* in: dulint */
/***********************************************************
-diff -urN mysql-5.1.58-old/storage/innodb_plugin/dict/dict0dict.c mysql-5.1.58/storage/innodb_plugin/dict/dict0dict.c
---- mysql-5.1.58-old/storage/innodb_plugin/dict/dict0dict.c 2011-07-15 02:20:33.636682640 +0000
-+++ mysql-5.1.58/storage/innodb_plugin/dict/dict0dict.c 2011-07-15 10:48:58.506682641 +0000
+diff -urN mysql-orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql-orig/storage/innodb_plugin/dict/dict0dict.c 2011-07-21 02:15:52.022095298 +0000
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2011-07-21 02:16:29.017095322 +0000
@@ -4858,7 +4858,7 @@
/**********************************************************************//**
@@ -2844,9 +2865,9 @@ diff -urN mysql-5.1.58-old/storage/innodb_plugin/dict/dict0dict.c mysql-5.1.58/s
min_index = NULL;
index = dict_table_get_first_index(table);
-diff -urN mysql-5.1.58-old/storage/innodb_plugin/include/dict0dict.h mysql-5.1.58/storage/innodb_plugin/include/dict0dict.h
---- mysql-5.1.58-old/storage/innodb_plugin/include/dict0dict.h 2011-07-15 02:20:33.643349306 +0000
-+++ mysql-5.1.58/storage/innodb_plugin/include/dict0dict.h 2011-07-15 10:48:58.683349307 +0000
+diff -urN mysql-orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql-orig/storage/innodb_plugin/include/dict0dict.h 2011-07-21 02:15:52.024095298 +0000
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2011-07-21 02:16:29.019095322 +0000
@@ -1123,7 +1123,7 @@
const char* name); /*!< in: name of the index to find */
/**********************************************************************//**
@@ -2856,9 +2877,9 @@ diff -urN mysql-5.1.58-old/storage/innodb_plugin/include/dict0dict.h mysql-5.1.5
@return index, NULL if does not exist */
UNIV_INTERN
dict_index_t*
-diff -urN mysql-5.1.58-old/storage/myisam/ft_boolean_search.c mysql-5.1.58/storage/myisam/ft_boolean_search.c
---- mysql-5.1.58-old/storage/myisam/ft_boolean_search.c 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/myisam/ft_boolean_search.c 2011-07-15 10:48:58.020015973 +0000
+diff -urN mysql-orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql-orig/storage/myisam/ft_boolean_search.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/ft_boolean_search.c 2011-07-21 02:16:29.020095322 +0000
@@ -46,9 +46,9 @@
three subexpressions (including the top-level one),
every one has its own max_docid, updated by its plus word.
@@ -2871,9 +2892,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/ft_boolean_search.c mysql-5.1.58/stora
*/
#define FT_CORE
-diff -urN mysql-5.1.58-old/storage/myisam/ha_myisam.cc mysql-5.1.58/storage/myisam/ha_myisam.cc
---- mysql-5.1.58-old/storage/myisam/ha_myisam.cc 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/ha_myisam.cc 2011-07-15 10:45:58.976682640 +0000
+diff -urN mysql-orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql-orig/storage/myisam/ha_myisam.cc 2011-07-21 02:15:52.018095298 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2011-07-21 02:16:29.021095322 +0000
@@ -1528,7 +1528,7 @@
{
DBUG_ENTER("ha_myisam::start_bulk_insert");
@@ -2883,9 +2904,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/ha_myisam.cc mysql-5.1.58/storage/myis
(ulong) (table->s->avg_row_length*rows));
DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
(ulong) rows, size));
-diff -urN mysql-5.1.58-old/storage/myisam/mi_cache.c mysql-5.1.58/storage/myisam/mi_cache.c
---- mysql-5.1.58-old/storage/myisam/mi_cache.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_cache.c 2011-07-15 10:48:58.080015973 +0000
+diff -urN mysql-orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql-orig/storage/myisam/mi_cache.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/mi_cache.c 2011-07-21 02:16:29.022095322 +0000
@@ -61,7 +61,7 @@
(my_off_t) (info->read_end - info->request_pos))
{
@@ -2895,9 +2916,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_cache.c mysql-5.1.58/storage/myisam
memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
if (!(length-=in_buff_length))
DBUG_RETURN(0);
-diff -urN mysql-5.1.58-old/storage/myisam/mi_check.c mysql-5.1.58/storage/myisam/mi_check.c
---- mysql-5.1.58-old/storage/myisam/mi_check.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_check.c 2011-07-15 10:48:58.186682640 +0000
+diff -urN mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql-orig/storage/myisam/mi_check.c 2011-07-21 02:15:52.020095298 +0000
++++ mysql/storage/myisam/mi_check.c 2011-07-21 02:16:29.023095322 +0000
@@ -2173,7 +2173,7 @@
ulong buff_length;
DBUG_ENTER("filecopy");
@@ -2952,9 +2973,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_check.c mysql-5.1.58/storage/myisam
create_info.reloc_rows=share.base.reloc;
create_info.old_options=(share.options |
(unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
-diff -urN mysql-5.1.58-old/storage/myisam/mi_create.c mysql-5.1.58/storage/myisam/mi_create.c
---- mysql-5.1.58-old/storage/myisam/mi_create.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_create.c 2011-07-15 10:48:58.100015973 +0000
+diff -urN mysql-orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql-orig/storage/myisam/mi_create.c 2011-07-21 02:15:52.020095298 +0000
++++ mysql/storage/myisam/mi_create.c 2011-07-21 02:16:29.025095322 +0000
@@ -437,8 +437,8 @@
block_length= (keydef->block_length ?
my_round_up_to_next_power(keydef->block_length) :
@@ -2984,9 +3005,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_create.c mysql-5.1.58/storage/myisa
MI_EXTEND_BLOCK_LENGTH;
if (! (flags & HA_DONT_TOUCH_DATA))
share.state.create_time= (long) time((time_t*) 0);
-diff -urN mysql-5.1.58-old/storage/myisam/mi_dynrec.c mysql-5.1.58/storage/myisam/mi_dynrec.c
---- mysql-5.1.58-old/storage/myisam/mi_dynrec.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_dynrec.c 2011-07-15 10:48:58.116682641 +0000
+diff -urN mysql-orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql-orig/storage/myisam/mi_dynrec.c 2011-07-21 02:15:52.021095298 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2011-07-21 02:16:29.026095322 +0000
@@ -880,7 +880,7 @@
uint tmp=MY_ALIGN(reclength - length + 3 +
test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
@@ -2996,9 +3017,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_dynrec.c mysql-5.1.58/storage/myisa
/* Check if we can extend this block */
if (block_info.filepos + block_info.block_len ==
info->state->data_file_length &&
-diff -urN mysql-5.1.58-old/storage/myisam/mi_extra.c mysql-5.1.58/storage/myisam/mi_extra.c
---- mysql-5.1.58-old/storage/myisam/mi_extra.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_extra.c 2011-07-15 10:48:58.153349307 +0000
+diff -urN mysql-orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql-orig/storage/myisam/mi_extra.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/mi_extra.c 2011-07-21 02:16:29.027095322 +0000
@@ -99,7 +99,7 @@
cache_size= (extra_arg ? *(ulong*) extra_arg :
my_default_record_cache_size);
@@ -3008,9 +3029,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_extra.c mysql-5.1.58/storage/myisam
cache_size),
READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
MYF(share->write_flag & MY_WAIT_IF_FULL))))
-diff -urN mysql-5.1.58-old/storage/myisam/mi_open.c mysql-5.1.58/storage/myisam/mi_open.c
---- mysql-5.1.58-old/storage/myisam/mi_open.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_open.c 2011-07-15 10:48:58.196682639 +0000
+diff -urN mysql-orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql-orig/storage/myisam/mi_open.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/mi_open.c 2011-07-21 02:16:29.027095322 +0000
@@ -328,7 +328,7 @@
strmov(share->index_file_name, index_name);
strmov(share->data_file_name, data_name);
@@ -3042,9 +3063,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_open.c mysql-5.1.58/storage/myisam/
/* Avoid unnecessary realloc */
if (newptr && length == old_length)
return newptr;
-diff -urN mysql-5.1.58-old/storage/myisam/mi_packrec.c mysql-5.1.58/storage/myisam/mi_packrec.c
---- mysql-5.1.58-old/storage/myisam/mi_packrec.c 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/myisam/mi_packrec.c 2011-07-15 10:48:58.040015973 +0000
+diff -urN mysql-orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql-orig/storage/myisam/mi_packrec.c 2011-07-21 02:15:52.020095298 +0000
++++ mysql/storage/myisam/mi_packrec.c 2011-07-21 02:16:29.028095322 +0000
@@ -684,7 +684,7 @@
return OFFSET_TABLE_SIZE;
}
@@ -3063,9 +3084,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_packrec.c mysql-5.1.58/storage/myis
memcpy(*rec_buff_p, header + head_length, info->offset);
}
return 0;
-diff -urN mysql-5.1.58-old/storage/myisam/mi_test1.c mysql-5.1.58/storage/myisam/mi_test1.c
---- mysql-5.1.58-old/storage/myisam/mi_test1.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/mi_test1.c 2011-07-15 10:48:58.106682639 +0000
+diff -urN mysql-orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql-orig/storage/myisam/mi_test1.c 2011-07-21 02:15:52.020095298 +0000
++++ mysql/storage/myisam/mi_test1.c 2011-07-21 02:16:29.029095322 +0000
@@ -436,7 +436,7 @@
uint tmp;
uchar *ptr;;
@@ -3075,9 +3096,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_test1.c mysql-5.1.58/storage/myisam
tmp=strlen((char*) blob_record);
int4store(pos,tmp);
ptr=blob_record;
-diff -urN mysql-5.1.58-old/storage/myisam/mi_test2.c mysql-5.1.58/storage/myisam/mi_test2.c
---- mysql-5.1.58-old/storage/myisam/mi_test2.c 2011-07-15 02:20:33.583349306 +0000
-+++ mysql-5.1.58/storage/myisam/mi_test2.c 2011-07-15 10:48:58.053349307 +0000
+diff -urN mysql-orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql-orig/storage/myisam/mi_test2.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/mi_test2.c 2011-07-21 02:16:29.030095322 +0000
@@ -601,7 +601,7 @@
goto err;
@@ -3087,9 +3108,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/mi_test2.c mysql-5.1.58/storage/myisam
{
if (mi_rsame(file,read_record2,(int) i)) goto err;
if (memcmp(read_record,read_record2,reclength) != 0)
-diff -urN mysql-5.1.58-old/storage/myisam/myisamlog.c mysql-5.1.58/storage/myisam/myisamlog.c
---- mysql-5.1.58-old/storage/myisam/myisamlog.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/myisamlog.c 2011-07-15 10:48:58.143349307 +0000
+diff -urN mysql-orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql-orig/storage/myisam/myisamlog.c 2011-07-21 02:15:52.021095298 +0000
++++ mysql/storage/myisam/myisamlog.c 2011-07-21 02:16:29.030095322 +0000
@@ -90,7 +90,7 @@
log_filename=myisam_log_filename;
get_options(&argc,&argv);
@@ -3099,9 +3120,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/myisamlog.c mysql-5.1.58/storage/myisa
if (update)
printf("Trying to %s MyISAM files according to log '%s'\n",
(recover ? "recover" : "update"),log_filename);
-diff -urN mysql-5.1.58-old/storage/myisam/myisampack.c mysql-5.1.58/storage/myisam/myisampack.c
---- mysql-5.1.58-old/storage/myisam/myisampack.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/myisampack.c 2011-07-15 10:48:58.130015973 +0000
+diff -urN mysql-orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql-orig/storage/myisam/myisampack.c 2011-07-21 02:15:52.020095298 +0000
++++ mysql/storage/myisam/myisampack.c 2011-07-21 02:16:29.032095322 +0000
@@ -1239,7 +1239,7 @@
{
if (huff_counts->field_length > 2 &&
@@ -3120,9 +3141,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/myisampack.c mysql-5.1.58/storage/myis
}
state.dellink= HA_OFFSET_ERROR;
state.version=(ulong) time((time_t*) 0);
-diff -urN mysql-5.1.58-old/storage/myisam/rt_mbr.c mysql-5.1.58/storage/myisam/rt_mbr.c
---- mysql-5.1.58-old/storage/myisam/rt_mbr.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/rt_mbr.c 2011-07-15 10:48:58.190015973 +0000
+diff -urN mysql-orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql-orig/storage/myisam/rt_mbr.c 2011-07-21 02:15:52.019095298 +0000
++++ mysql/storage/myisam/rt_mbr.c 2011-07-21 02:16:29.069095324 +0000
@@ -325,8 +325,8 @@
bmin = korr_func(b); \
amax = korr_func(a+len); \
@@ -3203,9 +3224,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/rt_mbr.c mysql-5.1.58/storage/myisam/r
}
/*
-diff -urN mysql-5.1.58-old/storage/myisam/sort.c mysql-5.1.58/storage/myisam/sort.c
---- mysql-5.1.58-old/storage/myisam/sort.c 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisam/sort.c 2011-07-15 10:48:58.160015973 +0000
+diff -urN mysql-orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql-orig/storage/myisam/sort.c 2011-07-21 02:15:52.021095298 +0000
++++ mysql/storage/myisam/sort.c 2011-07-21 02:16:29.070095324 +0000
@@ -129,7 +129,7 @@
sort_keys= (uchar **) NULL; error= 1;
maxbuffer=1;
@@ -3242,9 +3263,9 @@ diff -urN mysql-5.1.58-old/storage/myisam/sort.c mysql-5.1.58/storage/myisam/sor
{
buffp = buffpek->base;
-diff -urN mysql-5.1.58-old/storage/myisammrg/ha_myisammrg.cc mysql-5.1.58/storage/myisammrg/ha_myisammrg.cc
---- mysql-5.1.58-old/storage/myisammrg/ha_myisammrg.cc 2011-07-15 02:20:33.586682639 +0000
-+++ mysql-5.1.58/storage/myisammrg/ha_myisammrg.cc 2011-07-15 10:45:58.983349306 +0000
+diff -urN mysql-orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql-orig/storage/myisammrg/ha_myisammrg.cc 2011-07-21 02:15:52.016095298 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2011-07-21 02:16:29.071095324 +0000
@@ -964,7 +964,7 @@
memcpy((char*) table->key_info[0].rec_per_key,
(char*) mrg_info.rec_per_key,
@@ -3254,9 +3275,9 @@ diff -urN mysql-5.1.58-old/storage/myisammrg/ha_myisammrg.cc mysql-5.1.58/storag
}
}
if (flag & HA_STATUS_ERRKEY)
-diff -urN mysql-5.1.58-old/storage/ndb/src/common/portlib/NdbTCP.cpp mysql-5.1.58/storage/ndb/src/common/portlib/NdbTCP.cpp
---- mysql-5.1.58-old/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-15 02:20:33.610015973 +0000
-+++ mysql-5.1.58/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-15 10:45:58.983349306 +0000
+diff -urN mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-21 02:15:51.992095298 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-07-21 02:16:29.072095324 +0000
@@ -30,7 +30,7 @@
&tmp_errno);
if (hp)
@@ -3266,9 +3287,9 @@ diff -urN mysql-5.1.58-old/storage/ndb/src/common/portlib/NdbTCP.cpp mysql-5.1.5
my_gethostbyname_r_free();
return 0; //DBUG_RETURN(0);
}
-diff -urN mysql-5.1.58-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql-5.1.58/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
---- mysql-5.1.58-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-15 02:20:33.600015974 +0000
-+++ mysql-5.1.58/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-15 10:45:58.983349306 +0000
+diff -urN mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-21 02:15:51.979095298 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-07-21 02:16:29.072095324 +0000
@@ -212,7 +212,7 @@
}
}
@@ -3278,9 +3299,9 @@ diff -urN mysql-5.1.58-old/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp my
par.m_occup = node.getOccup();
for (unsigned i = 0; i <= 1; i++) {
if (node.getLink(i) == NullTupLoc)
-diff -urN mysql-5.1.58-old/storage/ndb/src/ndbapi/NdbBlob.cpp mysql-5.1.58/storage/ndb/src/ndbapi/NdbBlob.cpp
---- mysql-5.1.58-old/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-15 02:20:33.606682640 +0000
-+++ mysql-5.1.58/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-15 10:45:58.983349306 +0000
+diff -urN mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-21 02:15:51.974095298 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-07-21 02:16:29.074095324 +0000
@@ -1523,7 +1523,7 @@
}
// these buffers are always used
@@ -3290,9 +3311,9 @@ diff -urN mysql-5.1.58-old/storage/ndb/src/ndbapi/NdbBlob.cpp mysql-5.1.58/stora
theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
theHead = (Head*)theHeadInlineBuf.data;
theInlineData = theHeadInlineBuf.data + sizeof(Head);
-diff -urN mysql-5.1.58-old/storage/ndb/test/ndbapi/testIndexStat.cpp mysql-5.1.58/storage/ndb/test/ndbapi/testIndexStat.cpp
---- mysql-5.1.58-old/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-15 02:20:33.620015973 +0000
-+++ mysql-5.1.58/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-15 10:45:58.986682639 +0000
+diff -urN mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-21 02:15:52.000095298 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-07-21 02:16:29.075095324 +0000
@@ -30,10 +30,10 @@
* 0. baseline with same options as handler
*/
@@ -3335,9 +3356,9 @@ diff -urN mysql-5.1.58-old/storage/ndb/test/ndbapi/testIndexStat.cpp mysql-5.1.5
if (! g_opts.nochecks) {
int curr = -1;
for (i = 0; i < (int)g_sortcount; i++) {
-diff -urN mysql-5.1.58-old/storage/ndb/test/src/getarg.c mysql-5.1.58/storage/ndb/test/src/getarg.c
---- mysql-5.1.58-old/storage/ndb/test/src/getarg.c 2011-07-15 02:20:33.616682639 +0000
-+++ mysql-5.1.58/storage/ndb/test/src/getarg.c 2011-07-15 10:48:58.276682640 +0000
+diff -urN mysql-orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql-orig/storage/ndb/test/src/getarg.c 2011-07-21 02:15:51.998095298 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2011-07-21 02:16:29.075095324 +0000
@@ -65,8 +65,8 @@
#define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
@@ -3358,9 +3379,9 @@ diff -urN mysql-5.1.58-old/storage/ndb/test/src/getarg.c mysql-5.1.58/storage/nd
}
if (extra_string) {
col = check_column(stderr, col, strlen(extra_string) + 1, columns);
-diff -urN mysql-5.1.58-old/strings/ctype-big5.c mysql-5.1.58/strings/ctype-big5.c
---- mysql-5.1.58-old/strings/ctype-big5.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/ctype-big5.c 2011-07-15 10:48:59.236682640 +0000
+diff -urN mysql-orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql-orig/strings/ctype-big5.c 2011-07-21 02:15:51.933095298 +0000
++++ mysql/strings/ctype-big5.c 2011-07-21 02:16:29.078095324 +0000
@@ -253,7 +253,7 @@
const uchar *b, size_t b_length,
my_bool b_is_prefix)
@@ -3379,9 +3400,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-big5.c mysql-5.1.58/strings/ctype-big5.
int res= my_strnncoll_big5_internal(&a, &b, length);
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
-diff -urN mysql-5.1.58-old/strings/ctype-bin.c mysql-5.1.58/strings/ctype-bin.c
---- mysql-5.1.58-old/strings/ctype-bin.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/ctype-bin.c 2011-07-15 10:48:59.206682640 +0000
+diff -urN mysql-orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql-orig/strings/ctype-bin.c 2011-07-21 02:15:51.933095298 +0000
++++ mysql/strings/ctype-bin.c 2011-07-21 02:16:29.081095324 +0000
@@ -80,7 +80,7 @@
const uchar *t, size_t tlen,
my_bool t_is_prefix)
@@ -3427,9 +3448,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-bin.c mysql-5.1.58/strings/ctype-bin.c
if (dstlen > srclen)
bfill(dest + srclen, dstlen - srclen, ' ');
return dstlen;
-diff -urN mysql-5.1.58-old/strings/ctype-gbk.c mysql-5.1.58/strings/ctype-gbk.c
---- mysql-5.1.58-old/strings/ctype-gbk.c 2011-07-15 02:20:33.660015974 +0000
-+++ mysql-5.1.58/strings/ctype-gbk.c 2011-07-15 10:48:59.453349306 +0000
+diff -urN mysql-orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql-orig/strings/ctype-gbk.c 2011-07-21 02:15:51.935095298 +0000
++++ mysql/strings/ctype-gbk.c 2011-07-21 02:16:29.085095324 +0000
@@ -2616,7 +2616,7 @@
const uchar *b, size_t b_length,
my_bool b_is_prefix)
@@ -3448,9 +3469,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-gbk.c mysql-5.1.58/strings/ctype-gbk.c
int res= my_strnncoll_gbk_internal(&a, &b, length);
#ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
-diff -urN mysql-5.1.58-old/strings/ctype-mb.c mysql-5.1.58/strings/ctype-mb.c
---- mysql-5.1.58-old/strings/ctype-mb.c 2011-07-15 02:20:33.653349307 +0000
-+++ mysql-5.1.58/strings/ctype-mb.c 2011-07-15 10:48:59.066682639 +0000
+diff -urN mysql-orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql-orig/strings/ctype-mb.c 2011-07-21 02:15:51.935095298 +0000
++++ mysql/strings/ctype-mb.c 2011-07-21 02:16:29.089095324 +0000
@@ -368,7 +368,7 @@
const uchar *t, size_t tlen,
my_bool t_is_prefix)
@@ -3478,9 +3499,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-mb.c mysql-5.1.58/strings/ctype-mb.c
if (dstlen > srclen)
bfill(dest + srclen, dstlen - srclen, ' ');
return dstlen;
-diff -urN mysql-5.1.58-old/strings/ctype-simple.c mysql-5.1.58/strings/ctype-simple.c
---- mysql-5.1.58-old/strings/ctype-simple.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/ctype-simple.c 2011-07-15 10:48:59.283349307 +0000
+diff -urN mysql-orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql-orig/strings/ctype-simple.c 2011-07-21 02:15:51.930095298 +0000
++++ mysql/strings/ctype-simple.c 2011-07-21 02:16:29.144095324 +0000
@@ -159,7 +159,7 @@
diff_if_only_endspace_difference= 0;
#endif
@@ -3517,9 +3538,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-simple.c mysql-5.1.58/strings/ctype-sim
}
-diff -urN mysql-5.1.58-old/strings/ctype-tis620.c mysql-5.1.58/strings/ctype-tis620.c
---- mysql-5.1.58-old/strings/ctype-tis620.c 2011-07-15 02:20:33.660015974 +0000
-+++ mysql-5.1.58/strings/ctype-tis620.c 2011-07-15 10:48:59.356682640 +0000
+diff -urN mysql-orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql-orig/strings/ctype-tis620.c 2011-07-21 02:15:51.934095298 +0000
++++ mysql/strings/ctype-tis620.c 2011-07-21 02:16:29.171095324 +0000
@@ -581,7 +581,7 @@
a_length= thai2sortable(a, a_length);
b_length= thai2sortable(b, b_length);
@@ -3538,9 +3559,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-tis620.c mysql-5.1.58/strings/ctype-tis
(char*) dest);
len= thai2sortable(dest, len);
if (dstlen > len)
-diff -urN mysql-5.1.58-old/strings/ctype-uca.c mysql-5.1.58/strings/ctype-uca.c
---- mysql-5.1.58-old/strings/ctype-uca.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/ctype-uca.c 2011-07-15 10:48:59.273349306 +0000
+diff -urN mysql-orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql-orig/strings/ctype-uca.c 2011-07-21 02:15:51.932095298 +0000
++++ mysql/strings/ctype-uca.c 2011-07-21 02:16:29.186095324 +0000
@@ -7567,7 +7567,7 @@
{
char tail[30];
@@ -3550,9 +3571,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-uca.c mysql-5.1.58/strings/ctype-uca.c
errstr[errsize-1]= '\0';
my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
}
-diff -urN mysql-5.1.58-old/strings/ctype-ucs2.c mysql-5.1.58/strings/ctype-ucs2.c
---- mysql-5.1.58-old/strings/ctype-ucs2.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/ctype-ucs2.c 2011-07-15 10:48:59.203349307 +0000
+diff -urN mysql-orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql-orig/strings/ctype-ucs2.c 2011-07-21 02:15:51.936095298 +0000
++++ mysql/strings/ctype-ucs2.c 2011-07-21 02:16:29.225095324 +0000
@@ -279,7 +279,7 @@
se= s + slen;
te= t + tlen;
@@ -3589,9 +3610,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-ucs2.c mysql-5.1.58/strings/ctype-ucs2.
if (dstlen > srclen)
cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
return dstlen;
-diff -urN mysql-5.1.58-old/strings/ctype-utf8.c mysql-5.1.58/strings/ctype-utf8.c
---- mysql-5.1.58-old/strings/ctype-utf8.c 2011-07-15 02:20:33.660015974 +0000
-+++ mysql-5.1.58/strings/ctype-utf8.c 2011-07-15 10:48:59.370015973 +0000
+diff -urN mysql-orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql-orig/strings/ctype-utf8.c 2011-07-21 02:15:51.932095298 +0000
++++ mysql/strings/ctype-utf8.c 2011-07-21 02:16:29.249095324 +0000
@@ -1937,7 +1937,7 @@
const uchar *t, const uchar *te)
{
@@ -3601,9 +3622,9 @@ diff -urN mysql-5.1.58-old/strings/ctype-utf8.c mysql-5.1.58/strings/ctype-utf8.
int cmp= memcmp(s,t,len);
return cmp ? cmp : slen-tlen;
}
-diff -urN mysql-5.1.58-old/strings/decimal.c mysql-5.1.58/strings/decimal.c
---- mysql-5.1.58-old/strings/decimal.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/decimal.c 2011-07-15 10:48:59.196682641 +0000
+diff -urN mysql-orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql-orig/strings/decimal.c 2011-07-21 02:15:51.936095298 +0000
++++ mysql/strings/decimal.c 2011-07-21 02:16:29.251095324 +0000
@@ -404,7 +404,7 @@
for (; frac>0; frac-=DIG_PER_DEC1)
{
@@ -3788,9 +3809,9 @@ diff -urN mysql-5.1.58-old/strings/decimal.c mysql-5.1.58/strings/decimal.c
}
if (unlikely(intg0+frac0 > to->len))
{
-diff -urN mysql-5.1.58-old/strings/my_vsnprintf.c mysql-5.1.58/strings/my_vsnprintf.c
---- mysql-5.1.58-old/strings/my_vsnprintf.c 2011-07-15 02:20:33.656682641 +0000
-+++ mysql-5.1.58/strings/my_vsnprintf.c 2011-07-15 10:48:59.156682639 +0000
+diff -urN mysql-orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql-orig/strings/my_vsnprintf.c 2011-07-21 02:15:51.931095298 +0000
++++ mysql/strings/my_vsnprintf.c 2011-07-21 02:16:29.252095324 +0000
@@ -141,7 +141,7 @@
/* If %#d syntax was used, we have to pre-zero/pre-space the string */
if (store_start == buff)
@@ -3800,9 +3821,9 @@ diff -urN mysql-5.1.58-old/strings/my_vsnprintf.c mysql-5.1.58/strings/my_vsnpri
if (res_length < length)
{
size_t diff= (length- res_length);
-diff -urN mysql-5.1.58-old/strings/str2int.c mysql-5.1.58/strings/str2int.c
---- mysql-5.1.58-old/strings/str2int.c 2011-07-15 02:20:33.653349307 +0000
-+++ mysql-5.1.58/strings/str2int.c 2011-07-15 10:48:59.116682640 +0000
+diff -urN mysql-orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql-orig/strings/str2int.c 2011-07-21 02:15:51.932095298 +0000
++++ mysql/strings/str2int.c 2011-07-21 02:16:29.253095324 +0000
@@ -82,7 +82,7 @@
machines all, if +|n| is representable, so is -|n|, but on
twos complement machines the converse is not true. So the
@@ -3812,9 +3833,9 @@ diff -urN mysql-5.1.58-old/strings/str2int.c mysql-5.1.58/strings/str2int.c
number we are concerned with. */
/* Calculate Limit using Scale as a scratch variable */
-diff -urN mysql-5.1.58-old/tests/mysql_client_test.c mysql-5.1.58/tests/mysql_client_test.c
---- mysql-5.1.58-old/tests/mysql_client_test.c 2011-07-15 02:20:33.713349307 +0000
-+++ mysql-5.1.58/tests/mysql_client_test.c 2011-07-15 10:49:00.340015974 +0000
+diff -urN mysql-orig/tests/mysql_client_test.c mysql/tests/mysql_client_test.c
+--- mysql-orig/tests/mysql_client_test.c 2011-07-21 02:15:51.909095298 +0000
++++ mysql/tests/mysql_client_test.c 2011-07-21 02:16:29.259095324 +0000
@@ -610,7 +610,7 @@
return row_count;
}
@@ -3824,9 +3845,9 @@ diff -urN mysql-5.1.58-old/tests/mysql_client_test.c mysql-5.1.58/tests/mysql_cl
bzero((char*) buffer, sizeof(buffer));
bzero((char*) length, sizeof(length));
-diff -urN mysql-5.1.58-old/vio/viosocket.c mysql-5.1.58/vio/viosocket.c
---- mysql-5.1.58-old/vio/viosocket.c 2011-07-15 02:20:33.743349307 +0000
-+++ mysql-5.1.58/vio/viosocket.c 2011-07-15 10:49:00.653349306 +0000
+diff -urN mysql-orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql-orig/vio/viosocket.c 2011-07-21 02:15:51.908095298 +0000
++++ mysql/vio/viosocket.c 2011-07-21 02:16:29.262095324 +0000
@@ -71,7 +71,7 @@
if (vio->read_pos < vio->read_end)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-07-21 2:27 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-07-21 2:27 UTC (permalink / raw
To: gentoo-commits
commit: bf8c2e431145855eb3dd7de9fc683b46c9f9b8ed
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 02:26:57 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 02:26:57 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=bf8c2e43
Fix broken s/max/MYSQL_MAX/ replacements on 07110_all_mysql_gcc-4.2_5.1.58.patch.
---
07110_all_mysql_gcc-4.2_5.1.58.patch | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/07110_all_mysql_gcc-4.2_5.1.58.patch b/07110_all_mysql_gcc-4.2_5.1.58.patch
index 659728c..a4f56e2 100644
--- a/07110_all_mysql_gcc-4.2_5.1.58.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.58.patch
@@ -2942,7 +2942,7 @@ diff -urN mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
*/
sort_info.max_records= 10 *
- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
-+ MYSQL_MAXparam->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
sort_param.key_length;
}
@@ -2960,7 +2960,7 @@ diff -urN mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
/*
32 is just a safety margin here
- (at least max(val_len, sizeof(nod_flag)) should be there).
-+ (at least MYSQL_MAXval_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
May be better performance could be achieved if we'd put
(sort_info->keyinfo->block_length-32)/XXX
instead.
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-08-19 4:04 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-08-19 4:04 UTC (permalink / raw
To: gentoo-commits
commit: 648d49714f3de3bf0bdb7289ad7e56143be9b6d2
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 19 04:02:50 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Fri Aug 19 04:02:50 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=648d4971
Added Diego's patch to fix the duplicate install of files on mariadb - fixes bug 379059.
---
00000_index.txt | 5 +++++
16000_all_mariadb_fix_duplicate_install.patch | 11 +++++++++++
2 files changed, 16 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 62b1372..eccbdec 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1363,3 +1363,8 @@
@ver 5.01.53.00 to 5.01.99.99
@pn mysql
@@ Fix Test::Harness usage since the Perl class has changed and no longer execs by default.
+
+@patch 1600_all_mariadb_fix_duplicate_install.patch
+@ver 5.02.07.00 to 5.03.99.99
+@pn mariadb
+@@ Fix duplicate entries for files on support-files/Makefile.am
diff --git a/16000_all_mariadb_fix_duplicate_install.patch b/16000_all_mariadb_fix_duplicate_install.patch
new file mode 100644
index 0000000..6200d16
--- /dev/null
+++ b/16000_all_mariadb_fix_duplicate_install.patch
@@ -0,0 +1,11 @@
+--- mariadb-5.2.7/support-files/Makefile.am
++++ mariadb-5.2.7/support-files/Makefile.am
+@@ -48,8 +48,6 @@ pkgsupp_DATA = my-small.cnf \
+ config.medium.ini \
+ config.small.ini \
+ my-innodb-heavy-4G.cnf \
+- mysql-log-rotate \
+- binary-configure \
+ ndb-config-2-node.ini
+
+ pkgsupp_SCRIPTS = mysql.server \
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-08-19 4:15 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2011-08-19 4:15 UTC (permalink / raw
To: gentoo-commits
commit: de37b2fe9f78066b2c8c3d7db6f27f899b83ba0b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 19 04:14:50 2011 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Fri Aug 19 04:14:50 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=de37b2fe
The patch is named 16000 and not 1600.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index eccbdec..a0b07a8 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1364,7 +1364,7 @@
@pn mysql
@@ Fix Test::Harness usage since the Perl class has changed and no longer execs by default.
-@patch 1600_all_mariadb_fix_duplicate_install.patch
+@patch 16000_all_mariadb_fix_duplicate_install.patch
@ver 5.02.07.00 to 5.03.99.99
@pn mariadb
@@ Fix duplicate entries for files on support-files/Makefile.am
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2011-11-18 20:58 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2011-11-18 20:58 UTC (permalink / raw
To: gentoo-commits
commit: 6ab170bf92605919703b112734cc1bbc1215ef33
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Fri Nov 18 20:58:03 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Nov 18 20:58:09 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=6ab170bf
Respin 02040_all_embedded-library-shared-5.1.50.patch for 5.1.60 by editing it directly.
---
00000_index.txt | 7 +-
02040_all_embedded-library-shared-5.1.60.patch | 2298 ++++++++++++++++++++++++
2 files changed, 2304 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index a0b07a8..2577963 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -291,7 +291,12 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.1.50.patch
-@ver 5.01.50.00 to 5.01.99.99
+@ver 5.01.50.00 to 5.01.59.99
+@pn mysql
+@@ Take libmysqld to be a proper shared library.
+
+@patch 02040_all_embedded-library-shared-5.1.60.patch
+@ver 5.01.60.00 to 5.01.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
diff --git a/02040_all_embedded-library-shared-5.1.60.patch b/02040_all_embedded-library-shared-5.1.60.patch
new file mode 100644
index 0000000..4bff5b6
--- /dev/null
+++ b/02040_all_embedded-library-shared-5.1.60.patch
@@ -0,0 +1,2298 @@
+Convert all of the static libraries for the embedded libmysqld to build as
+shared.
+
+This enables amarok's mysql extension to properly build as a shared object,
+without statically including libmysqld or nor forcing libmysqld to be built
+with -fPIC.
+
+Thanks to <pageexec@freemail.hu> for the @plt fixes.
+Thanks to Diego Elio Pettenò <flameeyes@gentoo.org> for all the extensive build
+system help with libtool conversions.
+Thanks to Maciej Mrozowski <reavertm@gentoo.org> for working in the redo of the
+patch for mysql-5.1.
+
+Gentoo-Bug: 238487
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=238487
+MySQL-Bug-URL: http://bugs.mysql.com/bug.php?id=39288
+MySQL-Bug: 39288
+MySQL-Lists-URL: http://lists.mysql.com/internals/35947
+X-Patch-URL: http://bugs.gentoo.org/attachment.cgi?id=188019&action=view
+Signed-off-by: Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
+
+=== modified file 'client/Makefile.am'
+---
+ client/Makefile.am | 11 -
+ config/ac-macros/plugins.m4 | 107 ++++++++-----
+ configure.in | 8 -
+ dbug/Makefile.am | 6
+ extra/Makefile.am | 4
+ libmysqld/Makefile.am | 184 ++++++++---------------
+ libmysqld/examples/Makefile.am | 10 -
+ mysys/Makefile.am | 42 ++---
+ netware/BUILD/compile-linux-tools | 16 +-
+ netware/Makefile.am | 4
+ regex/Makefile.am | 6
+ server-tools/instance-manager/Makefile.am | 8 -
+ sql/Makefile.am | 12 -
+ storage/archive/Makefile.am | 23 +-
+ storage/archive/plug.in | 2
+ storage/blackhole/Makefile.am | 11 -
+ storage/blackhole/plug.in | 2
+ storage/csv/Makefile.am | 9 -
+ storage/csv/plug.in | 2
+ storage/example/Makefile.am | 11 -
+ storage/federated/Makefile.am | 15 +
+ storage/federated/plug.in | 3
+ storage/heap/Makefile.am | 37 +++-
+ storage/heap/plug.in | 3
+ storage/innobase/Makefile.am | 40 ++---
+ storage/innobase/plug.in | 2
+ storage/innodb_plugin/Makefile.am | 13 -
+ storage/myisam/Makefile.am | 118 ++++++++------
+ storage/myisam/plug.in | 4
+ storage/myisammrg/Makefile.am | 20 ++
+ storage/myisammrg/plug.in | 3
+ storage/ndb/config/type_ndbapitest.mk.am | 31 ++-
+ storage/ndb/config/type_ndbapitools.mk.am | 33 ++--
+ storage/ndb/config/win-libraries | 2
+ storage/ndb/src/common/util/Makefile.am | 6
+ storage/ndb/src/cw/cpcd/Makefile.am | 6
+ storage/ndb/src/kernel/Makefile.am | 7
+ storage/ndb/src/kernel/blocks/Makefile.am | 10 -
+ storage/ndb/src/kernel/blocks/backup/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dbdict/Makefile.am | 12 -
+ storage/ndb/src/kernel/blocks/dbdih/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dblqh/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dbtup/Makefile.am | 6
+ storage/ndb/src/kernel/vm/Makefile.am | 82 +++++-----
+ storage/ndb/src/mgmclient/Makefile.am | 65 ++++----
+ storage/ndb/src/mgmsrv/Makefile.am | 70 ++++----
+ storage/ndb/src/ndbapi/Makefile.am | 98 ++++++------
+ storage/ndb/test/run-test/Makefile.am | 6
+ strings/Makefile.am | 16 +-
+ unittest/mysys/Makefile.am | 15 +
+ unittest/strings/Makefile.am | 9 -
+ unittest/unit.pl | 2
+ vio/Makefile.am | 4
+ 53 files changed, 622 insertions(+), 612 deletions(-)
+
+Index: client/Makefile.am
+===================================================================
+--- client/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ client/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -75,7 +75,8 @@ mysqlimport_CFLAGS= -DTHREAD -UUNDEF_TH
+ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ mysqlshow_SOURCES= mysqlshow.c
+
+@@ -84,15 +85,17 @@ mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIE
+ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ mysqltest_SOURCES= mysqltest.cc
+ mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
+ mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/regex/libregex.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/strings/libmystrings.la \
+ $(CLIENT_THREAD_LIBS)
+
+ mysql_upgrade_SOURCES= mysql_upgrade.c \
+Index: config/ac-macros/plugins.m4
+===================================================================
+--- config/ac-macros/plugins.m4.orig 2010-11-27 15:02:45.000000000 +0100
++++ config/ac-macros/plugins.m4 2010-11-27 15:02:49.000000000 +0100
+@@ -115,18 +115,32 @@ dnl ------------------------------------
+ dnl Macro: MYSQL_PLUGIN_STATIC
+ dnl
+ dnl SYNOPSIS
+-dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a])
++dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a],[libmyplugin_embedded.a])
+ dnl
+ dnl DESCRIPTION
+-dnl Declare the name for the static library
++dnl Declare the name for the static library
++dnl
++dnl Third argument is optional, only needed for special plugins that depend
++dnl on server internals and have source files that must be compiled specially
++dnl with -DEMBEDDED_LIBRARY for embedded server. If specified, the third
++dnl argument is used to link embedded server instead of the second.
+ dnl
+ dnl ---------------------------------------------------------------------------
+
+ AC_DEFUN([MYSQL_PLUGIN_STATIC],[
+ MYSQL_REQUIRE_PLUGIN([$1])
+ m4_define([MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), [$2])
++ ifelse($#, 3, [
++ m4_define([MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]), [$3])
++ ])
+ ])
+
++dnl ---------------------------------------------------------------------------
++dnl Substitution variable to use to compile source files specially for
++dnl embedded server.
++dnl To be used by plugins that have sources that depend on server internals.
++dnl ---------------------------------------------------------------------------
++AC_SUBST([plugin_embedded_defs], ["-DEMBEDDED_LIBRARY -DMYSQL_SERVER"])
+
+ dnl ---------------------------------------------------------------------------
+ dnl Macro: MYSQL_PLUGIN_DYNAMIC
+@@ -254,29 +268,6 @@ AC_DEFUN([MYSQL_PLUGIN_ACTIONS],[
+ ])
+
+ dnl ---------------------------------------------------------------------------
+-dnl Macro: MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS
+-dnl
+-dnl SYNOPSIS
+-dnl MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS([name],[file name])
+-dnl
+-dnl DESCRIPTION
+-dnl Some modules in plugins keep dependance on structures
+-dnl declared in sql/ (THD class usually)
+-dnl That has to be fixed in the future, but until then
+-dnl we have to recompile these modules when we want to
+-dnl to compile server parts with the different #defines
+-dnl Normally it happens when we compile the embedded server
+-dnl Thus one should mark such files in his handler using this macro
+-dnl (currently only one such a file per plugin is supported)
+-dnl
+-dnl ---------------------------------------------------------------------------
+-
+-AC_DEFUN([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS],[
+- MYSQL_REQUIRE_PLUGIN([$1])
+- m4_define([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), [$2])
+-])
+-
+-dnl ---------------------------------------------------------------------------
+ dnl Macro: MYSQL_CONFIGURE_PLUGINS
+ dnl
+ dnl SYNOPSIS
+@@ -336,11 +327,25 @@ AC_DEFUN([_MYSQL_EMIT_CHECK_PLUGIN],[
+ [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]),
+- [MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]),
++ [MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1])
+ )
+ ])
+
++# __MYSQL_EMIT_CHECK_PLUGIN arguments:
++#
++# 1 - plugin identifying name
++# 2 - plugin identifying name, with `-' replaced by `_'
++# 3 - plugin long name
++# 4 - plugin description
++# 5 - mysql_plugin_define (eg. WITH_xxx_STORAGE_ENGINE)
++# 6 - directory
++# 7 - static target (if supports static build)
++# 8 - dynamic target (if supports dynamic build)
++# 9 - mandatory flag
++# 10 - disabled flag
++# 11 - static target for libmysqld (if different from mysqld)
++# 12 - actions
+ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ m4_ifdef([$5],[
+ AH_TEMPLATE($5, [Include ]$4[ into mysqld])
+@@ -407,6 +412,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ ])
+ AC_SUBST([plugin_]$2[_shared_target], "$8")
+ AC_SUBST([plugin_]$2[_static_target], [""])
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
+ [with_plugin_]$2=yes
+ AC_MSG_RESULT([plugin])
+ m4_ifdef([$6],[
+@@ -421,32 +427,47 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ ])
+ else
+ m4_ifdef([$7],[
+- ifelse(m4_bregexp($7, [^lib[^.]+\.a$]), -2, [
+-dnl change above "-2" to "0" to enable this section
+-dnl Although this is "pretty", it breaks libmysqld build
+- m4_ifdef([$6],[
+- mysql_use_plugin_dir="$6"
+- mysql_plugin_libs="$mysql_plugin_libs -L[\$(top_builddir)]/$6"
+- ])
+- mysql_plugin_libs="$mysql_plugin_libs dnl
+-[-l]m4_bregexp($7, [^lib\([^.]+\)], [\1])"
+- ], m4_bregexp($7, [^\\\$]), 0, [
++ ifelse(m4_bregexp($7, [^\\\$]), 0, [
+ m4_ifdef([$6],[
+ mysql_use_plugin_dir="$6"
+ ])
+ mysql_plugin_libs="$mysql_plugin_libs $7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7"
++ ])
+ ], [
+ m4_ifdef([$6],[
+ mysql_use_plugin_dir="$6"
+ mysql_plugin_libs="$mysql_plugin_libs \$(top_builddir)/$6/$7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$7"
++ ])
+ ],[
+ mysql_plugin_libs="$mysql_plugin_libs $7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7"
++ ])
+ ])
+ ])
+ m4_ifdef([$5],[
+ AC_DEFINE($5)
+ ])
+ AC_SUBST([plugin_]$2[_static_target], "$7")
++ m4_ifdef([$11], [
++ if test "$with_embedded_server" = "yes"; then
++ AC_SUBST([plugin_]$2[_embedded_static_target], "$11")
++ else
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
++ fi
++ ], [
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
++ ])
+ AC_SUBST([plugin_]$2[_shared_target], [""])
+ ],[
+ m4_ifdef([$6],[
+@@ -463,12 +484,6 @@ dnl Although this is "pretty", it breaks
+ mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ [with_plugin_]$2=yes
+ AC_MSG_RESULT([yes])
+- m4_ifdef([$11],[
+- condition_dependent_plugin_modules="$condition_dependent_plugin_modules m4_bregexp($11, [[^/]+$], [\&])"
+- condition_dependent_plugin_objects="$condition_dependent_plugin_objects m4_bregexp($11, [[^/]+\.], [\&o])"
+- condition_dependent_plugin_links="$condition_dependent_plugin_links $6/$11"
+- condition_dependent_plugin_includes="$condition_dependent_plugin_includes -I[\$(top_srcdir)]/$6/m4_bregexp($11, [^.+[/$]], [\&])"
+- ])
+ fi
+ fi
+
+@@ -516,6 +531,14 @@ dnl
+ ])
+ ])
+
++dnl If not building libmysqld embedded server, then there is no need to build
++dnl shared object versions of static plugins.
++if test "$with_embedded_server" = "yes"; then
++ AC_SUBST([plugin_static_if_no_embedded], "")
++else
++ AC_SUBST([plugin_static_if_no_embedded], "-static")
++fi
++
+ AC_DEFUN([_MYSQL_EMIT_PLUGIN_ACTIONS],[
+ ifelse($#, 0, [], $#, 1, [
+ _MYSQL_EMIT_PLUGIN_ACTION([$1])
+Index: configure.in
+===================================================================
+--- configure.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ configure.in 2010-11-27 19:41:49.000000000 +0100
+@@ -2483,8 +2483,6 @@ MYSQL_STORAGE_ENGINE(partition, partitio
+
+ dnl -- ndbcluster requires partition to be enabled
+
+-MYSQL_CONFIGURE_PLUGINS([none])
+-
+ # Only build client code?
+ AC_ARG_WITH(server,
+ [ --without-server Only build the client.],
+@@ -2498,6 +2496,8 @@ AC_ARG_WITH(embedded-server,
+ [with_embedded_server=no]
+ )
+
++MYSQL_CONFIGURE_PLUGINS([none])
++
+ AC_ARG_WITH(query_cache,
+ [ --without-query-cache Do not build query cache.],
+ [with_query_cache=$withval],
+@@ -2801,9 +2801,6 @@ if test "$with_server" != "no" -o "$THRE
+ then
+ AC_DEFINE([THREAD], [1],
+ [Define if you want to have threaded code. This may be undef on client code])
+- # Avoid _PROGRAMS names
+- THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
+- AC_SUBST(THREAD_LOBJECTS)
+ fi
+ AM_CONDITIONAL(NEED_THREAD, test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no")
+
+@@ -2831,6 +2828,7 @@ AC_SUBST(server_scripts)
+
+ AC_SUBST(mysql_plugin_dirs)
+ AC_SUBST(mysql_plugin_libs)
++AC_SUBST(mysql_embedded_plugin_libs)
+ AC_SUBST(mysql_plugin_defs)
+
+
+Index: dbug/Makefile.am
+===================================================================
+--- dbug/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ dbug/Makefile.am 2010-11-27 19:42:26.000000000 +0100
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a
+-pkglib_LIBRARIES = libdbug.a
++LDADD = libdbug.la ../mysys/libmysys.la ../strings/libmystrings.la $(ZLIB_LIBS)
++noinst_LTLIBRARIES = libdbug.la
+ noinst_HEADERS = dbug_long.h
+-libdbug_a_SOURCES = dbug.c sanity.c
++libdbug_la_SOURCES = dbug.c sanity.c
+ EXTRA_DIST = CMakeLists.txt example1.c example2.c example3.c \
+ user.r monty.doc dbug_add_tags.pl \
+ my_main.c main.c factorial.c dbug_analyze.c \
+Index: extra/Makefile.am
+===================================================================
+--- extra/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ extra/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -15,8 +15,8 @@
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_srcdir)/sql
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
++ ../dbug/libdbug.la ../strings/libmystrings.la \
+ $(ZLIB_LIBS)
+ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
+ $(top_builddir)/include/sql_state.h \
+Index: libmysqld/Makefile.am
+===================================================================
+--- libmysqld/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ libmysqld/Makefile.am 2010-11-27 20:58:00.000000000 +0100
+@@ -17,95 +17,91 @@
+ #
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+-MYSQLDATAdir = $(localstatedir)
+-MYSQLSHAREdir = $(pkgdatadir)
+-MYSQLBASEdir= $(prefix)
+-MYSQLLIBdir= $(libdir)
+-pkgplugindir = $(pkglibdir)/plugin
++MYSQLDATAdir = $(localstatedir)
++MYSQLSHAREdir = $(pkgdatadir)
++MYSQLBASEdir = $(prefix)
++MYSQLLIBdir = $(libdir)
++pkgplugindir = $(pkglibdir)/plugin
+
+-EXTRA_DIST = libmysqld.def CMakeLists.txt
+-DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
++EXTRA_DIST = libmysqld.def CMakeLists.txt
++DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+ -DPLUGINDIR="\"$(pkgplugindir)\""
+-INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \
++INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_builddir)/sql -I$(top_srcdir)/sql \
+ -I$(top_srcdir)/sql/examples \
+ -I$(top_srcdir)/regex \
+- $(openssl_includes) @ZLIB_INCLUDES@ \
+- @condition_dependent_plugin_includes@
++ $(openssl_includes) $(ZLIB_INCLUDES) \
++ @condition_dependent_plugin_includes@ \
++ $(ndbcluster_includes)
+
+-noinst_LIBRARIES = libmysqld_int.a
+-pkglib_LIBRARIES = libmysqld.a
+-SUBDIRS = . examples
++pkglib_LTLIBRARIES = libmysqld.la
++SUBDIRS = . examples
+ libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
+ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
+- my_time.c
++ my_time.c
+
+ noinst_HEADERS = embedded_priv.h emb_qcache.h
+
+-sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
+- ha_ndbcluster.cc ha_ndbcluster_cond.cc \
+- ha_ndbcluster_binlog.cc ha_partition.cc \
+- handler.cc sql_handler.cc \
+- hostname.cc init.cc password.c \
+- item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
+- item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
+- item_geofunc.cc item_subselect.cc item_row.cc\
+- item_xmlfunc.cc \
+- key.cc lock.cc log.cc sql_state.c \
+- log_event.cc rpl_record.cc \
+- log_event_old.cc rpl_record_old.cc \
+- protocol.cc net_serv.cc opt_range.cc \
+- opt_sum.cc procedure.cc records.cc sql_acl.cc \
+- sql_load.cc discover.cc sql_locale.cc \
+- sql_profile.cc \
+- sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
+- sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
+- sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
+- scheduler.cc sql_connect.cc sql_parse.cc \
+- sql_prepare.cc sql_derived.cc sql_rename.cc \
+- sql_select.cc sql_do.cc sql_show.cc set_var.cc \
+- sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
+- sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
+- unireg.cc uniques.cc sql_union.cc hash_filo.cc \
+- spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
+- sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
+- parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
+- rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
+- debug_sync.cc \
+- sql_tablespace.cc \
+- rpl_injector.cc my_user.c partition_info.cc \
+- sql_servers.cc event_parse_data.cc
+-
+-libmysqld_int_a_SOURCES= $(libmysqld_sources)
+-nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
+-libmysqld_a_SOURCES=
+-
+-sqlstoragesources = $(EXTRA_libmysqld_a_SOURCES)
+-storagesources = @condition_dependent_plugin_modules@
+-storageobjects = @condition_dependent_plugin_objects@
+-storagesourceslinks = @condition_dependent_plugin_links@
++sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
++ ha_ndbcluster.cc ha_ndbcluster_cond.cc \
++ ha_ndbcluster_binlog.cc ha_partition.cc \
++ handler.cc sql_handler.cc \
++ hostname.cc init.cc password.c \
++ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
++ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
++ item_geofunc.cc item_subselect.cc item_row.cc\
++ item_xmlfunc.cc \
++ key.cc lock.cc log.cc sql_state.c \
++ log_event.cc rpl_record.cc \
++ log_event_old.cc rpl_record_old.cc \
++ protocol.cc net_serv.cc opt_range.cc \
++ opt_sum.cc procedure.cc records.cc sql_acl.cc \
++ sql_load.cc discover.cc sql_locale.cc \
++ sql_profile.cc \
++ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
++ sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
++ sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
++ scheduler.cc sql_connect.cc sql_parse.cc \
++ sql_prepare.cc sql_derived.cc sql_rename.cc \
++ sql_select.cc sql_do.cc sql_show.cc set_var.cc \
++ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
++ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
++ unireg.cc uniques.cc sql_union.cc hash_filo.cc \
++ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
++ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
++ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
++ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
++ debug_sync.cc \
++ sql_tablespace.cc \
++ rpl_injector.cc my_user.c partition_info.cc \
++ sql_servers.cc event_parse_data.cc
+
+ # automake misses these
+ sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
+
+ # The following libraries should be included in libmysqld.a
+-INC_LIB= $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/vio/libvio.a \
+- @NDB_SCI_LIBS@ \
+- @mysql_plugin_libs@ \
+- $(yassl_inc_libs)
++INC_LIB= $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/vio/libvio.la \
++ @ZLIB_LIBS@ @LIBDL@ \
++ $(NDB_SCI_LIBS) \
++ $(mysql_embedded_plugin_libs) \
++ $(yassl_inc_libs)
+
+ if HAVE_YASSL
+-yassl_inc_libs= $(top_builddir)/extra/yassl/src/.libs/libyassl.a \
+- $(top_builddir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a
++yassl_inc_libs= $(top_builddir)/extra/yassl/src/libyassl.la \
++ $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la
+ endif
+
++libmysqld_la_SOURCES= $(libmysqld_sources)
++nodist_libmysqld_la_SOURCES= $(libmysqlsources) $(sqlsources)
++libmysqld_la_LIBADD = $(INC_LIB)
++
+ # Storage engine specific compilation options
+ ha_ndbcluster.o:ha_ndbcluster.cc
+ $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $<
+@@ -139,44 +135,6 @@ ha_myisam.o:ha_myisam.cc
+ ha_myisammrg.o:ha_myisammrg.cc
+ $(CXXCOMPILE) $(LM_CFLAGS) -c $<
+
+-#
+-# 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) $(libmysqld_a_DEPENDENCIES) $(storageobjects)
+-if DARWIN_MWCC
+- mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u` $(storageobjects)
+-else
+- -rm -f libmysqld.a
+- if test "$(host_os)" = "netware" ; \
+- then \
+- $(libmysqld_a_AR) libmysqld.a $(INC_LIB) libmysqld_int.a $(storageobjects); \
+- else \
+- current_dir=`pwd`; \
+- rm -rf tmp; mkdir tmp; \
+- (for arc in $(INC_LIB) ./libmysqld_int.a; do \
+- arpath=`echo $$arc|sed 's|[^/]*$$||'|sed 's|\.libs/$$||'`; \
+- artmp=`echo $$arc|sed 's|^.*/|tmp/lib-|'`; \
+- for F in `$(AR) t $$arc | grep -v SYMDEF`; do \
+- if test -e "$$arpath/$$F" ; then echo "$$arpath/$$F"; else \
+- mkdir $$artmp; cd $$artmp > /dev/null; \
+- $(AR) x ../../$$arc; \
+- cd $$current_dir > /dev/null; \
+- ls $$artmp/* | grep -v SYMDEF; \
+- continue 2; fi; done; \
+- done; echo $(libmysqld_a_DEPENDENCIES) ) | sort -u | xargs $(AR) cq libmysqld.a ; \
+- $(AR) r libmysqld.a $(storageobjects); \
+- $(RANLIB) libmysqld.a ; \
+- rm -rf tmp; \
+- fi
+-endif
+-
+ ## XXX: any time the client interface changes, we'll need to bump
+ ## the version info for libmysqld; however, it's possible for the
+ ## libmysqld interface to change without affecting the standard
+@@ -187,7 +145,7 @@ endif
+
+ BUILT_SOURCES = link_sources
+
+-CLEANFILES = $(BUILT_SOURCES)
++CLEANFILES = libmysqld.la
+
+ link_sources:
+ for f in $(sqlsources); do \
+@@ -208,20 +166,6 @@ link_sources:
+ @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \
+ fi ; \
+ done; \
+- if test -n "$(sqlstoragesources)" ; \
+- then \
+- for f in "$(sqlstoragesources)"; do \
+- rm -f "$$f"; \
+- @LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \
+- done; \
+- fi; \
+- if test -n "$(storagesources)" ; \
+- then \
+- rm -f $(storagesources); \
+- for f in $(storagesourceslinks); do \
+- @LN_CP_F@ $(top_srcdir)/$$f . ; \
+- done; \
+- fi; \
+ rm -f client_settings.h; \
+ @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h \
+ client_settings.h; \
+@@ -229,7 +173,7 @@ link_sources:
+
+
+ clean-local:
+- rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"`; \
++ rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"`; \
+ rm -f client_settings.h
+
+ # Don't update the files from bitkeeper
+Index: libmysqld/examples/Makefile.am
+===================================================================
+--- libmysqld/examples/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ libmysqld/examples/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -37,12 +37,16 @@ INCLUDES = -I$(top_builddir)/include -I$
+ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
+ $(openssl_includes)
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \
+- @NDB_SCI_LIBS@
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.la @LIBDL@ $(CXXLDFLAGS) \
++ @NDB_SCI_LIBS@ \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(ZLIB_LIBS)
+
+ mysqltest_embedded_LINK = $(CXXLINK)
+ nodist_mysqltest_embedded_SOURCES = mysqltest.cc
+-mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a \
++mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.la \
+ @MYSQLD_EXTRA_LDFLAGS@
+
+ nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+Index: mysys/Makefile.am
+===================================================================
+--- mysys/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ mysys/Makefile.am 2010-11-27 19:42:49.000000000 +0100
+@@ -18,10 +18,10 @@ MYSQLSHAREdir = $(pkgdatadir)
+ MYSQLBASEdir= $(prefix)
+ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include -I$(srcdir)
+-pkglib_LIBRARIES = libmysys.a
+-LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
++noinst_LTLIBRARIES = libmysys.la
++LDADD = libmysys.la $(top_builddir)/strings/libmystrings.la $(top_builddir)/dbug/libdbug.la
+ noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h
+-libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
++libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
+ mf_path.c mf_loadpath.c my_file.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
+ my_pread.c my_write.c my_getpagesize.c \
+@@ -57,18 +57,18 @@ if NEED_THREAD
+ # mf_keycache is used only in the server, so it is safe to leave the file
+ # out of the non-threaded library.
+ # In fact, it will currently not compile without thread support.
+-libmysys_a_SOURCES += mf_keycache.c
++libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c \
++ my_pthread.c my_thr_init.c mf_keycache.c
+ endif
+
+ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
+ thr_mutex.c thr_rwlock.c \
+ CMakeLists.txt mf_soundex.c \
+ my_conio.c my_wincond.c my_winthread.c
+-libmysys_a_LIBADD = @THREAD_LOBJECTS@
+-# test_dir_DEPENDENCIES= $(LIBRARIES)
+-# testhash_DEPENDENCIES= $(LIBRARIES)
+-# test_charset_DEPENDENCIES= $(LIBRARIES)
+-# charset2html_DEPENDENCIES= $(LIBRARIES)
++# test_dir_DEPENDENCIES= $(LTLIBRARIES)
++# testhash_DEPENDENCIES= $(LTLIBRARIES)
++# test_charset_DEPENDENCIES= $(LTLIBRARIES)
++# charset2html_DEPENDENCIES= $(LTLIBRARIES)
+ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
+ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+ -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
+@@ -78,8 +78,6 @@ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\"
+ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ @DEFS@
+
+-libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
+-
+ # I hope this always does the right thing. Otherwise this is only test programs
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+@@ -88,47 +86,47 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(
+ # which automaticly removes the object files you use to compile a final program
+ #
+
+-test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES)
++test_bitmap$(EXEEXT): my_bitmap.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS)
+
+-test_priority_queue$(EXEEXT): queues.c $(LIBRARIES)
++test_priority_queue$(EXEEXT): queues.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./queues.c $(LDADD) $(LIBS)
+
+-test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
++test_thr_alarm$(EXEEXT): thr_alarm.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_alarm.c
+
+-test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
++test_thr_lock$(EXEEXT): thr_lock.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_lock.c test_thr_lock.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_lock.c
+
+-test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
++test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
+ $(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
+ $(RM) -f test_vsnprintf.c
+
+-test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
++test_io_cache$(EXEEXT): mf_iocache.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.c
+
+-test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
++test_dir$(EXEEXT): test_dir.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
+
+-test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
++test_charset$(EXEEXT): test_charset.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
+
+-testhash$(EXEEXT): testhash.c $(LIBRARIES)
++testhash$(EXEEXT): testhash.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
+
+-test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
++test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
+ $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_gethwaddr.c
+
+-test_base64$(EXEEXT): base64.c $(LIBRARIES)
++test_base64$(EXEEXT): base64.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/base64.c ./test_base64.c
+ $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_base64.c
+Index: netware/BUILD/compile-linux-tools
+===================================================================
+--- netware/BUILD/compile-linux-tools.orig 2010-11-27 15:02:45.000000000 +0100
++++ netware/BUILD/compile-linux-tools 2010-11-27 15:02:49.000000000 +0100
+@@ -34,14 +34,14 @@ make
+ # Create mysql_version.h which was deleted my previous step
+ ./config.status include/mysql_version.h
+
+-(cd dbug; make libdbug.a)
+-(cd strings; make libmystrings.a)
+-(cd mysys; make libmysys.a)
+-(cd storage/heap; make libheap.a)
+-(cd vio; make libvio.a)
+-(cd regex; make libregex.a)
+-(cd storage/myisam; make libmyisam.a)
+-(cd storage/myisammrg; make libmyisammrg.a)
++(cd dbug; make libdbug.la)
++(cd strings; make libmystrings.la)
++(cd mysys; make libmysys.la)
++(cd storage/heap; make libheap.la)
++(cd vio; make libvio.la)
++(cd regex; make libregex.la)
++(cd storage/myisam; make libmyisam.la)
++(cd storage/myisammrg; make libmyisammrg.la)
+ (cd extra; make comp_err)
+ (cd libmysql; make conf_to_src)
+ (cd libmysql_r; make conf_to_src)
+Index: netware/Makefile.am
+===================================================================
+--- netware/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ netware/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,8 +16,8 @@
+
+ if HAVE_NETWARE
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I..
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
++ ../dbug/libdbug.la ../strings/libmystrings.la
+ bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
+ mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
+ mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
+Index: regex/Makefile.am
+===================================================================
+--- regex/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ regex/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-noinst_LIBRARIES = libregex.a
+-LDADD= libregex.a $(top_builddir)/strings/libmystrings.a
++noinst_LTLIBRARIES = libregex.la
++LDADD= libregex.la $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
+-libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
++libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
+ noinst_PROGRAMS = re
+ re_SOURCES = split.c debug.c main.c
+ re_LDFLAGS= @NOINST_LDFLAGS@
+Index: server-tools/instance-manager/Makefile.am
+===================================================================
+--- server-tools/instance-manager/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ server-tools/instance-manager/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -87,10 +87,10 @@ mysqlmanager_SOURCES= command.cc command
+ mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \
+ liboptions.la \
+ libnet.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+
+ EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
+Index: sql/Makefile.am
+===================================================================
+--- sql/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ sql/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,13 +32,13 @@ bin_PROGRAMS = mysql_tzinfo_to_sql
+ noinst_LTLIBRARIES= libndb.la \
+ udf_example.la
+
+-SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/strings/libmystrings.a
++SUPPORTING_LIBS = $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/strings/libmystrings.la
+ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
+-LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
++LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ $(openssl_libs) $(yassl_libs)
+ mysqld_LDADD = libndb.la \
+ @MYSQLD_EXTRA_LDFLAGS@ \
+ @pstack_libs@ \
+Index: storage/archive/Makefile.am
+===================================================================
+--- storage/archive/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/archive/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -33,7 +33,7 @@ DEFS = @DEFS@
+ noinst_HEADERS = ha_archive.h azlib.h
+ noinst_PROGRAMS = archive_test archive_reader
+
+-EXTRA_LTLIBRARIES = ha_archive.la
++EXTRA_LTLIBRARIES = libarchive.la ha_archive.la
+ pkgplugin_LTLIBRARIES = @plugin_archive_shared_target@
+ ha_archive_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_archive_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -41,26 +41,25 @@ ha_archive_la_CFLAGS = $(AM_CFLAGS) -DMY
+ ha_archive_la_SOURCES = ha_archive.cc azio.c
+
+
+-EXTRA_LIBRARIES = libarchive.a
+-noinst_LIBRARIES = @plugin_archive_static_target@
+-libarchive_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libarchive_a_CFLAGS = $(AM_CFLAGS)
+-libarchive_a_SOURCES = ha_archive.cc azio.c
++noinst_LTLIBRARIES = @plugin_archive_static_target@
++libarchive_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libarchive_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libarchive_la_SOURCES = ha_archive.cc azio.c
+
+
+ archive_test_SOURCES = archive_test.c azio.c
+ archive_test_CFLAGS = $(AM_CFLAGS)
+-archive_test_LDADD = $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a \
++archive_test_LDADD = $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @ZLIB_LIBS@
+ archive_test_LDFLAGS = @NOINST_LDFLAGS@
+
+ archive_reader_SOURCES = archive_reader.c azio.c
+ archive_reader_CFLAGS = $(AM_CFLAGS)
+-archive_reader_LDADD = $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a \
++archive_reader_LDADD = $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @ZLIB_LIBS@
+ archive_reader_LDFLAGS = @NOINST_LDFLAGS@
+
+Index: storage/archive/plug.in
+===================================================================
+--- storage/archive/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/archive/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,4 +1,4 @@
+ MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine],
+ [Archive Storage Engine], [max,max-no-ndb])
+-MYSQL_PLUGIN_STATIC(archive, [libarchive.a])
++MYSQL_PLUGIN_STATIC(archive, [libarchive.la])
+ MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la])
+Index: storage/blackhole/Makefile.am
+===================================================================
+--- storage/blackhole/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/blackhole/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_blackhole.h
+
+-EXTRA_LTLIBRARIES = ha_blackhole.la
++EXTRA_LTLIBRARIES = libblackhole.la ha_blackhole.la
+ pkgplugin_LTLIBRARIES = @plugin_blackhole_shared_target@
+ ha_blackhole_la_LDFLAGS=-module -rpath $(pkgplugindir)
+ ha_blackhole_la_CXXFLAGS=$(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,10 @@ ha_blackhole_la_CFLAGS= $(AM_CFLAGS) -DM
+ ha_blackhole_la_SOURCES=ha_blackhole.cc
+
+
+-EXTRA_LIBRARIES = libblackhole.a
+-noinst_LIBRARIES = @plugin_blackhole_static_target@
+-libblackhole_a_CXXFLAGS=$(AM_CXXFLAGS)
+-libblackhole_a_CFLAGS = $(AM_CFLAGS)
+-libblackhole_a_SOURCES= ha_blackhole.cc
++noinst_LTLIBRARIES = @plugin_blackhole_static_target@
++libblackhole_la_CXXFLAGS=$(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libblackhole_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libblackhole_la_SOURCES= ha_blackhole.cc
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/blackhole/plug.in
+===================================================================
+--- storage/blackhole/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/blackhole/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,6 +1,6 @@
+ MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine],
+ [Basic Write-only Read-never tables], [max,max-no-ndb])
+ MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole])
+-MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a])
++MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.la])
+ MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la])
+
+Index: storage/csv/Makefile.am
+===================================================================
+--- storage/csv/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/csv/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -29,16 +29,15 @@ LDADD =
+ DEFS = @DEFS@
+ noinst_HEADERS = ha_tina.h transparent_file.h
+
+-EXTRA_LTLIBRARIES = ha_csv.la
++EXTRA_LTLIBRARIES = libcsv.la ha_csv.la
+ pkglib_LTLIBRARIES = @plugin_csv_shared_target@
+ ha_csv_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
+ ha_csv_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_PLUGIN
+ ha_csv_la_SOURCES = transparent_file.cc ha_tina.cc
+
+-EXTRA_LIBRARIES = libcsv.a
+-noinst_LIBRARIES = @plugin_csv_static_target@
+-libcsv_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libcsv_a_SOURCES = transparent_file.cc ha_tina.cc
++noinst_LTLIBRARIES = @plugin_csv_static_target@
++libcsv_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libcsv_la_SOURCES = transparent_file.cc ha_tina.cc
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+ # Don't update the files from bitkeeper
+Index: storage/csv/plug.in
+===================================================================
+--- storage/csv/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/csv/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,5 +1,5 @@
+ MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine],
+ [Stores tables in text CSV format])
+ MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv])
+-MYSQL_PLUGIN_STATIC(csv, [libcsv.a])
++MYSQL_PLUGIN_STATIC(csv, [libcsv.la])
+ MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging
+Index: storage/example/Makefile.am
+===================================================================
+--- storage/example/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/example/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_example.h
+
+-EXTRA_LTLIBRARIES = ha_example.la
++EXTRA_LTLIBRARIES = libexample.la ha_example.la
+ pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
+ ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,10 @@ ha_example_la_CFLAGS = $(AM_CFLAGS) -DMY
+ ha_example_la_SOURCES = ha_example.cc
+
+
+-EXTRA_LIBRARIES = libexample.a
+-noinst_LIBRARIES = @plugin_example_static_target@
+-libexample_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libexample_a_CFLAGS = $(AM_CFLAGS)
+-libexample_a_SOURCES= ha_example.cc
++noinst_LTLIBRARIES = @plugin_example_static_target@
++libexample_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libexample_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libexample_la_SOURCES= ha_example.cc
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/federated/Makefile.am
+===================================================================
+--- storage/federated/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/federated/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_federated.h
+
+-EXTRA_LTLIBRARIES = ha_federated.la
++EXTRA_LTLIBRARIES = libfederated.la libfederated_embedded.la ha_federated.la
+ pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@
+ ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_federated_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,14 @@ ha_federated_la_CFLAGS = $(AM_CFLAGS) -D
+ ha_federated_la_SOURCES = ha_federated.cc $(top_srcdir)/mysys/string.c
+
+
+-EXTRA_LIBRARIES = libfederated.a
+-noinst_LIBRARIES = @plugin_federated_static_target@
+-libfederated_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libfederated_a_CFLAGS = $(AM_CFLAGS)
+-libfederated_a_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
++noinst_LTLIBRARIES = @plugin_federated_static_target@ @plugin_federated_embedded_static_target@
++libfederated_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libfederated_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libfederated_la_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
++
++libfederated_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++libfederated_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@
++libfederated_embedded_la_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/federated/plug.in
+===================================================================
+--- storage/federated/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/federated/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,5 +1,4 @@
+ MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine],
+ [Connects to tables on remote MySQL servers], [max,max-no-ndb])
+-MYSQL_PLUGIN_STATIC(federated, [libfederated.a])
++MYSQL_PLUGIN_STATIC(federated, [libfederated.la], [libfederated_embedded.la])
+ MYSQL_PLUGIN_DYNAMIC(federated, [ha_federated.la])
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federated, [ha_federated.cc])
+Index: storage/heap/Makefile.am
+===================================================================
+--- storage/heap/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/heap/Makefile.am 2010-11-27 19:44:23.000000000 +0100
+@@ -26,27 +26,40 @@ WRAPLIBS=
+ LDADD =
+
+ DEFS = @DEFS@
+-pkglib_LIBRARIES = libheap.a
++noinst_LTLIBRARIES = libheap.la libheap_s.la libheap_common.la \
++ @plugin_heap_embedded_static_target@
++EXTRA_LTLIBRARIES = libheap_embedded.la
++
+ noinst_PROGRAMS = hp_test1 hp_test2
+-noinst_LIBRARIES = libheap.a
+ hp_test1_LDFLAGS = @NOINST_LDFLAGS@
+-hp_test1_LDADD = libheap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++hp_test1_LDADD = libheap.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+ hp_test2_LDFLAGS = @NOINST_LDFLAGS@
+-hp_test2_LDADD = libheap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++hp_test2_LDADD = libheap.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = heapdef.h ha_heap.h
+-libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
++libheap_common_la_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
+ hp_rrnd.c hp_scan.c hp_update.c hp_write.c hp_delete.c \
+ hp_rsame.c hp_create.c hp_rename.c hp_rfirst.c \
+ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \
+ hp_rkey.c hp_block.c \
+- ha_heap.cc \
+ hp_hash.c _check.c _rectest.c hp_static.c
++libheap_common_la_CFLAGS = $(AM_LDFLAGS) @plugin_static_if_no_embedded@
++
++libheap_s_la_SOURCES = ha_heap.cc
++libheap_s_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libheap_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libheap_s_la_LIBADD = libheap_common.la
++libheap_embedded_la_SOURCES = ha_heap.cc
++libheap_embedded_la_LIBADD = libheap_common.la
++libheap_embedded_la_CXXFLAGS = @plugin_embedded_defs@
++libheap_la_SOURCES =
++libheap_la_LIBADD = libheap_s.la
++libheap_la_LDFLAGS = -static
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/heap/plug.in
+===================================================================
+--- storage/heap/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/heap/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,6 @@
+ MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine],
+ [Volatile memory based tables])
+ MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap])
+-MYSQL_PLUGIN_STATIC(heap, [libheap.a])
++MYSQL_PLUGIN_STATIC(heap, [libheap_s.la], [libheap_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(heap, [ha_heap.cc])
+
+Index: storage/innobase/Makefile.am
+===================================================================
+--- storage/innobase/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innobase/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -15,21 +15,20 @@
+
+ # Process this file with automake to create Makefile.in
+
+-MYSQLDATAdir= $(localstatedir)
+-MYSQLSHAREdir= $(pkgdatadir)
+-MYSQLBASEdir= $(prefix)
+-MYSQLLIBdir= $(pkglibdir)
+-pkgplugindir= $(pkglibdir)/plugin
+-INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
++MYSQLDATAdir = $(localstatedir)
++MYSQLSHAREdir = $(pkgdatadir)
++MYSQLBASEdir = $(prefix)
++MYSQLLIBdir = $(pkglibdir)
++pkgplugindir = $(pkglibdir)/plugin
++INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex \
+ -I$(top_srcdir)/storage/innobase/include \
+ -I$(top_srcdir)/sql \
+ -I$(srcdir)
+
+-DEFS= @DEFS@
++DEFS= @DEFS@
+
+-
+-noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
++noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
+ include/btr0cur.h include/btr0cur.ic \
+ include/btr0pcur.h include/btr0pcur.ic \
+ include/btr0sea.h include/btr0sea.ic \
+@@ -122,9 +121,8 @@ noinst_HEADERS= include/btr0btr.h inclu
+ include/ut0list.ic include/ut0wqueue.h \
+ include/ha_prototypes.h handler/ha_innodb.h
+
+-EXTRA_LIBRARIES= libinnobase.a
+-noinst_LIBRARIES= @plugin_innobase_static_target@
+-libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
++noinst_LTLIBRARIES = @plugin_innobase_static_target@
++libinnobase_la_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
+ btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \
+ buf/buf0lru.c buf/buf0rea.c data/data0data.c \
+ data/data0type.c dict/dict0boot.c \
+@@ -156,18 +154,18 @@ libinnobase_a_SOURCES= btr/btr0btr.c btr
+ ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
+ handler/ha_innodb.cc
+
+-libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
+-libinnobase_a_CFLAGS= $(AM_CFLAGS)
++libinnobase_la_CXXFLAGS = $(AM_CXXFLAGS)
++libinnobase_la_CFLAGS = $(AM_CFLAGS)
+
+-EXTRA_LTLIBRARIES= ha_innodb.la
+-pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
++EXTRA_LTLIBRARIES = libinnobase.la ha_innodb.la
++pkgplugin_LTLIBRARIES = @plugin_innobase_shared_target@
+
+-ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
+-ha_innodb_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
++ha_innodb_la_LDFLAGS = -module -rpath $(pkgplugindir)
++ha_innodb_la_CXXFLAGS = $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
++ha_innodb_la_CFLAGS = $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
++ha_innodb_la_SOURCES = $(libinnobase_la_SOURCES)
+
+-EXTRA_DIST= CMakeLists.txt plug.in \
++EXTRA_DIST = CMakeLists.txt plug.in \
+ pars/make_bison.sh pars/make_flex.sh \
+ pars/pars0grm.y pars/pars0lex.l
+
+Index: storage/innobase/plug.in
+===================================================================
+--- storage/innobase/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innobase/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine],
+ [Transactional Tables using InnoDB], [max,max-no-ndb])
+ MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase])
+-MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a])
++MYSQL_PLUGIN_STATIC(innobase, [libinnobase.la])
+ MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la])
+ MYSQL_PLUGIN_ACTIONS(innobase, [
+ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"])
+Index: storage/innodb_plugin/Makefile.am
+===================================================================
+--- storage/innodb_plugin/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innodb_plugin/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -228,9 +228,8 @@ noinst_HEADERS= \
+ include/ut0wqueue.h \
+ mem/mem0dbg.c
+
+-EXTRA_LIBRARIES= libinnobase.a
+-noinst_LIBRARIES= @plugin_innodb_plugin_static_target@
+-libinnobase_a_SOURCES= \
++noinst_LTLIBRARIES= @plugin_innodb_plugin_static_target@
++libinnobase_la_SOURCES= \
+ btr/btr0btr.c \
+ btr/btr0cur.c \
+ btr/btr0pcur.c \
+@@ -325,16 +324,16 @@ libinnobase_a_SOURCES= \
+ ut/ut0vec.c \
+ ut/ut0wqueue.c
+
+-libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
+-libinnobase_a_CFLAGS= $(AM_CFLAGS)
++libinnobase_la_CXXFLAGS= $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libinnobase_la_CFLAGS= $(AM_CFLAGS) @plugin_static_if_no_embedded@
+
+-EXTRA_LTLIBRARIES= ha_innodb_plugin.la
++EXTRA_LTLIBRARIES= libinnobase.la ha_innodb_plugin.la
+ pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@
+
+ ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir)
+ ha_innodb_plugin_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES)
++ha_innodb_plugin_la_SOURCES= $(libinnobase_la_SOURCES)
+
+ EXTRA_DIST= CMakeLists.txt plug.in \
+ pars/make_bison.sh pars/make_flex.sh \
+Index: storage/myisam/Makefile.am
+===================================================================
+--- storage/myisam/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisam/Makefile.am 2010-11-27 19:44:01.000000000 +0100
+@@ -30,60 +30,63 @@ DEFS = @DEFS@
+ EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in
+ pkgdata_DATA = mi_test_all mi_test_all.res
+
+-pkglib_LIBRARIES = libmyisam.a
++noinst_LTLIBRARIES = libmyisam.la libmyisam_common.la libmyisam_s.la \
++ @plugin_myisam_embedded_static_target@
++EXTRA_LTLIBRARIES = libmyisam_embedded.la
++
+ bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
+-myisamchk_DEPENDENCIES= $(LIBRARIES)
+-myisamchk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-myisamlog_DEPENDENCIES= $(LIBRARIES)
+-myisamlog_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-myisampack_DEPENDENCIES=$(LIBRARIES)
+-myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
++myisamchk_DEPENDENCIES= $(LTLIBRARIES)
++myisamchk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++myisamlog_DEPENDENCIES= $(LTLIBRARIES)
++myisamlog_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++myisampack_DEPENDENCIES=$(LTLIBRARIES)
++myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
+ noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
+ noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \
+ fulltext.h ftdefs.h ft_test1.h ft_eval.h \
+ ha_myisam.h
+-mi_test1_DEPENDENCIES= $(LIBRARIES)
+-mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-mi_test2_DEPENDENCIES= $(LIBRARIES)
+-mi_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-mi_test3_DEPENDENCIES= $(LIBRARIES)
+-mi_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-#ft_test1_DEPENDENCIES= $(LIBRARIES)
+-#ft_eval_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-rt_test_DEPENDENCIES= $(LIBRARIES)
+-rt_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-sp_test_DEPENDENCIES= $(LIBRARIES)
+-sp_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
++mi_test1_DEPENDENCIES= $(LTLIBRARIES)
++mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++mi_test2_DEPENDENCIES= $(LTLIBRARIES)
++mi_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++mi_test3_DEPENDENCIES= $(LTLIBRARIES)
++mi_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++#ft_test1_DEPENDENCIES= $(LTLIBRARIES)
++#ft_eval_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++rt_test_DEPENDENCIES= $(LTLIBRARIES)
++rt_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++sp_test_DEPENDENCIES= $(LTLIBRARIES)
++sp_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++libmyisam_common_la_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
+ mi_rnext.c mi_rnext_same.c \
+ mi_search.c mi_page.c mi_key.c mi_locking.c \
+ mi_rrnd.c mi_scan.c mi_cache.c \
+@@ -98,8 +101,23 @@ libmyisam_a_SOURCES = mi_open.c mi_extra
+ mi_keycache.c mi_preload.c \
+ ft_parser.c ft_stopwords.c ft_static.c \
+ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
+- ha_myisam.cc \
+ rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
++libmyisam_common_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libmyisam_s_la_SOURCES = ha_myisam.cc
++libmyisam_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libmyisam_s_la_LIBADD = libmyisam_common.la
++libmyisam_embedded_la_SOURCES = ha_myisam.cc
++libmyisam_embedded_la_LIBADD = libmyisam_common.la
++libmyisam_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++# libmyisam references symbols inside mysqld.
++# This means we cannot use it as shared library, as these references causes
++# undefined symbol errors at load time.
++# But a static library works (as long as those parts that references
++# problematic symbols are not linked).
++libmyisam_la_LDFLAGS = -static
++libmyisam_la_SOURCES =
++libmyisam_la_LIBADD = libmyisam_s.la
++
+ CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all rt_test.MY? sp_test.MY?
+
+ # Move to automake rules ?
+Index: storage/myisam/plug.in
+===================================================================
+--- storage/myisam/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisam/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,5 @@
+ MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine],
+ [Traditional non-transactional MySQL tables])
+ MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam])
+-MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a])
++MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(myisam) dnl Default
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisam, [ha_myisam.cc])
+-
+Index: storage/myisammrg/Makefile.am
+===================================================================
+--- storage/myisammrg/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisammrg/Makefile.am 2010-11-27 19:43:39.000000000 +0100
+@@ -26,16 +26,28 @@ WRAPLIBS=
+ LDADD =
+
+ DEFS = @DEFS@
+-pkglib_LIBRARIES = libmyisammrg.a
++noinst_LTLIBRARIES = libmyisammrg.la libmyisammrg_s.la libmyisammrg_common.la \
++ @plugin_myisammrg_embedded_static_target@
++EXTRA_LTLIBRARIES = libmyisammrg_embedded.la
+ noinst_HEADERS = myrg_def.h ha_myisammrg.h
+-noinst_LIBRARIES = libmyisammrg.a
+-libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
++libmyisammrg_common_la_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
+ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
+ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
+ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
+ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \
+- ha_myisammrg.cc \
+ myrg_rnext_same.c myrg_records.c
++libmyisammrg_common_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libmyisammrg_s_la_SOURCES = ha_myisammrg.cc
++libmyisammrg_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libmyisammrg_s_la_LIBADD = libmyisammrg_common.la
++libmyisammrg_embedded_la_SOURCES = ha_myisammrg.cc
++libmyisammrg_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@
++libmyisammrg_embedded_la_LIBADD = libmyisammrg_common.la
++libmyisammrg_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++libmyisammrg_la_SOURCES =
++libmyisammrg_la_LIBADD = libmyisammrg_s.la
++libmyisammrg_la_LDFLAGS = -static
++
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/myisammrg/plug.in
+===================================================================
+--- storage/myisammrg/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisammrg/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,6 +1,5 @@
+ MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine],
+ [Merge multiple MySQL tables into one])
+ MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg])
+-MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a])
++MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg_s.la], [libmyisammrg_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(myisammrg)
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisammrg, [ha_myisammrg.cc])
+Index: storage/ndb/src/common/util/Makefile.am
+===================================================================
+--- storage/ndb/src/common/util/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/common/util/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -31,9 +31,9 @@ EXTRA_PROGRAMS = testBitmask
+ testBitmask_SOURCES = testBitmask.cpp
+ testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testBitmask.cpp : Bitmask.cpp
+ rm -f testBitmask.cpp
+Index: storage/ndb/config/type_ndbapitest.mk.am
+===================================================================
+--- storage/ndb/config/type_ndbapitest.mk.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/type_ndbapitest.mk.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,19 +13,20 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-LDADD += $(top_builddir)/storage/ndb/test/src/libNDBT.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++LDADD += $(top_builddir)/storage/ndb/test/src/libNDBT.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+-INCLUDES += -I$(top_srcdir) \
+- -I$(top_builddir)/include \
+- -I$(top_builddir)/storage/ndb/include \
+- -I$(top_srcdir)/include \
+- -I$(top_srcdir)/storage/ndb/include \
+- -I$(top_srcdir)/storage/ndb/include/ndbapi \
+- -I$(top_srcdir)/storage/ndb/include/util \
+- -I$(top_srcdir)/storage/ndb/include/portlib \
+- -I$(top_srcdir)/storage/ndb/test/include \
+- -I$(top_srcdir)/storage/ndb/include/mgmapi
++INCLUDES += -I$(top_srcdir) \
++ -I$(top_builddir)/include \
++ -I$(top_builddir)/storage/ndb/include \
++ -I$(top_srcdir)/include \
++ -I$(top_srcdir)/storage/ndb/include \
++ -I$(top_srcdir)/storage/ndb/include/ndbapi \
++ -I$(top_srcdir)/storage/ndb/include/util \
++ -I$(top_srcdir)/storage/ndb/include/portlib \
++ -I$(top_srcdir)/storage/ndb/test/include \
++ -I$(top_srcdir)/storage/ndb/include/mgmapi
+Index: storage/ndb/config/type_ndbapitools.mk.am
+===================================================================
+--- storage/ndb/config/type_ndbapitools.mk.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/type_ndbapitools.mk.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,20 +13,21 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-LDADD += \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ @ZLIB_LIBS@
++LDADD += \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+-INCLUDES += -I$(srcdir) \
+- -I$(top_builddir)/include \
+- -I$(top_builddir)/storage/ndb/include \
+- -I$(top_srcdir)/include \
+- -I$(top_srcdir)/storage/ndb/include \
+- -I$(top_srcdir)/storage/ndb/include/ndbapi \
+- -I$(top_srcdir)/storage/ndb/include/util \
+- -I$(top_srcdir)/storage/ndb/include/portlib \
+- -I$(top_srcdir)/storage/ndb/test/include \
+- -I$(top_srcdir)/storage/ndb/include/mgmapi \
+- -I$(top_srcdir)/storage/ndb/include/kernel
++INCLUDES += -I$(srcdir) \
++ -I$(top_builddir)/include \
++ -I$(top_builddir)/storage/ndb/include \
++ -I$(top_srcdir)/include \
++ -I$(top_srcdir)/storage/ndb/include \
++ -I$(top_srcdir)/storage/ndb/include/ndbapi \
++ -I$(top_srcdir)/storage/ndb/include/util \
++ -I$(top_srcdir)/storage/ndb/include/portlib \
++ -I$(top_srcdir)/storage/ndb/test/include \
++ -I$(top_srcdir)/storage/ndb/include/mgmapi \
++ -I$(top_srcdir)/storage/ndb/include/kernel
+Index: storage/ndb/config/win-libraries
+===================================================================
+--- storage/ndb/config/win-libraries.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/win-libraries 2010-11-27 15:02:49.000000000 +0100
+@@ -21,7 +21,7 @@ do
+ # the same goes for mysys and strings
+ lib=$i
+ case $i in
+- *libdbug.a | *libmysys.a | *libmystrings.a)
++ *libdbug.la | *libmysys.la | *libmystrings.la)
+ lib=`echo $i | sed s'!dbug\/lib!!' | sed 's!mysys\/lib!!' | sed 's!strings\/libmy!!'`
+ echo "Changing from $i to $lib"
+ ;;
+Index: storage/ndb/src/cw/cpcd/Makefile.am
+===================================================================
+--- storage/ndb/src/cw/cpcd/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/cw/cpcd/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -19,9 +19,9 @@ ndb_cpcd_SOURCES = main.cpp CPCD.cpp Pro
+
+ LDADD_LOC = \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_util.mk.am
+Index: storage/ndb/src/kernel/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -53,9 +53,10 @@ LDADD += \
+ $(top_builddir)/storage/ndb/src/mgmapi/libmgmapi.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+ windoze-dsp: ndbd.dsp
+
+Index: storage/ndb/src/kernel/blocks/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -18,7 +18,7 @@ SUBDIRS = \
+ dbdih \
+ dblqh \
+ dbtup \
+- backup
++ backup
+
+ noinst_LIBRARIES = libblocks.a
+
+@@ -56,10 +56,10 @@ libblocks_a_SOURCES = tsman.cpp lgman.cp
+ EXTRA_PROGRAMS = ndb_print_file
+ ndb_print_file_SOURCES = print_file.cpp diskpage.cpp dbtup/tuppage.cpp
+ ndb_print_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+Index: storage/ndb/src/kernel/blocks/backup/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/backup/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/backup/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -17,9 +17,9 @@ ndbtools_PROGRAMS = ndb_print_backup_fil
+ ndb_print_backup_file_SOURCES = read.cpp
+ ndb_print_backup_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+Index: storage/ndb/src/kernel/blocks/dbdict/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbdict/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbdict/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -19,17 +19,17 @@ include $(top_srcdir)/storage/ndb/config
+ LDADD += \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ ndbtools_PROGRAMS = ndb_print_schema_file
+ ndb_print_schema_file_SOURCES = printSchemaFile.cpp
+ ndb_print_schema_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/blocks/dbdih/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbdih/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbdih/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -17,9 +17,9 @@ ndbtools_PROGRAMS = ndb_print_sys_file
+ ndb_print_sys_file_SOURCES = printSysfile.cpp
+ ndb_print_sys_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+Index: storage/ndb/src/kernel/blocks/dblqh/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dblqh/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dblqh/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -23,9 +23,9 @@ include $(top_srcdir)/storage/ndb/config
+
+ ndbd_redo_log_reader_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/blocks/dbtup/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbtup/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbtup/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -20,9 +20,9 @@ EXTRA_PROGRAMS = test_varpage
+ test_varpage_SOURCES = test_varpage.cpp tuppage.cpp
+ test_varpage_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/vm/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/vm/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/vm/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -21,22 +21,22 @@
+ noinst_LIBRARIES = libkernel.a
+
+ libkernel_a_SOURCES = \
+- SimulatedBlock.cpp \
+- FastScheduler.cpp \
+- TimeQueue.cpp \
+- VMSignal.cpp \
+- ThreadConfig.cpp \
+- TransporterCallback.cpp \
+- Emulator.cpp \
+- Configuration.cpp \
+- WatchDog.cpp \
+- SimplePropertiesSection.cpp \
+- SectionReader.cpp \
+- Mutex.cpp SafeCounter.cpp \
+- Rope.cpp \
+- ndbd_malloc.cpp ndbd_malloc_impl.cpp \
+- Pool.cpp WOPool.cpp RWPool.cpp \
+- DynArr256.cpp
++ SimulatedBlock.cpp \
++ FastScheduler.cpp \
++ TimeQueue.cpp \
++ VMSignal.cpp \
++ ThreadConfig.cpp \
++ TransporterCallback.cpp \
++ Emulator.cpp \
++ Configuration.cpp \
++ WatchDog.cpp \
++ SimplePropertiesSection.cpp \
++ SectionReader.cpp \
++ Mutex.cpp SafeCounter.cpp \
++ Rope.cpp \
++ ndbd_malloc.cpp ndbd_malloc_impl.cpp \
++ Pool.cpp WOPool.cpp RWPool.cpp \
++ DynArr256.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
+
+@@ -49,40 +49,40 @@ include $(top_srcdir)/storage/ndb/config
+ windoze-dsp: libkernel.dsp
+
+ libkernel.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
+
+ EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256
+ ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST
+ ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp
+ ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ bench_pool_SOURCES = bench_pool.cpp
+-bench_pool_LDFLAGS = @ndb_bin_am_ldflags@\
+- libkernel.a ../error/liberror.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++bench_pool_LDFLAGS = @ndb_bin_am_ldflags@ \
++ libkernel.a ../error/liberror.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testDynArr256_CXXFLAGS = -DUNIT_TEST
+ testDynArr256_SOURCES = DynArr256.cpp
+ testDynArr256_LDFLAGS = @ndb_bin_am_ldflags@ \
+- libkernel.a ../error/liberror.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ libkernel.a ../error/liberror.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+Index: storage/ndb/src/mgmclient/Makefile.am
+===================================================================
+--- storage/ndb/src/mgmclient/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/mgmclient/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -18,12 +18,11 @@ ndbtools_PROGRAMS = ndb_mgm
+
+ libndbmgmclient_la_SOURCES = CommandInterpreter.cpp
+ libndbmgmclient_la_LIBADD = ../mgmapi/libmgmapi.la \
+- ../common/logger/liblogger.la \
+- ../common/portlib/libportlib.la \
+- ../common/util/libgeneral.la \
+- ../common/portlib/libportlib.la \
+- ../common/debugger/libtrace.la
+-
++ ../common/logger/liblogger.la \
++ ../common/portlib/libportlib.la \
++ ../common/util/libgeneral.la \
++ ../common/portlib/libportlib.la \
++ ../common/debugger/libtrace.la
+
+ ndb_mgm_SOURCES = main.cpp
+
+@@ -34,13 +33,13 @@ INCLUDES += -I$(top_srcdir)/storage/ndb/
+ -I$(top_srcdir)/storage/ndb/src/common/mgmcommon
+
+ LDADD_LOC = $(noinst_LTLIBRARIES) \
+- ../common/portlib/libportlib.la \
+- @readline_link@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- @TERMCAP_LIB@ @NDB_SCI_LIBS@
++ ../common/portlib/libportlib.la \
++ @readline_link@ \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ @TERMCAP_LIB@ @NDB_SCI_LIBS@
+
+ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+
+@@ -50,25 +49,25 @@ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+ windoze-dsp: ndb_mgm.dsp libndbmgmclient.dsp
+
+ ndb_mgm.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-prg.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbtools_PROGRAMS)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgm_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-prg.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbtools_PROGRAMS)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgm_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
+
+ libndbmgmclient.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbmgmclient_la_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbmgmclient_la_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB
+Index: storage/ndb/src/mgmsrv/Makefile.am
+===================================================================
+--- storage/ndb/src/mgmsrv/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/mgmsrv/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -22,35 +22,35 @@ MYSQLCLUSTERdir= .
+ ndbbin_PROGRAMS = ndb_mgmd
+
+ ndb_mgmd_SOURCES = \
+- MgmtSrvr.cpp \
+- MgmtSrvrGeneralSignalHandling.cpp \
+- main.cpp \
+- Services.cpp \
+- convertStrToInt.cpp \
+- SignalQueue.cpp \
+- MgmtSrvrConfig.cpp \
+- ConfigInfo.cpp \
+- InitConfigFileParser.cpp \
+- Config.cpp
++ MgmtSrvr.cpp \
++ MgmtSrvrGeneralSignalHandling.cpp \
++ main.cpp \
++ Services.cpp \
++ convertStrToInt.cpp \
++ SignalQueue.cpp \
++ MgmtSrvrConfig.cpp \
++ ConfigInfo.cpp \
++ InitConfigFileParser.cpp \
++ Config.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/ndbapi \
+- -I$(top_srcdir)/storage/ndb/src/mgmapi \
+- -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \
+- -I$(top_srcdir)/storage/ndb/src/mgmclient
++ -I$(top_srcdir)/storage/ndb/src/mgmapi \
++ -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \
++ -I$(top_srcdir)/storage/ndb/src/mgmclient
+
+ LDADD_LOC = $(top_builddir)/storage/ndb/src/mgmclient/CommandInterpreter.lo \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- @readline_link@ \
+- @NDB_SCI_LIBS@ \
+- @TERMCAP_LIB@
+-
+-DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+- -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\""
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ @readline_link@ \
++ @NDB_SCI_LIBS@ \
++ @TERMCAP_LIB@
++
++DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
++ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
++ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
++ -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\""
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
+@@ -63,13 +63,13 @@ ndb_mgmd_LDFLAGS = @ndb_bin_am_ldflags@
+ windoze-dsp: ndb_mgmd.dsp
+
+ ndb_mgmd.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-prg.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-prg.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
+Index: storage/ndb/src/ndbapi/Makefile.am
+===================================================================
+--- storage/ndb/src/ndbapi/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/ndbapi/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -22,41 +22,42 @@ ndberror_check_SOURCES = ndberror_check.
+ noinst_LTLIBRARIES = libndbapi.la
+
+ libndbapi_la_SOURCES = \
+- TransporterFacade.cpp \
+- ClusterMgr.cpp \
+- Ndb.cpp \
+- NdbPoolImpl.cpp \
+- NdbPool.cpp \
+- Ndblist.cpp \
+- Ndbif.cpp \
+- Ndbinit.cpp \
+- Ndberr.cpp \
+- ndberror.c \
+- NdbErrorOut.cpp \
+- NdbTransaction.cpp \
+- NdbTransactionScan.cpp \
+- NdbOperation.cpp \
+- NdbOperationSearch.cpp \
+- NdbOperationScan.cpp \
+- NdbOperationInt.cpp \
+- NdbOperationDefine.cpp \
+- NdbOperationExec.cpp \
+- NdbScanOperation.cpp NdbScanFilter.cpp \
+- NdbIndexOperation.cpp \
+- NdbEventOperation.cpp \
+- NdbEventOperationImpl.cpp \
+- NdbApiSignal.cpp \
+- NdbRecAttr.cpp \
+- NdbUtil.cpp \
+- NdbReceiver.cpp \
+- NdbDictionary.cpp \
+- NdbDictionaryImpl.cpp \
+- DictCache.cpp \
+- ndb_cluster_connection.cpp \
+- NdbBlob.cpp \
+- NdbIndexStat.cpp \
+- SignalSender.cpp \
+- ObjectMap.cpp
++ TransporterFacade.cpp \
++ ClusterMgr.cpp \
++ Ndb.cpp \
++ NdbPoolImpl.cpp \
++ NdbPool.cpp \
++ Ndblist.cpp \
++ Ndbif.cpp \
++ Ndbinit.cpp \
++ Ndberr.cpp \
++ ndberror.c \
++ NdbErrorOut.cpp \
++ NdbTransaction.cpp \
++ NdbTransactionScan.cpp \
++ NdbOperation.cpp \
++ NdbOperationSearch.cpp \
++ NdbOperationScan.cpp \
++ NdbOperationInt.cpp \
++ NdbOperationDefine.cpp \
++ NdbOperationExec.cpp \
++ NdbScanOperation.cpp \
++ NdbScanFilter.cpp \
++ NdbIndexOperation.cpp \
++ NdbEventOperation.cpp \
++ NdbEventOperationImpl.cpp \
++ NdbApiSignal.cpp \
++ NdbRecAttr.cpp \
++ NdbUtil.cpp \
++ NdbReceiver.cpp \
++ NdbDictionary.cpp \
++ NdbDictionaryImpl.cpp \
++ DictCache.cpp \
++ ndb_cluster_connection.cpp \
++ NdbBlob.cpp \
++ NdbIndexStat.cpp \
++ SignalSender.cpp \
++ ObjectMap.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
+
+@@ -67,9 +68,10 @@ include $(top_srcdir)/storage/ndb/config
+ include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
+
+ ndberror_check_LDFLAGS = \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+@@ -77,13 +79,13 @@ ndberror_check_LDFLAGS = \
+ windoze-dsp: libndbapi.dsp
+
+ libndbapi.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbapi_la_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbapi_la_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
+Index: storage/ndb/test/run-test/Makefile.am
+===================================================================
+--- storage/ndb/test/run-test/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/test/run-test/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -34,9 +34,9 @@ atrt_SOURCES = main.cpp setup.cpp files.
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/test/include
+ LDADD_LOC = $(top_builddir)/storage/ndb/test/src/libNDBT.a \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ atrt_CXXFLAGS = -I$(top_srcdir)/ndb/src/mgmapi \
+ -I$(top_srcdir)/ndb/src/mgmsrv \
+Index: strings/Makefile.am
+===================================================================
+--- strings/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ strings/Makefile.am 2010-11-27 19:42:38.000000000 +0100
+@@ -16,7 +16,7 @@
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmystrings.a
++noinst_LTLIBRARIES = libmystrings.la
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+@@ -37,7 +37,7 @@ CSRCS = strxmov.c bmove_upp.c strappend
+ endif
+ endif
+
+-libmystrings_a_SOURCES = $(ASRCS) $(CSRCS)
++libmystrings_la_SOURCES = $(ASRCS) $(CSRCS)
+ noinst_PROGRAMS = conf_to_src
+ CLEANFILES = str_test uctypedump test_decimal
+ # Default charset definitions
+@@ -56,9 +56,9 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c
+ t_ctype.h my_strchr.c CMakeLists.txt \
+ CHARSET_INFO.txt
+
+-libmystrings_a_LIBADD=
+-conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c
+-conf_to_src_LDADD=
++libmystrings_la_LIBADD=
++conf_to_src_SOURCES = conf_to_src.c
++conf_to_src_LDADD = libmystrings.la
+ #force static linking of conf_to_src - essential when linking against
+ #custom installation of libc
+ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+@@ -69,15 +69,15 @@ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+-str_test: str_test.c $(pkglib_LIBRARIES)
+- $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LIBRARIES)
++str_test: str_test.c $(pkglib_LTLIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LTLIBRARIES)
+
+ uctypedump: uctypedump.c
+ $(LINK) $(INCLUDES) $(srcdir)/uctypedump.c
+
+ test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES)
+ $(CP) $(srcdir)/decimal.c ./test_decimal.c
+- $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LTLIBRARIES)
+ $(RM) -f ./test_decimal.c
+
+ # Don't update the files from bitkeeper
+Index: unittest/unit.pl
+===================================================================
+--- unittest/unit.pl.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/unit.pl 2010-11-27 15:02:49.000000000 +0100
+@@ -55,7 +55,7 @@ sub _find_test_files (@) {
+ my @dirs = @_;
+ my @files;
+ find sub {
+- $File::Find::prune = 1 if /^SCCS$/;
++ $File::Find::prune = 1 if /^(SCCS|\.libs)$/;
+ push(@files, $File::Find::name) if -x _ && /-t\z/;
+ }, @dirs;
+ return @files;
+Index: unittest/mysys/Makefile.am
+===================================================================
+--- unittest/mysys/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/mysys/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,15 +13,16 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
+-AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
++AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
++AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
+
+-LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+-noinst_PROGRAMS = bitmap-t base64-t
++noinst_PROGRAMS = bitmap-t base64-t
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: unittest/strings/Makefile.am
+===================================================================
+--- unittest/strings/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/strings/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,10 +16,11 @@
+ AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
+ AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
+
+-LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+ noinst_PROGRAMS = strings-t
+
+Index: vio/Makefile.am
+===================================================================
+--- vio/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ vio/Makefile.am 2010-11-27 19:43:02.000000000 +0100
+@@ -16,11 +16,11 @@
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ $(openssl_includes)
+ LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs)
+-pkglib_LIBRARIES = libvio.a
++noinst_LTLIBRARIES = libvio.la
+
+ noinst_HEADERS = vio_priv.h
+
+-libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
++libvio_la_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
+
+ EXTRA_DIST= CMakeLists.txt
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-01 5:13 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-01 5:13 UTC (permalink / raw
To: gentoo-commits
commit: 88ee41001b53e6cd8be352e537b8925f99a995d6
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Fri Nov 18 23:47:49 2011 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Nov 18 23:47:49 2011 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=88ee4100
Another patch port.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.60.patch | 3859 ++++++++++++++++++++++++++++++++++
2 files changed, 3866 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 2577963..23e76ca 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -540,7 +540,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.58.patch
-@ver 5.01.58.00 to 5.01.99.99
+@ver 5.01.58.00 to 5.01.59.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.60.patch
+@ver 5.01.60.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.60.patch b/07110_all_mysql_gcc-4.2_5.1.60.patch
new file mode 100644
index 0000000..c7bb844
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.60.patch
@@ -0,0 +1,3859 @@
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql.orig/client/mysqlbinlog.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/client/mysqlbinlog.cc 2011-11-18 15:43:16.995773774 -0800
+@@ -1954,7 +1954,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql.orig/client/mysql.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/client/mysql.cc 2011-11-18 15:43:16.997773806 -0800
+@@ -3334,9 +3334,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3356,7 +3356,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql.orig/client/mysqldump.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/client/mysqldump.c 2011-11-18 15:43:16.999773837 -0800
+@@ -833,7 +833,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4526,7 +4526,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql.orig/client/mysqltest.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/client/mysqltest.cc 2011-11-18 15:43:17.002773882 -0800
+@@ -5666,9 +5666,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql.orig/client/mysql_upgrade.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/client/mysql_upgrade.c 2011-11-18 15:43:17.003773897 -0800
+@@ -533,7 +533,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql.orig/client/sql_string.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/client/sql_string.cc 2011-11-18 15:43:17.003773897 -0800
+@@ -664,7 +664,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -750,7 +750,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -767,7 +767,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql.orig/dbug/dbug.c 2011-10-29 11:09:48.000000000 -0700
++++ mysql/dbug/dbug.c 2011-11-18 15:43:17.004773912 -0800
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql.orig/extra/yassl/src/ssl.cpp 2011-10-29 11:09:49.000000000 -0700
++++ mysql/extra/yassl/src/ssl.cpp 2011-11-18 15:43:17.004773912 -0800
+@@ -38,6 +38,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -113,7 +114,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp 2011-10-29 11:09:53.000000000 -0700
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2011-11-18 15:43:17.005773927 -0800
+@@ -67,7 +67,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql.orig/extra/yassl/taocrypt/src/dh.cpp 2011-10-29 11:09:51.000000000 -0700
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2011-11-18 15:43:17.005773927 -0800
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/include/my_global.h mysql/include/my_global.h
+--- mysql.orig/include/my_global.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/include/my_global.h 2011-11-18 15:43:17.005773927 -0800
+@@ -586,10 +586,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql.orig/libmysql/libmysql.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/libmysql/libmysql.c 2011-11-18 15:43:17.006773942 -0800
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql.orig/libmysqld/lib_sql.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/libmysqld/lib_sql.cc 2011-11-18 15:43:17.007773958 -0800
+@@ -848,7 +848,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/array.c mysql/mysys/array.c
+--- mysql.orig/mysys/array.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/array.c 2011-11-18 15:43:17.007773958 -0800
+@@ -50,7 +50,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -344,7 +344,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/default.c mysql/mysys/default.c
+--- mysql.orig/mysys/default.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/default.c 2011-11-18 15:43:17.008773974 -0800
+@@ -796,7 +796,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql.orig/mysys/mf_format.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/mf_format.c 2011-11-18 15:43:17.008773974 -0800
+@@ -86,7 +86,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql.orig/mysys/mf_iocache.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/mf_iocache.c 2011-11-18 15:43:17.008773974 -0800
+@@ -1099,7 +1099,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1258,7 +1258,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1367,7 +1367,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1401,7 +1401,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql.orig/mysys/my_alloc.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/my_alloc.c 2011-11-18 15:43:17.009773990 -0800
+@@ -214,7 +214,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql.orig/mysys/my_bitmap.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/my_bitmap.c 2011-11-18 15:43:17.009773990 -0800
+@@ -425,7 +425,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql.orig/mysys/my_compare.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/my_compare.c 2011-11-18 15:43:17.010774005 -0800
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql.orig/mysys/my_compress.c 2011-10-29 11:09:52.000000000 -0700
++++ mysql/mysys/my_compress.c 2011-11-18 15:43:17.010774005 -0800
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql.orig/mysys/my_conio.c 2011-10-29 11:09:52.000000000 -0700
++++ mysql/mysys/my_conio.c 2011-11-18 15:43:17.010774005 -0800
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql.orig/mysys/my_file.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/my_file.c 2011-11-18 15:43:17.010774005 -0800
+@@ -77,7 +77,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -99,7 +99,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -109,9 +109,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql.orig/mysys/my_getopt.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/my_getopt.c 2011-11-18 15:43:17.011774020 -0800
+@@ -985,7 +985,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql.orig/mysys/my_static.h 2011-10-29 11:09:52.000000000 -0700
++++ mysql/mysys/my_static.h 2011-11-18 15:43:17.011774020 -0800
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql.orig/mysys/safemalloc.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/safemalloc.c 2011-11-18 15:43:17.011774020 -0800
+@@ -250,7 +250,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql.orig/mysys/stacktrace.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/mysys/stacktrace.c 2011-11-18 15:43:17.012774035 -0800
+@@ -98,7 +98,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -326,7 +326,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) &
+ ~(ulong) 0xFFFF);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql.orig/server-tools/instance-manager/buffer.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/server-tools/instance-manager/buffer.cc 2011-11-18 15:43:17.012774035 -0800
+@@ -86,8 +86,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql.orig/server-tools/instance-manager/listener.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/server-tools/instance-manager/listener.cc 2011-11-18 15:43:17.012774035 -0800
+@@ -106,7 +106,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql.orig/sql/debug_sync.cc 2011-10-29 11:09:48.000000000 -0700
++++ mysql/sql/debug_sync.cc 2011-11-18 15:43:17.013774050 -0800
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/field.cc mysql/sql/field.cc
+--- mysql.orig/sql/field.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/field.cc 2011-11-18 15:43:17.015774080 -0800
+@@ -55,7 +55,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2073,7 +2073,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2081,7 +2081,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2506,7 +2506,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2522,7 +2522,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3092,7 +3092,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3304,7 +3304,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3521,7 +3521,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3740,7 +3740,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3981,7 +3981,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4204,7 +4204,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6443,13 +6443,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6457,7 +6457,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6715,7 +6715,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7709,7 +7709,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7869,7 +7869,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8065,7 +8065,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9112,7 +9112,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9198,7 +9198,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9326,7 +9326,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9783,7 +9783,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql.orig/sql/filesort.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/filesort.cc 2011-11-18 15:43:17.015774080 -0800
+@@ -193,7 +193,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -215,12 +215,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+ if ((table_sort.sort_keys=
+ (uchar **) make_char_array((char **) table_sort.sort_keys,
+ param.keys, param.rec_length, MYF(0))))
+@@ -1109,7 +1109,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1372,7 +1372,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql.orig/sql/ha_ndbcluster.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/ha_ndbcluster.cc 2011-11-18 15:43:17.017774112 -0800
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/handler.h mysql/sql/handler.h
+--- mysql.orig/sql/handler.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/handler.h 2011-11-18 15:43:17.018774127 -0800
+@@ -1607,15 +1607,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql.orig/sql/ha_partition.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/ha_partition.cc 2011-11-18 15:43:17.019774142 -0800
+@@ -6138,7 +6138,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql.orig/sql/item_buff.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_buff.cc 2011-11-18 15:43:17.020774157 -0800
+@@ -61,7 +61,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -71,7 +71,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item.cc mysql/sql/item.cc
+--- mysql.orig/sql/item.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item.cc 2011-11-18 15:43:17.021774172 -0800
+@@ -76,7 +76,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -444,9 +444,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -752,7 +752,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5416,7 +5416,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5471,7 +5471,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7561,14 +7561,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7599,7 +7599,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7621,7 +7621,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7639,7 +7639,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql.orig/sql/item_cmpfunc.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_cmpfunc.cc 2011-11-18 15:43:17.022774187 -0800
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql.orig/sql/item_func.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_func.cc 2011-11-18 15:43:17.025774233 -0800
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql.orig/sql/item_func.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_func.h 2011-11-18 15:43:17.026774249 -0800
+@@ -421,7 +421,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql.orig/sql/item_strfunc.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_strfunc.cc 2011-11-18 15:43:17.028774280 -0800
+@@ -389,7 +389,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -750,7 +750,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1251,7 +1251,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1271,7 +1271,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1962,7 +1962,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3114,11 +3114,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3582,7 +3582,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql.orig/sql/item_strfunc.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_strfunc.h 2011-11-18 15:43:17.029774295 -0800
+@@ -709,7 +709,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql.orig/sql/item_sum.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_sum.cc 2011-11-18 15:43:17.031774325 -0800
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql.orig/sql/item_timefunc.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/item_timefunc.cc 2011-11-18 15:43:17.032774340 -0800
+@@ -310,14 +310,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -326,7 +326,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -343,15 +343,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -362,14 +362,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -377,7 +377,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -429,7 +429,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -441,7 +441,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -453,7 +453,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -598,7 +598,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1830,7 +1830,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/key.cc mysql/sql/key.cc
+--- mysql.orig/sql/key.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/key.cc 2011-11-18 15:43:17.033774355 -0800
+@@ -128,13 +128,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -218,7 +218,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -227,7 +227,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -288,7 +288,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -354,7 +354,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log.cc mysql/sql/log.cc
+--- mysql.orig/sql/log.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/log.cc 2011-11-18 15:43:17.034774370 -0800
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2429,7 +2429,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5237,7 +5237,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql.orig/sql/log_event.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/log_event.cc 2011-11-18 15:43:17.036774401 -0800
+@@ -1082,7 +1082,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2678,7 +2678,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5595,7 +5595,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7322,7 +7322,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql.orig/sql/log_event_old.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/log_event_old.cc 2011-11-18 15:43:17.037774417 -0800
+@@ -1434,7 +1434,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql.orig/sql/mysqld.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/mysqld.cc 2011-11-18 15:43:17.039774448 -0800
+@@ -3397,7 +3397,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3409,15 +3409,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -5099,7 +5099,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql.orig/sql/net_serv.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/net_serv.cc 2011-11-18 15:43:17.039774448 -0800
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql.orig/sql/opt_range.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/opt_range.cc 2011-11-18 15:43:17.041774478 -0800
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql.orig/sql/opt_range.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/opt_range.h 2011-11-18 15:43:17.042774493 -0800
+@@ -85,7 +85,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -123,7 +123,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql.orig/sql/protocol.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/protocol.cc 2011-11-18 15:43:17.042774493 -0800
+@@ -168,7 +168,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -263,7 +263,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql.orig/sql/rpl_record.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/rpl_record.cc 2011-11-18 15:43:17.043774508 -0800
+@@ -287,7 +287,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql.orig/sql/rpl_rli.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/rpl_rli.cc 2011-11-18 15:43:17.043774508 -0800
+@@ -688,7 +688,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -698,7 +698,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql.orig/sql/rpl_utility.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/rpl_utility.cc 2011-11-18 15:43:17.044774523 -0800
+@@ -182,7 +182,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql.orig/sql/rpl_utility.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/rpl_utility.h 2011-11-18 15:43:17.044774523 -0800
+@@ -297,7 +297,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql.orig/sql/set_var.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/set_var.cc 2011-11-18 15:43:17.045774539 -0800
+@@ -1847,7 +1847,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4032,7 +4032,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql.orig/sql/slave.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/slave.cc 2011-11-18 15:43:17.046774555 -0800
+@@ -1743,7 +1743,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2360,7 +2360,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4057,7 +4057,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql.orig/sql/spatial.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/spatial.h 2011-11-18 15:43:17.047774570 -0800
+@@ -182,8 +182,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql.orig/sql/sp_head.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/sp_head.cc 2011-11-18 15:43:17.047774570 -0800
+@@ -2481,7 +2481,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2682,7 +2682,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql.orig/sql/sql_acl.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_acl.cc 2011-11-18 15:43:17.048774585 -0800
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql.orig/sql/sql_analyse.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_analyse.cc 2011-11-18 15:43:17.049774600 -0800
+@@ -282,16 +282,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1045,7 +1045,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1070,7 +1070,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1187,7 +1187,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql.orig/sql/sql_cache.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/sql_cache.cc 2011-11-18 15:43:17.050774615 -0800
+@@ -1006,7 +1006,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2451,7 +2451,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2506,7 +2506,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2534,7 +2534,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2622,8 +2622,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2655,7 +2655,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2664,7 +2664,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3087,7 +3087,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql.orig/sql/sql_class.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_class.cc 2011-11-18 15:43:17.051774630 -0800
+@@ -417,7 +417,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -432,7 +432,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2101,7 +2101,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql.orig/sql/sql_client.cc 2011-10-29 11:09:53.000000000 -0700
++++ mysql/sql/sql_client.cc 2011-11-18 15:43:17.051774630 -0800
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql.orig/sql/sql_connect.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_connect.cc 2011-11-18 15:43:17.052774645 -0800
+@@ -845,7 +845,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql.orig/sql/sql_parse.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/sql_parse.cc 2011-11-18 15:43:17.053774660 -0800
+@@ -5756,7 +5756,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7286,7 +7286,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql.orig/sql/sql_partition.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_partition.cc 2011-11-18 15:43:17.055774692 -0800
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql.orig/sql/sql_plugin.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_plugin.cc 2011-11-18 15:43:17.056774708 -0800
+@@ -512,7 +512,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2131,7 +2131,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql.orig/sql/sql_prepare.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_prepare.cc 2011-11-18 15:43:17.057774723 -0800
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql.orig/sql/sql_profile.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_profile.cc 2011-11-18 15:43:17.058774738 -0800
+@@ -254,7 +254,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql.orig/sql/sql_repl.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_repl.cc 2011-11-18 15:43:17.058774738 -0800
+@@ -1299,12 +1299,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1476,7 +1476,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1747,14 +1747,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1763,7 +1763,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql.orig/sql/sql_select.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/sql_select.cc 2011-11-18 15:43:17.061774783 -0800
+@@ -3016,7 +3016,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3952,7 +3952,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3975,7 +3975,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4138,7 +4138,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4458,7 +4458,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4625,7 +4625,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5575,7 +5575,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10491,7 +10491,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13703,7 +13703,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13715,7 +13715,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14413,7 +14413,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14535,7 +14535,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql.orig/sql/sql_show.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_show.cc 2011-11-18 15:43:17.063774813 -0800
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1871,7 +1871,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2002,7 +2002,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3267,7 +3267,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7084,7 +7084,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql.orig/sql/sql_string.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_string.cc 2011-11-18 15:43:17.064774828 -0800
+@@ -699,7 +699,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -785,7 +785,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -802,7 +802,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -1003,7 +1003,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1189,7 +1189,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql.orig/sql/sql_table.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/sql_table.cc 2011-11-18 15:43:17.065774844 -0800
+@@ -3276,7 +3276,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql.orig/sql/sql_yacc.cc 2011-10-29 11:16:20.000000000 -0700
++++ mysql/sql/sql_yacc.cc 2011-11-18 15:43:17.071774936 -0800
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql.orig/sql/sql_yacc.yy 2011-10-29 11:09:47.000000000 -0700
++++ mysql/sql/sql_yacc.yy 2011-11-18 15:43:17.075774996 -0800
+@@ -1807,7 +1807,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1817,7 +1817,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql.orig/sql/thr_malloc.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/thr_malloc.cc 2011-11-18 15:43:17.076775012 -0800
+@@ -132,7 +132,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql.orig/sql/tztime.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/tztime.cc 2011-11-18 15:43:17.076775012 -0800
+@@ -169,7 +169,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -398,7 +398,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1825,7 +1825,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql.orig/sql/unireg.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql/unireg.cc 2011-11-18 15:43:17.077775028 -0800
+@@ -498,7 +498,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -718,7 +718,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql.orig/sql-common/client.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql-common/client.c 2011-11-18 15:43:17.077775028 -0800
+@@ -730,7 +730,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2104,7 +2104,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql.orig/sql-common/my_time.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/sql-common/my_time.c 2011-11-18 15:43:17.078775044 -0800
+@@ -251,7 +251,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql.orig/storage/csv/ha_tina.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/csv/ha_tina.cc 2011-11-18 15:43:17.079775059 -0800
+@@ -1195,7 +1195,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1431,7 +1431,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql.orig/storage/example/ha_example.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/example/ha_example.h 2011-11-18 15:43:17.079775059 -0800
+@@ -112,14 +112,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -130,7 +130,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -141,7 +141,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql.orig/storage/federated/ha_federated.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/federated/ha_federated.cc 2011-11-18 15:43:17.080775074 -0800
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql.orig/storage/heap/hp_create.c 2011-10-29 11:09:47.000000000 -0700
++++ mysql/storage/heap/hp_create.c 2011-11-18 15:43:17.080775074 -0800
+@@ -230,7 +230,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql.orig/storage/heap/hp_test2.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/heap/hp_test2.c 2011-11-18 15:43:17.081775089 -0800
+@@ -138,7 +138,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -219,7 +219,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql.orig/storage/innobase/include/ut0byte.h 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/innobase/include/ut0byte.h 2011-11-18 15:43:17.081775089 -0800
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql.orig/storage/innodb_plugin/dict/dict0dict.c 2011-10-29 11:09:48.000000000 -0700
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2011-11-18 15:43:17.082775104 -0800
+@@ -4860,7 +4860,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4870,7 +4870,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql.orig/storage/innodb_plugin/include/dict0dict.h 2011-10-29 11:09:47.000000000 -0700
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2011-11-18 15:43:17.082775104 -0800
+@@ -1123,7 +1123,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql.orig/storage/myisam/ft_boolean_search.c 2011-10-29 11:09:47.000000000 -0700
++++ mysql/storage/myisam/ft_boolean_search.c 2011-11-18 15:43:17.083775119 -0800
+@@ -49,9 +49,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql.orig/storage/myisam/ha_myisam.cc 2011-10-29 11:09:47.000000000 -0700
++++ mysql/storage/myisam/ha_myisam.cc 2011-11-18 15:43:17.083775119 -0800
+@@ -1546,7 +1546,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql.orig/storage/myisam/mi_cache.c 2011-10-29 11:09:52.000000000 -0700
++++ mysql/storage/myisam/mi_cache.c 2011-11-18 15:43:17.084775134 -0800
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql.orig/storage/myisam/mi_check.c 2011-10-29 11:09:47.000000000 -0700
++++ mysql/storage/myisam/mi_check.c 2011-11-18 15:43:17.085775150 -0800
+@@ -2175,7 +2175,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2331,7 +2331,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2420,7 +2420,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2784,7 +2784,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3982,7 +3982,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+@@ -4333,7 +4333,7 @@
+
+ VOID(mi_close(*org_info));
+ bzero((char*) &create_info,sizeof(create_info));
+- create_info.max_rows=max(max_records,share.base.records);
++ create_info.max_rows=MYSQL_MAX(max_records,share.base.records);
+ create_info.reloc_rows=share.base.reloc;
+ create_info.old_options=(share.options |
+ (unpack ? HA_OPTION_TEMP_COMPRESS_RECORD : 0));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql.orig/storage/myisam/mi_create.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_create.c 2011-11-18 15:43:17.085775150 -0800
+@@ -439,8 +439,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -529,7 +529,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -567,7 +567,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql.orig/storage/myisam/mi_dynrec.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_dynrec.c 2011-11-18 15:43:17.086775166 -0800
+@@ -882,7 +882,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql.orig/storage/myisam/mi_extra.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_extra.c 2011-11-18 15:43:17.086775166 -0800
+@@ -101,7 +101,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql.orig/storage/myisam/mi_open.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_open.c 2011-11-18 15:43:17.087775181 -0800
+@@ -330,7 +330,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -503,7 +503,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -716,10 +716,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql.orig/storage/myisam/mi_packrec.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_packrec.c 2011-11-18 15:43:17.087775181 -0800
+@@ -687,7 +687,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1402,7 +1402,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql.orig/storage/myisam/mi_test1.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_test1.c 2011-11-18 15:43:17.087775181 -0800
+@@ -438,7 +438,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql.orig/storage/myisam/mi_test2.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/mi_test2.c 2011-11-18 15:43:17.088775196 -0800
+@@ -603,7 +603,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql.orig/storage/myisam/myisamlog.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/myisamlog.c 2011-11-18 15:43:17.089775211 -0800
+@@ -92,7 +92,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql.orig/storage/myisam/myisampack.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/myisampack.c 2011-11-18 15:43:17.089775211 -0800
+@@ -1240,7 +1240,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3002,7 +3002,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql.orig/storage/myisam/rt_mbr.c 2011-10-29 11:09:53.000000000 -0700
++++ mysql/storage/myisam/rt_mbr.c 2011-11-18 15:43:17.090775226 -0800
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql.orig/storage/myisam/sort.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisam/sort.c 2011-11-18 15:43:17.090775226 -0800
+@@ -131,7 +131,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -348,7 +348,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -822,7 +822,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -843,7 +843,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql.orig/storage/myisammrg/ha_myisammrg.cc 2011-10-29 11:09:49.000000000 -0700
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2011-11-18 15:43:17.091775241 -0800
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-10-29 11:09:52.000000000 -0700
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2011-11-18 15:43:17.091775241 -0800
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-10-29 11:09:51.000000000 -0700
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2011-11-18 15:43:17.091775241 -0800
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-10-29 11:09:52.000000000 -0700
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2011-11-18 15:43:17.092775256 -0800
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-10-29 11:09:53.000000000 -0700
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2011-11-18 15:43:17.092775256 -0800
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql.orig/storage/ndb/test/src/getarg.c 2011-10-29 11:09:51.000000000 -0700
++++ mysql/storage/ndb/test/src/getarg.c 2011-11-18 15:43:17.092775256 -0800
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql.orig/strings/ctype-big5.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-big5.c 2011-11-18 15:43:17.094775287 -0800
+@@ -254,7 +254,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -267,7 +267,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql.orig/strings/ctype-bin.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-bin.c 2011-11-18 15:43:17.094775287 -0800
+@@ -82,7 +82,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -133,7 +133,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -177,7 +177,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -406,7 +406,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -419,7 +419,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql.orig/strings/ctype-gbk.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-gbk.c 2011-11-18 15:43:17.096775319 -0800
+@@ -2617,7 +2617,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2628,7 +2628,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql.orig/strings/ctype-mb.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-mb.c 2011-11-18 15:43:17.097775334 -0800
+@@ -369,7 +369,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -413,7 +413,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -452,7 +452,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql.orig/strings/ctype-simple.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-simple.c 2011-11-18 15:43:17.098775349 -0800
+@@ -161,7 +161,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -875,7 +875,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -929,7 +929,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1160,7 +1160,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql.orig/strings/ctype-tis620.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-tis620.c 2011-11-18 15:43:17.098775349 -0800
+@@ -583,7 +583,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -640,7 +640,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql.orig/strings/ctype-uca.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-uca.c 2011-11-18 15:43:17.100775379 -0800
+@@ -7569,7 +7569,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql.orig/strings/ctype-ucs2.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-ucs2.c 2011-11-18 15:43:17.101775394 -0800
+@@ -280,7 +280,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1332,7 +1332,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1426,7 +1426,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1473,7 +1473,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql.orig/strings/ctype-utf8.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/ctype-utf8.c 2011-11-18 15:43:17.102775409 -0800
+@@ -1939,7 +1939,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql.orig/strings/decimal.c 2011-10-29 11:09:47.000000000 -0700
++++ mysql/strings/decimal.c 2011-11-18 15:44:22.403773051 -0800
+@@ -405,7 +405,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -428,7 +428,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1531,8 +1531,8 @@
+
+ if (to != from)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg0+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg0+MYSQL_MAX(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
+@@ -1543,7 +1543,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1645,7 +1645,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1664,7 +1664,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1713,11 +1713,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1732,7 +1732,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1757,7 +1757,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1768,7 +1768,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1786,14 +1786,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1814,7 +1814,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1889,7 +1889,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1900,7 +1900,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1924,7 +1924,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2187,11 +2187,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2315,7 +2315,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2353,7 +2353,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql.orig/strings/my_vsnprintf.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/my_vsnprintf.c 2011-11-18 15:43:17.103775424 -0800
+@@ -143,7 +143,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql.orig/strings/str2int.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/strings/str2int.c 2011-11-18 15:43:17.103775424 -0800
+@@ -84,7 +84,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/tests/mysql_client_test.c mysql/tests/mysql_client_test.c
+--- mysql.orig/tests/mysql_client_test.c 2011-11-18 13:00:01.595513776 -0800
++++ mysql/tests/mysql_client_test.c 2011-11-18 15:43:17.106775471 -0800
+@@ -610,7 +610,7 @@
+ return row_count;
+ }
+
+- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
++ field_count= MYSQL_MIN(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql.orig/vio/viosocket.c 2011-10-29 11:09:49.000000000 -0700
++++ mysql/vio/viosocket.c 2011-11-18 15:43:17.107775487 -0800
+@@ -72,7 +72,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-01 5:13 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-01 5:13 UTC (permalink / raw
To: gentoo-commits
commit: 98cfa336bb6a1b4580ae4f6c21f576e0b460cbb1
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sun Apr 1 05:12:20 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 1 05:12:20 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=98cfa336
New spin of min/max patch.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.62.patch | 3850 ++++++++++++++++++++++++++++++++++
2 files changed, 3857 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 23e76ca..8c38d58 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -546,7 +546,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.60.patch
-@ver 5.01.60.00 to 5.01.99.99
+@ver 5.01.60.00 to 5.01.61.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.62.patch
+@ver 5.01.62.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.62.patch b/07110_all_mysql_gcc-4.2_5.1.62.patch
new file mode 100644
index 0000000..2ab4150
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.62.patch
@@ -0,0 +1,3850 @@
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql.orig/client/mysqlbinlog.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/client/mysqlbinlog.cc 2012-03-31 22:08:57.703628635 -0700
+@@ -1954,7 +1954,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql.orig/client/mysql.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/client/mysql.cc 2012-03-31 22:08:57.705628671 -0700
+@@ -3334,9 +3334,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3356,7 +3356,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql.orig/client/mysqldump.c 2012-03-02 06:39:18.000000000 -0800
++++ mysql/client/mysqldump.c 2012-03-31 22:08:57.707628699 -0700
+@@ -840,7 +840,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4727,7 +4727,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql.orig/client/mysqltest.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/client/mysqltest.cc 2012-03-31 22:08:57.709628727 -0700
+@@ -5666,9 +5666,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql.orig/client/mysql_upgrade.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/client/mysql_upgrade.c 2012-03-31 22:08:57.710628744 -0700
+@@ -533,7 +533,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql.orig/client/sql_string.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/client/sql_string.cc 2012-03-31 22:08:57.710628744 -0700
+@@ -665,7 +665,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -751,7 +751,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -768,7 +768,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql.orig/dbug/dbug.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/dbug/dbug.c 2012-03-31 22:08:57.711628761 -0700
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql.orig/extra/yassl/src/ssl.cpp 2012-03-02 06:39:18.000000000 -0800
++++ mysql/extra/yassl/src/ssl.cpp 2012-03-31 22:08:57.711628761 -0700
+@@ -39,6 +39,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -114,7 +115,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql.orig/extra/yassl/taocrypt/include/pwdbased.hpp 2012-03-02 06:39:18.000000000 -0800
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2012-03-31 22:08:57.712628777 -0700
+@@ -68,7 +68,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql.orig/extra/yassl/taocrypt/src/dh.cpp 2012-03-02 06:39:23.000000000 -0800
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2012-03-31 22:08:57.712628777 -0700
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/include/my_global.h mysql/include/my_global.h
+--- mysql.orig/include/my_global.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/include/my_global.h 2012-03-31 22:08:57.713628793 -0700
+@@ -586,10 +586,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql.orig/libmysql/libmysql.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/libmysql/libmysql.c 2012-03-31 22:08:57.715628824 -0700
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql.orig/libmysqld/lib_sql.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/libmysqld/lib_sql.cc 2012-03-31 22:08:57.716628840 -0700
+@@ -848,7 +848,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/array.c mysql/mysys/array.c
+--- mysql.orig/mysys/array.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/mysys/array.c 2012-03-31 22:08:57.717628856 -0700
+@@ -50,7 +50,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -344,7 +344,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/default.c mysql/mysys/default.c
+--- mysql.orig/mysys/default.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/default.c 2012-03-31 22:08:57.717628856 -0700
+@@ -796,7 +796,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql.orig/mysys/mf_format.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/mf_format.c 2012-03-31 22:08:57.718628872 -0700
+@@ -86,7 +86,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql.orig/mysys/mf_iocache.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/mf_iocache.c 2012-03-31 22:08:57.719628888 -0700
+@@ -1099,7 +1099,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1258,7 +1258,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1367,7 +1367,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1401,7 +1401,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql.orig/mysys/my_alloc.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/my_alloc.c 2012-03-31 22:08:57.720628904 -0700
+@@ -214,7 +214,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql.orig/mysys/my_bitmap.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/my_bitmap.c 2012-03-31 22:08:57.720628904 -0700
+@@ -425,7 +425,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql.orig/mysys/my_compare.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/mysys/my_compare.c 2012-03-31 22:08:57.720628904 -0700
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql.orig/mysys/my_compress.c 2012-03-02 06:39:24.000000000 -0800
++++ mysql/mysys/my_compress.c 2012-03-31 22:08:57.720628904 -0700
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql.orig/mysys/my_conio.c 2012-03-02 06:39:24.000000000 -0800
++++ mysql/mysys/my_conio.c 2012-03-31 22:08:57.721628919 -0700
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql.orig/mysys/my_file.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/my_file.c 2012-03-31 22:08:57.721628919 -0700
+@@ -77,7 +77,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -99,7 +99,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -109,9 +109,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql.orig/mysys/my_getopt.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/my_getopt.c 2012-03-31 22:08:57.722628934 -0700
+@@ -985,7 +985,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql.orig/mysys/my_static.h 2012-03-02 06:39:24.000000000 -0800
++++ mysql/mysys/my_static.h 2012-03-31 22:08:57.723628950 -0700
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql.orig/mysys/safemalloc.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/mysys/safemalloc.c 2012-03-31 22:08:57.723628950 -0700
+@@ -250,7 +250,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql.orig/mysys/stacktrace.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/mysys/stacktrace.c 2012-03-31 22:08:57.724628966 -0700
+@@ -98,7 +98,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -328,7 +328,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
+ my_safe_printf_stderr("Cannot determine thread, fp=%p, "
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql.orig/server-tools/instance-manager/buffer.cc 2012-03-02 06:39:20.000000000 -0800
++++ mysql/server-tools/instance-manager/buffer.cc 2012-03-31 22:08:57.725628982 -0700
+@@ -86,8 +86,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql.orig/server-tools/instance-manager/listener.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/server-tools/instance-manager/listener.cc 2012-03-31 22:08:57.725628982 -0700
+@@ -106,7 +106,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql.orig/sql/debug_sync.cc 2012-03-02 06:39:20.000000000 -0800
++++ mysql/sql/debug_sync.cc 2012-03-31 22:08:57.726628998 -0700
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/field.cc mysql/sql/field.cc
+--- mysql.orig/sql/field.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/field.cc 2012-03-31 22:08:57.729629046 -0700
+@@ -55,7 +55,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2073,7 +2073,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2081,7 +2081,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2506,7 +2506,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2522,7 +2522,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3092,7 +3092,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3304,7 +3304,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3521,7 +3521,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3740,7 +3740,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3981,7 +3981,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4204,7 +4204,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6443,13 +6443,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6457,7 +6457,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6715,7 +6715,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7709,7 +7709,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7869,7 +7869,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8065,7 +8065,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9112,7 +9112,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9198,7 +9198,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9326,7 +9326,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9783,7 +9783,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql.orig/sql/filesort.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/sql/filesort.cc 2012-03-31 22:09:57.110571120 -0700
+@@ -194,7 +194,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -216,12 +216,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+
+ if (table_sort.sort_keys &&
+ table_sort.sort_keys_size != char_array_size(param.keys,
+@@ -1133,7 +1133,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1396,7 +1396,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql.orig/sql/ha_ndbcluster.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/ha_ndbcluster.cc 2012-03-31 22:08:57.731629078 -0700
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/handler.h mysql/sql/handler.h
+--- mysql.orig/sql/handler.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/handler.h 2012-03-31 22:08:57.732629094 -0700
+@@ -1607,15 +1607,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql.orig/sql/ha_partition.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/ha_partition.cc 2012-03-31 22:08:57.733629110 -0700
+@@ -6138,7 +6138,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql.orig/sql/item_buff.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/item_buff.cc 2012-03-31 22:08:57.733629110 -0700
+@@ -61,7 +61,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -71,7 +71,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item.cc mysql/sql/item.cc
+--- mysql.orig/sql/item.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/item.cc 2012-03-31 22:08:57.734629126 -0700
+@@ -76,7 +76,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -444,9 +444,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -752,7 +752,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5416,7 +5416,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5471,7 +5471,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7561,14 +7561,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7599,7 +7599,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7621,7 +7621,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7639,7 +7639,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql.orig/sql/item_cmpfunc.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/item_cmpfunc.cc 2012-03-31 22:08:57.736629157 -0700
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql.orig/sql/item_func.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/item_func.cc 2012-03-31 22:08:57.740629220 -0700
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql.orig/sql/item_func.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/item_func.h 2012-03-31 22:08:57.741629236 -0700
+@@ -421,7 +421,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql.orig/sql/item_strfunc.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/item_strfunc.cc 2012-03-31 22:08:57.742629252 -0700
+@@ -389,7 +389,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -750,7 +750,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1251,7 +1251,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1271,7 +1271,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1962,7 +1962,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3114,11 +3114,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3582,7 +3582,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql.orig/sql/item_strfunc.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/item_strfunc.h 2012-03-31 22:08:57.742629252 -0700
+@@ -709,7 +709,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql.orig/sql/item_sum.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/item_sum.cc 2012-03-31 22:08:57.743629268 -0700
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql.orig/sql/item_timefunc.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/item_timefunc.cc 2012-03-31 22:08:57.744629284 -0700
+@@ -310,14 +310,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -326,7 +326,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -343,15 +343,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -362,14 +362,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -377,7 +377,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -429,7 +429,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -441,7 +441,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -453,7 +453,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -598,7 +598,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1830,7 +1830,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/key.cc mysql/sql/key.cc
+--- mysql.orig/sql/key.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/key.cc 2012-03-31 22:08:57.744629284 -0700
+@@ -128,13 +128,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -218,7 +218,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -227,7 +227,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -288,7 +288,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -354,7 +354,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log.cc mysql/sql/log.cc
+--- mysql.orig/sql/log.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/log.cc 2012-03-31 22:08:57.746629316 -0700
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2429,7 +2429,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5237,7 +5237,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql.orig/sql/log_event.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/log_event.cc 2012-03-31 22:08:57.750629380 -0700
+@@ -1082,7 +1082,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2678,7 +2678,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5595,7 +5595,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7322,7 +7322,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql.orig/sql/log_event_old.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/log_event_old.cc 2012-03-31 22:08:57.750629380 -0700
+@@ -1434,7 +1434,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql.orig/sql/mysqld.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/mysqld.cc 2012-03-31 22:08:57.753629426 -0700
+@@ -3243,7 +3243,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3255,15 +3255,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -4949,7 +4949,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql.orig/sql/net_serv.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/net_serv.cc 2012-03-31 22:08:57.754629442 -0700
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql.orig/sql/opt_range.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/opt_range.cc 2012-03-31 22:08:57.758629506 -0700
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql.orig/sql/opt_range.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/opt_range.h 2012-03-31 22:08:57.762629570 -0700
+@@ -85,7 +85,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -123,7 +123,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql.orig/sql/protocol.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/protocol.cc 2012-03-31 22:08:57.763629586 -0700
+@@ -168,7 +168,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -263,7 +263,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql.orig/sql/rpl_record.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/rpl_record.cc 2012-03-31 22:08:57.764629602 -0700
+@@ -287,7 +287,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql.orig/sql/rpl_rli.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/rpl_rli.cc 2012-03-31 22:08:57.764629602 -0700
+@@ -688,7 +688,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -698,7 +698,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql.orig/sql/rpl_utility.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/rpl_utility.cc 2012-03-31 22:08:57.765629618 -0700
+@@ -182,7 +182,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql.orig/sql/rpl_utility.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/rpl_utility.h 2012-03-31 22:08:57.765629618 -0700
+@@ -297,7 +297,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql.orig/sql/set_var.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/set_var.cc 2012-03-31 22:08:57.767629648 -0700
+@@ -1847,7 +1847,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4032,7 +4032,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql.orig/sql/slave.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/sql/slave.cc 2012-03-31 22:08:57.768629664 -0700
+@@ -1743,7 +1743,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2360,7 +2360,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4057,7 +4057,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql.orig/sql/spatial.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/spatial.h 2012-03-31 22:08:57.769629680 -0700
+@@ -182,8 +182,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql.orig/sql/sp_head.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/sql/sp_head.cc 2012-03-31 22:08:57.770629696 -0700
+@@ -2481,7 +2481,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2682,7 +2682,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql.orig/sql/sql_acl.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_acl.cc 2012-03-31 22:08:57.772629728 -0700
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql.orig/sql/sql_analyse.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_analyse.cc 2012-03-31 22:08:57.773629744 -0700
+@@ -282,16 +282,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1045,7 +1045,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1070,7 +1070,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1187,7 +1187,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql.orig/sql/sql_cache.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_cache.cc 2012-03-31 22:08:57.775629776 -0700
+@@ -1006,7 +1006,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2451,7 +2451,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2506,7 +2506,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2534,7 +2534,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2622,8 +2622,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2655,7 +2655,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2664,7 +2664,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3087,7 +3087,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql.orig/sql/sql_class.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/sql/sql_class.cc 2012-03-31 22:08:57.777629808 -0700
+@@ -417,7 +417,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -432,7 +432,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2101,7 +2101,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql.orig/sql/sql_client.cc 2012-03-02 06:39:25.000000000 -0800
++++ mysql/sql/sql_client.cc 2012-03-31 22:08:57.777629808 -0700
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql.orig/sql/sql_connect.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_connect.cc 2012-03-31 22:08:57.778629824 -0700
+@@ -845,7 +845,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql.orig/sql/sql_parse.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_parse.cc 2012-03-31 22:08:57.779629840 -0700
+@@ -5756,7 +5756,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7286,7 +7286,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql.orig/sql/sql_partition.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_partition.cc 2012-03-31 22:08:57.781629871 -0700
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql.orig/sql/sql_plugin.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_plugin.cc 2012-03-31 22:08:57.783629902 -0700
+@@ -512,7 +512,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2131,7 +2131,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql.orig/sql/sql_prepare.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_prepare.cc 2012-03-31 22:08:57.784629918 -0700
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql.orig/sql/sql_profile.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_profile.cc 2012-03-31 22:08:57.785629934 -0700
+@@ -254,7 +254,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql.orig/sql/sql_repl.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/sql_repl.cc 2012-03-31 22:08:57.786629950 -0700
+@@ -1299,12 +1299,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1476,7 +1476,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1747,14 +1747,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1763,7 +1763,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql.orig/sql/sql_select.cc 2012-03-02 06:39:18.000000000 -0800
++++ mysql/sql/sql_select.cc 2012-03-31 22:08:57.790630014 -0700
+@@ -3016,7 +3016,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3952,7 +3952,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3975,7 +3975,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4138,7 +4138,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4458,7 +4458,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4625,7 +4625,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5575,7 +5575,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10481,7 +10481,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13696,7 +13696,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13708,7 +13708,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14406,7 +14406,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14528,7 +14528,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql.orig/sql/sql_show.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_show.cc 2012-03-31 22:08:57.791630030 -0700
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1875,7 +1875,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2006,7 +2006,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3271,7 +3271,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7088,7 +7088,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql.orig/sql/sql_string.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_string.cc 2012-03-31 22:08:57.792630046 -0700
+@@ -700,7 +700,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -786,7 +786,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -803,7 +803,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -1004,7 +1004,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1190,7 +1190,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql.orig/sql/sql_table.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_table.cc 2012-03-31 22:08:57.793630062 -0700
+@@ -3276,7 +3276,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql.orig/sql/sql_yacc.cc 2012-03-02 06:46:17.000000000 -0800
++++ mysql/sql/sql_yacc.cc 2012-03-31 22:08:57.799630156 -0700
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql.orig/sql/sql_yacc.yy 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql/sql_yacc.yy 2012-03-31 22:08:57.802630204 -0700
+@@ -1807,7 +1807,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1817,7 +1817,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql.orig/sql/thr_malloc.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/thr_malloc.cc 2012-03-31 22:08:57.803630220 -0700
+@@ -132,7 +132,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql.orig/sql/tztime.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/tztime.cc 2012-03-31 22:08:57.803630220 -0700
+@@ -169,7 +169,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -398,7 +398,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1825,7 +1825,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql.orig/sql/unireg.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/sql/unireg.cc 2012-03-31 22:08:57.804630236 -0700
+@@ -498,7 +498,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -718,7 +718,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql.orig/sql-common/client.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/sql-common/client.c 2012-03-31 22:08:57.805630252 -0700
+@@ -730,7 +730,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2104,7 +2104,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql.orig/sql-common/my_time.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/sql-common/my_time.c 2012-03-31 22:08:57.806630268 -0700
+@@ -251,7 +251,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql.orig/storage/csv/ha_tina.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/csv/ha_tina.cc 2012-03-31 22:08:57.807630284 -0700
+@@ -1195,7 +1195,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1431,7 +1431,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql.orig/storage/example/ha_example.h 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/example/ha_example.h 2012-03-31 22:08:57.808630300 -0700
+@@ -112,14 +112,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -130,7 +130,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -141,7 +141,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql.orig/storage/federated/ha_federated.cc 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/federated/ha_federated.cc 2012-03-31 22:08:57.808630300 -0700
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql.orig/storage/heap/hp_create.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/heap/hp_create.c 2012-03-31 22:08:57.809630316 -0700
+@@ -230,7 +230,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql.orig/storage/heap/hp_test2.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/heap/hp_test2.c 2012-03-31 22:08:57.810630332 -0700
+@@ -138,7 +138,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -219,7 +219,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql.orig/storage/innobase/include/ut0byte.h 2012-03-02 06:39:22.000000000 -0800
++++ mysql/storage/innobase/include/ut0byte.h 2012-03-31 22:08:57.810630332 -0700
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql.orig/storage/innodb_plugin/dict/dict0dict.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2012-03-31 22:08:57.812630362 -0700
+@@ -4860,7 +4860,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4870,7 +4870,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql.orig/storage/innodb_plugin/include/dict0dict.h 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2012-03-31 22:08:57.813630378 -0700
+@@ -1123,7 +1123,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql.orig/storage/myisam/ft_boolean_search.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/myisam/ft_boolean_search.c 2012-03-31 22:08:57.814630394 -0700
+@@ -48,9 +48,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql.orig/storage/myisam/ha_myisam.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/ha_myisam.cc 2012-03-31 22:08:57.815630410 -0700
+@@ -1546,7 +1546,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql.orig/storage/myisam/mi_cache.c 2012-03-02 06:39:24.000000000 -0800
++++ mysql/storage/myisam/mi_cache.c 2012-03-31 22:08:57.815630410 -0700
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql.orig/storage/myisam/mi_check.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/myisam/mi_check.c 2012-03-31 22:10:42.503291186 -0700
+@@ -2175,7 +2175,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2331,7 +2331,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2420,7 +2420,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2784,7 +2784,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3982,7 +3982,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql.orig/storage/myisam/mi_create.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_create.c 2012-03-31 22:08:57.818630458 -0700
+@@ -439,8 +439,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -529,7 +529,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -567,7 +567,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql.orig/storage/myisam/mi_dynrec.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_dynrec.c 2012-03-31 22:08:57.819630474 -0700
+@@ -882,7 +882,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql.orig/storage/myisam/mi_extra.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_extra.c 2012-03-31 22:08:57.820630490 -0700
+@@ -101,7 +101,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql.orig/storage/myisam/mi_open.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_open.c 2012-03-31 22:08:57.820630490 -0700
+@@ -330,7 +330,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -503,7 +503,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -716,10 +716,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql.orig/storage/myisam/mi_packrec.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/storage/myisam/mi_packrec.c 2012-03-31 22:08:57.821630506 -0700
+@@ -686,7 +686,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1401,7 +1401,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql.orig/storage/myisam/mi_test1.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_test1.c 2012-03-31 22:08:57.822630521 -0700
+@@ -438,7 +438,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql.orig/storage/myisam/mi_test2.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/mi_test2.c 2012-03-31 22:08:57.823630537 -0700
+@@ -603,7 +603,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql.orig/storage/myisam/myisamlog.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/myisamlog.c 2012-03-31 22:08:57.824630553 -0700
+@@ -92,7 +92,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql.orig/storage/myisam/myisampack.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/myisampack.c 2012-03-31 22:08:57.825630569 -0700
+@@ -1240,7 +1240,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3002,7 +3002,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql.orig/storage/myisam/rt_mbr.c 2012-03-02 06:39:25.000000000 -0800
++++ mysql/storage/myisam/rt_mbr.c 2012-03-31 22:08:57.826630585 -0700
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql.orig/storage/myisam/sort.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisam/sort.c 2012-03-31 22:08:57.827630601 -0700
+@@ -131,7 +131,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -348,7 +348,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -822,7 +822,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -843,7 +843,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql.orig/storage/myisammrg/ha_myisammrg.cc 2012-03-02 06:39:21.000000000 -0800
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2012-03-31 22:08:57.827630601 -0700
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql.orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-03-02 06:39:24.000000000 -0800
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-03-31 22:08:57.828630617 -0700
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql.orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-03-02 06:39:23.000000000 -0800
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-03-31 22:08:57.828630617 -0700
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql.orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-03-02 06:39:24.000000000 -0800
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-03-31 22:08:57.828630617 -0700
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql.orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-03-02 06:39:26.000000000 -0800
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-03-31 22:08:57.829630633 -0700
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql.orig/storage/ndb/test/src/getarg.c 2012-03-02 06:39:23.000000000 -0800
++++ mysql/storage/ndb/test/src/getarg.c 2012-03-31 22:08:57.830630648 -0700
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql.orig/strings/ctype-big5.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/strings/ctype-big5.c 2012-03-31 22:08:57.833630696 -0700
+@@ -254,7 +254,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -267,7 +267,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql.orig/strings/ctype-bin.c 2012-03-02 06:39:20.000000000 -0800
++++ mysql/strings/ctype-bin.c 2012-03-31 22:08:57.833630696 -0700
+@@ -82,7 +82,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -133,7 +133,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -177,7 +177,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -406,7 +406,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -419,7 +419,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql.orig/strings/ctype-gbk.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/ctype-gbk.c 2012-03-31 22:08:57.837630759 -0700
+@@ -2617,7 +2617,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2628,7 +2628,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql.orig/strings/ctype-mb.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/ctype-mb.c 2012-03-31 22:08:57.838630775 -0700
+@@ -369,7 +369,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -413,7 +413,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -452,7 +452,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql.orig/strings/ctype-simple.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/ctype-simple.c 2012-03-31 22:08:57.838630775 -0700
+@@ -161,7 +161,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -875,7 +875,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -929,7 +929,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1160,7 +1160,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql.orig/strings/ctype-tis620.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/ctype-tis620.c 2012-03-31 22:08:57.839630791 -0700
+@@ -583,7 +583,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -640,7 +640,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql.orig/strings/ctype-uca.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/ctype-uca.c 2012-03-31 22:08:57.840630807 -0700
+@@ -7569,7 +7569,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql.orig/strings/ctype-ucs2.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/strings/ctype-ucs2.c 2012-03-31 22:08:57.841630823 -0700
+@@ -280,7 +280,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1332,7 +1332,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1426,7 +1426,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1473,7 +1473,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql.orig/strings/ctype-utf8.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/strings/ctype-utf8.c 2012-03-31 22:08:57.842630839 -0700
+@@ -2114,7 +2114,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql.orig/strings/decimal.c 2012-03-02 06:39:19.000000000 -0800
++++ mysql/strings/decimal.c 2012-03-31 22:08:57.843630855 -0700
+@@ -405,7 +405,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -428,7 +428,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1531,8 +1531,8 @@
+
+ if (to != from)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg0+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg0+MYSQL_MAX(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
+@@ -1543,7 +1543,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1645,7 +1645,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1664,7 +1664,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1713,11 +1713,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1732,7 +1732,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1757,7 +1757,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1768,7 +1768,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1786,14 +1786,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1814,7 +1814,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1889,7 +1889,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1900,7 +1900,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1924,7 +1924,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2187,11 +2187,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2315,7 +2315,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2353,7 +2353,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql.orig/strings/my_vsnprintf.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/my_vsnprintf.c 2012-03-31 22:08:57.843630855 -0700
+@@ -143,7 +143,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql.orig/strings/str2int.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/strings/str2int.c 2012-03-31 22:08:57.843630855 -0700
+@@ -84,7 +84,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/tests/mysql_client_test.c mysql/tests/mysql_client_test.c
+--- mysql.orig/tests/mysql_client_test.c 2012-03-31 13:43:40.305204380 -0700
++++ mysql/tests/mysql_client_test.c 2012-03-31 22:08:57.845630886 -0700
+@@ -610,7 +610,7 @@
+ return row_count;
+ }
+
+- field_count= min(mysql_num_fields(result), MAX_RES_FIELDS);
++ field_count= MYSQL_MIN(mysql_num_fields(result), MAX_RES_FIELDS);
+
+ bzero((char*) buffer, sizeof(buffer));
+ bzero((char*) length, sizeof(length));
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql.orig/vio/viosocket.c 2012-03-02 06:39:21.000000000 -0800
++++ mysql/vio/viosocket.c 2012-03-31 22:08:57.846630902 -0700
+@@ -72,7 +72,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-01 17:54 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-01 17:54 UTC (permalink / raw
To: gentoo-commits
commit: 5516c7c35d43b1813e3ac90f8339135840057935
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sun Apr 1 17:53:26 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 1 17:53:26 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=5516c7c3
new spin of the shared lib patch.
---
00000_index.txt | 7 +-
02040_all_embedded-library-shared-5.0.96.patch | 1524 ++++++++++++++++++++++++
2 files changed, 1530 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 8c38d58..163c5a2 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -281,7 +281,12 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.0.92.patch
-@ver 5.0.92.00 to 5.00.99.99
+@ver 5.0.92.00 to 5.00.95.99
+@pn mysql
+@@ Take libmysqld to be a proper shared library.
+
+@patch 02040_all_embedded-library-shared-5.0.96.patch
+@ver 5.0.96.00 to 5.00.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
diff --git a/02040_all_embedded-library-shared-5.0.96.patch b/02040_all_embedded-library-shared-5.0.96.patch
new file mode 100644
index 0000000..f8e4b54
--- /dev/null
+++ b/02040_all_embedded-library-shared-5.0.96.patch
@@ -0,0 +1,1524 @@
+Convert all of the static libraries for the embedded libmysqld to build as
+shared.
+
+This enables amarok's mysql extension to properly build as a shared object,
+without statically including libmysqld or nor forcing libmysqld to be built
+with -fPIC.
+
+Thanks to <pageexec@freemail.hu> for the @plt fixes.
+Thanks to Diego Elio Pettenò <flameeyes@gentoo.org> for all the extensive build
+system help with libtool conversions.
+
+Gentoo-Bug: 238487
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=238487
+MySQL-Bug-URL: http://bugs.mysql.com/bug.php?id=39288
+MySQL-Bug: 39288
+MySQL-Lists-URL: http://lists.mysql.com/internals/35947
+X-Patch-URL: http://bugs.gentoo.org/attachment.cgi?id=188019&action=view
+Signed-off-by: Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/client/Makefile.am mysql/client/Makefile.am
+--- mysql.orig/client/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/client/Makefile.am 2012-04-01 10:47:50.422941695 -0700
+@@ -39,7 +39,7 @@
+ $(top_srcdir)/mysys/my_sync.c \
+ $(top_srcdir)/mysys/my_mkdir.c
+
+-mysqltest_LDADD = $(top_builddir)/regex/libregex.a $(LDADD)
++mysqltest_LDADD = $(top_builddir)/regex/libregex.la $(LDADD)
+ mysqlbinlog_SOURCES = mysqlbinlog.cc \
+ $(top_srcdir)/mysys/mf_tempdir.c \
+ $(top_srcdir)/mysys/my_new.cc
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/config/ac-macros/ha_innodb.m4 mysql/config/ac-macros/ha_innodb.m4
+--- mysql.orig/config/ac-macros/ha_innodb.m4 2012-03-02 06:04:11.000000000 -0800
++++ mysql/config/ac-macros/ha_innodb.m4 2012-04-01 10:47:50.422941695 -0700
+@@ -25,40 +25,35 @@
+ dnl Some libs are listed several times, in order for gcc to sort out
+ dnl circular references.
+ innodb_libs="\
+- \$(top_builddir)/innobase/usr/libusr.a\
+- \$(top_builddir)/innobase/srv/libsrv.a\
+- \$(top_builddir)/innobase/dict/libdict.a\
+- \$(top_builddir)/innobase/que/libque.a\
+- \$(top_builddir)/innobase/srv/libsrv.a\
+- \$(top_builddir)/innobase/ibuf/libibuf.a\
+- \$(top_builddir)/innobase/row/librow.a\
+- \$(top_builddir)/innobase/pars/libpars.a\
+- \$(top_builddir)/innobase/btr/libbtr.a\
+- \$(top_builddir)/innobase/trx/libtrx.a\
+- \$(top_builddir)/innobase/read/libread.a\
+- \$(top_builddir)/innobase/usr/libusr.a\
+- \$(top_builddir)/innobase/buf/libbuf.a\
+- \$(top_builddir)/innobase/ibuf/libibuf.a\
+- \$(top_builddir)/innobase/eval/libeval.a\
+- \$(top_builddir)/innobase/log/liblog.a\
+- \$(top_builddir)/innobase/fsp/libfsp.a\
+- \$(top_builddir)/innobase/fut/libfut.a\
+- \$(top_builddir)/innobase/fil/libfil.a\
+- \$(top_builddir)/innobase/lock/liblock.a\
+- \$(top_builddir)/innobase/mtr/libmtr.a\
+- \$(top_builddir)/innobase/page/libpage.a\
+- \$(top_builddir)/innobase/rem/librem.a\
+- \$(top_builddir)/innobase/thr/libthr.a\
+- \$(top_builddir)/innobase/sync/libsync.a\
+- \$(top_builddir)/innobase/data/libdata.a\
+- \$(top_builddir)/innobase/mach/libmach.a\
+- \$(top_builddir)/innobase/ha/libha.a\
+- \$(top_builddir)/innobase/dyn/libdyn.a\
+- \$(top_builddir)/innobase/mem/libmem.a\
+- \$(top_builddir)/innobase/sync/libsync.a\
+- \$(top_builddir)/innobase/ut/libut.a\
+- \$(top_builddir)/innobase/os/libos.a\
+- \$(top_builddir)/innobase/ut/libut.a"
++ \$(top_builddir)/innobase/usr/libusr.la\
++ \$(top_builddir)/innobase/srv/libsrv.la\
++ \$(top_builddir)/innobase/dict/libdict.la\
++ \$(top_builddir)/innobase/que/libque.la\
++ \$(top_builddir)/innobase/ibuf/libibuf.la\
++ \$(top_builddir)/innobase/row/librow.la\
++ \$(top_builddir)/innobase/pars/libpars.la\
++ \$(top_builddir)/innobase/btr/libbtr.la\
++ \$(top_builddir)/innobase/trx/libtrx.la\
++ \$(top_builddir)/innobase/read/libread.la\
++ \$(top_builddir)/innobase/buf/libbuf.la\
++ \$(top_builddir)/innobase/eval/libeval.la\
++ \$(top_builddir)/innobase/log/liblog.la\
++ \$(top_builddir)/innobase/fsp/libfsp.la\
++ \$(top_builddir)/innobase/fut/libfut.la\
++ \$(top_builddir)/innobase/fil/libfil.la\
++ \$(top_builddir)/innobase/lock/liblock.la\
++ \$(top_builddir)/innobase/mtr/libmtr.la\
++ \$(top_builddir)/innobase/page/libpage.la\
++ \$(top_builddir)/innobase/rem/librem.la\
++ \$(top_builddir)/innobase/thr/libthr.la\
++ \$(top_builddir)/innobase/sync/libsync.la\
++ \$(top_builddir)/innobase/data/libdata.la\
++ \$(top_builddir)/innobase/mach/libmach.la\
++ \$(top_builddir)/innobase/ha/libha.la\
++ \$(top_builddir)/innobase/dyn/libdyn.la\
++ \$(top_builddir)/innobase/mem/libmem.la\
++ \$(top_builddir)/innobase/ut/libut.la\
++ \$(top_builddir)/innobase/os/libos.la"
+
+ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"])
+ ;;
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/configure.in mysql/configure.in
+--- mysql.orig/configure.in 2012-03-02 06:04:07.000000000 -0800
++++ mysql/configure.in 2012-04-01 10:47:50.423941710 -0700
+@@ -256,7 +256,7 @@
+ fi
+
+ # Still need ranlib for readline; local static use only so no libtool.
+-AC_PROG_RANLIB
++#AC_PROG_RANLIB
+ # We use libtool
+ #AC_LIBTOOL_WIN32_DLL
+ AC_PROG_LIBTOOL
+@@ -577,6 +577,9 @@
+ # We need an ANSI C compiler
+ AM_PROG_CC_STDC
+
++# Testing as sugggested by Diego
++AM_PROG_CC_C_O
++
+ # We need an assembler, too
+ AM_PROG_AS
+ CCASFLAGS="$CCASFLAGS $ASFLAGS"
+@@ -2777,9 +2780,9 @@
+
+ if test "$THREAD_SAFE_CLIENT" = "no"
+ then
+- sql_client_dirs="strings regex mysys dbug extra libmysql client"
++ sql_client_dirs="strings regex dbug mysys extra libmysql client"
+ else
+- sql_client_dirs="strings regex mysys dbug extra libmysql libmysql_r client"
++ sql_client_dirs="strings regex dbug mysys extra libmysql libmysql_r client"
+ linked_client_targets="$linked_client_targets linked_libmysql_r_sources"
+ AC_CONFIG_FILES(libmysql_r/Makefile)
+ AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
+@@ -2808,13 +2811,11 @@
+ export CC CXX CFLAGS CXXFLAGS LD LDFLAGS AR
+ ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' CXXFLAGS='$CXXFLAGS'"
+
++AM_CONDITIONAL([NEED_THREADS], [test x"$with_server" != xno -o x"$THREAD_SAFE_CLIENT" != xno])
+ if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"
+ then
+ AC_DEFINE([THREAD], [1],
+ [Define if you want to have threaded code. This may be undef on client code])
+- # Avoid _PROGRAMS names
+- THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
+- AC_SUBST(THREAD_LOBJECTS)
+ fi
+
+ if test "$with_server" = "no"
+@@ -2822,7 +2823,7 @@
+ AM_CONDITIONAL([BUILD_INNODB_TOOLS], [false])
+ else
+ server_scripts="mysqld_safe mysql_install_db"
+- sql_server_dirs="strings mysys dbug extra regex"
++ sql_server_dirs="strings dbug mysys extra regex"
+
+
+ #
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/dbug/Makefile.am mysql/dbug/Makefile.am
+--- mysql.orig/dbug/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/dbug/Makefile.am 2012-04-01 10:47:50.423941710 -0700
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a
+-pkglib_LIBRARIES = libdbug.a
++LDADD = ../mysys/libmysys.la ../strings/libmystrings.la
++noinst_LTLIBRARIES = libdbug.la
+ noinst_HEADERS = dbug_long.h
+-libdbug_a_SOURCES = dbug.c sanity.c
++libdbug_la_SOURCES = dbug.c sanity.c
+ EXTRA_DIST = example1.c example2.c example3.c \
+ user.r monty.doc readme.prof dbug_add_tags.pl \
+ my_main.c main.c factorial.c dbug_analyze.c \
+@@ -31,11 +31,11 @@
+
+
+ # Must be linked with libs that are not compiled yet
+-noinst_PROGRAMS = factorial dbug_analyze
++EXTRA_PROGRAMS = factorial dbug_analyze
+ factorial_SOURCES = my_main.c factorial.c
+ dbug_analyze_SOURCES = dbug_analyze.c
+
+-all: user.t user.ps
++check-local: user.t user.ps
+
+ user.t: user.r $(NROFF_INC)
+ -nroff -mm user.r > $@
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/extra/Makefile.am mysql/extra/Makefile.am
+--- mysql.orig/extra/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/extra/Makefile.am 2012-04-01 10:47:50.424941725 -0700
+@@ -15,8 +15,7 @@
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ @ndbcluster_includes@ -I$(top_srcdir)/sql
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
+ $(ZLIB_LIBS)
+ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
+ $(top_builddir)/include/sql_state.h \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/heap/Makefile.am mysql/heap/Makefile.am
+--- mysql.orig/heap/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/heap/Makefile.am 2012-04-01 10:47:50.424941725 -0700
+@@ -14,14 +14,13 @@
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libheap.a ../mysys/libmysys.a ../dbug/libdbug.a \
+- ../strings/libmystrings.a
+-pkglib_LIBRARIES = libheap.a
++LDADD = libheap.la ../mysys/libmysys.la
++pkglib_LTLIBRARIES = libheap.la
+ noinst_PROGRAMS = hp_test1 hp_test2
+ hp_test1_LDFLAGS = @NOINST_LDFLAGS@
+ hp_test2_LDFLAGS = @NOINST_LDFLAGS@
+ noinst_HEADERS = heapdef.h
+-libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
++libheap_la_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
+ hp_rrnd.c hp_scan.c hp_update.c hp_write.c hp_delete.c \
+ hp_rsame.c hp_create.c hp_rename.c hp_rfirst.c \
+ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/btr/Makefile.am mysql/innobase/btr/Makefile.am
+--- mysql.orig/innobase/btr/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/btr/Makefile.am 2012-04-01 10:47:50.424941725 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libbtr.a
++noinst_LTLIBRARIES = libbtr.la
+
+-libbtr_a_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c
++libbtr_la_SOURCES = btr0btr.c btr0cur.c btr0pcur.c btr0sea.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/buf/Makefile.am mysql/innobase/buf/Makefile.am
+--- mysql.orig/innobase/buf/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/buf/Makefile.am 2012-04-01 10:47:50.424941725 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libbuf.a
++noinst_LTLIBRARIES = libbuf.la
+
+-libbuf_a_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
++libbuf_la_SOURCES = buf0buf.c buf0flu.c buf0lru.c buf0rea.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/configure.in mysql/innobase/configure.in
+--- mysql.orig/innobase/configure.in 2012-03-02 06:04:10.000000000 -0800
++++ mysql/innobase/configure.in 2012-04-01 10:47:50.425941740 -0700
+@@ -32,7 +32,7 @@
+ CXXFLAGS="$CXXFLAGS "
+
+ AC_PROG_CC
+-AC_PROG_RANLIB
++#AC_PROG_RANLIB
+ AC_PROG_INSTALL
+ AC_PROG_LIBTOOL
+ AC_CHECK_HEADERS(aio.h sched.h)
+@@ -126,14 +126,4 @@
+ fi
+ AC_SUBST(ARFLAGS)
+
+-AC_OUTPUT(Makefile os/Makefile ut/Makefile btr/Makefile dnl
+- buf/Makefile data/Makefile dnl
+- dict/Makefile dyn/Makefile dnl
+- eval/Makefile fil/Makefile fsp/Makefile fut/Makefile dnl
+- ha/Makefile ibuf/Makefile include/Makefile dnl
+- lock/Makefile log/Makefile dnl
+- mach/Makefile mem/Makefile mtr/Makefile dnl
+- page/Makefile pars/Makefile que/Makefile dnl
+- read/Makefile rem/Makefile row/Makefile dnl
+- srv/Makefile sync/Makefile thr/Makefile trx/Makefile dnl
+- usr/Makefile)
++AC_OUTPUT(Makefile)
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/data/Makefile.am mysql/innobase/data/Makefile.am
+--- mysql.orig/innobase/data/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/data/Makefile.am 2012-04-01 10:47:50.425941740 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdata.a
++noinst_LTLIBRARIES = libdata.la
+
+-libdata_a_SOURCES = data0data.c data0type.c
++libdata_la_SOURCES = data0data.c data0type.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/dict/Makefile.am mysql/innobase/dict/Makefile.am
+--- mysql.orig/innobase/dict/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/dict/Makefile.am 2012-04-01 10:47:50.425941740 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdict.a
++noinst_LTLIBRARIES = libdict.la
+
+-libdict_a_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\
++libdict_la_SOURCES = dict0boot.c dict0crea.c dict0dict.c dict0load.c\
+ dict0mem.c
+
+ EXTRA_PROGRAMS =
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/dyn/Makefile.am mysql/innobase/dyn/Makefile.am
+--- mysql.orig/innobase/dyn/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/dyn/Makefile.am 2012-04-01 10:47:50.425941740 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libdyn.a
++noinst_LTLIBRARIES = libdyn.la
+
+-libdyn_a_SOURCES = dyn0dyn.c
++libdyn_la_SOURCES = dyn0dyn.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/eval/Makefile.am mysql/innobase/eval/Makefile.am
+--- mysql.orig/innobase/eval/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/eval/Makefile.am 2012-04-01 10:47:50.425941740 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libeval.a
++noinst_LTLIBRARIES = libeval.la
+
+-libeval_a_SOURCES = eval0eval.c eval0proc.c
++libeval_la_SOURCES = eval0eval.c eval0proc.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/fil/Makefile.am mysql/innobase/fil/Makefile.am
+--- mysql.orig/innobase/fil/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/fil/Makefile.am 2012-04-01 10:47:50.426941755 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfil.a
++noinst_LTLIBRARIES = libfil.la
+
+-libfil_a_SOURCES = fil0fil.c
++libfil_la_SOURCES = fil0fil.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/fsp/Makefile.am mysql/innobase/fsp/Makefile.am
+--- mysql.orig/innobase/fsp/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/fsp/Makefile.am 2012-04-01 10:47:50.426941755 -0700
+@@ -16,9 +16,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfsp.a
++noinst_LTLIBRARIES = libfsp.la
+
+-libfsp_a_SOURCES = fsp0fsp.c
++libfsp_la_SOURCES = fsp0fsp.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/fut/Makefile.am mysql/innobase/fut/Makefile.am
+--- mysql.orig/innobase/fut/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/fut/Makefile.am 2012-04-01 10:47:50.426941755 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libfut.a
++noinst_LTLIBRARIES = libfut.la
+
+-libfut_a_SOURCES = fut0fut.c fut0lst.c
++libfut_la_SOURCES = fut0fut.c fut0lst.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/ha/Makefile.am mysql/innobase/ha/Makefile.am
+--- mysql.orig/innobase/ha/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/ha/Makefile.am 2012-04-01 10:47:50.426941755 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libha.a
++noinst_LTLIBRARIES = libha.la
+
+-libha_a_SOURCES = ha0ha.c hash0hash.c
++libha_la_SOURCES = ha0ha.c hash0hash.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/ibuf/Makefile.am mysql/innobase/ibuf/Makefile.am
+--- mysql.orig/innobase/ibuf/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/ibuf/Makefile.am 2012-04-01 10:47:50.427941770 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libibuf.a
++noinst_LTLIBRARIES = libibuf.la
+
+-libibuf_a_SOURCES = ibuf0ibuf.c
++libibuf_la_SOURCES = ibuf0ibuf.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/lock/Makefile.am mysql/innobase/lock/Makefile.am
+--- mysql.orig/innobase/lock/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/lock/Makefile.am 2012-04-01 10:47:50.427941770 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = liblock.a
++noinst_LTLIBRARIES = liblock.la
+
+-liblock_a_SOURCES = lock0lock.c
++liblock_la_SOURCES = lock0lock.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/log/Makefile.am mysql/innobase/log/Makefile.am
+--- mysql.orig/innobase/log/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/log/Makefile.am 2012-04-01 10:47:50.427941770 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = liblog.a
++noinst_LTLIBRARIES = liblog.la
+
+-liblog_a_SOURCES = log0log.c log0recv.c
++liblog_la_SOURCES = log0log.c log0recv.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/mach/Makefile.am mysql/innobase/mach/Makefile.am
+--- mysql.orig/innobase/mach/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/mach/Makefile.am 2012-04-01 10:47:50.427941770 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmach.a
++noinst_LTLIBRARIES = libmach.la
+
+-libmach_a_SOURCES = mach0data.c
++libmach_la_SOURCES = mach0data.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/Makefile.am mysql/innobase/Makefile.am
+--- mysql.orig/innobase/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/Makefile.am 2012-04-01 10:47:50.428941784 -0700
+@@ -15,14 +15,35 @@
+
+ # Process this file with automake to create Makefile.in
+
+-AUTOMAKE_OPTIONS = foreign
+-TAR = gtar
+-
+ noinst_HEADERS = ib_config.h
+
+-SUBDIRS = os ut btr buf data dict dyn eval fil fsp fut \
+- ha ibuf include lock log mach mem mtr page \
+- pars que read rem row srv sync thr trx usr
++INCLUDES = -I$(srcdir)/include -I$(srcdir)/../include
++
++pkglib_LTLIBRARIES = libinnobase.la
++
++libinnobase_la_SOURCES = btr/btr0btr.c btr/btr0cur.c \
++ btr/btr0pcur.c btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \
++ buf/buf0lru.c buf/buf0rea.c data/data0data.c data/data0type.c \
++ dict/dict0boot.c dict/dict0crea.c dict/dict0dict.c \
++ dict/dict0load.c dict/dict0mem.c dyn/dyn0dyn.c \
++ eval/eval0eval.c eval/eval0proc.c fil/fil0fil.c \
++ fsp/fsp0fsp.c fut/fut0fut.c fut/fut0lst.c ha/ha0ha.c \
++ ha/hash0hash.c ibuf/ibuf0ibuf.c lock/lock0lock.c \
++ log/log0log.c log/log0recv.c mach/mach0data.c \
++ mem/mem0mem.c mem/mem0pool.c mtr/mtr0mtr.c mtr/mtr0log.c \
++ os/os0proc.c os/os0sync.c os/os0thread.c os/os0file.c \
++ page/page0page.c page/page0cur.c pars/pars0grm.c pars/lexyy.c \
++ pars/pars0opt.c pars/pars0pars.c pars/pars0sym.c \
++ que/que0que.c read/read0read.c rem/rem0rec.c rem/rem0cmp.c \
++ row/row0ins.c row/row0mysql.c row/row0purge.c row/row0row.c \
++ row/row0sel.c row/row0uins.c row/row0umod.c row/row0undo.c \
++ row/row0upd.c row/row0vers.c srv/srv0srv.c srv/srv0que.c \
++ srv/srv0start.c sync/sync0arr.c sync/sync0rw.c \
++ sync/sync0sync.c thr/thr0loc.c trx/trx0purge.c \
++ trx/trx0rec.c trx/trx0roll.c trx/trx0rseg.c trx/trx0sys.c \
++ trx/trx0trx.c trx/trx0undo.c usr/usr0sess.c ut/ut0byte.c \
++ ut/ut0dbg.c ut/ut0mem.c ut/ut0rnd.c ut/ut0ut.c
++
+ EXTRA_DIST = CMakeLists.txt
+
+ # Don't update the files from bitkeeper
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/mem/Makefile.am mysql/innobase/mem/Makefile.am
+--- mysql.orig/innobase/mem/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/mem/Makefile.am 2012-04-01 10:47:50.428941784 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmem.a
++noinst_LTLIBRARIES = libmem.la
+
+-libmem_a_SOURCES = mem0mem.c mem0pool.c
++libmem_la_SOURCES = mem0mem.c mem0pool.c
+
+ EXTRA_DIST = mem0dbg.c
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/mtr/Makefile.am mysql/innobase/mtr/Makefile.am
+--- mysql.orig/innobase/mtr/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/mtr/Makefile.am 2012-04-01 10:47:50.428941784 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libmtr.a
++noinst_LTLIBRARIES = libmtr.la
+
+-libmtr_a_SOURCES = mtr0mtr.c mtr0log.c
++libmtr_la_SOURCES = mtr0mtr.c mtr0log.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/os/Makefile.am mysql/innobase/os/Makefile.am
+--- mysql.orig/innobase/os/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/os/Makefile.am 2012-04-01 10:47:50.428941784 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libos.a
++noinst_LTLIBRARIES = libos.la
+
+-libos_a_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c
++libos_la_SOURCES = os0proc.c os0sync.c os0thread.c os0file.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/page/Makefile.am mysql/innobase/page/Makefile.am
+--- mysql.orig/innobase/page/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/page/Makefile.am 2012-04-01 10:47:50.429941798 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libpage.a
++noinst_LTLIBRARIES = libpage.la
+
+-libpage_a_SOURCES = page0page.c page0cur.c
++libpage_la_SOURCES = page0page.c page0cur.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/pars/Makefile.am mysql/innobase/pars/Makefile.am
+--- mysql.orig/innobase/pars/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/pars/Makefile.am 2012-04-01 10:47:50.433941856 -0700
+@@ -15,11 +15,11 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libpars.a
++noinst_LTLIBRARIES = libpars.la
+
+ noinst_HEADERS = pars0grm.h
+
+-libpars_a_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c
++libpars_la_SOURCES = pars0grm.c lexyy.c pars0opt.c pars0pars.c pars0sym.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/que/Makefile.am mysql/innobase/que/Makefile.am
+--- mysql.orig/innobase/que/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/que/Makefile.am 2012-04-01 10:47:50.433941856 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libque.a
++noinst_LTLIBRARIES = libque.la
+
+-libque_a_SOURCES = que0que.c
++libque_la_SOURCES = que0que.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/read/Makefile.am mysql/innobase/read/Makefile.am
+--- mysql.orig/innobase/read/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/read/Makefile.am 2012-04-01 10:47:50.433941856 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libread.a
++noinst_LTLIBRARIES = libread.la
+
+-libread_a_SOURCES = read0read.c
++libread_la_SOURCES = read0read.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/rem/Makefile.am mysql/innobase/rem/Makefile.am
+--- mysql.orig/innobase/rem/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/rem/Makefile.am 2012-04-01 10:47:50.433941856 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = librem.a
++noinst_LTLIBRARIES = librem.la
+
+-librem_a_SOURCES = rem0rec.c rem0cmp.c
++librem_la_SOURCES = rem0rec.c rem0cmp.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/row/Makefile.am mysql/innobase/row/Makefile.am
+--- mysql.orig/innobase/row/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/row/Makefile.am 2012-04-01 10:47:50.434941870 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = librow.a
++noinst_LTLIBRARIES = librow.la
+
+-librow_a_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\
++librow_la_SOURCES = row0ins.c row0mysql.c row0purge.c row0row.c row0sel.c\
+ row0uins.c row0umod.c row0undo.c row0upd.c row0vers.c
+
+ EXTRA_PROGRAMS =
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/srv/Makefile.am mysql/innobase/srv/Makefile.am
+--- mysql.orig/innobase/srv/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/srv/Makefile.am 2012-04-01 10:47:50.434941870 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libsrv.a
++noinst_LTLIBRARIES = libsrv.la
+
+-libsrv_a_SOURCES = srv0srv.c srv0que.c srv0start.c
++libsrv_la_SOURCES = srv0srv.c srv0que.c srv0start.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/sync/Makefile.am mysql/innobase/sync/Makefile.am
+--- mysql.orig/innobase/sync/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/sync/Makefile.am 2012-04-01 10:47:50.434941870 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libsync.a
++noinst_LTLIBRARIES = libsync.la
+
+-libsync_a_SOURCES = sync0arr.c sync0rw.c sync0sync.c
++libsync_la_SOURCES = sync0arr.c sync0rw.c sync0sync.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/thr/Makefile.am mysql/innobase/thr/Makefile.am
+--- mysql.orig/innobase/thr/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/thr/Makefile.am 2012-04-01 10:47:50.434941870 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libthr.a
++noinst_LTLIBRARIES = libthr.la
+
+-libthr_a_SOURCES = thr0loc.c
++libthr_la_SOURCES = thr0loc.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/trx/Makefile.am mysql/innobase/trx/Makefile.am
+--- mysql.orig/innobase/trx/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/trx/Makefile.am 2012-04-01 10:47:50.435941885 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libtrx.a
++noinst_LTLIBRARIES = libtrx.la
+
+-libtrx_a_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\
++libtrx_la_SOURCES = trx0purge.c trx0rec.c trx0roll.c trx0rseg.c\
+ trx0sys.c trx0trx.c trx0undo.c
+
+ EXTRA_PROGRAMS =
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/usr/Makefile.am mysql/innobase/usr/Makefile.am
+--- mysql.orig/innobase/usr/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/usr/Makefile.am 2012-04-01 10:47:50.435941885 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libusr.a
++noinst_LTLIBRARIES = libusr.la
+
+-libusr_a_SOURCES = usr0sess.c
++libusr_la_SOURCES = usr0sess.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/innobase/ut/Makefile.am mysql/innobase/ut/Makefile.am
+--- mysql.orig/innobase/ut/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/innobase/ut/Makefile.am 2012-04-01 10:47:50.435941885 -0700
+@@ -15,9 +15,9 @@
+
+ include ../include/Makefile.i
+
+-noinst_LIBRARIES = libut.a
++noinst_LTLIBRARIES = libut.la
+
+-libut_a_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c
++libut_la_SOURCES = ut0byte.c ut0dbg.c ut0mem.c ut0rnd.c ut0ut.c
+
+ EXTRA_PROGRAMS =
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysql/Makefile.am mysql/libmysql/Makefile.am
+--- mysql.orig/libmysql/Makefile.am 2012-03-02 06:04:07.000000000 -0800
++++ mysql/libmysql/Makefile.am 2012-04-01 10:47:50.435941885 -0700
+@@ -105,8 +105,8 @@
+ echo "# This file is autogenerated from Makefile.am" >> $$dir/Makefile; \
+ echo 'CFLAGS= -I. -DUNDEF_THREADS_HACK' >>$$dir/Makefile; \
+ echo "obj=$$objs" >>$$dir/Makefile; \
+- echo 'all: libmysql.a' >>$$dir/Makefile; \
+- echo 'libmysql.a: $$(obj)' >>$$dir/Makefile; \
++ echo 'all: libmysql.la' >>$$dir/Makefile; \
++ echo 'libmysql.la: $$(obj)' >>$$dir/Makefile; \
+ echo ' $$(AR) r $$@ $$?' >>$$dir/Makefile; \
+ gtar cvzf $$dir.tar.gz $$dir; \
+ cd $$dir; gmake
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysqld/examples/Makefile.am mysql/libmysqld/examples/Makefile.am
+--- mysql.orig/libmysqld/examples/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/libmysqld/examples/Makefile.am 2012-04-01 10:47:50.436941900 -0700
+@@ -35,12 +35,12 @@
+ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
+ $(openssl_includes)
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.la @innodb_system_libs@ @LIBDL@ $(CXXLDFLAGS) \
+ @NDB_SCI_LIBS@
+
+ mysqltest_embedded_LINK = $(CXXLINK)
+ mysqltest_embedded_SOURCES = mysqltest.c
+-mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a
++mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.la
+
+ mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+ my_readline.h sql_string.h completion_hash.h
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/libmysqld/Makefile.am mysql/libmysqld/Makefile.am
+--- mysql.orig/libmysqld/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/libmysqld/Makefile.am 2012-04-01 10:47:50.436941900 -0700
+@@ -33,10 +33,10 @@
+ -I$(top_srcdir)/regex \
+ $(openssl_includes) @ZLIB_INCLUDES@
+
+-noinst_LIBRARIES = libmysqld_int.a
+-pkglib_LIBRARIES = libmysqld.a
++noinst_LTLIBRARIES = libmysqld_int.la
++pkglib_LTLIBRARIES = libmysqld.la
+ SUBDIRS = . examples
+-libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
++#libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
+ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
+ my_time.c
+ sqlexamplessources = ha_example.cc ha_tina.cc
+@@ -68,50 +68,22 @@
+ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
+ ha_blackhole.cc ha_archive.cc my_user.c
+
+-libmysqld_int_a_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources)
+-libmysqld_a_SOURCES=
++libmysqld_int_la_SOURCES= $(libmysqld_sources) $(libmysqlsources) $(sqlsources) $(sqlexamplessources)
++#libmysqld_la_SOURCES=
++libmysqld_la_SOURCES= libmysqld.c lib_sql.cc emb_qcache.cc
+
+ # automake misses these
+ sql_yacc.cc sql_yacc.h: $(top_srcdir)/sql/sql_yacc.yy
+
+-# The following libraries should be included in libmysqld.a
+-INC_LIB= $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/myisam/libmyisam.a \
+- $(top_builddir)/myisammrg/libmyisammrg.a \
+- $(top_builddir)/heap/libheap.a \
+- @innodb_libs@ @bdb_libs_with_path@ \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/vio/libvio.a @NDB_SCI_LIBS@
+-
+-
+-#
+-# 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 `echo $(INC_LIB) | sort -u`
+-else
+- -rm -f libmysqld.a
+- if test "$(host_os)" = "netware" ; \
+- then \
+- $(libmysqld_a_AR) libmysqld.a libmysqld_int.a $(INC_LIB) ; \
+- else \
+- 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
++# The following libraries should be included in libmysqld.la
++libmysqld_la_LIBADD= $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/myisam/libmyisam.la \
++ $(top_builddir)/myisammrg/libmyisammrg.la \
++ $(top_builddir)/heap/libheap.la \
++ $(top_builddir)/innobase/libinnobase.la @bdb_libs_with_path@ \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/vio/libvio.la @NDB_SCI_LIBS@ \
++ libmysqld_int.la
+
+ ## XXX: any time the client interface changes, we'll need to bump
+ ## the version info for libmysqld; however, it's possible for the
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/myisam/Makefile.am mysql/myisam/Makefile.am
+--- mysql.orig/myisam/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/myisam/Makefile.am 2012-04-01 10:47:50.436941900 -0700
+@@ -16,27 +16,27 @@
+ EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt
+ pkgdata_DATA = mi_test_all mi_test_all.res
+
+-INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-pkglib_LIBRARIES = libmyisam.a
++INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
++ -I$(top_builddir)/sql -I$(top_srcdir)/sql
++LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(ZLIB_LIBS)
++noinst_LTLIBRARIES = libmyisam.la
+ bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
+-myisamchk_DEPENDENCIES= $(LIBRARIES)
+-myisamlog_DEPENDENCIES= $(LIBRARIES)
+-myisampack_DEPENDENCIES=$(LIBRARIES)
++myisamchk_DEPENDENCIES= $(LTLIBRARIES)
++myisamlog_DEPENDENCIES= $(LTLIBRARIES)
++myisampack_DEPENDENCIES=$(LTLIBRARIES)
+ noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
+ noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h fulltext.h ftdefs.h ft_test1.h ft_eval.h
+-mi_test1_DEPENDENCIES= $(LIBRARIES)
+-mi_test2_DEPENDENCIES= $(LIBRARIES)
+-mi_test3_DEPENDENCIES= $(LIBRARIES)
+-#ft_test1_DEPENDENCIES= $(LIBRARIES)
+-#ft_eval_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
+-rt_test_DEPENDENCIES= $(LIBRARIES)
+-sp_test_DEPENDENCIES= $(LIBRARIES)
+-libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
++mi_test1_DEPENDENCIES= $(LTLIBRARIES)
++mi_test2_DEPENDENCIES= $(LTLIBRARIES)
++mi_test3_DEPENDENCIES= $(LTLIBRARIES)
++#ft_test1_DEPENDENCIES= $(LTLIBRARIES)
++#ft_eval_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_DEPENDENCIES= $(LTLIBRARIES)
++rt_test_DEPENDENCIES= $(LTLIBRARIES)
++sp_test_DEPENDENCIES= $(LTLIBRARIES)
++libmyisam_la_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
+ mi_rnext.c mi_rnext_same.c \
+ mi_search.c mi_page.c mi_key.c mi_locking.c \
+ mi_rrnd.c mi_scan.c mi_cache.c \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/myisammrg/Makefile.am mysql/myisammrg/Makefile.am
+--- mysql.orig/myisammrg/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/myisammrg/Makefile.am 2012-04-01 10:47:50.437941915 -0700
+@@ -14,9 +14,9 @@
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmyisammrg.a
++noinst_LTLIBRARIES = libmyisammrg.la
+ noinst_HEADERS = myrg_def.h
+-libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
++libmyisammrg_la_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
+ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
+ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
+ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/mysys/Makefile.am mysql/mysys/Makefile.am
+--- mysql.orig/mysys/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/mysys/Makefile.am 2012-04-01 10:51:23.928012030 -0700
+@@ -18,11 +18,9 @@
+ MYSQLBASEdir= $(prefix)
+ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include -I$(srcdir)
+-pkglib_LIBRARIES = libmysys.a
+-LDADD = libmysys.a ../dbug/libdbug.a \
+- ../strings/libmystrings.a
++pkglib_LTLIBRARIES = libmysys.la
+ noinst_HEADERS = mysys_priv.h my_static.h
+-libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
++libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
+ mf_path.c mf_loadpath.c my_file.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
+ my_pread.c my_write.c my_getpagesize.c \
+@@ -51,16 +49,21 @@
+ charset.c charset-def.c my_bitmap.c my_bit.c md5.c \
+ rijndael.c my_aes.c sha1.c \
+ my_netware.c my_largepage.c \
+- my_memmem.c \
+- my_windac.c my_access.c base64.c my_libwrap.c
++ my_memmem.c my_windac.c my_access.c base64.c \
++ my_libwrap.c
++libmysys_la_LIBADD = $(top_builddir)/dbug/libdbug.la $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
++if NEED_THREADS
++libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c my_pthread.c my_thr_init.c
++endif
++
+ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
+ thr_mutex.c thr_rwlock.c mf_soundex.c my_conio.c \
+ my_wincond.c my_winthread.c CMakeLists.txt
+-libmysys_a_LIBADD = @THREAD_LOBJECTS@
+-# test_dir_DEPENDENCIES= $(LIBRARIES)
+-# testhash_DEPENDENCIES= $(LIBRARIES)
+-# test_charset_DEPENDENCIES= $(LIBRARIES)
+-# charset2html_DEPENDENCIES= $(LIBRARIES)
++# test_dir_DEPENDENCIES= $(LTLIBRARIES)
++# testhash_DEPENDENCIES= $(LTLIBRARIES)
++# test_charset_DEPENDENCIES= $(LTLIBRARIES)
++# charset2html_DEPENDENCIES= $(LTLIBRARIES)
+ EXTRA_PROGRAMS =
+ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
+ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+@@ -71,8 +74,6 @@
+ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ @DEFS@
+
+-libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
+-
+ # I hope this always does the right thing. Otherwise this is only test programs
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+@@ -81,41 +82,41 @@
+ # which automaticly removes the object files you use to compile a final program
+ #
+
+-test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
++test_thr_alarm$(EXEEXT): thr_alarm.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_alarm.c
+
+-test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
++test_thr_lock$(EXEEXT): thr_lock.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_lock.c test_thr_lock.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_lock.c
+
+-test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
++test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
+ $(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
+ $(RM) -f test_vsnprintf.c
+
+-test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
++test_io_cache$(EXEEXT): mf_iocache.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.c
+
+-test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
++test_dir$(EXEEXT): test_dir.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
+
+-test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
++test_charset$(EXEEXT): test_charset.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
+
+-testhash$(EXEEXT): testhash.c $(LIBRARIES)
++testhash$(EXEEXT): testhash.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
+
+-test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
++test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
+ $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_gethwaddr.c
+
+-test_base64$(EXEEXT): base64.c $(LIBRARIES)
++test_base64$(EXEEXT): base64.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/base64.c ./test_base64.c
+ $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_base64.c
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/config/type_ndbapitest.mk.am mysql/ndb/config/type_ndbapitest.mk.am
+--- mysql.orig/ndb/config/type_ndbapitest.mk.am 2012-03-02 06:04:13.000000000 -0800
++++ mysql/ndb/config/type_ndbapitest.mk.am 2012-04-01 10:47:50.443942002 -0700
+@@ -15,9 +15,9 @@
+
+ LDADD += $(top_builddir)/ndb/test/src/libNDBT.a \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ INCLUDES += -I$(top_srcdir) \
+ -I$(top_builddir)/include \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/config/type_ndbapitools.mk.am mysql/ndb/config/type_ndbapitools.mk.am
+--- mysql.orig/ndb/config/type_ndbapitools.mk.am 2012-03-02 06:04:13.000000000 -0800
++++ mysql/ndb/config/type_ndbapitools.mk.am 2012-04-01 10:47:50.443942002 -0700
+@@ -15,9 +15,9 @@
+
+ LDADD += \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ INCLUDES += -I$(srcdir) \
+ -I$(top_builddir)/include \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/config/win-libraries mysql/ndb/config/win-libraries
+--- mysql.orig/ndb/config/win-libraries 2012-03-02 06:04:08.000000000 -0800
++++ mysql/ndb/config/win-libraries 2012-04-01 10:47:50.443942002 -0700
+@@ -36,7 +36,7 @@
+ # the same goes for mysys and strings
+ lib=$i
+ case $i in
+- *libdbug.a | *libmysys.a | *libmystrings.a)
++ *libdbug.la | *libmysys.la | *libmystrings.la)
+ lib=`echo $i | sed s'!dbug\/lib!!' | sed 's!mysys\/lib!!' | sed 's!strings\/libmy!!'`
+ echo "Changing from $i to $lib"
+ ;;
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/common/util/Makefile.am mysql/ndb/src/common/util/Makefile.am
+--- mysql.orig/ndb/src/common/util/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/src/common/util/Makefile.am 2012-04-01 10:47:50.441941973 -0700
+@@ -31,9 +31,9 @@
+ testBitmask_SOURCES = testBitmask.cpp
+ testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testBitmask.cpp : Bitmask.cpp
+ rm -f testBitmask.cpp
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/cw/cpcd/Makefile.am mysql/ndb/src/cw/cpcd/Makefile.am
+--- mysql.orig/ndb/src/cw/cpcd/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/src/cw/cpcd/Makefile.am 2012-04-01 10:47:50.442941987 -0700
+@@ -19,9 +19,9 @@
+
+ LDADD_LOC = \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ include $(top_srcdir)/ndb/config/common.mk.am
+ include $(top_srcdir)/ndb/config/type_util.mk.am
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.am mysql/ndb/src/kernel/blocks/dbdict/Makefile.am
+--- mysql.orig/ndb/src/kernel/blocks/dbdict/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/src/kernel/blocks/dbdict/Makefile.am 2012-04-01 10:47:50.442941987 -0700
+@@ -26,9 +26,9 @@
+ LDADD += \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/kernel/Makefile.am mysql/ndb/src/kernel/Makefile.am
+--- mysql.orig/ndb/src/kernel/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/src/kernel/Makefile.am 2012-04-01 10:47:50.442941987 -0700
+@@ -66,9 +66,9 @@
+ $(top_builddir)/ndb/src/mgmapi/libmgmapi.la \
+ $(top_builddir)/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/ndb/src/common/util/libgeneral.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/mgmclient/Makefile.am mysql/ndb/src/mgmclient/Makefile.am
+--- mysql.orig/ndb/src/mgmclient/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/src/mgmclient/Makefile.am 2012-04-01 10:47:50.442941987 -0700
+@@ -37,9 +37,9 @@
+ ../common/portlib/libportlib.la \
+ @readline_link@ \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @TERMCAP_LIB@ @NDB_SCI_LIBS@
+
+ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/src/mgmsrv/Makefile.am mysql/ndb/src/mgmsrv/Makefile.am
+--- mysql.orig/ndb/src/mgmsrv/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/ndb/src/mgmsrv/Makefile.am 2012-04-01 10:47:50.442941987 -0700
+@@ -41,9 +41,9 @@
+
+ LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CommandInterpreter.lo \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @readline_link@ \
+ @NDB_SCI_LIBS@ \
+ @TERMCAP_LIB@
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/ndb/test/run-test/Makefile.am mysql/ndb/test/run-test/Makefile.am
+--- mysql.orig/ndb/test/run-test/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/ndb/test/run-test/Makefile.am 2012-04-01 10:47:50.443942002 -0700
+@@ -32,9 +32,9 @@
+ INCLUDES_LOC = -I$(top_srcdir)/ndb/test/include
+ LDADD_LOC = $(top_builddir)/ndb/test/src/libNDBT.a \
+ $(top_builddir)/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ wrappersdir=$(prefix)/bin
+ wrappers_SCRIPTS=atrt-testBackup atrt-mysql-test-run
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/netware/Makefile.am mysql/netware/Makefile.am
+--- mysql.orig/netware/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/netware/Makefile.am 2012-04-01 10:47:50.437941915 -0700
+@@ -16,14 +16,13 @@
+
+ if HAVE_NETWARE
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I..
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la
+ bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
+ mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
+ mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
+ mysql_test_run_SOURCES= mysql_test_run.c my_manage.c
+ libmysql_SOURCES= libmysqlmain.c
+-libmysql_LDADD = ../libmysql/.libs/libmysqlclient.a \
++libmysql_LDADD = ../libmysql/.libs/libmysqlclient.la \
+ @openssl_libs@ @yassl_libs@
+
+ netware_build_files = client/mysql.def client/mysqladmin.def \
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/pstack/Makefile.am mysql/pstack/Makefile.am
+--- mysql.orig/pstack/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/pstack/Makefile.am 2012-04-01 10:47:50.438941930 -0700
+@@ -27,8 +27,8 @@
+ EXTRA_DIST= $(SRC)
+
+ if COMPILE_PSTACK
+-pkglib_LIBRARIES = libpstack.a
+-libpstack_a_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
++pkglib_LTLIBRARIES = libpstack.la
++libpstack_la_SOURCES = bucomm.c filemode.c linuxthreads.c rddbg.c debug.c ieee.c pstack.c stabs.c
+ endif
+
+ # Don't update the files from bitkeeper
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/regex/Makefile.am mysql/regex/Makefile.am
+--- mysql.orig/regex/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/regex/Makefile.am 2012-04-01 10:47:50.439941945 -0700
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-noinst_LIBRARIES = libregex.a
+-LDADD= libregex.a $(top_builddir)/strings/libmystrings.a
++noinst_LTLIBRARIES = libregex.la
++LDADD= libregex.la $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
+-libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
++libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
+ noinst_PROGRAMS = re
+ re_SOURCES = split.c debug.c main.c
+ re_LDFLAGS= @NOINST_LDFLAGS@
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/server-tools/instance-manager/Makefile.am mysql/server-tools/instance-manager/Makefile.am
+--- mysql.orig/server-tools/instance-manager/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/server-tools/instance-manager/Makefile.am 2012-04-01 10:47:50.439941945 -0700
+@@ -24,8 +24,7 @@
+ # default_options.h, generated from default_options.h.in)
+ # See automake/autoconf docs for details
+
+-noinst_LTLIBRARIES= liboptions.la
+-noinst_LIBRARIES= libnet.a
++noinst_LTLIBRARIES= liboptions.la libnet.la
+
+ liboptions_la_CXXFLAGS= $(CXXFLAGS) \
+ -DDEFAULT_PID_FILE_NAME="$(localstatedir)/mysqlmanager.pid" \
+@@ -37,17 +36,17 @@
+ -DPROTOCOL_VERSION=@PROTOCOL_VERSION@
+
+ liboptions_la_SOURCES= options.h options.cc priv.h priv.cc
+-liboptions_la_LIBADD= $(top_builddir)/libmysql/get_password.lo
++
++liboptions_la_LIBADD= $(top_builddir)/libmysql/libmysqlclient.la
+
+ # MySQL sometimes uses symlinks to reuse code
+ # All symlinked files are grouped in libnet.a
+
+-nodist_libnet_a_SOURCES= net_serv.cc client_settings.h
+-libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \
+- $(top_builddir)/sql/pack.$(OBJEXT) \
+- $(top_builddir)/sql/sql_state.$(OBJEXT) \
+- $(top_builddir)/sql/mini_client_errors.$(OBJEXT)\
+- $(top_builddir)/sql/client.$(OBJEXT)
++nodist_libnet_la_SOURCES= net_serv.cc client_settings.h \
++ $(srcdir)/../../sql/password.c $(srcdir)/../../sql/pack.c \
++ $(srcdir)/../../sql/sql_state.c $(srcdir)/../../sql/mini_client_errors.c \
++ $(srcdir)/../../sql/client.c
++
+
+ CLEANFILES= net_serv.cc client_settings.h
+
+@@ -79,11 +78,11 @@
+ portability.h
+
+ mysqlmanager_LDADD= liboptions.la \
+- libnet.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
++ libnet.la \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+
+
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/sql/Makefile.am mysql/sql/Makefile.am
+--- mysql.orig/sql/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/sql/Makefile.am 2012-04-01 10:47:50.440941959 -0700
+@@ -30,18 +30,17 @@
+ EXTRA_PROGRAMS = gen_lex_hash
+ bin_PROGRAMS = mysql_tzinfo_to_sql
+ gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@
+-LDADD = $(top_builddir)/myisam/libmyisam.a \
+- $(top_builddir)/myisammrg/libmyisammrg.a \
+- $(top_builddir)/heap/libheap.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@ @NDB_SCI_LIBS@
++LDADD = $(top_builddir)/myisam/libmyisam.la \
++ $(top_builddir)/myisammrg/libmyisammrg.la \
++ $(top_builddir)/heap/libheap.la \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/regex/libregex.la \
++ @ZLIB_LIBS@ @NDB_SCI_LIBS@
+
+ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \
+- @bdb_libs@ @innodb_libs@ @pstack_libs@ \
+- @innodb_system_libs@ \
++ @bdb_libs@ $(top_builddir)/innobase/libinnobase.la \
++ @pstack_libs@ @innodb_system_libs@ \
+ @ndbcluster_libs@ @ndbcluster_system_libs@ \
+ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ \
+ $(yassl_libs) $(openssl_libs) @MYSQLD_EXTRA_LIBS@
+@@ -53,45 +52,36 @@
+ procedure.h sql_class.h sql_lex.h sql_list.h \
+ sql_manager.h sql_map.h sql_string.h unireg.h \
+ sql_error.h field.h handler.h mysqld_suffix.h \
+- sql_profile.h \
+- ha_myisammrg.h\
+- ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
+- ha_ndbcluster.h ha_ndbcluster_cond.h \
+- opt_range.h protocol.h \
+- sql_select.h structs.h table.h sql_udf.h hash_filo.h\
+- lex.h lex_symbol.h sql_acl.h sql_crypt.h \
+- log_event.h sql_repl.h slave.h \
+- stacktrace.h sql_sort.h sql_cache.h set_var.h \
+- spatial.h gstream.h client_settings.h tzfile.h \
+- tztime.h my_decimal.h\
++ sql_profile.h ha_heap.h ha_berkeley.h ha_innodb.h \
++ ha_ndbcluster.h ha_ndbcluster_cond.h opt_range.h \
++ protocol.h sql_select.h structs.h table.h sql_udf.h \
++ hash_filo.h lex.h lex_symbol.h sql_acl.h sql_crypt.h \
++ log_event.h sql_repl.h slave.h stacktrace.h sql_sort.h \
++ sql_cache.h set_var.h spatial.h gstream.h \
++ client_settings.h tzfile.h tztime.h my_decimal.h \
+ sp_head.h sp_pcontext.h sp_rcontext.h sp.h sp_cache.h \
+ parse_file.h sql_view.h sql_trigger.h \
+- sql_array.h sql_cursor.h \
+- examples/ha_example.h ha_archive.h \
+- examples/ha_tina.h ha_blackhole.h \
++ sql_array.h sql_cursor.h examples/ha_example.h \
++ ha_archive.h examples/ha_tina.h ha_blackhole.h \
+ ha_federated.h
+-mysqld_SOURCES = sql_lex.cc sql_handler.cc \
+- item.cc item_sum.cc item_buff.cc item_func.cc \
+- item_cmpfunc.cc item_strfunc.cc item_timefunc.cc \
+- thr_malloc.cc item_create.cc item_subselect.cc \
+- item_row.cc item_geofunc.cc \
+- field.cc strfunc.cc key.cc sql_class.cc sql_list.cc \
+- net_serv.cc protocol.cc sql_state.c \
+- lock.cc my_lock.c \
+- sql_string.cc sql_manager.cc sql_map.cc \
+- mysqld.cc password.c hash_filo.cc hostname.cc \
+- set_var.cc sql_parse.cc sql_yacc.yy \
+- sql_base.cc table.cc sql_select.cc sql_insert.cc \
+- sql_prepare.cc sql_error.cc sql_locale.cc \
+- sql_profile.cc \
+- sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
+- procedure.cc item_uniq.cc sql_test.cc \
+- log.cc log_event.cc init.cc derror.cc sql_acl.cc \
+- unireg.cc des_key_file.cc \
+- discover.cc time.cc opt_range.cc opt_sum.cc \
+- records.cc filesort.cc handler.cc \
+- ha_heap.cc ha_myisam.cc ha_myisammrg.cc \
+- ha_berkeley.cc ha_innodb.cc \
++mysqld_SOURCES = sql_lex.cc sql_handler.cc item.cc item_sum.cc \
++ item_buff.cc item_func.cc item_cmpfunc.cc \
++ item_strfunc.cc item_timefunc.cc thr_malloc.cc \
++ item_create.cc item_subselect.cc item_row.cc \
++ item_geofunc.cc field.cc strfunc.cc key.cc \
++ sql_class.cc sql_list.cc net_serv.cc protocol.cc \
++ sql_state.c lock.cc my_lock.c sql_string.cc \
++ sql_manager.cc sql_map.cc mysqld.cc password.c \
++ hash_filo.cc hostname.cc set_var.cc sql_parse.cc \
++ sql_yacc.yy sql_base.cc table.cc sql_select.cc \
++ sql_insert.cc sql_prepare.cc sql_error.cc \
++ sql_locale.cc sql_profile.cc sql_update.cc \
++ sql_delete.cc uniques.cc sql_do.cc procedure.cc \
++ item_uniq.cc sql_test.cc log.cc log_event.cc \
++ init.cc derror.cc sql_acl.cc unireg.cc \
++ des_key_file.cc discover.cc time.cc opt_range.cc \
++ opt_sum.cc records.cc filesort.cc handler.cc \
++ ha_heap.cc ha_berkeley.cc ha_innodb.cc \
+ ha_ndbcluster.cc ha_ndbcluster_cond.cc \
+ sql_db.cc sql_table.cc sql_rename.cc sql_crypt.cc \
+ sql_load.cc mf_iocache.cc field_conv.cc sql_show.cc \
+@@ -99,14 +89,13 @@
+ slave.cc sql_repl.cc sql_union.cc sql_derived.cc \
+ client.c sql_client.cc mini_client_errors.c pack.c\
+ stacktrace.c repl_failsafe.h repl_failsafe.cc \
+- sql_olap.cc sql_view.cc \
+- gstream.cc spatial.cc sql_help.cc sql_cursor.cc \
+- tztime.cc my_time.c my_user.c my_decimal.cc\
+- sp_head.cc sp_pcontext.cc sp_rcontext.cc sp.cc \
+- sp_cache.cc parse_file.cc sql_trigger.cc \
+- examples/ha_example.cc ha_archive.cc \
+- examples/ha_tina.cc ha_blackhole.cc \
+- ha_federated.cc
++ sql_olap.cc sql_view.cc gstream.cc spatial.cc \
++ sql_help.cc sql_cursor.cc tztime.cc my_time.c \
++ my_user.c my_decimal.cc sp_head.cc sp_pcontext.cc \
++ sp_rcontext.cc sp.cc sp_cache.cc parse_file.cc \
++ sql_trigger.cc examples/ha_example.cc ha_archive.cc \
++ examples/ha_tina.cc ha_blackhole.cc ha_federated.cc \
++ ha_myisam.cc ha_myisammrg.cc
+
+ gen_lex_hash_SOURCES = gen_lex_hash.cc
+ gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS)
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/Makefile.am mysql/strings/Makefile.am
+--- mysql.orig/strings/Makefile.am 2012-03-02 06:04:08.000000000 -0800
++++ mysql/strings/Makefile.am 2012-04-01 10:47:50.440941959 -0700
+@@ -17,7 +17,7 @@
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmystrings.a
++noinst_LTLIBRARIES = libmystrings.la
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+@@ -38,7 +38,7 @@
+ endif
+ endif
+
+-libmystrings_a_SOURCES = $(ASRCS) $(CSRCS)
++libmystrings_la_SOURCES = $(ASRCS) $(CSRCS)
+ noinst_PROGRAMS = conf_to_src
+ # Default charset definitions
+ EXTRA_DIST = ctype-big5.c ctype-cp932.c ctype-czech.c ctype-eucjpms.c ctype-euc_kr.c ctype-win1250ch.c \
+@@ -55,25 +55,25 @@
+ strnmov-sparc.s strstr-sparc.s strxmov-sparc.s \
+ t_ctype.h CMakeLists.txt CHARSET_INFO.txt
+
+-libmystrings_a_LIBADD=
+-conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c bcmp.c
+-conf_to_src_LDADD=
++libmystrings_la_LIBADD=
++conf_to_src_SOURCES = conf_to_src.c
++conf_to_src_LDADD = libmystrings.la
+ #force static linking of conf_to_src - essential when linking against
+ #custom installation of libc
+-conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
++#conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+
+ # This is because the dependency tracking misses @FOO@ vars in sources.
+ #strtoull.o: @CHARSET_OBJS@
+
+
+-FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
++FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
+
+-str_test: str_test.c $(pkglib_LIBRARIES)
+- $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LIBRARIES)
++str_test: str_test.c $(pkglib_LTLIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LTLIBRARIES)
+
+-test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES)
++test_decimal$(EXEEXT): decimal.c $(pkglib_LTLIBRARIES)
+ $(CP) $(srcdir)/decimal.c ./test_decimal.c
+- $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LTLIBRARIES)
+ $(RM) -f ./test_decimal.c
+
+ # Don't update the files from bitkeeper
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/strings/strings-x86.s mysql/strings/strings-x86.s
+--- mysql.orig/strings/strings-x86.s 2012-03-02 06:04:13.000000000 -0800
++++ mysql/strings/strings-x86.s 2012-04-01 10:47:50.440941959 -0700
+@@ -293,7 +293,7 @@
+ movl %esp,%ebp
+ pushl 12(%ebp) # search
+ pushl 8(%ebp) # str
+- call strstr
++ call strstr@plt
+ add $8,%esp
+ or %eax,%eax
+ jz si_99 # Not found, return NULL
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/tests/Makefile.am mysql/tests/Makefile.am
+--- mysql.orig/tests/Makefile.am 2012-03-02 06:04:07.000000000 -0800
++++ mysql/tests/Makefile.am 2012-04-01 10:47:50.441941973 -0700
+@@ -42,11 +42,11 @@
+
+ insert_test_SOURCES= insert_test.c
+ select_test_SOURCES= select_test.c
+-insert_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
+-select_test_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++insert_test_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
++select_test_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+
+ bug25714_SOURCES= bug25714.c
+-bug25714_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++bug25714_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+
+ # Fix for mit-threads
+ DEFS = -DUNDEF_THREADS_HACK
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/tools/Makefile.am mysql/tools/Makefile.am
+--- mysql.orig/tools/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/tools/Makefile.am 2012-04-01 10:47:50.441941973 -0700
+@@ -23,7 +23,7 @@
+
+ bin_PROGRAMS= mysqltestmanager
+ mysqltestmanager_SOURCES= mysqlmanager.c
+-mysqltestmanager_DEPENDENCIES= $(LIBRARIES) $(pkglib_LTLIBRARIES)
++mysqltestmanager_DEPENDENCIES= $(LTLIBRARIES) $(pkglib_LTLIBRARIES)
+ DEF= -DUNDEF_THREADS_HACK
+
+ # Don't update the files from bitkeeper
+diff -NuarwbB --exclude '*.orig' --exclude '*.rej' mysql.orig/vio/Makefile.am mysql/vio/Makefile.am
+--- mysql.orig/vio/Makefile.am 2012-03-02 06:04:12.000000000 -0800
++++ mysql/vio/Makefile.am 2012-04-01 10:47:50.441941973 -0700
+@@ -16,11 +16,12 @@
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ $(openssl_includes)
+ LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs)
+-pkglib_LIBRARIES = libvio.a
++pkglib_LTLIBRARIES = libvio.la
+
+ noinst_HEADERS = vio_priv.h
+
+-libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
++libvio_la_LIBADD = -lssl
++libvio_la_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
+
+ EXTRA_DIST= CMakeLists.txt
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-01 17:59 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-01 17:59 UTC (permalink / raw
To: gentoo-commits
commit: 43bb20efca6cc827d8b20ed4a54ba88cdfb2b09c
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sun Apr 1 17:59:06 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Apr 1 17:59:06 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=43bb20ef
Forward-port a Percona patch.
---
00000_index.txt | 7 +-
10030_all_userstatv2-percona-5.0.96.patch | 4378 +++++++++++++++++++++++++++++
2 files changed, 4384 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 163c5a2..d5cd020 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -883,10 +883,15 @@
@@ Percona 5.0.91-b22-20100522: SHOW USER/TABLE/INDEX statistics
@patch 10030_all_userstatv2-percona-5.0.92.patch
-@ver 5.00.92.00 to 5.00.99.99
+@ver 5.00.92.00 to 5.00.95.99
@pn mysql
@@ Percona 5.0.92: SHOW USER/TABLE/INDEX statistics
+@patch 10030_all_userstatv2-percona-5.0.96.patch
+@ver 5.00.96.00 to 5.00.99.99
+@pn mysql
+@@ Percona 5.0.96: SHOW USER/TABLE/INDEX statistics (Gentoo forward-port)
+
@patch 10040_all_microsec_process-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
diff --git a/10030_all_userstatv2-percona-5.0.96.patch b/10030_all_userstatv2-percona-5.0.96.patch
new file mode 100644
index 0000000..79ba002
--- /dev/null
+++ b/10030_all_userstatv2-percona-5.0.96.patch
@@ -0,0 +1,4378 @@
+Forward ported from 10030_all_userstatv2-percona-5.0.92.patch by robbat2@gentoo
+
+diff -r 592f6c3641ba BUILD/Makefile.in
+--- a/BUILD/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/BUILD/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -146,6 +146,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba Docs/Makefile.in
+--- a/Docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/Docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba Makefile.in
+--- a/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba SSL/Makefile.in
+--- a/SSL/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/SSL/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba client/Makefile.in
+--- a/client/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/client/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -247,6 +247,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/Makefile.in
+--- a/cmd-line-utils/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -157,6 +157,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/libedit/Makefile.in
+--- a/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/libedit/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -166,6 +166,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba cmd-line-utils/readline/Makefile.in
+--- a/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/cmd-line-utils/readline/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -173,6 +173,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba configure
+--- a/configure Wed Jul 29 13:33:34 2009 -0700
++++ b/configure Wed Jul 29 13:34:11 2009 -0700
+@@ -35347,7 +35347,91 @@
+ # We also disable for SCO for the time being, the headers for the
+ # thread library we use conflicts with other headers.
+ ;;
+- *)
++*)
++ # most systems require the program be linked with librt library to use
++ # the function clock_gettime
++ my_save_LIBS="$LIBS"
++ LIBS=""
++
++echo "$as_me:$LINENO: checking for clock_gettime in -lrt" >&5
++echo $ECHO_N "checking for clock_gettime in -lrt... $ECHO_C" >&6
++if test "${ac_cv_lib_rt_clock_gettime+set}" = set; then
++ echo $ECHO_N "(cached) $ECHO_C" >&6
++else
++ ac_check_lib_save_LIBS=$LIBS
++LIBS="-lrt $LIBS"
++cat >conftest.$ac_ext <<_ACEOF
++/* confdefs.h. */
++_ACEOF
++cat confdefs.h >>conftest.$ac_ext
++cat >>conftest.$ac_ext <<_ACEOF
++/* end confdefs.h. */
++
++/* Override any gcc2 internal prototype to avoid an error. */
++#ifdef __cplusplus
++extern "C"
++#endif
++/* We use char because int might match the return type of a gcc2
++ builtin and then its argument prototype would still apply. */
++char clock_gettime ();
++int
++main ()
++{
++clock_gettime ();
++ ;
++ return 0;
++}
++_ACEOF
++rm -f conftest.$ac_objext conftest$ac_exeext
++if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
++ (eval $ac_link) 2>conftest.er1
++ ac_status=$?
++ grep -v '^ *+' conftest.er1 >conftest.err
++ rm -f conftest.er1
++ cat conftest.err >&5
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); } &&
++ { ac_try='test -z "$ac_c_werror_flag"
++ || test ! -s conftest.err'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; } &&
++ { ac_try='test -s conftest$ac_exeext'
++ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
++ (eval $ac_try) 2>&5
++ ac_status=$?
++ echo "$as_me:$LINENO: \$? = $ac_status" >&5
++ (exit $ac_status); }; }; then
++ ac_cv_lib_rt_clock_gettime=yes
++else
++ echo "$as_me: failed program was:" >&5
++sed 's/^/| /' conftest.$ac_ext >&5
++
++ac_cv_lib_rt_clock_gettime=no
++fi
++rm -f conftest.err conftest.$ac_objext \
++ conftest$ac_exeext conftest.$ac_ext
++LIBS=$ac_check_lib_save_LIBS
++fi
++echo "$as_me:$LINENO: result: $ac_cv_lib_rt_clock_gettime" >&5
++echo "${ECHO_T}$ac_cv_lib_rt_clock_gettime" >&6
++if test $ac_cv_lib_rt_clock_gettime = yes; then
++ cat >>confdefs.h <<_ACEOF
++#define HAVE_LIBRT 1
++_ACEOF
++
++ LIBS="-lrt $LIBS"
++
++fi
++
++ LIBRT=$LIBS
++ LIBS="$my_save_LIBS"
++
++
++ LIBS="$LIBS $LIBRT"
++
+ for ac_func in clock_gettime
+ do
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+@@ -38791,7 +38875,7 @@
+
+ fi
+
+-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
+
+
+
+diff -r 592f6c3641ba configure.in
+--- a/configure.in Wed Jul 29 13:33:34 2009 -0700
++++ b/configure.in Wed Jul 29 13:34:11 2009 -0700
+@@ -2136,7 +2136,18 @@
+ # We also disable for SCO for the time being, the headers for the
+ # thread library we use conflicts with other headers.
+ ;;
+- *) AC_CHECK_FUNCS(clock_gettime)
++*)
++ # most systems require the program be linked with librt library to use
++ # the function clock_gettime
++ my_save_LIBS="$LIBS"
++ LIBS=""
++ AC_CHECK_LIB(rt,clock_gettime)
++ LIBRT=$LIBS
++ LIBS="$my_save_LIBS"
++ AC_SUBST(LIBRT)
++
++ LIBS="$LIBS $LIBRT"
++ AC_CHECK_FUNCS(clock_gettime)
+ ;;
+ esac
+
+@@ -2772,7 +2783,7 @@
+ AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
+ fi
+
+-CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS"
++CLIENT_LIBS="$NON_THREADED_LIBS $openssl_libs $ZLIB_LIBS $STATIC_NSS_FLAGS $LIBRT"
+
+ AC_SUBST(CLIENT_LIBS)
+ AC_SUBST(NON_THREADED_LIBS)
+diff -r 592f6c3641ba dbug/Makefile.in
+--- a/dbug/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/dbug/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -192,6 +192,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/Makefile.in
+--- a/extra/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -240,6 +240,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/Makefile.in
+--- a/extra/yassl/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -142,6 +142,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/src/Makefile.in
+--- a/extra/yassl/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -151,6 +151,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/Makefile.in
+--- a/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -142,6 +142,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/benchmark/Makefile.in
+--- a/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/benchmark/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -153,6 +153,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/src/Makefile.in
+--- a/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -164,6 +164,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/taocrypt/test/Makefile.in
+--- a/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/taocrypt/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -153,6 +153,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba extra/yassl/testsuite/Makefile.in
+--- a/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/extra/yassl/testsuite/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba heap/Makefile.in
+--- a/heap/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/heap/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -202,6 +202,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba include/Makefile.in
+--- a/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -160,6 +160,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba include/mysql_com.h
+--- a/include/mysql_com.h Wed Jul 29 13:33:34 2009 -0700
++++ b/include/mysql_com.h Wed Jul 29 13:34:11 2009 -0700
+@@ -25,6 +25,7 @@
+ #define USERNAME_LENGTH 16
+ #define SERVER_VERSION_LENGTH 60
+ #define SQLSTATE_LENGTH 5
++#define LIST_PROCESS_HOST_LEN 64
+
+ /*
+ USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
+@@ -106,6 +107,11 @@
+ thread */
+ #define REFRESH_MASTER 128 /* Remove all bin logs in the index
+ and truncate the index */
++#define REFRESH_TABLE_STATS 256 /* Refresh table stats hash table */
++#define REFRESH_INDEX_STATS 512 /* Refresh index stats hash table */
++#define REFRESH_USER_STATS 1024 /* Refresh user stats hash table */
++#define REFRESH_SLOW_QUERY_LOG 4096 /* Flush slow query log and rotate*/
++#define REFRESH_CLIENT_STATS 8192 /* Refresh client stats hash table */
+
+ /* The following can't be set with mysql_refresh() */
+ #define REFRESH_READ_LOCK 16384 /* Lock tables for read */
+diff -r 592f6c3641ba libmysql/Makefile.in
+--- a/libmysql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -224,6 +224,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysql_r/Makefile.in
+--- a/libmysql_r/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysql_r/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -221,6 +221,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@ @ZLIB_LIBS@ @openssl_libs@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysqld/Makefile.in
+--- a/libmysqld/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysqld/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -246,6 +246,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba libmysqld/examples/Makefile.in
+--- a/libmysqld/examples/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/libmysqld/examples/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -192,6 +192,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba man/Makefile.in
+--- a/man/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/man/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -151,6 +151,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba myisam/Makefile.in
+--- a/myisam/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/myisam/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -235,6 +235,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba myisammrg/Makefile.in
+--- a/myisammrg/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/myisammrg/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -183,6 +183,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/Makefile.in
+--- a/mysql-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -161,6 +161,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/ndb/Makefile.in
+--- a/mysql-test/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -147,6 +147,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba mysql-test/r/information_schema.result
+--- a/mysql-test/r/information_schema.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/information_schema.result Wed Jul 29 13:34:11 2009 -0700
+@@ -37,10 +37,12 @@
+ select * from v1;
+ c
+ CHARACTER_SETS
++CLIENT_STATISTICS
+ COLLATIONS
+ COLLATION_CHARACTER_SET_APPLICABILITY
+ COLUMNS
+ COLUMN_PRIVILEGES
++INDEX_STATISTICS
+ KEY_COLUMN_USAGE
+ PROFILING
+ ROUTINES
+@@ -50,8 +52,10 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ USER_PRIVILEGES
++USER_STATISTICS
+ VIEWS
+ columns_priv
+ db
+@@ -83,6 +87,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -102,6 +107,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -121,6 +127,7 @@
+ TABLES TABLES
+ TABLE_CONSTRAINTS TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES TABLE_PRIVILEGES
++TABLE_STATISTICS TABLE_STATISTICS
+ TRIGGERS TRIGGERS
+ tables_priv tables_priv
+ time_zone time_zone
+@@ -594,12 +601,13 @@
+ where table_schema='information_schema' limit 2;
+ TABLE_NAME TABLE_TYPE ENGINE
+ CHARACTER_SETS SYSTEM VIEW MEMORY
+-COLLATIONS SYSTEM VIEW MEMORY
++CLIENT_STATISTICS SYSTEM VIEW MEMORY
+ show tables from information_schema like "T%";
+ Tables_in_information_schema (T%)
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ create database information_schema;
+ ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
+@@ -609,6 +617,7 @@
+ TABLES SYSTEM VIEW
+ TABLE_CONSTRAINTS SYSTEM VIEW
+ TABLE_PRIVILEGES SYSTEM VIEW
++TABLE_STATISTICS SYSTEM VIEW
+ TRIGGERS SYSTEM VIEW
+ create table t1(a int);
+ ERROR 42S02: Unknown table 't1' in information_schema
+@@ -621,6 +630,7 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ select table_name from tables where table_name='user';
+ table_name
+@@ -730,7 +740,7 @@
+ CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
+ CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
+ count(*)
+-102
++106
+ drop view a2, a1;
+ drop table t_crashme;
+ select table_schema,table_name, column_name from
+@@ -790,18 +800,20 @@
+ TABLE_NAME COLUMN_NAME PRIVILEGES
+ COLUMNS TABLE_NAME select
+ COLUMN_PRIVILEGES TABLE_NAME select
++INDEX_STATISTICS TABLE_NAME select
+ KEY_COLUMN_USAGE TABLE_NAME select
+ STATISTICS TABLE_NAME select
+ TABLES TABLE_NAME select
+ TABLE_CONSTRAINTS TABLE_NAME select
+ TABLE_PRIVILEGES TABLE_NAME select
++TABLE_STATISTICS TABLE_NAME select
+ VIEWS TABLE_NAME select
+ delete from mysql.user where user='mysqltest_4';
+ delete from mysql.db where user='mysqltest_4';
+ flush privileges;
+ SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
+ table_schema count(*)
+-information_schema 17
++information_schema 21
+ mysql 17
+ create table t1 (i int, j int);
+ create trigger trg1 before insert on t1 for each row
+@@ -1187,10 +1199,12 @@
+ );
+ table_name column_name
+ CHARACTER_SETS CHARACTER_SET_NAME
++CLIENT_STATISTICS CLIENT
+ COLLATIONS COLLATION_NAME
+ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
+ COLUMNS TABLE_SCHEMA
+ COLUMN_PRIVILEGES TABLE_SCHEMA
++INDEX_STATISTICS TABLE_SCHEMA
+ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+ PROFILING QUERY_ID
+ ROUTINES ROUTINE_SCHEMA
+@@ -1200,8 +1214,10 @@
+ TABLES TABLE_SCHEMA
+ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
+ TABLE_PRIVILEGES TABLE_SCHEMA
++TABLE_STATISTICS TABLE_SCHEMA
+ TRIGGERS TRIGGER_SCHEMA
+ USER_PRIVILEGES GRANTEE
++USER_STATISTICS USER
+ VIEWS TABLE_SCHEMA
+ SELECT t.table_name, c1.column_name
+ FROM information_schema.tables t
+@@ -1219,10 +1235,12 @@
+ );
+ table_name column_name
+ CHARACTER_SETS CHARACTER_SET_NAME
++CLIENT_STATISTICS CLIENT
+ COLLATIONS COLLATION_NAME
+ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
+ COLUMNS TABLE_SCHEMA
+ COLUMN_PRIVILEGES TABLE_SCHEMA
++INDEX_STATISTICS TABLE_SCHEMA
+ KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+ PROFILING QUERY_ID
+ ROUTINES ROUTINE_SCHEMA
+@@ -1232,8 +1250,10 @@
+ TABLES TABLE_SCHEMA
+ TABLE_CONSTRAINTS CONSTRAINT_SCHEMA
+ TABLE_PRIVILEGES TABLE_SCHEMA
++TABLE_STATISTICS TABLE_SCHEMA
+ TRIGGERS TRIGGER_SCHEMA
+ USER_PRIVILEGES GRANTEE
++USER_STATISTICS USER
+ VIEWS TABLE_SCHEMA
+ SELECT MAX(table_name) FROM information_schema.tables;
+ MAX(table_name)
+@@ -1302,10 +1322,12 @@
+ group by t.table_name order by num1, t.table_name;
+ table_name group_concat(t.table_schema, '.', t.table_name) num1
+ CHARACTER_SETS information_schema.CHARACTER_SETS 1
++CLIENT_STATISTICS information_schema.CLIENT_STATISTICS 1
+ COLLATIONS information_schema.COLLATIONS 1
+ COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET_APPLICABILITY 1
+ COLUMNS information_schema.COLUMNS 1
+ COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
++INDEX_STATISTICS information_schema.INDEX_STATISTICS 1
+ KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
+ PROFILING information_schema.PROFILING 1
+ ROUTINES information_schema.ROUTINES 1
+@@ -1315,8 +1337,10 @@
+ TABLES information_schema.TABLES 1
+ TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1
+ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
++TABLE_STATISTICS information_schema.TABLE_STATISTICS 1
+ TRIGGERS information_schema.TRIGGERS 1
+ USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
++USER_STATISTICS information_schema.USER_STATISTICS 1
+ VIEWS information_schema.VIEWS 1
+ create table t1(f1 int);
+ create view v1 as select f1+1 as a from t1;
+diff -r 592f6c3641ba mysql-test/r/information_schema_db.result
+--- a/mysql-test/r/information_schema_db.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/information_schema_db.result Wed Jul 29 13:34:11 2009 -0700
+@@ -6,10 +6,12 @@
+ show tables;
+ Tables_in_information_schema
+ CHARACTER_SETS
++CLIENT_STATISTICS
+ COLLATIONS
+ COLLATION_CHARACTER_SET_APPLICABILITY
+ COLUMNS
+ COLUMN_PRIVILEGES
++INDEX_STATISTICS
+ KEY_COLUMN_USAGE
+ PROFILING
+ ROUTINES
+@@ -19,14 +21,17 @@
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ USER_PRIVILEGES
++USER_STATISTICS
+ VIEWS
+ show tables from INFORMATION_SCHEMA like 'T%';
+ Tables_in_information_schema (T%)
+ TABLES
+ TABLE_CONSTRAINTS
+ TABLE_PRIVILEGES
++TABLE_STATISTICS
+ TRIGGERS
+ create database `inf%`;
+ create database mbase;
+diff -r 592f6c3641ba mysql-test/r/mysqlshow.result
+--- a/mysql-test/r/mysqlshow.result Wed Jul 29 13:33:34 2009 -0700
++++ b/mysql-test/r/mysqlshow.result Wed Jul 29 13:34:11 2009 -0700
+@@ -80,10 +80,12 @@
+ | Tables |
+ +---------------------------------------+
+ | CHARACTER_SETS |
++| CLIENT_STATISTICS |
+ | COLLATIONS |
+ | COLLATION_CHARACTER_SET_APPLICABILITY |
+ | COLUMNS |
+ | COLUMN_PRIVILEGES |
++| INDEX_STATISTICS |
+ | KEY_COLUMN_USAGE |
+ | PROFILING |
+ | ROUTINES |
+@@ -93,8 +95,10 @@
+ | TABLES |
+ | TABLE_CONSTRAINTS |
+ | TABLE_PRIVILEGES |
++| TABLE_STATISTICS |
+ | TRIGGERS |
+ | USER_PRIVILEGES |
++| USER_STATISTICS |
+ | VIEWS |
+ +---------------------------------------+
+ Database: INFORMATION_SCHEMA
+@@ -102,10 +106,12 @@
+ | Tables |
+ +---------------------------------------+
+ | CHARACTER_SETS |
++| CLIENT_STATISTICS |
+ | COLLATIONS |
+ | COLLATION_CHARACTER_SET_APPLICABILITY |
+ | COLUMNS |
+ | COLUMN_PRIVILEGES |
++| INDEX_STATISTICS |
+ | KEY_COLUMN_USAGE |
+ | PROFILING |
+ | ROUTINES |
+@@ -115,8 +121,10 @@
+ | TABLES |
+ | TABLE_CONSTRAINTS |
+ | TABLE_PRIVILEGES |
++| TABLE_STATISTICS |
+ | TRIGGERS |
+ | USER_PRIVILEGES |
++| USER_STATISTICS |
+ | VIEWS |
+ +---------------------------------------+
+ Wildcard: inf_rmation_schema
+diff -r 592f6c3641ba mysys/Makefile.in
+--- a/mysys/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/mysys/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -228,6 +228,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/Makefile.in
+--- a/ndb/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/docs/Makefile.in
+--- a/ndb/docs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/docs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -149,6 +149,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/include/Makefile.in
+--- a/ndb/include/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/include/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -179,6 +179,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/Makefile.in
+--- a/ndb/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/Makefile.in
+--- a/ndb/src/common/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -174,6 +174,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/debugger/Makefile.in
+--- a/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/debugger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/debugger/signaldata/Makefile.in
+--- a/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/debugger/signaldata/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -211,6 +211,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/logger/Makefile.in
+--- a/ndb/src/common/logger/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/logger/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/mgmcommon/Makefile.in
+--- a/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/mgmcommon/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -211,6 +211,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/portlib/Makefile.in
+--- a/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/portlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -222,6 +222,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/transporter/Makefile.in
+--- a/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/transporter/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/common/util/Makefile.in
+--- a/ndb/src/common/util/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/common/util/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -217,6 +217,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/cw/Makefile.in
+--- a/ndb/src/cw/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/cw/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/cw/cpcd/Makefile.in
+--- a/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/cw/cpcd/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -207,6 +207,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/Makefile.in
+--- a/ndb/src/kernel/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -227,6 +227,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/Makefile.in
+--- a/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/backup/Makefile.in
+--- a/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/backup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/cmvmi/Makefile.in
+--- a/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/cmvmi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbacc/Makefile.in
+--- a/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbacc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdict/Makefile.in
+--- a/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbdict/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbdih/Makefile.in
+--- a/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbdih/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -203,6 +203,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dblqh/Makefile.in
+--- a/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dblqh/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtc/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtc/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtup/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtup/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -204,6 +204,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbtux/Makefile.in
+--- a/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbtux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -199,6 +199,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/dbutil/Makefile.in
+--- a/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/dbutil/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbcntr/Makefile.in
+--- a/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/ndbcntr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/ndbfs/Makefile.in
+--- a/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/ndbfs/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -197,6 +197,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/qmgr/Makefile.in
+--- a/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/qmgr/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/suma/Makefile.in
+--- a/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/suma/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/blocks/trix/Makefile.in
+--- a/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/blocks/trix/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/error/Makefile.in
+--- a/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/error/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -206,6 +206,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/kernel/vm/Makefile.in
+--- a/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/kernel/vm/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -207,6 +207,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmapi/Makefile.in
+--- a/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -205,6 +205,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmclient/Makefile.in
+--- a/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmclient/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -216,6 +216,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/mgmsrv/Makefile.in
+--- a/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/mgmsrv/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -213,6 +213,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/src/ndbapi/Makefile.in
+--- a/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/src/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -215,6 +215,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/Makefile.in
+--- a/ndb/test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -156,6 +156,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/ndbapi/Makefile.in
+--- a/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/ndbapi/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -595,6 +595,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/ndbapi/bank/Makefile.in
+--- a/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/ndbapi/bank/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -282,6 +282,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/run-test/Makefile.in
+--- a/ndb/test/run-test/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/run-test/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -243,6 +243,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/src/Makefile.in
+--- a/ndb/test/src/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/src/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -213,6 +213,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/test/tools/Makefile.in
+--- a/ndb/test/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/test/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -325,6 +325,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba ndb/tools/Makefile.in
+--- a/ndb/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/ndb/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -344,6 +344,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba netware/Makefile.in
+--- a/netware/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/netware/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -199,6 +199,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba patch_info/userstats.info
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ b/patch_info/userstats.info Wed Jul 29 13:34:11 2009 -0700
+@@ -0,0 +1,14 @@
++File=userstatsv2.patch
++Name=SHOW USER/TABLE/INDEX statistics
++Version=V2
++Author=Google
++License=GPL
++Comment=Added INFORMATION_SCHEMA.*_STATISTICS
++2008-12-01
++YK: fix behavior for prepared statements
++
++2008-11-26
++YK: add switch variable "userstat_running" to control INFORMATION_SCHEMA.*_STATISTICS (default:OFF)
++
++2008-12-09
++YK: fixed "Row_sent: 0" problem at microslow_innodb.patch
+diff -r 592f6c3641ba pstack/Makefile.in
+--- a/pstack/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/pstack/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -196,6 +196,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba pstack/aout/Makefile.in
+--- a/pstack/aout/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/pstack/aout/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -134,6 +134,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba regex/Makefile.in
+--- a/regex/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/regex/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -180,6 +180,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba scripts/Makefile.in
+--- a/scripts/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/scripts/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -176,6 +176,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba server-tools/Makefile.in
+--- a/server-tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/server-tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -155,6 +155,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba server-tools/instance-manager/Makefile.in
+--- a/server-tools/instance-manager/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/server-tools/instance-manager/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -205,6 +205,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/Makefile.in
+--- a/sql/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -274,6 +274,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/ha_innodb.cc
+--- a/sql/ha_innodb.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/ha_innodb.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -3341,6 +3341,8 @@
+
+ error = row_insert_for_mysql((byte*) record, prebuilt);
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ if (error == DB_SUCCESS && auto_inc_used) {
+
+ /* Fetch the value that was set in the autoincrement field */
+@@ -3613,6 +3615,8 @@
+ }
+ }
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+@@ -3661,6 +3665,8 @@
+
+ error = row_update_for_mysql((byte*) record, prebuilt);
+
++ if (error == DB_SUCCESS) rows_changed++;
++
+ innodb_srv_conc_exit_innodb(prebuilt->trx);
+
+ error = convert_error_code_to_mysql(error, user_thd);
+@@ -4092,6 +4098,9 @@
+ if (ret == DB_SUCCESS) {
+ error = 0;
+ table->status = 0;
++ rows_read++;
++ if (active_index >= 0 && active_index < MAX_KEY)
++ index_rows_read[active_index]++;
+
+ } else if (ret == DB_RECORD_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+diff -r 592f6c3641ba sql/ha_myisam.cc
+--- a/sql/ha_myisam.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/ha_myisam.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -670,7 +670,9 @@
+ if ((error= update_auto_increment()))
+ return error;
+ }
+- return mi_write(file,buf);
++ int error=mi_write(file,buf);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
+@@ -1521,13 +1523,17 @@
+ statistic_increment(table->in_use->status_var.ha_update_count,&LOCK_status);
+ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
+ table->timestamp_field->set_time();
+- return mi_update(file,old_data,new_data);
++ int error=mi_update(file,old_data,new_data);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::delete_row(const byte * buf)
+ {
+ statistic_increment(table->in_use->status_var.ha_delete_count,&LOCK_status);
+- return mi_delete(file,buf);
++ int error=mi_delete(file,buf);
++ if (!error) rows_changed++;
++ return error;
+ }
+
+ int ha_myisam::index_read(byte * buf, const byte * key,
+@@ -1538,6 +1544,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, find_flag);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1548,6 +1561,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,index, key, key_len, find_flag);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1558,6 +1578,13 @@
+ &LOCK_status);
+ int error=mi_rkey(file,buf,active_index, key, key_len, HA_READ_PREFIX_LAST);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1568,6 +1595,13 @@
+ &LOCK_status);
+ int error=mi_rnext(file,buf,active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1578,6 +1612,13 @@
+ &LOCK_status);
+ int error=mi_rprev(file,buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1588,6 +1629,13 @@
+ &LOCK_status);
+ int error=mi_rfirst(file, buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1598,6 +1646,13 @@
+ &LOCK_status);
+ int error=mi_rlast(file, buf, active_index);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1614,6 +1669,13 @@
+ error= mi_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) {
++ rows_read++;
++
++ int inx = (active_index == -1) ? file->lastinx : active_index;
++ if (inx >= 0 && inx < MAX_KEY)
++ index_rows_read[inx]++;
++ }
+ return error;
+ }
+
+@@ -1631,6 +1693,7 @@
+ &LOCK_status);
+ int error=mi_scan(file, buf);
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) rows_read++;
+ return error;
+ }
+
+@@ -1645,6 +1708,7 @@
+ &LOCK_status);
+ int error=mi_rrnd(file, buf, my_get_ptr(pos,ref_length));
+ table->status=error ? STATUS_NOT_FOUND: 0;
++ if (!error) rows_read++;
+ return error;
+ }
+
+diff -r 592f6c3641ba sql/handler.cc
+--- a/sql/handler.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/handler.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -726,6 +726,8 @@
+ if (cookie)
+ tc_log->unlog(cookie, xid);
+ DBUG_EXECUTE_IF("crash_commit_after", abort(););
++ if (is_real_trans)
++ thd->diff_commit_trans++;
+ end:
+ if (is_real_trans)
+ start_waiting_global_read_lock(thd);
+@@ -783,6 +785,7 @@
+ thd->transaction.cleanup();
+ }
+ }
++ thd->diff_rollback_trans++;
+ #endif /* USING_TRANSACTIONS */
+ DBUG_RETURN(error);
+ }
+@@ -1223,6 +1226,7 @@
+ statistic_increment(thd->status_var.ha_rollback_count,&LOCK_status);
+ *ht=0; // keep it conveniently zero-filled
+ }
++ thd->diff_rollback_trans++;
+ DBUG_RETURN(error);
+ }
+
+@@ -1453,6 +1457,8 @@
+ else
+ dupp_ref=ref+ALIGN_SIZE(ref_length);
+ }
++ rows_read = rows_changed = 0;
++ memset(index_rows_read, 0, sizeof(index_rows_read));
+ DBUG_RETURN(error);
+ }
+
+@@ -2287,6 +2293,111 @@
+ return error;
+ }
+
++// Updates the global table stats with the TABLE this handler represents.
++void handler::update_global_table_stats() {
++ if (!opt_userstat_running) {
++ rows_read = rows_changed = 0;
++ return;
++ }
++
++ if (!rows_read && !rows_changed) return; // Nothing to update.
++ // table_cache_key is db_name + '\0' + table_name + '\0'.
++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
++
++ TABLE_STATS* table_stats;
++ char key[NAME_LEN * 2 + 2];
++ // [db] + '.' + [table]
++ sprintf(key, "%s.%s", table->s->table_cache_key, table->s->table_name);
++
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ // Gets the global table stats, creating one if necessary.
++ if (!(table_stats = (TABLE_STATS*)hash_search(&global_table_stats,
++ (byte*)key,
++ strlen(key)))) {
++ if (!(table_stats = ((TABLE_STATS*)
++ my_malloc(sizeof(TABLE_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
++ // Out of memory.
++ sql_print_error("Allocating table stats failed.");
++ goto end;
++ }
++ strncpy(table_stats->table, key, sizeof(table_stats->table));
++ table_stats->rows_read = 0;
++ table_stats->rows_changed = 0;
++ table_stats->rows_changed_x_indexes = 0;
++ table_stats->engine_type = (int) ht->db_type;
++
++ if (my_hash_insert(&global_table_stats, (byte*)table_stats)) {
++ // Out of memory.
++ sql_print_error("Inserting table stats failed.");
++ my_free((char*)table_stats, 0);
++ goto end;
++ }
++ }
++ // Updates the global table stats.
++ table_stats->rows_read += rows_read;
++ table_stats->rows_changed += rows_changed;
++ table_stats->rows_changed_x_indexes +=
++ rows_changed * (table->s->keys ? table->s->keys : 1);
++ current_thd->diff_total_read_rows += rows_read;
++ rows_read = rows_changed = 0;
++end:
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++}
++
++// Updates the global index stats with this handler's accumulated index reads.
++void handler::update_global_index_stats() {
++ // table_cache_key is db_name + '\0' + table_name + '\0'.
++ if (!table->s || !table->s->table_cache_key || !table->s->table_name) return;
++
++ if (!opt_userstat_running) {
++ for (int x = 0; x < table->s->keys; x++) {
++ index_rows_read[x] = 0;
++ }
++ return;
++ }
++
++ for (int x = 0; x < table->s->keys; x++) {
++ if (index_rows_read[x]) {
++ // Rows were read using this index.
++ KEY* key_info = &table->key_info[x];
++
++ if (!key_info->name) continue;
++
++ INDEX_STATS* index_stats;
++ char key[NAME_LEN * 3 + 3];
++ // [db] + '.' + [table] + '.' + [index]
++ sprintf(key, "%s.%s.%s", table->s->table_cache_key,
++ table->s->table_name, key_info->name);
++
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ // Gets the global index stats, creating one if necessary.
++ if (!(index_stats = (INDEX_STATS*)hash_search(&global_index_stats,
++ (byte*)key,
++ strlen(key)))) {
++ if (!(index_stats = ((INDEX_STATS*)
++ my_malloc(sizeof(INDEX_STATS), MYF(MY_WME | MY_ZEROFILL))))) {
++ // Out of memory.
++ sql_print_error("Allocating index stats failed.");
++ goto end;
++ }
++ strncpy(index_stats->index, key, sizeof(index_stats->index));
++ index_stats->rows_read = 0;
++
++ if (my_hash_insert(&global_index_stats, (byte*)index_stats)) {
++ // Out of memory.
++ sql_print_error("Inserting index stats failed.");
++ my_free((char*)index_stats, 0);
++ goto end;
++ }
++ }
++ // Updates the global index stats.
++ index_stats->rows_read += index_rows_read[x];
++ index_rows_read[x] = 0;
++end:
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ }
++ }
++}
+
+ /****************************************************************************
+ ** Some general functions that isn't in the handler class
+diff -r 592f6c3641ba sql/handler.h
+--- a/sql/handler.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/handler.h Wed Jul 29 13:34:11 2009 -0700
+@@ -32,6 +32,10 @@
+ #define USING_TRANSACTIONS
+ #endif
+
++#if MAX_KEY > 128
++#error MAX_KEY is too large. Values up to 128 are supported.
++#endif
++
+ // the following is for checking tables
+
+ #define HA_ADMIN_ALREADY_DONE 1
+@@ -604,6 +608,9 @@
+ bool auto_increment_column_changed;
+ bool implicit_emptied; /* Can be !=0 only if HEAP */
+ const COND *pushed_cond;
++ ulonglong rows_read;
++ ulonglong rows_changed;
++ ulonglong index_rows_read[MAX_KEY];
+
+ handler(const handlerton *ht_arg, TABLE *table_arg) :table(table_arg),
+ ht(ht_arg),
+@@ -615,8 +622,10 @@
+ ref_length(sizeof(my_off_t)), block_size(0),
+ raid_type(0), ft_handler(0), inited(NONE),
+ locked(FALSE), implicit_emptied(0),
+- pushed_cond(NULL)
+- {}
++ pushed_cond(NULL), rows_read(0), rows_changed(0)
++ {
++ memset(index_rows_read, 0, sizeof(index_rows_read));
++ }
+ virtual ~handler(void) { DBUG_ASSERT(locked == FALSE); /* TODO: DBUG_ASSERT(inited == NONE); */ }
+ virtual handler *clone(MEM_ROOT *mem_root);
+ int ha_open(const char *name, int mode, int test_if_locked);
+@@ -625,7 +634,11 @@
+ virtual void print_error(int error, myf errflag);
+ virtual bool get_error_message(int error, String *buf);
+ uint get_dup_key(int error);
+- void change_table_ptr(TABLE *table_arg) { table=table_arg; }
++ void change_table_ptr(TABLE *table_arg) {
++ table=table_arg;
++ rows_read = rows_changed = 0;
++ memset(index_rows_read, 0, sizeof(index_rows_read));
++ }
+ virtual double scan_time()
+ { return ulonglong2double(data_file_length) / IO_SIZE + 2; }
+ virtual double read_time(uint index, uint ranges, ha_rows rows)
+@@ -886,6 +899,9 @@
+ virtual bool is_crashed() const { return 0; }
+ virtual bool auto_repair() const { return 0; }
+
++ void update_global_table_stats();
++ void update_global_index_stats();
++
+ /*
+ default rename_table() and delete_table() rename/delete files with a
+ given name and extensions from bas_ext()
+diff -r 592f6c3641ba sql/lex.h
+--- a/sql/lex.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/lex.h Wed Jul 29 13:34:11 2009 -0700
+@@ -109,6 +109,7 @@
+ { "CHECKSUM", SYM(CHECKSUM_SYM)},
+ { "CIPHER", SYM(CIPHER_SYM)},
+ { "CLIENT", SYM(CLIENT_SYM)},
++ { "CLIENT_STATISTICS", SYM(CLIENT_STATS_SYM)},
+ { "CLOSE", SYM(CLOSE_SYM)},
+ { "CODE", SYM(CODE_SYM)},
+ { "COLLATE", SYM(COLLATE_SYM)},
+@@ -238,6 +239,7 @@
+ { "IN", SYM(IN_SYM)},
+ { "INDEX", SYM(INDEX_SYM)},
+ { "INDEXES", SYM(INDEXES)},
++ { "INDEX_STATISTICS", SYM(INDEX_STATS_SYM)},
+ { "INFILE", SYM(INFILE)},
+ { "INNER", SYM(INNER_SYM)},
+ { "INNOBASE", SYM(INNOBASE_SYM)},
+@@ -443,6 +445,7 @@
+ { "SIGNED", SYM(SIGNED_SYM)},
+ { "SIMPLE", SYM(SIMPLE_SYM)},
+ { "SLAVE", SYM(SLAVE)},
++ { "SLOW", SYM(SLOW_SYM)},
+ { "SNAPSHOT", SYM(SNAPSHOT_SYM)},
+ { "SMALLINT", SYM(SMALLINT)},
+ { "SOME", SYM(ANY_SYM)},
+@@ -488,6 +491,7 @@
+ { "TABLE", SYM(TABLE_SYM)},
+ { "TABLES", SYM(TABLES)},
+ { "TABLESPACE", SYM(TABLESPACE)},
++ { "TABLE_STATISTICS", SYM(TABLE_STATS_SYM)},
+ { "TEMPORARY", SYM(TEMPORARY)},
+ { "TEMPTABLE", SYM(TEMPTABLE_SYM)},
+ { "TERMINATED", SYM(TERMINATED)},
+@@ -525,6 +529,7 @@
+ { "USE", SYM(USE_SYM)},
+ { "USER", SYM(USER)},
+ { "USER_RESOURCES", SYM(RESOURCES)},
++ { "USER_STATISTICS", SYM(USER_STATS_SYM)},
+ { "USE_FRM", SYM(USE_FRM)},
+ { "USING", SYM(USING)},
+ { "UTC_DATE", SYM(UTC_DATE_SYM)},
+diff -r 592f6c3641ba sql/log.cc
+--- a/sql/log.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/log.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -1958,18 +1958,24 @@
+ thd->current_insert_id);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->insert_id_used)
+ {
+ Intvar_log_event e(thd,(uchar) INSERT_ID_EVENT,thd->last_insert_id);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->rand_used)
+ {
+ Rand_log_event e(thd,thd->rand_saved_seed1,thd->rand_saved_seed2);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ if (thd->user_var_events.elements)
+ {
+@@ -1985,6 +1991,8 @@
+ user_var_event->charset_number);
+ if (e.write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += e.data_written;
+ }
+ }
+ }
+@@ -1995,6 +2003,8 @@
+
+ if (event_info->write(file))
+ goto err;
++ if (file == &log_file)
++ thd->binlog_bytes_written += event_info->data_written;
+
+ if (file == &log_file) // we are writing to the real log (disk)
+ {
+@@ -2117,6 +2127,7 @@
+ */
+ if (qinfo.write(&log_file))
+ goto err;
++ thd->binlog_bytes_written += qinfo.data_written;
+
+ /* Read from the file used to cache the queries .*/
+ if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
+@@ -2163,6 +2174,7 @@
+ /* write the first half of the split header */
+ if (my_b_write(&log_file, header, carry))
+ goto err;
++ thd->binlog_bytes_written += carry;
+
+ /*
+ copy fixed second half of header to cache so the correct
+@@ -2231,6 +2243,8 @@
+ /* Write data to the binary log file */
+ if (my_b_write(&log_file, cache->read_pos, length))
+ goto err;
++ thd->binlog_bytes_written += length;
++
+ cache->read_pos=cache->read_end; // Mark buffer used up
+ DBUG_EXECUTE_IF("half_binlogged_transaction", goto DBUG_skip_commit;);
+ } while ((length=my_b_fill(cache)));
+@@ -2239,6 +2253,8 @@
+
+ if (commit_event->write(&log_file))
+ goto err;
++ thd->binlog_bytes_written += commit_event->data_written;
++
+ #ifndef DBUG_OFF
+ DBUG_skip_commit:
+ #endif
+diff -r 592f6c3641ba sql/mysql_priv.h
+--- a/sql/mysql_priv.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/mysql_priv.h Wed Jul 29 13:34:11 2009 -0700
+@@ -837,7 +837,15 @@
+ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex);
+ void init_max_user_conn(void);
+ void init_update_queries(void);
++void init_global_user_stats(void);
++void init_global_table_stats(void);
++void init_global_index_stats(void);
++void init_global_client_stats(void);
+ void free_max_user_conn(void);
++void free_global_user_stats(void);
++void free_global_table_stats(void);
++void free_global_index_stats(void);
++void free_global_client_stats(void);
+ pthread_handler_t handle_one_connection(void *arg);
+ pthread_handler_t handle_bootstrap(void *arg);
+ void end_thread(THD *thd,bool put_in_cache);
+@@ -1416,6 +1424,7 @@
+ extern ulong max_connections,max_connect_errors, connect_timeout;
+ extern ulong slave_net_timeout, slave_trans_retries;
+ extern uint max_user_connections;
++extern ulonglong denied_connections;
+ extern ulong what_to_log,flush_time;
+ extern ulong query_buff_size, thread_stack;
+ extern ulong max_prepared_stmt_count, prepared_stmt_count;
+@@ -1446,6 +1455,7 @@
+ extern my_bool opt_safe_show_db, opt_local_infile;
+ extern my_bool opt_slave_compressed_protocol, use_temp_pool;
+ extern my_bool opt_readonly, lower_case_file_system;
++extern my_bool opt_userstat_running;
+ extern my_bool opt_enable_named_pipe, opt_sync_frm, opt_allow_suspicious_udfs;
+ extern my_bool opt_secure_auth;
+ extern char* opt_secure_file_priv;
+@@ -1493,6 +1503,14 @@
+ extern struct system_variables max_system_variables;
+ extern struct system_status_var global_status_var;
+ extern struct rand_struct sql_rand;
++extern HASH global_user_stats;
++extern HASH global_client_stats;
++extern pthread_mutex_t LOCK_global_user_client_stats;
++extern HASH global_table_stats;
++extern pthread_mutex_t LOCK_global_table_stats;
++extern HASH global_index_stats;
++extern pthread_mutex_t LOCK_global_index_stats;
++extern pthread_mutex_t LOCK_stats;
+
+ extern const char *opt_date_time_formats[];
+ extern KNOWN_DATE_TIME_FORMAT known_date_time_formats[];
+diff -r 592f6c3641ba sql/mysqld.cc
+--- a/sql/mysqld.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/mysqld.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -417,6 +417,7 @@
+ uint opt_large_page_size= 0;
+ my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
+ char* opt_slow_logname= 0;
++my_bool opt_userstat_running= 0;
+ /*
+ True if there is at least one per-hour limit for some user, so we should
+ check them before each query (and possibly reset counters when hour is
+@@ -453,6 +454,7 @@
+ ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
+ ulong max_connections, max_connect_errors;
+ uint max_user_connections= 0;
++ulonglong denied_connections = 0;
+ /*
+ Limit of the total number of prepared statements in the server.
+ Is necessary to protect the server against out-of-memory attacks.
+@@ -555,6 +557,10 @@
+ LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
+ LOCK_global_system_variables,
+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi;
++pthread_mutex_t LOCK_stats;
++pthread_mutex_t LOCK_global_user_client_stats;
++pthread_mutex_t LOCK_global_table_stats;
++pthread_mutex_t LOCK_global_index_stats;
+ /*
+ The below lock protects access to two global server variables:
+ max_prepared_stmt_count and prepared_stmt_count. These variables
+@@ -1196,6 +1202,10 @@
+ x_free(opt_secure_file_priv);
+ bitmap_free(&temp_pool);
+ free_max_user_conn();
++ free_global_user_stats();
++ free_global_client_stats();
++ free_global_table_stats();
++ free_global_index_stats();
+ #ifdef HAVE_REPLICATION
+ end_slave_list();
+ free_list(&replicate_do_db);
+@@ -1310,6 +1320,10 @@
+ (void) pthread_cond_destroy(&COND_thread_cache);
+ (void) pthread_cond_destroy(&COND_flush_thread_cache);
+ (void) pthread_cond_destroy(&COND_manager);
++ (void) pthread_mutex_destroy(&LOCK_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_user_client_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_table_stats);
++ (void) pthread_mutex_destroy(&LOCK_global_index_stats);
+ }
+
+ #endif /*EMBEDDED_LIBRARY*/
+@@ -3157,6 +3171,10 @@
+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
+ (void) pthread_cond_init(&COND_rpl_status, NULL);
+ #endif
++ (void) pthread_mutex_init(&LOCK_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_user_client_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_table_stats, MY_MUTEX_INIT_FAST);
++ (void) pthread_mutex_init(&LOCK_global_index_stats, MY_MUTEX_INIT_FAST);
+ sp_cache_init();
+ /* Parameter for threads created for connections */
+ (void) pthread_attr_init(&connection_attrib);
+@@ -3428,6 +3446,10 @@
+ sql_print_error("Out of memory");
+ unireg_abort(1);
+ }
++
++ init_global_table_stats();
++ init_global_index_stats();
++
+ if (ha_init())
+ {
+ sql_print_error("Can't init databases");
+@@ -3510,6 +3532,8 @@
+
+ init_max_user_conn();
+ init_update_queries();
++ init_global_user_stats();
++ init_global_client_stats();
+ DBUG_RETURN(0);
+ }
+
+@@ -4236,6 +4260,7 @@
+ {
+ DBUG_PRINT("error",("Too many connections"));
+ close_connection(thd, ER_CON_COUNT_ERROR, 1);
++ statistic_increment(denied_connections, &LOCK_status);
+ delete thd;
+ DBUG_VOID_RETURN;
+ }
+@@ -5056,6 +5081,7 @@
+ OPT_PROFILING_USE_GETRUSAGE,
+ OPT_SLOW_LOG,
+ OPT_SLOW_QUERY_LOG_FILE,
++ OPT_USERSTAT_RUNNING,
+ OPT_USE_GLOBAL_LONG_QUERY_TIME,
+ OPT_INNODB_ROLLBACK_ON_TIMEOUT,
+ OPT_SECURE_FILE_PRIV,
+@@ -6523,6 +6549,10 @@
+ (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG,
+ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
+ 0, 1, 0},
++ {"userstat_running", OPT_USERSTAT_RUNNING,
++ "Control USER_STATISTICS, CLIENT_STATISTICS, INDEX_STATISTICS and TABLE_STATISTICS running",
++ (gptr*) &opt_userstat_running, (gptr*) &opt_userstat_running,
++ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+ };
+
+diff -r 592f6c3641ba sql/set_var.cc
+--- a/sql/set_var.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/set_var.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -325,6 +325,7 @@
+ sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
+ &SV::read_buff_size);
+ sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
++sys_var_bool_ptr sys_userstat_running("userstat_running", &opt_userstat_running);
+ sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
+ &SV::read_rnd_buff_size);
+ sys_var_thd_ulong sys_div_precincrement("div_precision_increment",
+@@ -837,6 +838,7 @@
+ &sys_trans_alloc_block_size,
+ &sys_trans_prealloc_size,
+ &sys_tx_isolation,
++ &sys_userstat_running,
+ &sys_version,
+ #ifdef HAVE_BERKELEY_DB
+ &sys_version_bdb,
+@@ -1190,6 +1192,7 @@
+ {sys_tx_isolation.name, (char*) &sys_tx_isolation, SHOW_SYS},
+ {sys_updatable_views_with_limit.name,
+ (char*) &sys_updatable_views_with_limit,SHOW_SYS},
++ {sys_userstat_running.name, (char*) &sys_userstat_running, SHOW_SYS},
+ {sys_use_global_long_query_time.name, (char*) &sys_use_global_long_query_time, SHOW_SYS},
+ {sys_version.name, (char*) &sys_version, SHOW_SYS},
+ #ifdef HAVE_BERKELEY_DB
+diff -r 592f6c3641ba sql/share/Makefile.in
+--- a/sql/share/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/share/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba sql/sql_base.cc
+--- a/sql/sql_base.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_base.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -624,6 +624,12 @@
+ DBUG_ENTER("close_thread_table");
+ DBUG_ASSERT(table->key_read == 0);
+ DBUG_ASSERT(!table->file || table->file->inited == handler::NONE);
++
++ if(table->file)
++ {
++ table->file->update_global_table_stats();
++ table->file->update_global_index_stats();
++ }
+
+ *table_ptr=table->next;
+ if (table->needs_reopen_or_name_lock() ||
+@@ -670,6 +676,9 @@
+ {
+ DBUG_ENTER("close_temporary");
+ char path[FN_REFLEN];
++
++ table->file->update_global_table_stats();
++ table->file->update_global_index_stats();
+ db_type table_type=table->s->db_type;
+ strmov(path,table->s->path);
+ free_io_cache(table);
+diff -r 592f6c3641ba sql/sql_class.cc
+--- a/sql/sql_class.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_class.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -239,6 +239,13 @@
+ bzero(ha_data, sizeof(ha_data));
+ mysys_var=0;
+ binlog_evt_union.do_union= FALSE;
++ busy_time = 0;
++ cpu_time = 0;
++ bytes_received = 0;
++ bytes_sent = 0;
++ binlog_bytes_written = 0;
++ updated_row_count = 0;
++ sent_row_count_2 = 0;
+ #ifndef DBUG_OFF
+ dbug_sentry=THD_SENTRY_MAGIC;
+ #endif
+@@ -378,6 +385,88 @@
+ total_warn_count= 0;
+ update_charset();
+ bzero((char *) &status_var, sizeof(status_var));
++ reset_stats();
++}
++
++// Resets stats in a THD.
++void THD::reset_stats(void) {
++ current_connect_time = time(NULL);
++ last_global_update_time = current_connect_time;
++ reset_diff_stats();
++}
++
++// Resets the 'diff' stats, which are used to update global stats.
++void THD::reset_diff_stats(void) {
++ diff_total_busy_time = 0;
++ diff_total_cpu_time = 0;
++ diff_total_bytes_received = 0;
++ diff_total_bytes_sent = 0;
++ diff_total_binlog_bytes_written = 0;
++ diff_total_sent_rows = 0;
++ diff_total_updated_rows = 0;
++ diff_total_read_rows = 0;
++ diff_select_commands = 0;
++ diff_update_commands = 0;
++ diff_other_commands = 0;
++ diff_commit_trans = 0;
++ diff_rollback_trans = 0;
++ diff_denied_connections = 0;
++ diff_lost_connections = 0;
++ diff_access_denied_errors = 0;
++ diff_empty_queries = 0;
++}
++
++// Updates 'diff' stats of a THD.
++void THD::update_stats(bool ran_command) {
++ if (opt_userstat_running) {
++ diff_total_busy_time += busy_time;
++ diff_total_cpu_time += cpu_time;
++ diff_total_bytes_received += bytes_received;
++ diff_total_bytes_sent += bytes_sent;
++ diff_total_binlog_bytes_written += binlog_bytes_written;
++ diff_total_sent_rows += sent_row_count_2;
++ diff_total_updated_rows += updated_row_count;
++ // diff_total_read_rows is updated in handler.cc.
++
++ if (ran_command) {
++ // The replication thread has the COM_CONNECT command.
++ if ((old_command == COM_QUERY || command == COM_CONNECT) &&
++ (lex->sql_command >= 0 && lex->sql_command < SQLCOM_END)) {
++ // A SQL query.
++ if (lex->sql_command == SQLCOM_SELECT) {
++ if (lex->orig_sql_command == SQLCOM_END) {
++ diff_select_commands++;
++ if (!sent_row_count_2)
++ diff_empty_queries++;
++ } else {
++ // 'SHOW ' commands become SQLCOM_SELECT.
++ diff_other_commands++;
++ // 'SHOW ' commands shouldn't inflate total sent row count.
++ diff_total_sent_rows -= sent_row_count_2;
++ }
++ } else if (is_update_query(lex->sql_command)) {
++ diff_update_commands++;
++ } else {
++ diff_other_commands++;
++ }
++ }
++ }
++ // diff_commit_trans is updated in handler.cc.
++ // diff_rollback_trans is updated in handler.cc.
++ // diff_denied_connections is updated in sql_parse.cc.
++ // diff_lost_connections is updated in sql_parse.cc.
++ // diff_access_denied_errors is updated in sql_parse.cc.
++
++ /* reset counters to zero to avoid double-counting since values
++ are already store in diff_total_*. */
++ }
++ busy_time = 0;
++ cpu_time = 0;
++ bytes_received = 0;
++ bytes_sent = 0;
++ binlog_bytes_written = 0;
++ updated_row_count = 0;
++ sent_row_count_2 = 0;
+ }
+
+
+@@ -907,6 +996,33 @@
+ }
+ #endif
+
++char *THD::get_client_host_port(THD *client)
++{
++ Security_context *client_sctx= client->security_ctx;
++ char *client_host= NULL;
++
++ if (client->peer_port && (client_sctx->host || client_sctx->ip) &&
++ security_ctx->host_or_ip[0])
++ {
++ if ((client_host= this->alloc(LIST_PROCESS_HOST_LEN+1)))
++ my_snprintf((char *) client_host, LIST_PROCESS_HOST_LEN,
++ "%s:%u", client_sctx->host_or_ip, client->peer_port);
++ }
++ else
++ client_host= this->strdup(client_sctx->host_or_ip[0] ?
++ client_sctx->host_or_ip :
++ client_sctx->host ? client_sctx->host : "");
++
++ return client_host;
++}
++
++const char *get_client_host(THD *client)
++{
++ return client->security_ctx->host_or_ip[0] ?
++ client->security_ctx->host_or_ip :
++ client->security_ctx->host ? client->security_ctx->host : "";
++}
++
+
+ struct Item_change_record: public ilink
+ {
+@@ -1082,6 +1198,7 @@
+ buffer.set(buff, sizeof(buff), &my_charset_bin);
+ }
+ thd->sent_row_count++;
++ thd->sent_row_count_2++;
+ if (!thd->vio_ok())
+ DBUG_RETURN(0);
+ if (!thd->net.report_error)
+@@ -1174,6 +1291,7 @@
+ select_export::~select_export()
+ {
+ thd->sent_row_count=row_count;
++ thd->sent_row_count_2=row_count;
+ }
+
+
+@@ -2108,6 +2226,7 @@
+ if (likely(thd != 0))
+ { /* current_thd==0 when close_connection() calls net_send_error() */
+ thd->status_var.bytes_sent+= length;
++ thd->bytes_sent+= length;
+ }
+ }
+
+@@ -2115,6 +2234,7 @@
+ void thd_increment_bytes_received(ulong length)
+ {
+ current_thd->status_var.bytes_received+= length;
++ current_thd->bytes_received+= length;
+ }
+
+
+diff -r 592f6c3641ba sql/sql_class.h
+--- a/sql/sql_class.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_class.h Wed Jul 29 13:34:11 2009 -0700
+@@ -1302,6 +1302,8 @@
+ first byte of the packet in do_command()
+ */
+ enum enum_server_command command;
++ // Used to save the command, before it is set to COM_SLEEP.
++ enum enum_server_command old_command;
+ uint32 server_id;
+ uint32 file_id; // for LOAD DATA INFILE
+ /*
+@@ -1498,6 +1500,8 @@
+ /* variables.transaction_isolation is reset to this after each commit */
+ enum_tx_isolation session_tx_isolation;
+ enum_check_fields count_cuted_fields;
++ ha_rows updated_row_count;
++ ha_rows sent_row_count_2; /* for userstat */
+
+ DYNAMIC_ARRAY user_var_events; /* For user variables replication */
+ MEM_ROOT *user_var_events_alloc; /* Allocate above array elements here */
+@@ -1607,6 +1611,49 @@
+ */
+ LOG_INFO* current_linfo;
+ NET* slave_net; // network connection from slave -> m.
++
++ /*
++ Used to update global user stats. The global user stats are updated
++ occasionally with the 'diff' variables. After the update, the 'diff'
++ variables are reset to 0.
++ */
++ // Time when the current thread connected to MySQL.
++ time_t current_connect_time;
++ // Last time when THD stats were updated in global_user_stats.
++ time_t last_global_update_time;
++ // Busy (non-idle) time for just one command.
++ double busy_time;
++ // Busy time not updated in global_user_stats yet.
++ double diff_total_busy_time;
++ // Cpu (non-idle) time for just one thread.
++ double cpu_time;
++ // Cpu time not updated in global_user_stats yet.
++ double diff_total_cpu_time;
++ /* bytes counting */
++ ulonglong bytes_received;
++ ulonglong diff_total_bytes_received;
++ ulonglong bytes_sent;
++ ulonglong diff_total_bytes_sent;
++ ulonglong binlog_bytes_written;
++ ulonglong diff_total_binlog_bytes_written;
++
++ // Number of rows not reflected in global_user_stats yet.
++ ha_rows diff_total_sent_rows, diff_total_updated_rows, diff_total_read_rows;
++ // Number of commands not reflected in global_user_stats yet.
++ ulonglong diff_select_commands, diff_update_commands, diff_other_commands;
++ // Number of transactions not reflected in global_user_stats yet.
++ ulonglong diff_commit_trans, diff_rollback_trans;
++ // Number of connection errors not reflected in global_user_stats yet.
++ ulonglong diff_denied_connections, diff_lost_connections;
++ // Number of db access denied, not reflected in global_user_stats yet.
++ ulonglong diff_access_denied_errors;
++ // Number of queries that return 0 rows
++ ulonglong diff_empty_queries;
++
++ // Per account query delay in miliseconds. When not 0, sleep this number of
++ // milliseconds before every SQL command.
++ ulonglong query_delay_millis;
++
+ /* Used by the sys_var class to store temporary values */
+ union
+ {
+@@ -1662,6 +1709,11 @@
+ alloc_root.
+ */
+ void init_for_queries();
++ void reset_stats(void);
++ void reset_diff_stats(void);
++ // ran_command is true when this is called immediately after a
++ // command has been run.
++ void update_stats(bool ran_command);
+ void change_user(void);
+ void cleanup(void);
+ void cleanup_after_query();
+@@ -1891,8 +1943,14 @@
+ if (p_db_length)
+ *p_db_length= db_length;
+ return FALSE;
++
++ // Returns string as 'IP:port' for the client-side of the connnection represented
++ // by 'client' as displayed by SHOW PROCESSLIST. Allocates memory from the heap of
++ // this THD and that is not reclaimed immediately, so use sparingly. May return NULL.
+ }
+
++ char *get_client_host_port(THD *client);
++
+ public:
+ /**
+ Add an internal error handler to the thread execution context.
+@@ -1935,6 +1993,10 @@
+ MEM_ROOT main_mem_root;
+ };
+
++// Returns string as 'IP' for the client-side of the connection represented by
++// 'client'. Does not allocate memory. May return "".
++const char *get_client_host(THD *client);
++
+
+ #define tmp_disable_binlog(A) \
+ {ulonglong tmp_disable_binlog__save_options= (A)->options; \
+diff -r 592f6c3641ba sql/sql_delete.cc
+--- a/sql/sql_delete.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_delete.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -358,6 +358,7 @@
+ send_ok(thd,deleted);
+ DBUG_PRINT("info",("%ld records deleted",(long) deleted));
+ }
++ thd->updated_row_count += deleted;
+ DBUG_RETURN(error >= 0 || thd->net.report_error);
+ }
+
+@@ -887,6 +888,7 @@
+ thd->row_count_func= deleted;
+ ::send_ok(thd, deleted);
+ }
++ thd->updated_row_count += deleted;
+ return 0;
+ }
+
+diff -r 592f6c3641ba sql/sql_insert.cc
+--- a/sql/sql_insert.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_insert.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -990,6 +990,7 @@
+ thd->row_count_func= info.copied + info.deleted + updated;
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
+ }
++ thd->updated_row_count += thd->row_count_func;
+ thd->abort_on_warning= 0;
+ DBUG_RETURN(FALSE);
+
+@@ -3094,6 +3095,7 @@
+ autoinc_value_of_first_inserted_row : thd->insert_id_used ?
+ thd->last_insert_id : 0;
+ ::send_ok(thd, (ulong) thd->row_count_func, id, buff);
++ thd->updated_row_count += thd->row_count_func;
+ DBUG_RETURN(0);
+ }
+
+diff -r 592f6c3641ba sql/sql_lex.h
+--- a/sql/sql_lex.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_lex.h Wed Jul 29 13:34:11 2009 -0700
+@@ -101,6 +101,9 @@
+ When a command is added here, be sure it's also added in mysqld.cc
+ in "struct show_var_st status_vars[]= {" ...
+ */
++ // TODO(mcallaghan): update status_vars in mysqld to export these
++ SQLCOM_SHOW_USER_STATS, SQLCOM_SHOW_TABLE_STATS, SQLCOM_SHOW_INDEX_STATS,
++ SQLCOM_SHOW_CLIENT_STATS,
+ /* This should be the last !!! */
+ SQLCOM_END
+ };
+diff -r 592f6c3641ba sql/sql_parse.cc
+--- a/sql/sql_parse.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_parse.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -78,6 +78,12 @@
+ const char *table_name);
+ static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
+
++// Increments connection count for user.
++static int increment_connection_count(THD* thd, bool use_lock);
++
++// Uses the THD to update the global stats by user name and client IP
++void update_global_user_stats(THD* thd, bool create_user, time_t now);
++
+ const char *any_db="*any*"; // Special symbol for check_access
+
+ const char *command_name[]={
+@@ -146,6 +152,17 @@
+ static bool do_command(THD *thd);
+ #endif // EMBEDDED_LIBRARY
+
++HASH global_user_stats;
++HASH global_client_stats;
++// Protects global_user_stats and global_client_stats
++extern pthread_mutex_t LOCK_global_user_client_stats;
++
++HASH global_table_stats;
++extern pthread_mutex_t LOCK_global_table_stats;
++
++HASH global_index_stats;
++extern pthread_mutex_t LOCK_global_index_stats;
++
+ #ifdef __WIN__
+ extern void win_install_sigabrt_handler(void);
+ #endif
+@@ -504,6 +521,7 @@
+ mysql_log.write(thd,COM_CONNECT,"%s",ER(ER_NOT_SUPPORTED_AUTH_MODE));
+ DBUG_RETURN(-1);
+ }
++ thd->diff_access_denied_errors++;
+ net_printf_error(thd, ER_ACCESS_DENIED_ERROR,
+ thd->main_security_ctx.user,
+ thd->main_security_ctx.host_or_ip,
+@@ -536,12 +554,190 @@
+ void init_max_user_conn(void)
+ {
+ #ifndef NO_EMBEDDED_ACCESS_CHECKS
+- (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
+- 0,0,
+- (hash_get_key) get_key_conn, (hash_free_key) free_user,
+- 0);
+-#endif
+-}
++ if (hash_init(&hash_user_connections,system_charset_info,max_connections,
++ 0,0,
++ (hash_get_key) get_key_conn, (hash_free_key) free_user,
++ 0)) {
++ sql_print_error("Initializing hash_user_connections failed.");
++ exit(1);
++ }
++#endif
++}
++
++byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(user_stats->user);
++ return (byte*)user_stats->user;
++}
++
++void free_user_stats(USER_STATS* user_stats)
++{
++ my_free((char*)user_stats, MYF(0));
++}
++
++void init_user_stats(USER_STATS *user_stats,
++ const char *user,
++ const char *priv_user,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries)
++{
++ DBUG_ENTER("init_user_stats");
++ DBUG_PRINT("info",
++ ("Add user_stats entry for user %s - priv_user %s",
++ user, priv_user));
++ strncpy(user_stats->user, user, sizeof(user_stats->user));
++ strncpy(user_stats->priv_user, priv_user, sizeof(user_stats->priv_user));
++
++ user_stats->total_connections = total_connections;
++ user_stats->concurrent_connections = concurrent_connections;
++ user_stats->connected_time = connected_time;
++ user_stats->busy_time = busy_time;
++ user_stats->cpu_time = cpu_time;
++ user_stats->bytes_received = bytes_received;
++ user_stats->bytes_sent = bytes_sent;
++ user_stats->binlog_bytes_written = binlog_bytes_written;
++ user_stats->rows_fetched = rows_fetched;
++ user_stats->rows_updated = rows_updated;
++ user_stats->rows_read = rows_read;
++ user_stats->select_commands = select_commands;
++ user_stats->update_commands = update_commands;
++ user_stats->other_commands = other_commands;
++ user_stats->commit_trans = commit_trans;
++ user_stats->rollback_trans = rollback_trans;
++ user_stats->denied_connections = denied_connections;
++ user_stats->lost_connections = lost_connections;
++ user_stats->access_denied_errors = access_denied_errors;
++ user_stats->empty_queries = empty_queries;
++ DBUG_VOID_RETURN;
++}
++
++void add_user_stats(USER_STATS *user_stats,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries)
++{
++ user_stats->total_connections += total_connections;
++ user_stats->concurrent_connections += concurrent_connections;
++ user_stats->connected_time += connected_time;
++ user_stats->busy_time += busy_time;
++ user_stats->cpu_time += cpu_time;
++ user_stats->bytes_received += bytes_received;
++ user_stats->bytes_sent += bytes_sent;
++ user_stats->binlog_bytes_written += binlog_bytes_written;
++ user_stats->rows_fetched += rows_fetched;
++ user_stats->rows_updated += rows_updated;
++ user_stats->rows_read += rows_read;
++ user_stats->select_commands += select_commands;
++ user_stats->update_commands += update_commands;
++ user_stats->other_commands += other_commands;
++ user_stats->commit_trans += commit_trans;
++ user_stats->rollback_trans += rollback_trans;
++ user_stats->denied_connections += denied_connections;
++ user_stats->lost_connections += lost_connections;
++ user_stats->access_denied_errors += access_denied_errors;
++ user_stats->empty_queries += empty_queries;
++}
++
++void init_global_user_stats(void)
++{
++ if (hash_init(&global_user_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0)) {
++ sql_print_error("Initializing global_user_stats failed.");
++ exit(1);
++ }
++}
++
++void init_global_client_stats(void)
++{
++ if (hash_init(&global_client_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0)) {
++ sql_print_error("Initializing global_client_stats failed.");
++ exit(1);
++ }
++}
++
++extern "C" byte *get_key_table_stats(TABLE_STATS *table_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(table_stats->table);
++ return (byte*)table_stats->table;
++}
++
++extern "C" void free_table_stats(TABLE_STATS* table_stats)
++{
++ my_free((char*)table_stats, MYF(0));
++}
++
++void init_global_table_stats(void)
++{
++ if (hash_init(&global_table_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_table_stats,
++ (hash_free_key)free_table_stats, 0)) {
++ sql_print_error("Initializing global_table_stats failed.");
++ exit(1);
++ }
++}
++
++extern "C" byte *get_key_index_stats(INDEX_STATS *index_stats, uint *length,
++ my_bool not_used __attribute__((unused)))
++{
++ *length = strlen(index_stats->index);
++ return (byte*)index_stats->index;
++}
++
++extern "C" void free_index_stats(INDEX_STATS* index_stats)
++{
++ my_free((char*)index_stats, MYF(0));
++}
++
++void init_global_index_stats(void)
++{
++ if (hash_init(&global_index_stats, system_charset_info, max_connections,
++ 0, 0, (hash_get_key)get_key_index_stats,
++ (hash_free_key)free_index_stats, 0)) {
++ sql_print_error("Initializing global_index_stats failed.");
++ exit(1);
++ }
++}
++
+
+
+ /*
+@@ -599,7 +795,10 @@
+
+ end:
+ if (error)
++ {
++ statistic_increment(denied_connections, &LOCK_status);
+ uc->connections--; // no need for decrease_user_connections() here
++ }
+ (void) pthread_mutex_unlock(&LOCK_user_conn);
+ DBUG_RETURN(error);
+ }
+@@ -646,6 +845,25 @@
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ }
+
++void free_global_user_stats(void)
++{
++ hash_free(&global_user_stats);
++}
++
++void free_global_table_stats(void)
++{
++ hash_free(&global_table_stats);
++}
++
++void free_global_index_stats(void)
++{
++ hash_free(&global_index_stats);
++}
++
++void free_global_client_stats(void)
++{
++ hash_free(&global_client_stats);
++}
+
+
+ /*
+@@ -698,6 +916,214 @@
+ return uc_update_queries[command] != 0;
+ }
+
++// 'mysql_system_user' is used for when the user is not defined for a THD.
++static char mysql_system_user[] = "#mysql_system#";
++
++// Returns 'user' if it's not NULL. Returns 'mysql_system_user' otherwise.
++static char* get_valid_user_string(char* user) {
++ return user ? user : mysql_system_user;
++}
++
++// Increments the global stats connection count for an entry from
++// global_client_stats or global_user_stats. Returns 0 on success
++// and 1 on error.
++static int increment_count_by_name(const char *name, const char *role_name,
++ HASH *users_or_clients, THD *thd)
++{
++ USER_STATS* user_stats;
++
++ if (!(user_stats = (USER_STATS*)hash_search(users_or_clients, name,
++ strlen(name))))
++ {
++ // First connection for this user or client
++ if (!(user_stats = ((USER_STATS*)
++ my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL)))))
++ {
++ return 1; // Out of memory
++ }
++
++ init_user_stats(user_stats, name, role_name,
++ 0, 0, // connections
++ 0, 0, 0, // time
++ 0, 0, 0, // bytes sent, received and written
++ 0, 0, 0, // rows fetched, updated and read
++ 0, 0, 0, // select, update and other commands
++ 0, 0, // commit and rollback trans
++ thd->diff_denied_connections,
++ 0, // lost connections
++ 0, // access denied errors
++ 0); // empty queries
++
++ if (my_hash_insert(users_or_clients, (byte*)user_stats))
++ {
++ my_free((char*)user_stats, 0);
++ return 1; // Out of memory
++ }
++ }
++ user_stats->total_connections++;
++ return 0;
++}
++
++// Increments the global user and client stats connection count. If 'use_lock'
++// is true, LOCK_global_user_client_stats will be locked/unlocked. Returns
++// 0 on success, 1 on error.
++static int increment_connection_count(THD* thd, bool use_lock)
++{
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ const char* client_string = get_client_host(thd);
++ int return_value = 0;
++
++ if (!opt_userstat_running)
++ return return_value;
++
++ if (use_lock) pthread_mutex_lock(&LOCK_global_user_client_stats);
++
++ if (increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd))
++ {
++ return_value = 1;
++ goto end;
++ }
++ if (increment_count_by_name(client_string,
++ user_string,
++ &global_client_stats, thd))
++ {
++ return_value = 1;
++ goto end;
++ }
++
++end:
++ if (use_lock) pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ return return_value;
++}
++
++// Used to update the global user and client stats.
++static void update_global_user_stats_with_user(THD* thd,
++ USER_STATS* user_stats,
++ time_t now)
++{
++ user_stats->connected_time += now - thd->last_global_update_time;
++ thd->last_global_update_time = now;
++ user_stats->busy_time += thd->diff_total_busy_time;
++ user_stats->cpu_time += thd->diff_total_cpu_time;
++ user_stats->bytes_received += thd->diff_total_bytes_received;
++ user_stats->bytes_sent += thd->diff_total_bytes_sent;
++ user_stats->binlog_bytes_written += thd->diff_total_binlog_bytes_written;
++ user_stats->rows_fetched += thd->diff_total_sent_rows;
++ user_stats->rows_updated += thd->diff_total_updated_rows;
++ user_stats->rows_read += thd->diff_total_read_rows;
++ user_stats->select_commands += thd->diff_select_commands;
++ user_stats->update_commands += thd->diff_update_commands;
++ user_stats->other_commands += thd->diff_other_commands;
++ user_stats->commit_trans += thd->diff_commit_trans;
++ user_stats->rollback_trans += thd->diff_rollback_trans;
++ user_stats->denied_connections += thd->diff_denied_connections;
++ user_stats->lost_connections += thd->diff_lost_connections;
++ user_stats->access_denied_errors += thd->diff_access_denied_errors;
++ user_stats->empty_queries += thd->diff_empty_queries;
++}
++
++// Updates the global stats of a user or client
++void update_global_user_stats(THD* thd, bool create_user, time_t now)
++{
++ if (opt_userstat_running) {
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ const char* client_string = get_client_host(thd);
++
++ USER_STATS* user_stats;
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++
++ // Update by user name
++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
++ (byte*)user_string,
++ strlen(user_string)))) {
++ // Found user.
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Create the entry
++ if (create_user) {
++ increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd);
++ }
++ }
++
++ // Update by client IP
++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
++ (byte*)client_string,
++ strlen(client_string)))) {
++ // Found by client IP
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Create the entry
++ if (create_user) {
++ increment_count_by_name(client_string,
++ user_string,
++ &global_client_stats, thd);
++ }
++ }
++ thd->reset_diff_stats();
++
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ } else {
++ thd->reset_diff_stats();
++ }
++}
++
++// Determines the concurrent number of connections of current threads.
++static void set_connections_stats()
++{
++ USER_STATS* user_stats;
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ pthread_mutex_lock(&LOCK_thread_count);
++
++ // Resets all concurrent connections to 0.
++ for (int i = 0; i < global_user_stats.records; ++i) {
++ user_stats = (USER_STATS*)hash_element(&global_user_stats, i);
++ user_stats->concurrent_connections = 0;
++ }
++ for (int i = 0; i < global_client_stats.records; ++i) {
++ user_stats = (USER_STATS*)hash_element(&global_client_stats, i);
++ user_stats->concurrent_connections = 0;
++ }
++
++ I_List_iterator<THD> it(threads);
++ THD* thd;
++ time_t now = time(NULL);
++ // Iterates through the current threads.
++ while ((thd = it++)) {
++ char* user_string = get_valid_user_string(thd->main_security_ctx.user);
++ if ((user_stats = (USER_STATS*)hash_search(&global_user_stats,
++ (byte*)user_string,
++ strlen(user_string)))) {
++ // Found user.
++ user_stats->concurrent_connections++;
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // The user name should exist.
++ if (user_string == mysql_system_user) {
++ // Only create the user if it is the mysql_system_user
++ increment_count_by_name(user_string, user_string,
++ &global_user_stats, thd);
++ }
++ }
++
++ const char* client_string = get_client_host(thd);
++ if ((user_stats = (USER_STATS*)hash_search(&global_client_stats,
++ (byte*)client_string,
++ strlen(client_string)))) {
++ // Found user.
++ user_stats->concurrent_connections++;
++ update_global_user_stats_with_user(thd, user_stats, now);
++ } else {
++ // Do nothing, unlike what is done for global_user_stats
++ }
++ thd->reset_diff_stats();
++ }
++ pthread_mutex_unlock(&LOCK_thread_count);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++}
++
+ /*
+ Reset per-hour user resource limits when it has been more than
+ an hour since they were last checked
+@@ -1184,6 +1610,8 @@
+ my_net_set_read_timeout(net, connect_timeout);
+ my_net_set_write_timeout(net, connect_timeout);
+
++ bool create_user = true;
++
+ if ((error=check_connection(thd)))
+ { // Wrong permissions
+ if (error > 0)
+@@ -1193,8 +1621,22 @@
+ my_sleep(1000); /* must wait after eof() */
+ #endif
+ statistic_increment(aborted_connects,&LOCK_status);
++ thd->diff_denied_connections++;
++ if (error == -2) {
++ // Do not create statistics for a user who does not exist, or failed
++ // to authenticate.
++ create_user = false;
++ }
+ goto end_thread;
+ }
++
++ thd->reset_stats();
++ // Updates global user connection stats.
++ if (increment_connection_count(thd, true)) {
++ net_send_error(thd, ER_OUTOFMEMORY); // Out of memory
++ goto end_thread;
++ }
++
+ #ifdef __NETWARE__
+ netware_reg_user(sctx->ip, sctx->user, "MySQL");
+ #endif
+@@ -1251,6 +1693,7 @@
+ (net->vio && net->error && net->report_error))
+ {
+ statistic_increment(aborted_threads, &LOCK_status);
++ thd->diff_lost_connections++;
+ }
+
+ if (net->error && net->vio != 0 && net->report_error)
+@@ -1270,6 +1713,8 @@
+
+ end_thread:
+ close_connection(thd, 0, 1);
++ thd->update_stats(false);
++ update_global_user_stats(thd, create_user, time(NULL));
+ end_thread(thd,1);
+ /*
+ If end_thread returns, we are either running with --one-thread
+@@ -1601,6 +2046,13 @@
+
+ thd->clear_error(); // Clear error message
+
++ thd->updated_row_count=0;
++ thd->busy_time=0;
++ thd->cpu_time=0;
++ thd->bytes_received=0;
++ thd->bytes_sent=0;
++ thd->binlog_bytes_written=0;
++
+ net_new_transaction(net);
+
+ packet_length= my_net_read(net);
+@@ -1759,6 +2211,9 @@
+ }
+
+ thd->command=command;
++ // To increment the corrent command counter for user stats, 'command' must
++ // be saved because it is set to COM_SLEEP at the end of this function.
++ thd->old_command = command;
+ /*
+ Commands which always take a long time are logged into
+ the slow log only if opt_log_slow_admin_statements is set.
+@@ -4539,6 +4994,15 @@
+ if (check_global_access(thd,RELOAD_ACL))
+ goto error;
+
++ if(lex->type & REFRESH_SLOW_QUERY_LOG) {
++ /* We are only flushing slow query log */
++ mysql_slow_log.new_file(1);
++
++ send_ok(thd);
++ break;
++ }
++
++
+ /*
+ reload_acl_and_cache() will tell us if we are allowed to write to the
+ binlog or not.
+@@ -4847,6 +5311,7 @@
+ {
+ if (check_global_access(thd, SUPER_ACL))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
+ goto create_sp_error;
+ }
+@@ -5691,6 +6156,7 @@
+ if (!no_errors)
+ {
+ const char *db_name= db ? db : thd->db;
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host, db_name);
+ }
+@@ -5726,6 +6192,7 @@
+ { // We can never grant this
+ DBUG_PRINT("error",("No possible access"));
+ if (!no_errors)
++ thd->diff_access_denied_errors++;
+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user,
+ sctx->priv_host,
+@@ -5758,11 +6225,15 @@
+
+ DBUG_PRINT("error",("Access denied"));
+ if (!no_errors)
++ {
++ // increment needs !no_errors condition, otherwise double counting.
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host,
+ (db ? db : (thd->db ?
+ thd->db :
+ "unknown"))); /* purecov: tested */
++ }
+ DBUG_RETURN(TRUE); /* purecov: tested */
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+ }
+@@ -5796,6 +6267,7 @@
+ if ((thd->security_ctx->master_access & want_access))
+ return 0;
+ get_privilege_desc(command, sizeof(command), want_access);
++ thd->diff_access_denied_errors++;
+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
+ return 1;
+ #endif /* NO_EMBEDDED_ACCESS_CHECKS */
+@@ -5828,6 +6300,7 @@
+
+ if (!thd->col_access && check_grant_db(thd, dst_db_name))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ thd->security_ctx->priv_user,
+ thd->security_ctx->priv_host,
+@@ -5859,6 +6332,12 @@
+ check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE);
+ }
+
++
++ case SCH_USER_STATS:
++ case SCH_CLIENT_STATS:
++ return check_global_access(thd, SUPER_ACL | PROCESS_ACL);
++ case SCH_TABLE_STATS:
++ case SCH_INDEX_STATS:
+ case SCH_OPEN_TABLES:
+ case SCH_VARIABLES:
+ case SCH_STATUS:
+@@ -5912,8 +6391,8 @@
+ #ifndef NO_EMBEDDED_ACCESS_CHECKS
+ TABLE_LIST *org_tables= tables;
+ #endif
++ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
+ TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
+- Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
+ /*
+ The check that first_not_own_table is not reached is for the case when
+ the given table list refers to the list for prelocking (contains tables
+@@ -5930,9 +6409,12 @@
+ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
+ {
+ if (!no_errors)
++ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->priv_host,
+ INFORMATION_SCHEMA_NAME.str);
++ }
+ return TRUE;
+ }
+ /*
+@@ -6442,6 +6924,30 @@
+ lex_start(thd);
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
+ {
+ LEX *lex= thd->lex;
+@@ -6520,6 +7026,43 @@
+ *found_semicolon= NULL;
+ }
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -7531,8 +8074,35 @@
+ pthread_mutex_unlock(&LOCK_active_mi);
+ }
+ #endif
+- if (options & REFRESH_USER_RESOURCES)
+- reset_mqh((LEX_USER *) NULL);
++ if (options & REFRESH_TABLE_STATS)
++ {
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ free_global_table_stats();
++ init_global_table_stats();
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++ }
++ if (options & REFRESH_INDEX_STATS)
++ {
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ free_global_index_stats();
++ init_global_index_stats();
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ }
++ if (options & (REFRESH_USER_STATS | REFRESH_CLIENT_STATS))
++ {
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ if (options & REFRESH_USER_STATS)
++ {
++ free_global_user_stats();
++ init_global_user_stats();
++ }
++ if (options & REFRESH_CLIENT_STATS)
++ {
++ free_global_client_stats();
++ init_global_client_stats();
++ }
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ }
+ *write_to_binlog= tmp_write_to_binlog;
+ return result;
+ }
+diff -r 592f6c3641ba sql/sql_prepare.cc
+--- a/sql/sql_prepare.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_prepare.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -81,6 +81,9 @@
+ #include <mysql_com.h>
+ #endif
+
++// Uses the THD to update the global stats by user name and client IP
++void update_global_user_stats(THD* thd, bool create_user, time_t now);
++
+ /* A result class used to send cursor rows using the binary protocol. */
+
+ class Select_fetch_protocol_prep: public select_send
+@@ -1910,8 +1913,32 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (! (stmt= new Prepared_statement(thd, &thd->protocol_prep)))
+- DBUG_VOID_RETURN; /* out of memory: error is set in Sql_alloc */
++ goto end; /* out of memory: error is set in Sql_alloc */
+
+ if (thd->stmt_map.insert(thd, stmt))
+ {
+@@ -1919,7 +1946,7 @@
+ The error is set in the insert. The statement itself
+ will be also deleted there (this is how the hash works).
+ */
+- DBUG_VOID_RETURN;
++ goto end;
+ }
+
+ /* Reset warnings from previous command */
+@@ -1941,6 +1968,44 @@
+ thd->stmt_map.erase(stmt);
+ }
+ /* check_prepared_statemnt sends the metadata packet in case of success */
++end:
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2281,8 +2346,32 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
+- DBUG_VOID_RETURN;
++ goto end;
+
+ #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.set_query_source(stmt->query, stmt->query_length);
+@@ -2325,11 +2414,50 @@
+ test(flags & (ulong) CURSOR_TYPE_READ_ONLY));
+ if (!(specialflag & SPECIAL_NO_PRIOR))
+ my_pthread_setprio(pthread_self(), WAIT_PRIOR);
+- DBUG_VOID_RETURN;
++ goto end;
+
+ set_params_data_err:
+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "mysql_stmt_execute");
+ reset_stmt_params(stmt);
++
++end:
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2423,6 +2551,31 @@
+
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
++
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ statistic_increment(thd->status_var.com_stmt_fetch, &LOCK_status);
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_fetch")))
+ DBUG_VOID_RETURN;
+@@ -2455,6 +2608,43 @@
+ thd->restore_backup_statement(stmt, &stmt_backup);
+ thd->stmt_arena= thd;
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+@@ -2487,6 +2677,30 @@
+ /* First of all clear possible warnings from the previous command */
+ mysql_reset_thd_for_next_command(thd);
+
++ int start_time_error = 0;
++ int end_time_error = 0;
++ struct timeval start_time, end_time;
++ double start_usecs = 0;
++ double end_usecs = 0;
++ /* cpu time */
++ int cputime_error = 0;
++ struct timespec tp;
++ double start_cpu_nsecs = 0;
++ double end_cpu_nsecs = 0;
++
++ if (opt_userstat_running) {
++#ifdef HAVE_CLOCK_GETTIME
++ /* get start cputime */
++ if (!(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ start_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++
++ // Gets the start time, in order to measure how long this command takes.
++ if (!(start_time_error = gettimeofday(&start_time, NULL))) {
++ start_usecs = start_time.tv_sec * 1000000.0 + start_time.tv_usec;
++ }
++ }
++
+ statistic_increment(thd->status_var.com_stmt_reset, &LOCK_status);
+ if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_reset")))
+ DBUG_VOID_RETURN;
+@@ -2503,6 +2717,43 @@
+
+ send_ok(thd);
+
++ if (opt_userstat_running) {
++ // Gets the end time.
++ if (!(end_time_error = gettimeofday(&end_time, NULL))) {
++ end_usecs = end_time.tv_sec * 1000000.0 + end_time.tv_usec;
++ }
++
++ // Calculates the difference between the end and start times.
++ if (start_usecs && end_usecs >= start_usecs && !start_time_error && !end_time_error) {
++ thd->busy_time = (end_usecs - start_usecs) / 1000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->busy_time > 2629743) {
++ thd->busy_time = 0;
++ }
++ } else {
++ // end time went back in time, or gettimeofday() failed.
++ thd->busy_time = 0;
++ }
++
++#ifdef HAVE_CLOCK_GETTIME
++ /* get end cputime */
++ if (!cputime_error &&
++ !(cputime_error = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tp)))
++ end_cpu_nsecs = tp.tv_sec*1000000000.0+tp.tv_nsec;
++#endif
++ if (start_cpu_nsecs && !cputime_error) {
++ thd->cpu_time = (end_cpu_nsecs - start_cpu_nsecs) / 1000000000;
++ // In case there are bad values, 2629743 is the #seconds in a month.
++ if (thd->cpu_time > 2629743) {
++ thd->cpu_time = 0;
++ }
++ } else
++ thd->cpu_time = 0;
++ }
++ // Updates THD stats and the global user stats.
++ thd->update_stats(true);
++ update_global_user_stats(thd, true, time(NULL));
++
+ DBUG_VOID_RETURN;
+ }
+
+diff -r 592f6c3641ba sql/sql_show.cc
+--- a/sql/sql_show.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_show.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -540,6 +540,7 @@
+ sctx->master_access);
+ if (!(db_access & DB_ACLS) && (!grant_option || check_grant_db(thd,dbname)))
+ {
++ thd->diff_access_denied_errors++;
+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
+ sctx->priv_user, sctx->host_or_ip, dbname);
+ mysql_log.write(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
+@@ -1890,6 +1891,300 @@
+ DBUG_RETURN(FALSE);
+ }
+
++/*
++ Aggregate values for mapped_user entries by their role.
++
++ SYNOPSIS
++ aggregate_user_stats
++ all_user_stats - input to aggregate
++ agg_user_stats - returns aggregated values
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++static int
++aggregate_user_stats(HASH *all_user_stats, HASH *agg_user_stats)
++{
++ DBUG_ENTER("aggregate_user_stats");
++ if (hash_init(agg_user_stats, system_charset_info,
++ max(all_user_stats->records, 1),
++ 0, 0, (hash_get_key)get_key_user_stats,
++ (hash_free_key)free_user_stats, 0))
++ {
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++
++ for (int i = 0; i < all_user_stats->records; ++i) {
++ USER_STATS *user = (USER_STATS*)hash_element(all_user_stats, i);
++ USER_STATS *agg_user;
++ if (!(agg_user = (USER_STATS*)hash_search(agg_user_stats,
++ (byte*)user->priv_user,
++ strlen(user->priv_user))))
++ {
++ // First entry for this role.
++ if (!(agg_user =
++ (USER_STATS*) my_malloc(sizeof(USER_STATS), MYF(MY_WME | MY_ZEROFILL))))
++ {
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++
++ init_user_stats(agg_user, user->priv_user, user->priv_user,
++ user->total_connections, user->concurrent_connections,
++ user->connected_time, user->busy_time, user->cpu_time,
++ user->bytes_received, user->bytes_sent,
++ user->binlog_bytes_written,
++ user->rows_fetched, user->rows_updated, user->rows_read,
++ user->select_commands, user->update_commands,
++ user->other_commands,
++ user->commit_trans, user->rollback_trans,
++ user->denied_connections, user->lost_connections,
++ user->access_denied_errors, user->empty_queries);
++
++ if (my_hash_insert(agg_user_stats, (byte*)agg_user))
++ {
++ // Out of memory.
++ my_free((char*)agg_user, 0);
++ sql_print_error("Malloc in aggregate_user_stats failed");
++ DBUG_RETURN(1);
++ }
++ }
++ else
++ {
++ // Aggregate with existing values for this role.
++ add_user_stats(agg_user,
++ user->total_connections, user->concurrent_connections,
++ user->connected_time, user->busy_time, user->cpu_time,
++ user->bytes_received, user->bytes_sent,
++ user->binlog_bytes_written,
++ user->rows_fetched, user->rows_updated, user->rows_read,
++ user->select_commands, user->update_commands,
++ user->other_commands,
++ user->commit_trans, user->rollback_trans,
++ user->denied_connections, user->lost_connections,
++ user->access_denied_errors, user->empty_queries);
++ }
++ }
++ DBUG_PRINT("exit", ("aggregated %d input into %d output entries",
++ all_user_stats->records, agg_user_stats->records));
++ DBUG_RETURN(0);
++}
++
++/*
++ Write result to network for SHOW USER_STATISTICS
++
++ SYNOPSIS
++ send_user_stats
++ all_user_stats - values to return
++ table - I_S table
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++int send_user_stats(THD* thd, HASH *all_user_stats, TABLE *table)
++{
++ DBUG_ENTER("send_user_stats");
++ for (int i = 0; i < all_user_stats->records; ++i) {
++ restore_record(table, s->default_values);
++ USER_STATS *user_stats = (USER_STATS*)hash_element(all_user_stats, i);
++ table->field[0]->store(user_stats->user, strlen(user_stats->user), system_charset_info);
++ table->field[1]->store((longlong)user_stats->total_connections);
++ table->field[2]->store((longlong)user_stats->concurrent_connections);
++ table->field[3]->store((longlong)user_stats->connected_time);
++ table->field[4]->store((longlong)user_stats->busy_time);
++ table->field[5]->store((longlong)user_stats->cpu_time);
++ table->field[6]->store((longlong)user_stats->bytes_received);
++ table->field[7]->store((longlong)user_stats->bytes_sent);
++ table->field[8]->store((longlong)user_stats->binlog_bytes_written);
++ table->field[9]->store((longlong)user_stats->rows_fetched);
++ table->field[10]->store((longlong)user_stats->rows_updated);
++ table->field[11]->store((longlong)user_stats->rows_read);
++ table->field[12]->store((longlong)user_stats->select_commands);
++ table->field[13]->store((longlong)user_stats->update_commands);
++ table->field[14]->store((longlong)user_stats->other_commands);
++ table->field[15]->store((longlong)user_stats->commit_trans);
++ table->field[16]->store((longlong)user_stats->rollback_trans);
++ table->field[17]->store((longlong)user_stats->denied_connections);
++ table->field[18]->store((longlong)user_stats->lost_connections);
++ table->field[19]->store((longlong)user_stats->access_denied_errors);
++ table->field[20]->store((longlong)user_stats->empty_queries);
++ if (schema_table_store_record(thd, table))
++ {
++ DBUG_PRINT("error", ("store record error"));
++ DBUG_RETURN(1);
++ }
++ }
++ DBUG_RETURN(0);
++}
++
++/*
++ Process SHOW USER_STATISTICS
++
++ SYNOPSIS
++ mysqld_show_user_stats
++ thd - current thread
++ wild - limit results to the entry for this user
++ with_roles - when true, display role for mapped users
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++
++
++int fill_schema_user_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_user_stats");
++
++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
++ DBUG_RETURN(1);
++
++ // Iterates through all the global stats and sends them to the client.
++ // Pattern matching on the client IP is supported.
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ int result= send_user_stats(thd, &global_user_stats, table);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ if (result)
++ goto err;
++
++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 0"));
++ DBUG_RETURN(0);
++
++ err:
++ DBUG_PRINT("exit", ("fill_schema_user_stats result is 1"));
++ DBUG_RETURN(1);
++}
++
++/*
++ Process SHOW CLIENT_STATISTICS
++
++ SYNOPSIS
++ mysqld_show_client_stats
++ thd - current thread
++ wild - limit results to the entry for this client
++
++ RETURN
++ 0 - OK
++ 1 - error
++ */
++
++
++int fill_schema_client_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_client_stats");
++
++ if (check_global_access(thd, SUPER_ACL | PROCESS_ACL))
++ DBUG_RETURN(1);
++
++ // Iterates through all the global stats and sends them to the client.
++ // Pattern matching on the client IP is supported.
++
++ pthread_mutex_lock(&LOCK_global_user_client_stats);
++ int result= send_user_stats(thd, &global_client_stats, table);
++ pthread_mutex_unlock(&LOCK_global_user_client_stats);
++ if (result)
++ goto err;
++
++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 0"));
++ DBUG_RETURN(0);
++
++ err:
++ DBUG_PRINT("exit", ("mysqld_show_client_stats result is 1"));
++ DBUG_RETURN(1);
++}
++
++
++// Sends the global table stats back to the client.
++int fill_schema_table_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_table_stats");
++ char *table_full_name, *table_schema;
++
++ pthread_mutex_lock(&LOCK_global_table_stats);
++ for (int i = 0; i < global_table_stats.records; ++i) {
++ restore_record(table, s->default_values);
++ TABLE_STATS *table_stats =
++ (TABLE_STATS*)hash_element(&global_table_stats, i);
++
++ table_full_name= thd->strdup(table_stats->table);
++ table_schema= strsep(&table_full_name, ".");
++
++ TABLE_LIST tmp_table;
++ bzero((char*) &tmp_table,sizeof(tmp_table));
++ tmp_table.table_name= table_full_name;
++ tmp_table.db= table_schema;
++ tmp_table.grant.privilege= 0;
++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
++ &tmp_table.grant.privilege, 0, 0,
++ is_schema_db(table_schema)) ||
++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
++ continue;
++
++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
++ table->field[1]->store(table_full_name, strlen(table_full_name), system_charset_info);
++ table->field[2]->store((longlong)table_stats->rows_read, TRUE);
++ table->field[3]->store((longlong)table_stats->rows_changed, TRUE);
++ table->field[4]->store((longlong)table_stats->rows_changed_x_indexes, TRUE);
++
++ if (schema_table_store_record(thd, table))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_global_table_stats));
++ DBUG_RETURN(1);
++ }
++ }
++ pthread_mutex_unlock(&LOCK_global_table_stats);
++ DBUG_RETURN(0);
++}
++
++// Sends the global index stats back to the client.
++int fill_schema_index_stats(THD* thd, TABLE_LIST* tables, COND* cond)
++{
++ TABLE *table= tables->table;
++ DBUG_ENTER("fill_schema_index_stats");
++ char *index_full_name, *table_schema, *table_name;
++
++ pthread_mutex_lock(&LOCK_global_index_stats);
++ for (int i = 0; i < global_index_stats.records; ++i) {
++ restore_record(table, s->default_values);
++ INDEX_STATS *index_stats =
++ (INDEX_STATS*)hash_element(&global_index_stats, i);
++
++ index_full_name= thd->strdup(index_stats->index);
++ table_schema= strsep(&index_full_name, ".");
++ table_name= strsep(&index_full_name, ".");
++
++ TABLE_LIST tmp_table;
++ bzero((char*) &tmp_table,sizeof(tmp_table));
++ tmp_table.table_name= table_name;
++ tmp_table.db= table_schema;
++ tmp_table.grant.privilege= 0;
++ if (check_access(thd, SELECT_ACL | EXTRA_ACL, tmp_table.db,
++ &tmp_table.grant.privilege, 0, 0,
++ is_schema_db(table_schema)) ||
++ grant_option && check_grant(thd, SELECT_ACL, &tmp_table, 1, UINT_MAX, 1))
++ continue;
++
++ table->field[0]->store(table_schema, strlen(table_schema), system_charset_info);
++ table->field[1]->store(table_name, strlen(table_name), system_charset_info);
++ table->field[2]->store(index_full_name, strlen(index_full_name), system_charset_info);
++ table->field[3]->store((longlong)index_stats->rows_read, TRUE);
++
++ if (schema_table_store_record(thd, table))
++ {
++ VOID(pthread_mutex_unlock(&LOCK_global_index_stats));
++ DBUG_RETURN(1);
++ }
++ }
++ pthread_mutex_unlock(&LOCK_global_index_stats);
++ DBUG_RETURN(0);
++}
+
+ /* collect status for all running threads */
+
+@@ -4500,6 +4795,77 @@
+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
+ };
+
++ST_FIELD_INFO user_stats_fields_info[]=
++{
++ {"USER", USERNAME_LENGTH, MYSQL_TYPE_STRING, 0, 0, "User"},
++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++ST_FIELD_INFO client_stats_fields_info[]=
++{
++ {"CLIENT", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Client"},
++ {"TOTAL_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Total_connections"},
++ {"CONCURRENT_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Concurrent_connections"},
++ {"CONNECTED_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Connected_time"},
++ {"BUSY_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Busy_time"},
++ {"CPU_TIME", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Cpu_time"},
++ {"BYTES_RECEIVED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_received"},
++ {"BYTES_SENT", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Bytes_sent"},
++ {"BINLOG_BYTES_WRITTEN", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Binlog_bytes_written"},
++ {"ROWS_FETCHED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_fetched"},
++ {"ROWS_UPDATED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_updated"},
++ {"TABLE_ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Table_rows_read"},
++ {"SELECT_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Select_commands"},
++ {"UPDATE_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Update_commands"},
++ {"OTHER_COMMANDS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Other_commands"},
++ {"COMMIT_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Commit_transactions"},
++ {"ROLLBACK_TRANSACTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rollback_transactions"},
++ {"DENIED_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Denied_connections"},
++ {"LOST_CONNECTIONS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Lost_connections"},
++ {"ACCESS_DENIED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Access_denied"},
++ {"EMPTY_QUERIES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Empty_queries"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++
++ST_FIELD_INFO table_stats_fields_info[]=
++{
++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
++ {"ROWS_CHANGED", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed"},
++ {"ROWS_CHANGED_X_INDEXES", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_changed_x_#indexes"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
++
++ST_FIELD_INFO index_stats_fields_info[]=
++{
++ {"TABLE_SCHEMA", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_schema"},
++ {"TABLE_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_name"},
++ {"INDEX_NAME", NAME_LEN, MYSQL_TYPE_STRING, 0, 0, "Index_name"},
++ {"ROWS_READ", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONG, 0, 0, "Rows_read"},
++ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0}
++};
+
+ /*
+ Description of ST_FIELD_INFO in table.h
+@@ -4509,6 +4875,8 @@
+ {
+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
+ fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0},
++ {"CLIENT_STATISTICS", client_stats_fields_info, create_schema_table,
++ fill_schema_client_stats, make_old_format, 0, -1, -1, 0},
+ {"COLLATIONS", collation_fields_info, create_schema_table,
+ fill_schema_collation, make_old_format, 0, -1, -1, 0},
+ {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
+@@ -4517,6 +4885,8 @@
+ get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0},
+ {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
+ fill_schema_column_privileges, 0, 0, -1, -1, 0},
++ {"INDEX_STATISTICS", index_stats_fields_info, create_schema_table,
++ fill_schema_index_stats, make_old_format, 0, -1, -1, 0},
+ {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
+ get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
+ {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
+@@ -4542,6 +4912,8 @@
+ get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0},
+ {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
+ get_all_tables, 0, get_schema_constraints_record, 3, 4, 0},
++ {"TABLE_STATISTICS", table_stats_fields_info, create_schema_table,
++ fill_schema_table_stats, make_old_format, 0, -1, -1, 0},
+ {"TABLE_NAMES", table_names_fields_info, create_schema_table,
+ get_all_tables, make_table_names_old_format, 0, 1, 2, 1},
+ {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
+@@ -4550,6 +4920,8 @@
+ get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0},
+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
+ fill_schema_user_privileges, 0, 0, -1, -1, 0},
++ {"USER_STATISTICS", user_stats_fields_info, create_schema_table,
++ fill_schema_user_stats, make_old_format, 0, -1, -1, 0},
+ {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
+ make_old_format, 0, -1, -1, 1},
+ {"VIEWS", view_fields_info, create_schema_table,
+diff -r 592f6c3641ba sql/sql_update.cc
+--- a/sql/sql_update.cc Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_update.cc Wed Jul 29 13:34:11 2009 -0700
+@@ -601,7 +601,8 @@
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
+ send_ok(thd, (ulong) thd->row_count_func,
+ thd->insert_id_used ? thd->last_insert_id : 0L,buff);
+- DBUG_PRINT("info",("%ld records updated", (long) updated));
++ thd->updated_row_count += thd->row_count_func;
++ DBUG_PRINT("info",("%d records updated",updated));
+ }
+ thd->count_cuted_fields= CHECK_FIELD_IGNORE; /* calc cuted fields */
+ thd->abort_on_warning= 0;
+@@ -1832,5 +1833,6 @@
+ (thd->client_capabilities & CLIENT_FOUND_ROWS) ? found : updated;
+ ::send_ok(thd, (ulong) thd->row_count_func,
+ thd->insert_id_used ? thd->last_insert_id : 0L,buff);
++ thd->updated_row_count += thd->row_count_func;
+ return FALSE;
+ }
+diff -r 592f6c3641ba sql/sql_yacc.yy
+--- a/sql/sql_yacc.yy Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/sql_yacc.yy Wed Jul 29 13:34:11 2009 -0700
+@@ -523,6 +523,7 @@
+ %token CHECK_SYM
+ %token CIPHER_SYM
+ %token CLIENT_SYM
++%token CLIENT_STATS_SYM
+ %token CLOSE_SYM
+ %token COALESCE
+ %token CODE_SYM
+@@ -680,6 +681,7 @@
+ %token IMPORT
+ %token INDEXES
+ %token INDEX_SYM
++%token INDEX_STATS_SYM
+ %token INFILE
+ %token INNER_SYM
+ %token INNOBASE_SYM
+@@ -909,6 +911,7 @@
+ %token SIGNED_SYM
+ %token SIMPLE_SYM
+ %token SLAVE
++%token SLOW_SYM
+ %token SMALLINT
+ %token SNAPSHOT_SYM
+ %token SOUNDS_SYM
+@@ -949,6 +952,7 @@
+ %token TABLES
+ %token TABLESPACE
+ %token TABLE_SYM
++%token TABLE_STATS_SYM
+ %token TEMPORARY
+ %token TEMPTABLE_SYM
+ %token TERMINATED
+@@ -991,6 +995,7 @@
+ %token UPGRADE_SYM
+ %token USAGE
+ %token USER
++%token USER_STATS_SYM
+ %token USE_FRM
+ %token USE_SYM
+ %token USING
+@@ -8255,6 +8260,38 @@
+ {
+ Lex->sql_command = SQLCOM_SHOW_SLAVE_STAT;
+ }
++ | CLIENT_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ Lex->sql_command = SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_CLIENT_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_CLIENT_STATS))
++ MYSQL_YYABORT;
++ }
++ | USER_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command = SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_USER_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_USER_STATS))
++ MYSQL_YYABORT;
++ }
++ | TABLE_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command= SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_TABLE_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_TABLE_STATS))
++ MYSQL_YYABORT;
++ }
++ | INDEX_STATS_SYM wild_and_where
++ {
++ LEX *lex= Lex;
++ lex->sql_command= SQLCOM_SELECT;
++ lex->orig_sql_command= SQLCOM_SHOW_INDEX_STATS;
++ if (prepare_schema_table(YYTHD, lex, 0, SCH_INDEX_STATS))
++ MYSQL_YYABORT;
++ }
+ | CREATE PROCEDURE sp_name
+ {
+ LEX *lex= Lex;
+@@ -8459,9 +8496,14 @@
+ | LOGS_SYM { Lex->type|= REFRESH_LOG; }
+ | STATUS_SYM { Lex->type|= REFRESH_STATUS; }
+ | SLAVE { Lex->type|= REFRESH_SLAVE; }
++ | SLOW_SYM QUERY_SYM LOGS_SYM { Lex->type |= REFRESH_SLOW_QUERY_LOG; }
+ | MASTER_SYM { Lex->type|= REFRESH_MASTER; }
+ | DES_KEY_FILE { Lex->type|= REFRESH_DES_KEY_FILE; }
+- | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; };
++ | RESOURCES { Lex->type|= REFRESH_USER_RESOURCES; }
++ | CLIENT_STATS_SYM { Lex->type|= REFRESH_CLIENT_STATS; }
++ | USER_STATS_SYM { Lex->type|= REFRESH_USER_STATS; }
++ | TABLE_STATS_SYM { Lex->type|= REFRESH_TABLE_STATS; }
++ | INDEX_STATS_SYM { Lex->type|= REFRESH_INDEX_STATS; };
+
+ opt_table_list:
+ /* empty */ {;}
+@@ -9450,6 +9492,7 @@
+ | CHAIN_SYM {}
+ | CHANGED {}
+ | CIPHER_SYM {}
++ | CLIENT_STATS_SYM {}
+ | CLIENT_SYM {}
+ | CODE_SYM {}
+ | COLLATION_SYM {}
+@@ -9502,6 +9545,7 @@
+ | HOSTS_SYM {}
+ | HOUR_SYM {}
+ | IDENTIFIED_SYM {}
++ | INDEX_STATS_SYM {}
+ | INVOKER_SYM {}
+ | IMPORT {}
+ | INDEXES {}
+@@ -9611,6 +9655,7 @@
+ | SIMPLE_SYM {}
+ | SHARE_SYM {}
+ | SHUTDOWN {}
++ | SLOW_SYM {}
+ | SNAPSHOT_SYM {}
+ | SOUNDS_SYM {}
+ | SOURCE_SYM {}
+@@ -9627,6 +9672,7 @@
+ | SUSPEND_SYM {}
+ | SWAPS_SYM {}
+ | SWITCHES_SYM {}
++ | TABLE_STATS_SYM {}
+ | TABLES {}
+ | TABLESPACE {}
+ | TEMPORARY {}
+@@ -9647,6 +9693,7 @@
+ | UNKNOWN_SYM {}
+ | UNTIL_SYM {}
+ | USER {}
++ | USER_STATS_SYM {}
+ | USE_FRM {}
+ | VARIABLES {}
+ | VIEW_SYM {}
+diff -r 592f6c3641ba sql/structs.h
+--- a/sql/structs.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/structs.h Wed Jul 29 13:34:11 2009 -0700
+@@ -273,6 +273,98 @@
+ time_t intime;
+ } USER_CONN;
+
++typedef struct st_user_stats {
++ char user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
++ // Account name the user is mapped to when this is a user from mapped_user.
++ // Otherwise, the same value as user.
++ char priv_user[max(USERNAME_LENGTH, LIST_PROCESS_HOST_LEN) + 1];
++ uint total_connections;
++ uint concurrent_connections;
++ time_t connected_time; // in seconds
++ double busy_time; // in seconds
++ double cpu_time; // in seconds
++ ulonglong bytes_received;
++ ulonglong bytes_sent;
++ ulonglong binlog_bytes_written;
++ ha_rows rows_fetched, rows_updated, rows_read;
++ ulonglong select_commands, update_commands, other_commands;
++ ulonglong commit_trans, rollback_trans;
++ ulonglong denied_connections, lost_connections;
++ ulonglong access_denied_errors;
++ ulonglong empty_queries;
++} USER_STATS;
++
++/* Lookup function for hash tables with USER_STATS entries */
++extern byte *get_key_user_stats(USER_STATS *user_stats, uint *length,
++ my_bool not_used __attribute__((unused)));
++
++/* Free all memory for a hash table with USER_STATS entries */
++extern void free_user_stats(USER_STATS* user_stats);
++
++/* Intialize an instance of USER_STATS */
++extern void
++init_user_stats(USER_STATS *user_stats,
++ const char *user,
++ const char *priv_user,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries);
++
++/* Increment values of an instance of USER_STATS */
++extern void
++add_user_stats(USER_STATS *user_stats,
++ uint total_connections,
++ uint concurrent_connections,
++ time_t connected_time,
++ double busy_time,
++ double cpu_time,
++ ulonglong bytes_received,
++ ulonglong bytes_sent,
++ ulonglong binlog_bytes_written,
++ ha_rows rows_fetched,
++ ha_rows rows_updated,
++ ha_rows rows_read,
++ ulonglong select_commands,
++ ulonglong update_commands,
++ ulonglong other_commands,
++ ulonglong commit_trans,
++ ulonglong rollback_trans,
++ ulonglong denied_connections,
++ ulonglong lost_connections,
++ ulonglong access_denied_errors,
++ ulonglong empty_queries);
++
++typedef struct st_table_stats {
++ char table[NAME_LEN * 2 + 2]; // [db] + '.' + [table] + '\0'
++ ulonglong rows_read, rows_changed;
++ ulonglong rows_changed_x_indexes;
++ /* Stores enum db_type, but forward declarations cannot be done */
++ int engine_type;
++} TABLE_STATS;
++
++typedef struct st_index_stats {
++ char index[NAME_LEN * 3 + 3]; // [db] + '.' + [table] + '.' + [index] + '\0'
++ ulonglong rows_read;
++} INDEX_STATS;
++
++
+ /* Bits in form->update */
+ #define REG_MAKE_DUPP 1 /* Make a copy of record when read */
+ #define REG_NEW_RECORD 2 /* Write a new record if not found */
+diff -r 592f6c3641ba sql/table.h
+--- a/sql/table.h Wed Jul 29 13:33:34 2009 -0700
++++ b/sql/table.h Wed Jul 29 13:34:11 2009 -0700
+@@ -371,10 +371,12 @@
+ enum enum_schema_tables
+ {
+ SCH_CHARSETS= 0,
++ SCH_CLIENT_STATS,
+ SCH_COLLATIONS,
+ SCH_COLLATION_CHARACTER_SET_APPLICABILITY,
+ SCH_COLUMNS,
+ SCH_COLUMN_PRIVILEGES,
++ SCH_INDEX_STATS,
+ SCH_KEY_COLUMN_USAGE,
+ SCH_OPEN_TABLES,
+ SCH_PROFILES,
+@@ -387,8 +389,10 @@
+ SCH_TABLE_CONSTRAINTS,
+ SCH_TABLE_NAMES,
+ SCH_TABLE_PRIVILEGES,
++ SCH_TABLE_STATS,
+ SCH_TRIGGERS,
+ SCH_USER_PRIVILEGES,
++ SCH_USER_STATS,
+ SCH_VARIABLES,
+ SCH_VIEWS
+ };
+diff -r 592f6c3641ba strings/Makefile.in
+--- a/strings/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/strings/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -342,6 +342,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/MacOSX/Makefile.in
+--- a/support-files/MacOSX/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/MacOSX/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -148,6 +148,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/Makefile.in
+--- a/support-files/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -171,6 +171,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba support-files/RHEL4-SElinux/Makefile.in
+--- a/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/support-files/RHEL4-SElinux/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -146,6 +146,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba tests/Makefile.in
+--- a/tests/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/tests/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -193,6 +193,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @CLIENT_LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba tools/Makefile.in
+--- a/tools/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/tools/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -167,6 +167,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba vio/Makefile.in
+--- a/vio/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/vio/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -176,6 +176,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba win/Makefile.in
+--- a/win/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/win/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -144,6 +144,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = @LIBS@
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -r 592f6c3641ba zlib/Makefile.in
+--- a/zlib/Makefile.in Wed Jul 29 13:33:34 2009 -0700
++++ b/zlib/Makefile.in Wed Jul 29 13:34:11 2009 -0700
+@@ -187,6 +187,7 @@
+ LIBDL = @LIBDL@
+ LIBEDIT_LOBJECTS = @LIBEDIT_LOBJECTS@
+ LIBOBJS = @LIBOBJS@
++LIBRT = @LIBRT@
+ LIBS = $(NON_THREADED_LIBS)
+ LIBTOOL = @LIBTOOL@
+ LIB_EXTRA_CCFLAGS = @LIB_EXTRA_CCFLAGS@
+diff -Nur a/include/mysql_com.h b/include/mysql_com.h
+--- a/include/mysql_com.h 2010-05-22 00:26:45.000000000 -0700
++++ b/include/mysql_com.h 2010-05-22 00:27:14.000000000 -0700
+@@ -228,7 +228,7 @@
+
+ my_bool report_error; /* We should report error (we have unreported error) */
+ my_bool return_errno;
+-#if defined(MYSQL_SERVER) && !defined(EMBEDDED_LIBRARY)
++#if defined(MYSQL_SERVER)
+ /*
+ Controls whether a big packet should be skipped.
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-16 20:20 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-16 20:20 UTC (permalink / raw
To: gentoo-commits
commit: 1fff1558d58b499bde98cf044f93b8f74aaf23d9
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Mon Apr 16 20:21:41 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Apr 16 20:21:41 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1fff1558
Respin of 07280_all_stdbool-maria-5.1.42.patch for newer MariaDB.
---
00000_index.txt | 7 ++-
07280_all_stdbool-maria-5.1.62.patch | 99 ++++++++++++++++++++++++++++++++++
2 files changed, 105 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index d5cd020..2f51125 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -702,7 +702,12 @@
@@ Fix GCC4.4 stdbool requirement.
@patch 07280_all_stdbool-maria-5.1.42.patch
-@ver 5.01.00.00 to 5.01.99.99
+@ver 5.01.00.00 to 5.01.61.99
+@pn mariadb
+@@ Fix GCC4.4 stdbool requirement.
+
+@patch 07280_all_stdbool-maria-5.1.62.patch
+@ver 5.01.62.00 to 5.01.99.99
@pn mariadb
@@ Fix GCC4.4 stdbool requirement.
diff --git a/07280_all_stdbool-maria-5.1.62.patch b/07280_all_stdbool-maria-5.1.62.patch
new file mode 100644
index 0000000..817f05c
--- /dev/null
+++ b/07280_all_stdbool-maria-5.1.62.patch
@@ -0,0 +1,99 @@
+GCC4.4 header requirements.
+
+X-Gentoo-Bug: 30522
+X-Gentoo-Patch: http://bugs.gentoo.org/attachment.cgi?id=220053&action=view
+X-Ported: from 07280_all_stdbool-maria-5.1.42.patch
+X-Ported: from 07280_all_stdbool-5.1.44.patch
+X-Ported: from 07280_all_stdbool-5.0.90.patch
+
+diff -Nuar --exclude '*.orig' mysql/extra/replace.c mysql.new/extra/replace.c
+--- mysql/extra/replace.c 2010-01-31 04:17:57.000000000 -0500
++++ mysql.new/extra/replace.c 2010-02-24 10:42:32.055074861 -0500
+@@ -40,6 +40,7 @@
+ */
+
+ #define DONT_USE_RAID
++#include <stdbool.h>
+ #include <my_global.h>
+ #include <m_ctype.h>
+ #include <my_sys.h>
+diff -Nuar --exclude '*.orig' mysql/include/my_getopt.h mysql.new/include/my_getopt.h
+--- mysql/include/my_getopt.h 2010-01-31 04:17:59.000000000 -0500
++++ mysql.new/include/my_getopt.h 2010-02-24 10:41:32.365074952 -0500
+@@ -16,6 +16,8 @@
+ #ifndef _my_getopt_h
+ #define _my_getopt_h
+
++#include <stdbool.h>
++
+ C_MODE_START
+
+ #define GET_NO_ARG 1
+diff -Nuar --exclude '*.orig' mysql/include/my_time.h mysql.new/include/my_time.h
+--- mysql/include/my_time.h 2010-01-31 04:17:59.000000000 -0500
++++ mysql.new/include/my_time.h 2010-02-24 10:41:58.705074961 -0500
+@@ -20,6 +20,9 @@
+
+ #ifndef _my_time_h_
+ #define _my_time_h_
++
++#include <stdbool.h>
++
+ #include "my_global.h"
+ #include "mysql_time.h"
+
+diff -Nuar --exclude '*.orig' mysql/mysys/thr_lock.c mysql.new/mysys/thr_lock.c
+--- mysql/mysys/thr_lock.c 2010-01-31 04:18:19.000000000 -0500
++++ mysql.new/mysys/thr_lock.c 2010-02-24 10:19:11.045074691 -0500
+@@ -80,6 +80,8 @@
+ #define FORCE_DBUG_OFF
+ #endif
+
++#include <stdbool.h>
++
+ #include "mysys_priv.h"
+
+ #ifdef THREAD
+diff -Nuar --exclude '*.orig' mysql/regex/reginit.c mysql.new/regex/reginit.c
+--- mysql/regex/reginit.c 2010-01-31 04:18:19.000000000 -0500
++++ mysql.new/regex/reginit.c 2010-02-24 10:43:07.695074821 -0500
+@@ -1,5 +1,6 @@
+ /* Init cclasses array from ctypes */
+
++#include <stdbool.h>
+ #include <my_global.h>
+ #include <m_ctype.h>
+ #include <m_string.h>
+diff -Nuar --exclude '*.orig' mysql/storage/heap/hp_update.c mysql.new/storage/heap/hp_update.c
+--- mysql/storage/heap/hp_update.c 2010-01-31 04:18:23.000000000 -0500
++++ mysql.new/storage/heap/hp_update.c 2010-02-24 10:44:03.015074446 -0500
+@@ -15,6 +15,7 @@
+
+ /* Update current record in heap-database */
+
++#include <stdbool.h>
+ #include "heapdef.h"
+
+ int heap_update(HP_INFO *info, const uchar *old, const uchar *heap_new)
+diff -Nuar --exclude '*.orig' mysql/storage/myisam/myisamdef.h mysql.new/storage/myisam/myisamdef.h
+--- mysql/storage/myisam/myisamdef.h 2010-01-31 04:18:26.000000000 -0500
++++ mysql.new/storage/myisam/myisamdef.h 2010-02-24 10:44:37.345074924 -0500
+@@ -15,6 +15,7 @@
+
+ /* This file is included by all internal myisam files */
+
++#include <stdbool.h>
+ #include <myisam.h> /* Structs & some defines */
+ #include <myisampack.h> /* packing of keys */
+ #include <my_tree.h>
+diff -Nuar --exclude '*.orig' mysql/vio/viosslfactories.c mysql.new/vio/viosslfactories.c
+--- mysql/vio/viosslfactories.c 2010-01-31 04:18:34.000000000 -0500
++++ mysql.new/vio/viosslfactories.c 2010-02-24 10:44:56.245075119 -0500
+@@ -13,6 +13,7 @@
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
++#include <stdbool.h>
+ #include "vio_priv.h"
+
+ #ifdef HAVE_OPENSSL
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-21 20:34 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-21 20:34 UTC (permalink / raw
To: gentoo-commits
commit: 7aa54c7d20620cbceeed24a65723d7d1c5a60bc4
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sat Apr 21 19:54:41 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Apr 21 20:03:26 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=7aa54c7d
Fix auth bypass discovered by MontyProgram, already fix in last week's MariaDB releases.
---
00000_index.txt | 10 ++++++++++
07342_all_mysql_auth_bypass-5.1.62.patch | 29 +++++++++++++++++++++++++++++
07342_all_mysql_auth_bypass-5.5.22.patch | 17 +++++++++++++++++
3 files changed, 56 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index d5cd020..bafb35f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -767,6 +767,16 @@
@pn mariadb
@@ Gentoo Bug #344031: Fix new TEXTRELs
+@patch 07342_all_mysql_auth_bypass-5.1.62.patch
+@ver 5.01.62.00 to 5.01.62.99
+@pn mysql
+@@ Upstream bug #64884: auth bypass
+
+@patch 07342_all_mysql_auth_bypass-5.5.22.patch
+@ver 5.05.22.00 to 5.05.22.99
+@pn mysql
+@@ Upstream bug #64884: auth bypass
+
@patch 10010_all_show_patches-percona-5.0.75-b12.patch
@ver 5.00.75.00 to 5.00.76.99
@pn mysql-community
diff --git a/07342_all_mysql_auth_bypass-5.1.62.patch b/07342_all_mysql_auth_bypass-5.1.62.patch
new file mode 100644
index 0000000..63cecf1
--- /dev/null
+++ b/07342_all_mysql_auth_bypass-5.1.62.patch
@@ -0,0 +1,29 @@
+Security bug http://bugs.mysql.com/bug.php?id=64884
+Already fixed in MariaDB 5.1.62+/5.5.23+
+
+Depends on the result of check_scramble being cast to char directly.
+
+diff -Nuar mysql.orig/libmysql/password.c mysql/libmysql/password.c
+--- mysql.orig/libmysql/password.c 2012-04-21 10:58:15.485424022 -0700
++++ mysql/libmysql/password.c 2012-04-21 10:57:34.077773190 -0700
+@@ -531,7 +531,7 @@
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, hash_stage2_reassured);
+- return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
++ return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
+ }
+
+
+diff -Nuar mysql.orig/sql/password.c mysql/sql/password.c
+--- mysql.orig/sql/password.c 2012-04-21 10:58:18.941478337 -0700
++++ mysql/sql/password.c 2012-04-21 10:57:50.318028470 -0700
+@@ -531,7 +531,7 @@
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, hash_stage2_reassured);
+- return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
++ return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
+ }
+
+
diff --git a/07342_all_mysql_auth_bypass-5.5.22.patch b/07342_all_mysql_auth_bypass-5.5.22.patch
new file mode 100644
index 0000000..84e306a
--- /dev/null
+++ b/07342_all_mysql_auth_bypass-5.5.22.patch
@@ -0,0 +1,17 @@
+Security bug http://bugs.mysql.com/bug.php?id=64884
+Already fixed in MariaDB 5.1.62+/5.5.23+
+
+Depends on the result of check_scramble being cast to char directly.
+
+diff -Nuar mysql.orig/sql/password.c mysql/sql/password.c
+--- mysql.orig/sql/password.c 2012-03-02 11:44:47.000000000 -0800
++++ mysql/sql/password.c 2012-04-21 10:59:39.502744613 -0700
+@@ -531,7 +531,7 @@
+ mysql_sha1_reset(&sha1_context);
+ mysql_sha1_input(&sha1_context, buf, SHA1_HASH_SIZE);
+ mysql_sha1_result(&sha1_context, hash_stage2_reassured);
+- return memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE);
++ return test(memcmp(hash_stage2, hash_stage2_reassured, SHA1_HASH_SIZE));
+ }
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-04-21 20:34 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-04-21 20:34 UTC (permalink / raw
To: gentoo-commits
commit: c0e6d7d7409e3eecd0ad1864e81f9a2603c69fdd
Author: Robin H. Johnson <robbat2 <AT> orbis-terrarum <DOT> net>
AuthorDate: Sat Apr 21 20:34:09 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Apr 21 20:34:09 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c0e6d7d7
Merge branch 'master' of git+ssh://git.overlays.gentoo.org/proj/mysql-extras
00000_index.txt | 7 ++++++-
...2.patch => 07280_all_stdbool-maria-5.1.62.patch | 5 +++--
2 files changed, 9 insertions(+), 3 deletions(-)
^ permalink raw reply [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-08-02 19:27 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-08-02 19:27 UTC (permalink / raw
To: gentoo-commits
commit: bb11ef195710b977eb2165bd8600a83c4cc88e7d
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Thu Aug 2 19:13:06 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Aug 2 19:13:06 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=bb11ef19
Patch to fix unit tests that randomly fail on ma_test2 binary. Bugs #41001 #423467
---
00000_index.txt | 5 +++++
20000_all_mariadb_fix_tests.patch | 20 ++++++++++++++++++++
2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index ad79cd7..59e6c46 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1410,3 +1410,8 @@
@ver 5.02.07.00 to 5.03.99.99
@pn mariadb
@@ Fix duplicate entries for files on support-files/Makefile.am
+
+@patch 20000_all_mariadb_fix_tests.patch
+@ver 5.01.00.00 to 5.03.99.99
+@pn mariadb
+@@ Fix bad index in the ma_test2 unit test binary
diff --git a/20000_all_mariadb_fix_tests.patch b/20000_all_mariadb_fix_tests.patch
new file mode 100644
index 0000000..e5959c0
--- /dev/null
+++ b/20000_all_mariadb_fix_tests.patch
@@ -0,0 +1,20 @@
+--- mysql/storage/maria/ma_test2.c 2012-04-05 06:48:45.000000000 -0400
++++ mysql.new/storage/maria/ma_test2.c 2012-04-25 10:08:30.768603663 -0400
+@@ -259,7 +259,7 @@
+ for (i=0 ; i < recant ; i++)
+ {
+ ulong blob_length;
+- n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
++ n1=rnd(1000); n2=rnd(100); n3=rnd(4999);
+ sprintf((char*) record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count);
+ int4store(record+STANDARD_LENGTH-4,(long) i);
+ fix_length(record,(uint) STANDARD_LENGTH+rnd(60));
+@@ -374,7 +374,7 @@
+
+ for (i=0 ; i < update_count ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(5000);
++ n1=rnd(1000); n2=rnd(100); n3=rnd(4999);
+ sprintf((char*) record2,"%6d:%4d:%8d:XXX: %4d ",n1,n2,n3,update);
+ int4store(record2+STANDARD_LENGTH-4,(long) i);
+ fix_length(record2,(uint) STANDARD_LENGTH+rnd(60));
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-08-06 18:58 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-08-06 18:58 UTC (permalink / raw
To: gentoo-commits
commit: 4218898ead7a97f80d808d371d60b5d78c3d3448
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Mon Aug 6 17:49:47 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Aug 6 17:49:47 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=4218898e
Fix USE="minimal" on cmake builds to mimic the autotools builds.
The mariadb patch comments out a file that is only referenced by
the server and the aria storage engine.
---
00000_index.txt | 10 +++++++
20001_all_fix-minimal-build-cmake-mariadb.patch | 33 +++++++++++++++++++++++
20001_all_fix-minimal-build-cmake-mysql.patch | 17 ++++++++++++
3 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 59e6c46..1845b84 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1415,3 +1415,13 @@
@ver 5.01.00.00 to 5.03.99.99
@pn mariadb
@@ Fix bad index in the ma_test2 unit test binary
+
+@patch 20001_all_fix-minimal-build-cmake-mysql.patch
+@ver 5.05.00.00 to 5.99.99.99
+@pn mysql
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
+@ver 5.05.00.00 to 5.99.99.99
+@pn mariadb
+@@ Fix the minimal build by reordering CMakeLists.txt
diff --git a/20001_all_fix-minimal-build-cmake-mariadb.patch b/20001_all_fix-minimal-build-cmake-mariadb.patch
new file mode 100644
index 0000000..2d70db5
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mariadb.patch
@@ -0,0 +1,33 @@
+--- mysql/CMakeLists.txt 2012-08-03 16:37:52.234629566 -0400
++++ mysql/CMakeLists.txt 2012-08-03 16:35:47.797340969 -0400
+@@ -320,6 +320,13 @@
+ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
++ELSE()
++ ADD_SUBDIRECTORY(client)
++ ADD_SUBDIRECTORY(sql/share)
++ ADD_SUBDIRECTORY(scripts)
++ IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ ENDIF()
+ ENDIF()
+
+ INCLUDE(cmake/abi_check.cmake)
+--- mysql/mysys/CMakeLists.txt 2012-06-21 16:03:32.000000000 -0400
++++ mysql/mysys/CMakeLists.txt 2012-08-06 11:23:39.315296578 -0400
+@@ -36,9 +36,13 @@
+ lf_alloc-pin.c lf_dynarray.c lf_hash.c
+ safemalloc.c my_new.cc
+ my_atomic.c my_getncpus.c my_safehash.c my_chmod.c my_rnd.c
+- my_uuid.c wqueue.c waiting_threads.c ma_dyncol.c
++ my_uuid.c wqueue.c ma_dyncol.c
+ my_rdtsc.c my_context.c)
+
++IF(NOT WITHOUT_SERVER)
++ SET (MYSYS_SOURCES ${MYSYS_SOURCES} waiting_threads.c)
++ENDIF()
++
+ IF (WIN32)
+ SET (MYSYS_SOURCES ${MYSYS_SOURCES} my_winthread.c my_wincond.c my_winerr.c my_winfile.c my_windac.c my_conio.c)
+ ENDIF()
diff --git a/20001_all_fix-minimal-build-cmake-mysql.patch b/20001_all_fix-minimal-build-cmake-mysql.patch
new file mode 100644
index 0000000..24c77f8
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql.patch
@@ -0,0 +1,17 @@
+--- mysql/CMakeLists.txt 2012-08-03 16:37:52.234629566 -0400
++++ mysql.new/CMakeLists.txt 2012-08-03 16:35:47.797340969 -0400
+@@ -320,6 +320,13 @@
+ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
++ELSE()
++ ADD_SUBDIRECTORY(client)
++ ADD_SUBDIRECTORY(sql/share)
++ ADD_SUBDIRECTORY(scripts)
++ IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ ENDIF()
+ ENDIF()
+
+ INCLUDE(cmake/abi_check.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-08-07 17:42 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2012-08-07 17:42 UTC (permalink / raw
To: gentoo-commits
commit: 48c4205e4a6b98dd7a04c8c249184682610e0fc5
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Tue Aug 7 16:48:36 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Aug 7 16:48:36 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=48c4205e
Add in support-files to minimal build to add aclocal/mysql.m4 in install
---
20001_all_fix-minimal-build-cmake-mariadb.patch | 3 ++-
20001_all_fix-minimal-build-cmake-mysql.patch | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/20001_all_fix-minimal-build-cmake-mariadb.patch b/20001_all_fix-minimal-build-cmake-mariadb.patch
index 2d70db5..f3d5ee3 100644
--- a/20001_all_fix-minimal-build-cmake-mariadb.patch
+++ b/20001_all_fix-minimal-build-cmake-mariadb.patch
@@ -1,6 +1,6 @@
--- mysql/CMakeLists.txt 2012-08-03 16:37:52.234629566 -0400
+++ mysql/CMakeLists.txt 2012-08-03 16:35:47.797340969 -0400
-@@ -320,6 +320,13 @@
+@@ -320,6 +320,14 @@
IF(UNIX)
ADD_SUBDIRECTORY(man)
ENDIF()
@@ -8,6 +8,7 @@
+ ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(scripts)
++ ADD_SUBDIRECTORY(support-files)
+ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
diff --git a/20001_all_fix-minimal-build-cmake-mysql.patch b/20001_all_fix-minimal-build-cmake-mysql.patch
index 24c77f8..98ac62b 100644
--- a/20001_all_fix-minimal-build-cmake-mysql.patch
+++ b/20001_all_fix-minimal-build-cmake-mysql.patch
@@ -1,6 +1,6 @@
--- mysql/CMakeLists.txt 2012-08-03 16:37:52.234629566 -0400
+++ mysql.new/CMakeLists.txt 2012-08-03 16:35:47.797340969 -0400
-@@ -320,6 +320,13 @@
+@@ -320,6 +320,14 @@
IF(UNIX)
ADD_SUBDIRECTORY(man)
ENDIF()
@@ -8,6 +8,7 @@
+ ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(scripts)
++ ADD_SUBDIRECTORY(support-files)
+ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-08-14 1:23 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2012-08-14 1:23 UTC (permalink / raw
To: gentoo-commits
commit: d885833c62c056f6f470e19e7a917b172eb03be3
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Tue Aug 14 01:22:51 2012 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Tue Aug 14 01:22:51 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d885833c
Respin 07110_all_mysql_gcc-4.2 for mysql-5.1.65.
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.65.patch | 3833 ++++++++++++++++++++++++++++++++++
2 files changed, 3840 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1845b84..64daab2 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -557,7 +557,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.62.patch
-@ver 5.01.62.00 to 5.01.99.99
+@ver 5.01.62.00 to 5.01.64.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.65.patch
+@ver 5.01.65.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.65.patch b/07110_all_mysql_gcc-4.2_5.1.65.patch
new file mode 100644
index 0000000..89abf1a
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.65.patch
@@ -0,0 +1,3833 @@
+diff -ur mysql-orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql-orig/client/mysqlbinlog.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqlbinlog.cc 2012-08-14 01:14:59.292197574 +0000
+@@ -1978,7 +1978,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -ur mysql-orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql-orig/client/mysql.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -3334,9 +3334,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3356,7 +3356,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -ur mysql-orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql-orig/client/mysqldump.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqldump.c 2012-08-14 01:14:59.322198687 +0000
+@@ -849,7 +849,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4769,7 +4769,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -ur mysql-orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql-orig/client/mysqltest.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqltest.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -5666,9 +5666,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -ur mysql-orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql-orig/client/mysql_upgrade.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql_upgrade.c 2012-08-14 01:14:59.332198575 +0000
+@@ -533,7 +533,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -ur mysql-orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql-orig/client/sql_string.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/sql_string.cc 2012-08-14 01:14:59.332198575 +0000
+@@ -665,7 +665,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -751,7 +751,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -768,7 +768,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -ur mysql-orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql-orig/dbug/dbug.c 2012-08-14 01:12:29.743434923 +0000
++++ mysql/dbug/dbug.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -ur mysql-orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql-orig/extra/yassl/src/ssl.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -39,6 +39,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -114,7 +115,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -ur mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:14:59.332198575 +0000
+@@ -68,7 +68,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -ur mysql-orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-orig/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -ur mysql-orig/include/my_global.h mysql/include/my_global.h
+--- mysql-orig/include/my_global.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/include/my_global.h 2012-08-14 01:14:59.332198575 +0000
+@@ -586,10 +586,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -ur mysql-orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql-orig/libmysql/libmysql.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/libmysql/libmysql.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -ur mysql-orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql-orig/libmysqld/lib_sql.cc 2012-08-14 01:12:29.723435087 +0000
++++ mysql/libmysqld/lib_sql.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -844,7 +844,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -ur mysql-orig/mysys/array.c mysql/mysys/array.c
+--- mysql-orig/mysys/array.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/array.c 2012-08-14 01:14:59.372198019 +0000
+@@ -50,7 +50,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -344,7 +344,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -ur mysql-orig/mysys/default.c mysql/mysys/default.c
+--- mysql-orig/mysys/default.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/default.c 2012-08-14 01:14:59.372198019 +0000
+@@ -796,7 +796,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -ur mysql-orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql-orig/mysys/mf_format.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_format.c 2012-08-14 01:14:59.372198019 +0000
+@@ -86,7 +86,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -ur mysql-orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql-orig/mysys/mf_iocache.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_iocache.c 2012-08-14 01:14:59.372198019 +0000
+@@ -1099,7 +1099,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1258,7 +1258,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1367,7 +1367,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1401,7 +1401,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -ur mysql-orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql-orig/mysys/my_alloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_alloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -214,7 +214,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -ur mysql-orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql-orig/mysys/my_bitmap.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_bitmap.c 2012-08-14 01:14:59.372198019 +0000
+@@ -425,7 +425,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -ur mysql-orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql-orig/mysys/my_compare.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compare.c 2012-08-14 01:14:59.372198019 +0000
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -ur mysql-orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql-orig/mysys/my_compress.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compress.c 2012-08-14 01:14:59.372198019 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -ur mysql-orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql-orig/mysys/my_conio.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_conio.c 2012-08-14 01:14:59.372198019 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -ur mysql-orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql-orig/mysys/my_file.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_file.c 2012-08-14 01:14:59.372198019 +0000
+@@ -77,7 +77,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -99,7 +99,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -109,9 +109,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -ur mysql-orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql-orig/mysys/my_getopt.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_getopt.c 2012-08-14 01:14:59.372198019 +0000
+@@ -985,7 +985,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -ur mysql-orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql-orig/mysys/my_static.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_static.h 2012-08-14 01:14:59.372198019 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -ur mysql-orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql-orig/mysys/safemalloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/safemalloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -250,7 +250,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -ur mysql-orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql-orig/mysys/stacktrace.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/stacktrace.c 2012-08-14 01:14:59.372198019 +0000
+@@ -98,7 +98,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -328,7 +328,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
+ my_safe_printf_stderr("Cannot determine thread, fp=%p, "
+diff -ur mysql-orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql-orig/server-tools/instance-manager/buffer.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -86,8 +86,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -ur mysql-orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql-orig/server-tools/instance-manager/listener.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -106,7 +106,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -ur mysql-orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql-orig/sql/debug_sync.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/debug_sync.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -ur mysql-orig/sql/field.cc mysql/sql/field.cc
+--- mysql-orig/sql/field.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/field.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -55,7 +55,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2073,7 +2073,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2081,7 +2081,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2506,7 +2506,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2522,7 +2522,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3092,7 +3092,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3304,7 +3304,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3521,7 +3521,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3740,7 +3740,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3981,7 +3981,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4204,7 +4204,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6443,13 +6443,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6457,7 +6457,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6715,7 +6715,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7709,7 +7709,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7869,7 +7869,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8065,7 +8065,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9112,7 +9112,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9198,7 +9198,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9326,7 +9326,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9783,7 +9783,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -ur mysql-orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql-orig/sql/filesort.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/filesort.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -194,7 +194,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -216,12 +216,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+
+ if (table_sort.sort_keys &&
+ table_sort.sort_keys_size != char_array_size(param.keys,
+@@ -1133,7 +1133,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1396,7 +1396,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -ur mysql-orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql-orig/sql/ha_ndbcluster.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/ha_ndbcluster.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -ur mysql-orig/sql/handler.h mysql/sql/handler.h
+--- mysql-orig/sql/handler.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/handler.h 2012-08-14 01:14:59.382197947 +0000
+@@ -1607,15 +1607,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -ur mysql-orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql-orig/sql/ha_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/ha_partition.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -6138,7 +6138,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -ur mysql-orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql-orig/sql/item_buff.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_buff.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -61,7 +61,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -71,7 +71,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -ur mysql-orig/sql/item.cc mysql/sql/item.cc
+--- mysql-orig/sql/item.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -76,7 +76,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -444,9 +444,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -752,7 +752,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5417,7 +5417,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5472,7 +5472,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7554,14 +7554,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7592,7 +7592,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7614,7 +7614,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7632,7 +7632,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -ur mysql-orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql-orig/sql/item_cmpfunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_cmpfunc.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -ur mysql-orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql-orig/sql/item_func.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -ur mysql-orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql-orig/sql/item_func.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.h 2012-08-14 01:14:59.402197785 +0000
+@@ -421,7 +421,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
++ max_length= MYSQL_MIN(args[0]->max_length, DECIMAL_MAX_PRECISION + 2);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -ur mysql-orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql-orig/sql/item_strfunc.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -389,7 +389,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -750,7 +750,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1251,7 +1251,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1271,7 +1271,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1962,7 +1962,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3114,11 +3114,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3582,7 +3582,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -ur mysql-orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql-orig/sql/item_strfunc.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.h 2012-08-14 01:14:59.402197785 +0000
+@@ -709,7 +709,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -ur mysql-orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql-orig/sql/item_sum.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_sum.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -ur mysql-orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql-orig/sql/item_timefunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_timefunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -310,14 +310,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -326,7 +326,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -343,15 +343,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -362,14 +362,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -377,7 +377,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -429,7 +429,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -441,7 +441,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -453,7 +453,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -598,7 +598,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1830,7 +1830,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -ur mysql-orig/sql/key.cc mysql/sql/key.cc
+--- mysql-orig/sql/key.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/key.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -128,13 +128,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -218,7 +218,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -227,7 +227,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -288,7 +288,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -354,7 +354,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -ur mysql-orig/sql/log.cc mysql/sql/log.cc
+--- mysql-orig/sql/log.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2432,7 +2432,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5238,7 +5238,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -ur mysql-orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql-orig/sql/log_event.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/log_event.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1099,7 +1099,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2695,7 +2695,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5676,7 +5676,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7426,7 +7426,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql-orig/sql/log_event_old.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log_event_old.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1434,7 +1434,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql-orig/sql/mysqld.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/mysqld.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -3241,7 +3241,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3253,15 +3253,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -4947,7 +4947,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -ur mysql-orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql-orig/sql/net_serv.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/net_serv.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -ur mysql-orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql-orig/sql/opt_range.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -ur mysql-orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql-orig/sql/opt_range.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.h 2012-08-14 01:14:59.422197616 +0000
+@@ -85,7 +85,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -123,7 +123,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -ur mysql-orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql-orig/sql/protocol.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/protocol.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -168,7 +168,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -263,7 +263,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -ur mysql-orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql-orig/sql/rpl_record.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/rpl_record.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -287,7 +287,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -ur mysql-orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql-orig/sql/rpl_rli.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_rli.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -690,7 +690,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -700,7 +700,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -ur mysql-orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql-orig/sql/rpl_utility.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -182,7 +182,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -ur mysql-orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql-orig/sql/rpl_utility.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.h 2012-08-14 01:14:59.422197616 +0000
+@@ -315,7 +315,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -ur mysql-orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql-orig/sql/set_var.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/set_var.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1849,7 +1849,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4034,7 +4034,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -ur mysql-orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql-orig/sql/slave.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/slave.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1791,7 +1791,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2408,7 +2408,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4112,7 +4112,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -ur mysql-orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql-orig/sql/spatial.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/spatial.h 2012-08-14 01:14:59.432197532 +0000
+@@ -182,8 +182,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -ur mysql-orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql-orig/sql/sp_head.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sp_head.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -2481,7 +2481,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2682,7 +2682,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql-orig/sql/sql_acl.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_acl.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -ur mysql-orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql-orig/sql/sql_analyse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_analyse.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -282,16 +282,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1045,7 +1045,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1070,7 +1070,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1187,7 +1187,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -ur mysql-orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql-orig/sql/sql_cache.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_cache.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -1006,7 +1006,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2451,7 +2451,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2506,7 +2506,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2534,7 +2534,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2622,8 +2622,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2655,7 +2655,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2664,7 +2664,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3087,7 +3087,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -ur mysql-orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql-orig/sql/sql_class.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_class.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -418,7 +418,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -433,7 +433,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2116,7 +2116,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -ur mysql-orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql-orig/sql/sql_client.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_client.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -ur mysql-orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql-orig/sql/sql_connect.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_connect.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -845,7 +845,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -ur mysql-orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql-orig/sql/sql_parse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_parse.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -5762,7 +5762,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7293,7 +7293,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -ur mysql-orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql-orig/sql/sql_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_partition.cc 2012-08-14 01:14:59.462197286 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -ur mysql-orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql-orig/sql/sql_plugin.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_plugin.cc 2012-08-14 01:14:59.472197202 +0000
+@@ -512,7 +512,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2131,7 +2131,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -ur mysql-orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql-orig/sql/sql_prepare.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_prepare.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -ur mysql-orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql-orig/sql/sql_profile.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_profile.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -254,7 +254,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -ur mysql-orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql-orig/sql/sql_repl.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_repl.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -1299,12 +1299,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1478,7 +1478,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1750,14 +1750,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1766,7 +1766,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql-orig/sql/sql_select.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_select.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -3022,7 +3022,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3958,7 +3958,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3981,7 +3981,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4144,7 +4144,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4464,7 +4464,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4631,7 +4631,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5581,7 +5581,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10488,7 +10488,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13708,7 +13708,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13720,7 +13720,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14416,7 +14416,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14538,7 +14538,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -ur mysql-orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql-orig/sql/sql_show.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_show.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1875,7 +1875,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2006,7 +2006,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3276,7 +3276,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7095,7 +7095,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -ur mysql-orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql-orig/sql/sql_string.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_string.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -700,7 +700,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -786,7 +786,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -803,7 +803,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -1004,7 +1004,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1190,7 +1190,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -ur mysql-orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql-orig/sql/sql_table.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_table.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -3276,7 +3276,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -ur mysql-orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql-orig/sql/sql_yacc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.cc 2012-08-14 01:14:59.502196954 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -ur mysql-orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql-orig/sql/sql_yacc.yy 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.yy 2012-08-14 01:14:59.512196872 +0000
+@@ -1807,7 +1807,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1817,7 +1817,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -ur mysql-orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql-orig/sql/thr_malloc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/thr_malloc.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -132,7 +132,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -ur mysql-orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql-orig/sql/tztime.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/tztime.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -169,7 +169,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -398,7 +398,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1825,7 +1825,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -ur mysql-orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql-orig/sql/unireg.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/unireg.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -498,7 +498,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -718,7 +718,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -ur mysql-orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql-orig/sql-common/client.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/client.c 2012-08-14 01:14:59.512196872 +0000
+@@ -730,7 +730,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2113,7 +2113,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -ur mysql-orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql-orig/sql-common/my_time.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/my_time.c 2012-08-14 01:14:59.512196872 +0000
+@@ -251,7 +251,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -ur mysql-orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql-orig/storage/csv/ha_tina.cc 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/csv/ha_tina.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -1195,7 +1195,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1431,7 +1431,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -ur mysql-orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql-orig/storage/example/ha_example.h 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/example/ha_example.h 2012-08-14 01:14:59.512196872 +0000
+@@ -112,14 +112,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -130,7 +130,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -141,7 +141,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -ur mysql-orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql-orig/storage/federated/ha_federated.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/federated/ha_federated.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -ur mysql-orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql-orig/storage/heap/hp_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_create.c 2012-08-14 01:14:59.512196872 +0000
+@@ -230,7 +230,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -ur mysql-orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql-orig/storage/heap/hp_test2.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_test2.c 2012-08-14 01:14:59.512196872 +0000
+@@ -138,7 +138,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -219,7 +219,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -ur mysql-orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql-orig/storage/innobase/include/ut0byte.h 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/innobase/include/ut0byte.h 2012-08-14 01:14:59.522196790 +0000
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -ur mysql-orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql-orig/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:14:59.522196790 +0000
+@@ -4898,7 +4898,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4908,7 +4908,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -ur mysql-orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql-orig/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:14:59.552196542 +0000
+@@ -1115,7 +1115,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -ur mysql-orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql-orig/storage/myisam/ft_boolean_search.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/ft_boolean_search.c 2012-08-14 01:14:59.552196542 +0000
+@@ -48,9 +48,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -ur mysql-orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql-orig/storage/myisam/ha_myisam.cc 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2012-08-14 01:14:59.552196542 +0000
+@@ -1546,7 +1546,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -ur mysql-orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql-orig/storage/myisam/mi_cache.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_cache.c 2012-08-14 01:14:59.572196376 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -ur mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql-orig/storage/myisam/mi_check.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_check.c 2012-08-14 01:14:59.572196376 +0000
+@@ -2175,7 +2175,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2331,7 +2331,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2420,7 +2420,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2784,7 +2784,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3982,7 +3982,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+diff -ur mysql-orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql-orig/storage/myisam/mi_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_create.c 2012-08-14 01:14:59.572196376 +0000
+@@ -439,8 +439,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -529,7 +529,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -567,7 +567,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql-orig/storage/myisam/mi_dynrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2012-08-14 01:14:59.572196376 +0000
+@@ -882,7 +882,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -ur mysql-orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql-orig/storage/myisam/mi_extra.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_extra.c 2012-08-14 01:14:59.572196376 +0000
+@@ -101,7 +101,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -ur mysql-orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql-orig/storage/myisam/mi_open.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_open.c 2012-08-14 01:14:59.582196294 +0000
+@@ -330,7 +330,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -503,7 +503,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -716,10 +716,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -ur mysql-orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql-orig/storage/myisam/mi_packrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_packrec.c 2012-08-14 01:14:59.582196294 +0000
+@@ -686,7 +686,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1401,7 +1401,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -ur mysql-orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql-orig/storage/myisam/mi_test1.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test1.c 2012-08-14 01:14:59.582196294 +0000
+@@ -438,7 +438,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -ur mysql-orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql-orig/storage/myisam/mi_test2.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test2.c 2012-08-14 01:14:59.582196294 +0000
+@@ -603,7 +603,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -ur mysql-orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql-orig/storage/myisam/myisamlog.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/myisamlog.c 2012-08-14 01:14:59.582196294 +0000
+@@ -92,7 +92,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -ur mysql-orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql-orig/storage/myisam/myisampack.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/myisampack.c 2012-08-14 01:14:59.582196294 +0000
+@@ -1240,7 +1240,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3002,7 +3002,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql-orig/storage/myisam/rt_mbr.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/rt_mbr.c 2012-08-14 01:14:59.582196294 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -ur mysql-orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql-orig/storage/myisam/sort.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/sort.c 2012-08-14 01:14:59.582196294 +0000
+@@ -131,7 +131,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -348,7 +348,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -822,7 +822,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -843,7 +843,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -ur mysql-orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql-orig/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:14:59.582196294 +0000
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -ur mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:12:29.673435501 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -ur mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:12:29.683435419 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -ur mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -ur mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -ur mysql-orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql-orig/storage/ndb/test/src/getarg.c 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2012-08-14 01:14:59.582196294 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -ur mysql-orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql-orig/strings/ctype-big5.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-big5.c 2012-08-14 01:14:59.592196210 +0000
+@@ -254,7 +254,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -267,7 +267,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql-orig/strings/ctype-bin.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-bin.c 2012-08-14 01:14:59.592196210 +0000
+@@ -82,7 +82,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -133,7 +133,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -177,7 +177,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -406,7 +406,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -419,7 +419,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql-orig/strings/ctype-gbk.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-gbk.c 2012-08-14 01:14:59.592196210 +0000
+@@ -2617,7 +2617,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2628,7 +2628,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql-orig/strings/ctype-mb.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-mb.c 2012-08-14 01:14:59.592196210 +0000
+@@ -369,7 +369,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -413,7 +413,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -452,7 +452,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql-orig/strings/ctype-simple.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-simple.c 2012-08-14 01:14:59.592196210 +0000
+@@ -161,7 +161,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -875,7 +875,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -929,7 +929,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1160,7 +1160,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -ur mysql-orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql-orig/strings/ctype-tis620.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-tis620.c 2012-08-14 01:14:59.592196210 +0000
+@@ -583,7 +583,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -640,7 +640,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -ur mysql-orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql-orig/strings/ctype-uca.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-uca.c 2012-08-14 01:14:59.592196210 +0000
+@@ -7569,7 +7569,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -ur mysql-orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql-orig/strings/ctype-ucs2.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-ucs2.c 2012-08-14 01:14:59.602196128 +0000
+@@ -280,7 +280,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1332,7 +1332,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1426,7 +1426,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1473,7 +1473,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql-orig/strings/ctype-utf8.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-utf8.c 2012-08-14 01:14:59.602196128 +0000
+@@ -2114,7 +2114,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -ur mysql-orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql-orig/strings/decimal.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/decimal.c 2012-08-14 01:14:59.602196128 +0000
+@@ -405,7 +405,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -428,7 +428,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1531,8 +1531,8 @@
+
+ if (to != from)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg0+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg0+MYSQL_MAX(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
+@@ -1543,7 +1543,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1645,7 +1645,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1664,7 +1664,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1713,11 +1713,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1732,7 +1732,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1757,7 +1757,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1768,7 +1768,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1786,14 +1786,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1814,7 +1814,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1889,7 +1889,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1900,7 +1900,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1924,7 +1924,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2187,11 +2187,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2315,7 +2315,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2353,7 +2353,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -ur mysql-orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql-orig/strings/my_vsnprintf.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/my_vsnprintf.c 2012-08-14 01:14:59.602196128 +0000
+@@ -143,7 +143,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -ur mysql-orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql-orig/strings/str2int.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/str2int.c 2012-08-14 01:14:59.602196128 +0000
+@@ -84,7 +84,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -ur mysql-orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql-orig/vio/viosocket.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/vio/viosocket.c 2012-08-14 01:14:59.602196128 +0000
+@@ -79,7 +79,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-09-05 15:11 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2012-09-05 15:11 UTC (permalink / raw
To: gentoo-commits
commit: 27004b89ad9bd63c8d11e87a80c32c49278ced44
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 5 02:45:06 2012 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Wed Sep 5 02:45:06 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=27004b89
Add patches to fix sql issue.
---
00000_index.txt | 20 +
21000_sql-5.1.62.patch | 3199 ++++++++++++++++++++++++++++++++++++++++++++++
21000_sql-5.2.12.patch | 3234 ++++++++++++++++++++++++++++++++++++++++++++++
21000_sql-5.3.7.patch | 3258 ++++++++++++++++++++++++++++++++++++++++++++++
21000_sql-5.5.25.patch | 3338 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 13049 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 64daab2..073e8ed 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1431,3 +1431,23 @@
@ver 5.05.00.00 to 5.99.99.99
@pn mariadb
@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 21000_sql-5.1.62.patch
+@ver 5.01.62.00 to 5.01.64.99
+@pn mariadb
+@@ Fix sql
+
+@patch 21000_sql-5.2.12.patch
+@ver 5.02.12.00 to 5.02.12.99
+@pn mariadb
+@@ Fix sql
+
+@patch 21000_sql-5.3.7.patch
+@ver 5.03.07.00 to 5.03.07.99
+@pn mariadb
+@@ Fix sql
+
+@patch 21000_sql-5.5.25.patch
+@ver 5.05.25.00 to 5.05.26.99
+@pn mariadb
+@@ Fix sql
diff --git a/21000_sql-5.1.62.patch b/21000_sql-5.1.62.patch
new file mode 100644
index 0000000..a763955
--- /dev/null
+++ b/21000_sql-5.1.62.patch
@@ -0,0 +1,3199 @@
+=== modified file 'include/my_sys.h'
+--- include/my_sys.h 2011-11-21 17:13:14 +0000
++++ include/my_sys.h 2012-08-24 08:06:16 +0000
+@@ -806,6 +806,8 @@
+ extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+ extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
+ extern my_off_t my_b_filelength(IO_CACHE *info);
++extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
++ size_t len);
+ extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
+ extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
+ extern int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+
+=== modified file 'mysql-test/r/func_compress.result'
+--- mysql-test/r/func_compress.result 2009-06-19 09:29:21 +0000
++++ mysql-test/r/func_compress.result 2012-08-24 08:06:16 +0000
+@@ -11,7 +11,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select uncompress(compress((@test_compress_string))) AS `uncompress(compress(@test_compress_string))`
++Note 1003 select uncompress(compress((@`test_compress_string`))) AS `uncompress(compress(@test_compress_string))`
+ select uncompressed_length(compress(@test_compress_string))=length(@test_compress_string);
+ uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)
+ 1
+@@ -19,7 +19,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (uncompressed_length(compress((@test_compress_string))) = length((@test_compress_string))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
++Note 1003 select (uncompressed_length(compress((@`test_compress_string`))) = length((@`test_compress_string`))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
+ select uncompressed_length(compress(@test_compress_string));
+ uncompressed_length(compress(@test_compress_string))
+ 117
+
+=== modified file 'mysql-test/r/mysqlbinlog.result'
+--- mysql-test/r/mysqlbinlog.result 2011-03-25 14:16:13 +0000
++++ mysql-test/r/mysqlbinlog.result 2012-08-24 08:06:16 +0000
+@@ -18,7 +18,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -64,7 +64,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -97,7 +97,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -119,7 +119,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -165,7 +165,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -198,7 +198,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -220,7 +220,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844556/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+@@ -239,7 +239,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844556/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+@@ -299,7 +299,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -349,7 +349,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -484,7 +484,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1253783037/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -581,22 +581,22 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+ /*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t1 VALUES(40)
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ ROLLBACK TO mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("after rollback to")
+ /*!*/;
+@@ -624,7 +624,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog2.result'
+--- mysql-test/r/mysqlbinlog2.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/mysqlbinlog2.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -62,7 +62,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -101,7 +101,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -127,7 +127,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -162,7 +162,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -185,7 +185,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -215,7 +215,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -246,7 +246,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -281,7 +281,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -304,7 +304,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -335,7 +335,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -358,7 +358,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -377,7 +377,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -399,7 +399,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -445,7 +445,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -468,7 +468,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -490,7 +490,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -520,7 +520,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -563,7 +563,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -601,7 +601,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -627,7 +627,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -661,7 +661,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -684,7 +684,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -714,7 +714,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -744,7 +744,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -779,7 +779,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -802,7 +802,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -833,7 +833,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -855,7 +855,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -874,7 +874,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -896,7 +896,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -942,7 +942,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -965,7 +965,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -987,7 +987,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1017,7 +1017,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row.result'
+--- mysql-test/r/mysqlbinlog_row.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row.result 2012-08-24 08:06:16 +0000
+@@ -336,7 +336,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_innodb.result'
+--- mysql-test/r/mysqlbinlog_row_innodb.result 2010-03-22 12:10:18 +0000
++++ mysql-test/r/mysqlbinlog_row_innodb.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3876,7 +3876,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4243,7 +4243,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4804,7 +4804,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_myisam.result'
+--- mysql-test/r/mysqlbinlog_row_myisam.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row_myisam.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3898,7 +3898,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4271,7 +4271,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4842,7 +4842,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_trans.result'
+--- mysql-test/r/mysqlbinlog_row_trans.result 2009-08-27 09:32:27 +0000
++++ mysql-test/r/mysqlbinlog_row_trans.result 2012-08-24 08:06:16 +0000
+@@ -132,7 +132,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/user_var-binlog.result'
+--- mysql-test/r/user_var-binlog.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/user_var-binlog.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/variables.result'
+--- mysql-test/r/variables.result 2011-05-02 17:58:45 +0000
++++ mysql-test/r/variables.result 2012-08-24 08:06:16 +0000
+@@ -76,7 +76,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@t1) AS `@t1`,(@t2) AS `@t2`,(@t3) AS `@t3`
++Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@`t1`) AS `@t1`,(@`t2`) AS `@t2`,(@`t3`) AS `@t3`
+ select @t5;
+ @t5
+ 1.23456
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
+--- mysql-test/suite/binlog/r/binlog_base64_flag.result 2011-02-23 09:31:37 +0000
++++ mysql-test/suite/binlog/r/binlog_base64_flag.result 2012-08-24 08:06:16 +0000
+@@ -35,7 +35,7 @@
+ # at 4
+ <#>ROLLBACK/*!*/;
+ # at 102
+-<#>use test/*!*/;
++<#>use `test`/*!*/;
+ SET TIMESTAMP=1196959712/*!*/;
+ <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+ SET @@session.sql_mode=0/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result'
+--- mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2008-10-23 19:27:09 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2012-08-24 08:06:16 +0000
+@@ -13,7 +13,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result'
+--- mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2010-09-02 13:05:06 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2012-08-24 08:06:16 +0000
+@@ -631,7 +631,7 @@
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ /* the output must denote there is the query */;
+ drop trigger trg_del_t2;
+@@ -869,7 +869,7 @@
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ drop trigger trg_del_t2;
+ drop table t1,t2,t3,t4,t5;
+
+=== added file 'mysql-test/suite/rpl/r/rpl_mdev382.result'
+--- mysql-test/suite/rpl/r/rpl_mdev382.result 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/r/rpl_mdev382.result 2012-08-24 08:06:16 +0000
+@@ -0,0 +1,275 @@
++include/master-slave.inc
++[connection master]
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
++insert into t1 values (3);
++commit;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `test`; create table t1 (a int primary key) engine=innodb
++master-bin.000001 # Query # # use `test`; create table t2 (a int primary key) engine=myisam
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values (1)
++master-bin.000001 # Query # # SAVEPOINT "a`; create database couldbebadthingshere; savepoint `dummy"
++master-bin.000001 # Query # # use `test`; insert into t1 values (2)
++master-bin.000001 # Query # # use `test`; insert into t2 values (1)
++master-bin.000001 # Query # # ROLLBACK TO `a``; create database couldbebadthingshere; savepoint ``dummy`
++master-bin.000001 # Query # # use `test`; insert into t1 values (3)
++master-bin.000001 # Xid # # COMMIT /* XID */
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values(10)
++master-bin.000001 # Query # # SAVEPOINT "a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(11)
++master-bin.000001 # Query # # SAVEPOINT "a""a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(12)
++master-bin.000001 # Query # # SAVEPOINT b
++master-bin.000001 # Query # # use `test`; insert into t1 values(13)
++master-bin.000001 # Query # # SAVEPOINT "b""b"
++master-bin.000001 # Query # # use `test`; insert into t1 values(14)
++master-bin.000001 # Query # # SAVEPOINT `c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(15)
++master-bin.000001 # Query # # SAVEPOINT `c``c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(16)
++master-bin.000001 # Query # # SAVEPOINT d
++master-bin.000001 # Query # # use `test`; insert into t1 values(17)
++master-bin.000001 # Query # # SAVEPOINT `d``d`
++master-bin.000001 # Query # # use `test`; insert into t1 values(18)
++master-bin.000001 # Xid # # COMMIT /* XID */
++*** Test correct USE statement in SHOW BINLOG EVENTS ***
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (2)
++set sql_mode = '';
++set sql_quote_show_create = 0;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++DROP TABLE t1;
++use test;
++***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++use `db1``; SELECT 'oops!'`;
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++truncate `t``1`;
++use test;
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `db1``; SELECT 'oops!'`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!') ;file_id=#
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; truncate `t``1`
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!') ;file_id=#
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++truncate `t``1`
++/*!*/;
++use `test`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++drop table t1,t2;
++*** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE t1
++FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE `t1` FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=concat((@`b`),'| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|',(@`b`)) ;file_id=#
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++DROP TABLE t1;
++*** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++@`a``1`:=a1 @`a``2`:=a2 @`a``3`:=a3 @`a``4`:=a4 @`b```:=b @```c`:=c @```d```:=d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++master-bin.000001 # User var # # @`a``1`=-9223372036854775808
++master-bin.000001 # User var # # @`a``2`=42
++master-bin.000001 # User var # # @`a``3`=9223372036854775807
++master-bin.000001 # User var # # @`a``4`=-1
++master-bin.000001 # User var # # @`b```=-1.2345601234568e+125
++master-bin.000001 # User var # # @```c`=-1234501234567890123456789012345678901234567890123456789.0123456789
++master-bin.000001 # User var # # @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++/*!*/;
++SET @`a``1`:=-9223372036854775808/*!*/;
++SET @`a``2`:=42/*!*/;
++SET @`a``3`:=9223372036854775807/*!*/;
++SET @`a``4`:=-1/*!*/;
++SET @`b```:=-1.2345601234568e+125/*!*/;
++SET @```c`:=-1234501234567890123456789012345678901234567890123456789.0123456789/*!*/;
++SET @```d```:=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE `latin1_swedish_ci`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++a1 a2 a3 a4 b c d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++-9223372036854775807 4200 9223372036854775806 0 -6.17280061728394e+124 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++DROP TABLE t1;
++*** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++include/stop_slave.inc
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++a`
++1
++2
++5
++set timestamp=1000000000;
++# The table should be empty on the master.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++# The DELETE statement should be correctly quoted
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # use `test`; DELETE FROM `db1``; SELECT 'oops!'`.`t``1`
++include/start_slave.inc
++# The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++include/rpl_end.inc
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
+--- mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2012-08-24 08:06:16 +0000
+@@ -153,7 +153,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -175,7 +175,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -284,7 +284,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -316,7 +316,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
+--- mysql-test/suite/rpl/r/rpl_sp.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_sp.result 2012-08-24 08:06:16 +0000
+@@ -627,7 +627,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest1
+ /*!*/;
+-use mysqltest1/*!*/;
++use `mysqltest1`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t1 (a varchar(100))
+ /*!*/;
+@@ -840,7 +840,7 @@
+ SET TIMESTAMP=t/*!*/;
+ drop user "zedjzlcsjhd"@127.0.0.1
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ drop function if exists f1
+ /*!*/;
+@@ -925,7 +925,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest2
+ /*!*/;
+-use mysqltest2/*!*/;
++use `mysqltest2`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t ( t integer )
+ /*!*/;
+@@ -943,7 +943,7 @@
+ return 0;
+ end
+ /*!*/;
+-use mysqltest/*!*/;
++use `mysqltest`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ SELECT `mysqltest2`.`f1`()
+ /*!*/;
+@@ -953,14 +953,14 @@
+ SET TIMESTAMP=t/*!*/;
+ drop database mysqltest2
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltestbug36570_p1`()
+ begin
+ select 1;
+ end
+ /*!*/;
+-use mysql/*!*/;
++use `mysql`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.` mysqltestbug36570_p2`( a int)
+ `label`:
+
+=== added file 'mysql-test/suite/rpl/t/rpl_mdev382.test'
+--- mysql-test/suite/rpl/t/rpl_mdev382.test 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/t/rpl_mdev382.test 2012-08-24 08:06:16 +0000
+@@ -0,0 +1,249 @@
++--source include/have_innodb.inc
++--source include/not_windows.inc
++--source include/have_binlog_format_statement.inc
++--source include/master-slave.inc
++
++# MDEV-382: multiple SQL injections in replication code.
++
++# Test previous SQL injection attack against binlog for SAVEPOINT statement.
++# The test would cause syntax error on slave due to improper quoting of
++# the savepoint name.
++connection master;
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (3);
++commit;
++
++--source include/show_binlog_events.inc
++
++# This failed due to syntax error in query when the bug was not fixed.
++sync_slave_with_master;
++connection slave;
++
++# Test some more combinations of ANSI_QUOTES and sql_quote_show_create
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++
++--source include/show_binlog_events.inc
++
++--echo *** Test correct USE statement in SHOW BINLOG EVENTS ***
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++--source include/show_binlog_events.inc
++set sql_mode = '';
++set sql_quote_show_create = 0;
++--source include/show_binlog_events.inc
++set sql_quote_show_create = 1;
++--source include/show_binlog_events.inc
++DROP TABLE t1;
++
++use test;
++
++--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++
++--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt
++--write_file $load_file
++'fo\\o','bar'
++EOF
++--exec chmod go+r "$load_file"
++
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++ `c``3` VARCHAR(7));
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++
++SELECT * FROM `t``1`;
++# Also test when code prefixes table name with database.
++truncate `t``1`;
++use test;
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++let $MYSQLD_DATADIR= `select @@datadir`;
++--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '<name>' INTO/
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++connection master;
++
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++--remove_file $load_file
++
++connection master;
++drop table t1,t2;
++
++
++--echo *** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++--let $load_file= $MYSQLTEST_VARDIR/tmp/file.txt
++--write_file $load_file
++1,X
++2,A
++EOF
++--exec chmod go+r "$load_file"
++
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++# The bug was that the SET expression was truncated to 256 bytes, so test with
++# an expression longer than that.
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$load_file' INTO TABLE t1
++ FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++
++SELECT * FROM t1 ORDER BY a;
++--source include/show_binlog_events.inc
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM t1 ORDER BY a;
++
++connection master;
++--remove_file $load_file
++DROP TABLE t1;
++
++
++--echo *** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++
++connection master;
++DROP TABLE t1;
++
++
++--echo *** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++
++# Let's keep the slave stopped during master restart, to avoid any potential
++# races between slave reconnect and master restart.
++connection slave;
++--source include/stop_slave.inc
++
++connection master;
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++
++# Restart the master mysqld.
++# This will cause an implicit truncation of the memory-based table, which will
++# cause logging of an explicit DELETE FROM to binlog.
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++wait-rpl_mdev382.test
++EOF
++
++--shutdown_server 30
++
++--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++restart-rpl_mdev382.test
++EOF
++
++connection default;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++# rpl_end.inc needs to use the connection server_1
++connection server_1;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++connection master;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++set timestamp=1000000000;
++
++--echo # The table should be empty on the master.
++let $binlog_file= master-bin.000002;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++--echo # The DELETE statement should be correctly quoted
++--source include/show_binlog_events.inc
++
++connection slave;
++--source include/start_slave.inc
++
++connection master;
++sync_slave_with_master;
++connection slave;
++--echo # The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++connection master;
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++sync_slave_with_master;
++
++
++connection master;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++
++
++--source include/rpl_end.inc
+
+=== modified file 'mysys/mf_iocache2.c'
+--- mysys/mf_iocache2.c 2011-11-21 17:13:14 +0000
++++ mysys/mf_iocache2.c 2012-08-24 08:06:16 +0000
+@@ -284,6 +284,40 @@
+ }
+
+
++size_t
++my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
++{
++ const uchar *start;
++ const uchar *p= (const uchar *)str;
++ const uchar *end= p + len;
++ size_t count;
++ size_t total= 0;
++
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ for (;;)
++ {
++ start= p;
++ while (p < end && *p != '`')
++ ++p;
++ count= p - start;
++ if (count && my_b_write(info, start, count))
++ return (size_t)-1;
++ total+= count;
++ if (p >= end)
++ break;
++ if (my_b_write(info, (uchar *)"``", 2))
++ return (size_t)-1;
++ total+= 2;
++ ++p;
++ }
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ return total;
++}
++
+ /*
+ Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
+ Used for logging in MySQL
+@@ -308,6 +342,7 @@
+ uint minimum_width_sign;
+ uint precision; /* as yet unimplemented for anything but %b */
+ my_bool is_zero_padded;
++ my_bool backtick_quoting;
+
+ /*
+ Store the location of the beginning of a format directive, for the
+@@ -342,6 +377,7 @@
+ fmt++;
+
+ is_zero_padded= FALSE;
++ backtick_quoting= FALSE;
+ minimum_width_sign= 1;
+ minimum_width= 0;
+ precision= 0;
+@@ -354,6 +390,8 @@
+ minimum_width_sign= -1; fmt++; goto process_flags;
+ case '0':
+ is_zero_padded= TRUE; fmt++; goto process_flags;
++ case '`':
++ backtick_quoting= TRUE; fmt++; goto process_flags;
+ case '#':
+ /** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
+ case ' ':
+@@ -397,9 +435,19 @@
+ reg2 char *par = va_arg(args, char *);
+ size_t length2 = strlen(par);
+ /* TODO: implement precision */
+- out_length+= length2;
+- if (my_b_write(info, (uchar*) par, length2))
+- goto err;
++ if (backtick_quoting)
++ {
++ size_t total= my_b_write_backtick_quote(info, (uchar *) par, length2);
++ if (total == (size_t)-1)
++ goto err;
++ out_length+= total;
++ }
++ else
++ {
++ out_length+= length2;
++ if (my_b_write(info, (uchar*) par, length2))
++ goto err;
++ }
+ }
+ else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
+ {
+
+=== modified file 'sql/ha_ndbcluster_binlog.cc'
+--- sql/ha_ndbcluster_binlog.cc 2011-11-21 17:13:14 +0000
++++ sql/ha_ndbcluster_binlog.cc 2012-08-24 08:06:16 +0000
+@@ -1268,7 +1268,9 @@
+ DBUG_RETURN(0);
+ }
+
+- char tmp_buf2[FN_REFLEN];
++ char tmp_buf2_mem[FN_REFLEN];
++ String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info);
++ tmp_buf2.length(0);
+ const char *type_str;
+ switch (type)
+ {
+@@ -1277,17 +1279,24 @@
+ if (thd->lex->sql_command == SQLCOM_DROP_DB)
+ DBUG_RETURN(0);
+ /* redo the drop table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "drop table `",
+- table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("drop table "));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "drop table";
+ break;
+ case SOT_RENAME_TABLE:
+ /* redo the rename table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "rename table `",
+- db, ".", table_name, "` to `",
+- new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("rename table "));
++ append_identifier(thd, &tmp_buf2, db, strlen(db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ tmp_buf2.append(STRING_WITH_LEN(" to "));
++ append_identifier(thd, &tmp_buf2, new_db, strlen(new_db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "rename table";
+ break;
+ case SOT_CREATE_TABLE:
+
+=== modified file 'sql/item.cc'
+--- sql/item.cc 2012-05-17 10:12:33 +0000
++++ sql/item.cc 2012-08-24 08:06:16 +0000
+@@ -749,15 +749,31 @@
+ if (!my_charset_same(cs, system_charset_info))
+ {
+ size_t res_length;
+- name= sql_strmake_with_convert(str, name_length= length, cs,
++ name= sql_strmake_with_convert(str, length, cs,
+ MAX_ALIAS_NAME, system_charset_info,
+ &res_length);
++ name_length= res_length;
+ }
+ else
+ name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
+ }
+
+
++void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
++{
++ if (!my_charset_same(cs, system_charset_info))
++ {
++ size_t res_length;
++ name= sql_strmake_with_convert(str, length, cs,
++ UINT_MAX, system_charset_info,
++ &res_length);
++ name_length= res_length;
++ }
++ else
++ name= sql_strmake(str, (name_length= length));
++}
++
++
+ /**
+ @details
+ This function is called when:
+
+=== modified file 'sql/item.h'
+--- sql/item.h 2012-05-17 10:12:33 +0000
++++ sql/item.h 2012-08-24 08:06:16 +0000
+@@ -554,6 +554,7 @@
+ #endif
+ } /*lint -e1509 */
+ void set_name(const char *str, uint length, CHARSET_INFO *cs);
++ void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs);
+ void rename(char *new_name);
+ void init_make_field(Send_field *tmp_field,enum enum_field_types type);
+ virtual void cleanup();
+
+=== modified file 'sql/item_func.cc'
+--- sql/item_func.cc 2011-11-21 17:13:14 +0000
++++ sql/item_func.cc 2012-08-24 08:06:16 +0000
+@@ -4743,7 +4743,7 @@
+ void Item_func_get_user_var::print(String *str, enum_query_type query_type)
+ {
+ str->append(STRING_WITH_LEN("(@"));
+- str->append(name.str,name.length);
++ append_identifier(current_thd, str, name.str, name.length);
+ str->append(')');
+ }
+
+@@ -4841,10 +4841,10 @@
+ }
+
+
+-void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
++void Item_user_var_as_out_param::print_for_load(THD *thd, String *str)
+ {
+ str->append('@');
+- str->append(name.str,name.length);
++ append_identifier(thd, str, name.str, name.length);
+ }
+
+
+
+=== modified file 'sql/item_func.h'
+--- sql/item_func.h 2011-11-21 17:13:14 +0000
++++ sql/item_func.h 2012-08-24 08:06:16 +0000
+@@ -1503,7 +1503,7 @@
+ my_decimal *val_decimal(my_decimal *decimal_buffer);
+ /* fix_fields() binds variable name with its entry structure */
+ bool fix_fields(THD *thd, Item **ref);
+- virtual void print(String *str, enum_query_type query_type);
++ void print_for_load(THD *thd, String *str);
+ void set_null_value(CHARSET_INFO* cs);
+ void set_value(const char *str, uint length, CHARSET_INFO* cs);
+ };
+
+=== modified file 'sql/log.cc'
+--- sql/log.cc 2012-05-17 10:12:33 +0000
++++ sql/log.cc 2012-08-24 08:06:16 +0000
+@@ -38,6 +38,7 @@
+ #endif
+
+ #include <mysql/plugin.h>
++#include "sql_show.h"
+
+ /* max size of the log message */
+ #define MAX_LOG_BUFFER_SIZE 1024
+@@ -1726,9 +1727,8 @@
+
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+@@ -1750,9 +1750,8 @@
+ {
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.c_ptr_safe(), log_query.length(),
+
+=== modified file 'sql/log_event.cc'
+--- sql/log_event.cc 2012-05-17 10:12:33 +0000
++++ sql/log_event.cc 2012-08-24 08:06:16 +0000
+@@ -34,6 +34,7 @@
+ #include "rpl_utility.h"
+ #include "rpl_record.h"
+ #include <my_dir.h>
++#include "sql_show.h"
+
+ #endif /* MYSQL_CLIENT */
+
+@@ -413,29 +414,28 @@
+ pretty_print_str()
+ */
+
+-static char *pretty_print_str(char *packet, const char *str, int len)
++static void
++pretty_print_str(String *packet, const char *str, int len)
+ {
+ const char *end= str + len;
+- char *pos= packet;
+- *pos++= '\'';
++ packet->append(STRING_WITH_LEN("'"));
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+- case '\n': *pos++= '\\'; *pos++= 'n'; break;
+- case '\r': *pos++= '\\'; *pos++= 'r'; break;
+- case '\\': *pos++= '\\'; *pos++= '\\'; break;
+- case '\b': *pos++= '\\'; *pos++= 'b'; break;
+- case '\t': *pos++= '\\'; *pos++= 't'; break;
+- case '\'': *pos++= '\\'; *pos++= '\''; break;
+- case 0 : *pos++= '\\'; *pos++= '0'; break;
++ case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
++ case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
++ case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
++ case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
++ case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
++ case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
++ case 0 : packet->append(STRING_WITH_LEN("\\0")); break;
+ default:
+- *pos++= c;
++ packet->append(&c, 1);
+ break;
+ }
+ }
+- *pos++= '\'';
+- return pos;
++ packet->append(STRING_WITH_LEN("'"));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -861,7 +861,7 @@
+ Log_event::pack_info()
+ */
+
+-void Log_event::pack_info(Protocol *protocol)
++void Log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ protocol->store("", &my_charset_bin);
+ }
+@@ -870,7 +870,8 @@
+ /**
+ Only called by SHOW BINLOG EVENTS
+ */
+-int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
++int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos)
+ {
+ const char *p= strrchr(log_name, FN_LIBCHAR);
+ const char *event_type;
+@@ -884,7 +885,7 @@
+ protocol->store(event_type, strlen(event_type), &my_charset_bin);
+ protocol->store((uint32) server_id);
+ protocol->store((ulonglong) log_pos);
+- pack_info(protocol);
++ pack_info(thd, protocol);
+ return protocol->write();
+ }
+ #endif /* HAVE_REPLICATION */
+@@ -2139,27 +2140,22 @@
+ show the catalog ??
+ */
+
+-void Query_log_event::pack_info(Protocol *protocol)
++void Query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ // TODO: show the catalog ??
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len);
+ if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
+ && db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf.append(STRING_WITH_LEN("use "));
++ append_identifier(thd, &buf, db, db_len);
++ buf.append("; ");
+ }
+ if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ buf.append(query, q_len);
++ protocol->store(&buf);
+ }
+ #endif
+
+@@ -2924,11 +2920,17 @@
+ }
+ else if (db)
+ {
++ /* Room for expand ` to `` + initial/final ` + \0 */
++ char buf[FN_REFLEN*2+3];
++
+ different_db= memcmp(print_event_info->db, db, db_len + 1);
+ if (different_db)
+ memcpy(print_event_info->db, db, db_len + 1);
+ if (db[0] && different_db)
+- my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
++ {
++ my_snprintf(buf, sizeof(buf), "%`s", db);
++ my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
++ }
+ }
+
+ end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
+@@ -3545,7 +3547,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Start_log_event_v3::pack_info(Protocol *protocol)
++void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
+ pos= strmov(buf, "Server ver: ");
+@@ -4194,131 +4196,115 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-uint Load_log_event::get_query_buffer_length()
+-{
+- return
+- 5 + db_len + 3 + // "use DB; "
+- 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+- 11 + // "CONCURRENT "
+- 7 + // LOCAL
+- 9 + // " REPLACE or IGNORE "
+- 13 + table_name_len*2 + // "INTO TABLE `table`"
+- 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
+- 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
+- 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
+- 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
+- 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
+- 15 + 22 + // " IGNORE xxx LINES"
+- 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
+-}
+-
+-
+-void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
+- char **end, char **fn_start, char **fn_end)
+-{
+- char *pos= buf;
+-
++void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
++ String *buf, my_off_t *fn_start,
++ my_off_t *fn_end, const char *qualify_db)
++{
+ if (need_db && db && db_len)
+ {
+- pos= strmov(pos, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf->append(STRING_WITH_LEN("use "));
++ append_identifier(thd, buf, db, db_len);
++ buf->append(STRING_WITH_LEN("; "));
+ }
+
+- pos= strmov(pos, "LOAD DATA ");
++ buf->append(STRING_WITH_LEN("LOAD DATA "));
+
+ if (thd->lex->lock_option == TL_WRITE_CONCURRENT_INSERT)
+- pos= strmov(pos, "CONCURRENT ");
++ buf->append(STRING_WITH_LEN("CONCURRENT "));
+
+ if (fn_start)
+- *fn_start= pos;
++ *fn_start= buf->length();
+
+ if (check_fname_outside_temp_buf())
+- pos= strmov(pos, "LOCAL ");
+- pos= strmov(pos, "INFILE '");
+- memcpy(pos, fname, fname_len);
+- pos= strmov(pos+fname_len, "' ");
++ buf->append(STRING_WITH_LEN("LOCAL "));
++ buf->append(STRING_WITH_LEN("INFILE '"));
++ buf->append_for_single_quote(fname, fname_len);
++ buf->append(STRING_WITH_LEN("' "));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+- pos= strmov(pos, "REPLACE ");
++ buf->append(STRING_WITH_LEN("REPLACE "));
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+- pos= strmov(pos, "IGNORE ");
++ buf->append(STRING_WITH_LEN("IGNORE "));
+
+- pos= strmov(pos ,"INTO");
++ buf->append(STRING_WITH_LEN("INTO"));
+
+ if (fn_end)
+- *fn_end= pos;
++ *fn_end= buf->length();
+
+- pos= strmov(pos ," TABLE `");
+- memcpy(pos, table_name, table_name_len);
+- pos+= table_name_len;
++ buf->append(STRING_WITH_LEN(" TABLE "));
++ if (qualify_db)
++ {
++ append_identifier(thd, buf, qualify_db, strlen(qualify_db));
++ buf->append(STRING_WITH_LEN("."));
++ }
++ append_identifier(thd, buf, table_name, table_name_len);
+
+ if (cs != NULL)
+ {
+- pos= strmov(pos ,"` CHARACTER SET ");
+- pos= strmov(pos , cs);
++ buf->append(STRING_WITH_LEN(" CHARACTER SET "));
++ buf->append(cs, strlen(cs));
+ }
+- else
+- pos= strmov(pos, "`");
+
+ /* We have to create all optional fields as the default is not empty */
+- pos= strmov(pos, " FIELDS TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
++ buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+- pos= strmov(pos, " OPTIONALLY ");
+- pos= strmov(pos, " ENCLOSED BY ");
+- pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
+-
+- pos= strmov(pos, " ESCAPED BY ");
+- pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+-
+- pos= strmov(pos, " LINES TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
++ buf->append(STRING_WITH_LEN(" OPTIONALLY "));
++ buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
++ pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
++
++ buf->append(STRING_WITH_LEN(" ESCAPED BY "));
++ pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
++
++ buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
+ if (sql_ex.line_start_len)
+ {
+- pos= strmov(pos, " STARTING BY ");
+- pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
++ buf->append(STRING_WITH_LEN(" STARTING BY "));
++ pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((long) skip_lines > 0)
+ {
+- pos= strmov(pos, " IGNORE ");
+- pos= longlong10_to_str((longlong) skip_lines, pos, 10);
+- pos= strmov(pos," LINES ");
++ char skipbuf[22];
++ buf->append(STRING_WITH_LEN(" IGNORE "));
++ longlong10_to_str((longlong) skip_lines, skipbuf, 10);
++ buf->append(skipbuf);
++ buf->append(STRING_WITH_LEN(" LINES "));
+ }
+
+ if (num_fields)
+ {
+ uint i;
+ const char *field= fields;
+- pos= strmov(pos, " (");
++ buf->append(STRING_WITH_LEN(" ("));
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ {
+- *pos++= ' ';
+- *pos++= ',';
++ /*
++ Yes, the space and comma is reversed here. But this is mostly dead
++ code, at most used when reading really old binlogs from old servers,
++ so better just leave it as is...
++ */
++ buf->append(STRING_WITH_LEN(" ,"));
+ }
+- memcpy(pos, field, field_lens[i]);
+- pos+= field_lens[i];
++ append_identifier(thd, buf, field, field_lens[i]);
+ field+= field_lens[i] + 1;
+ }
+- *pos++= ')';
++ buf->append(STRING_WITH_LEN(")"));
+ }
+-
+- *end= pos;
+ }
+
+
+-void Load_log_event::pack_info(Protocol *protocol)
++void Load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *end;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+
+- if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
+- return;
+- print_query(TRUE, NULL, buf, &end, 0, 0);
+- protocol->store(buf, end-buf, &my_charset_bin);
+- my_free(buf, MYF(0));
++ query_str.length(0);
++ print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL);
++ protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
+ }
+ #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+
+@@ -4585,7 +4571,7 @@
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ my_b_printf(&cache,"IGNORE ");
+
+- my_b_printf(&cache, "INTO TABLE `%s`", table_name);
++ my_b_printf(&cache, "INTO TABLE %`s", table_name);
+ my_b_printf(&cache, " FIELDS TERMINATED BY ");
+ pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
+
+@@ -4774,16 +4760,20 @@
+ else
+ {
+ char llbuff[22];
+- char *end;
+ enum enum_duplicates handle_dup;
+ bool ignore= 0;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+ char *load_data_query;
+
++ query_str.length(0);
+ /*
+ Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
+ and written to slave's binlog if binlogging is on.
+ */
+- if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
++ print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
++ query_str.length())))
+ {
+ /*
+ This will set thd->fatal_error in case of OOM. So we surely will notice
+@@ -4792,9 +4782,7 @@
+ goto error;
+ }
+
+- print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
+- *end= 0;
+- thd->set_query(load_data_query, (uint) (end - load_data_query));
++ thd->set_query(load_data_query, (uint) (query_str.length()));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ {
+@@ -4959,7 +4947,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rotate_log_event::pack_info(Protocol *protocol)
++void Rotate_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1), log_cs);
+@@ -5174,7 +5162,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Intvar_log_event::pack_info(Protocol *protocol)
++void Intvar_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256], *pos;
+ pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
+@@ -5323,7 +5311,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rand_log_event::pack_info(Protocol *protocol)
++void Rand_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], *pos;
+ pos= strmov(buf1,"rand_seed1=");
+@@ -5421,7 +5409,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Xid_log_event::pack_info(Protocol *protocol)
++void Xid_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[128], *pos;
+ pos= strmov(buf, "COMMIT /* xid=");
+@@ -5508,69 +5496,109 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void User_var_log_event::pack_info(Protocol* protocol)
++static bool
++user_var_append_name_part(THD *thd, String *buf,
++ const char *name, size_t name_len)
+ {
+- char *buf= 0;
+- uint val_offset= 4 + name_len;
+- uint event_len= val_offset;
++ return buf->append("@") ||
++ append_identifier(thd, buf, name, name_len) ||
++ buf->append("=");
++}
+
++void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
++{
+ if (is_null)
+ {
+- if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
++ char buf_mem[FN_REFLEN+7];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("NULL"))
+ return;
+- strmov(buf + val_offset, "NULL");
+- event_len= val_offset + 4;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+ else
+ {
+ switch (type) {
+ case REAL_RESULT:
++ {
+ double real_val;
++ char buf2[FLOATING_POINT_BUFFER];
++ char buf_mem[FN_REFLEN + FLOATING_POINT_BUFFER];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ float8get(real_val, val);
+- if (!(buf= (char*) my_malloc(val_offset + FLOATING_POINT_BUFFER,
+- MYF(MY_WME))))
+- return;
+- event_len+= my_sprintf(buf + val_offset,
+- (buf + val_offset, "%.14g", real_val));
++ buf.length(0);
++ my_sprintf(buf2, (buf2, "%.14g", real_val));
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case INT_RESULT:
+- if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
++ {
++ char buf2[22];
++ char buf_mem[FN_REFLEN + 22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2, longlong10_to_str(uint8korr(val), buf2, -10)-buf2))
+ return;
+- event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case DECIMAL_RESULT:
+ {
+- if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
+- MYF(MY_WME))))
+- return;
+- String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
++ char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ char buf2[DECIMAL_MAX_STR_LENGTH+1];
++ String str(buf2, sizeof(buf2), &my_charset_bin);
+ my_decimal dec;
++ buf.length(0);
+ binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
+ val[1]);
+ my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
+- event_len= str.length() + val_offset;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
+ }
+ case STRING_RESULT:
++ {
+ /* 15 is for 'COLLATE' and other chars */
+- buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
+- MYF(MY_WME));
++ char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ CHARSET_INFO *cs;
+- if (!buf)
+- return;
++ buf.length(0);
+ if (!(cs= get_charset(charset_number, MYF(0))))
+ {
+- strmov(buf+val_offset, "???");
+- event_len+= 3;
++ if (buf.append("???"))
++ return;
+ }
+ else
+ {
+- char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
+- p= str_to_hex(p, val, val_len);
+- p= strxmov(p, " COLLATE ", cs->name, NullS);
+- event_len= p-buf;
++ size_t old_len;
++ char *beg, *end;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("_") ||
++ buf.append(cs->csname) ||
++ buf.append(" "))
++ return;
++ old_len= buf.length();
++ if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") +
++ MY_CS_NAME_SIZE))
++ return;
++ beg= const_cast<char *>(buf.ptr()) + old_len;
++ end= str_to_hex(beg, val, val_len);
++ buf.length(old_len + (end - beg));
++ if (buf.append(" COLLATE ") ||
++ buf.append(cs->name))
++ return;
+ }
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
+ default:
+@@ -5578,13 +5606,6 @@
+ return;
+ }
+ }
+- buf[0]= '@';
+- buf[1]= '`';
+- memcpy(buf+2, name, name_len);
+- buf[2+name_len]= '`';
+- buf[3+name_len]= '=';
+- protocol->store(buf, event_len, &my_charset_bin);
+- my_free(buf, MYF(0));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -5700,9 +5721,8 @@
+ my_b_printf(&cache, "\tUser_var\n");
+ }
+
+- my_b_printf(&cache, "SET @`");
+- my_b_write(&cache, (uchar*) name, (uint) (name_len));
+- my_b_printf(&cache, "`");
++ my_b_printf(&cache, "SET @");
++ my_b_write_backtick_quote(&cache, name, name_len);
+
+ if (is_null)
+ {
+@@ -5775,7 +5795,7 @@
+ */
+ my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
+ else
+- my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
++ my_b_printf(&cache, ":=_%s %s COLLATE %`s%s\n",
+ cs->csname, hex_str, cs->name,
+ print_event_info->delimiter);
+ my_afree(hex_str);
+@@ -5914,7 +5934,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+-void Slave_log_event::pack_info(Protocol *protocol)
++void Slave_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256+HOSTNAME_LENGTH], *pos;
+ pos= strmov(buf, "host=");
+@@ -6286,7 +6306,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Create_file_log_event::pack_info(Protocol *protocol)
++void Create_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
+ pos= strmov(buf, "db=");
+@@ -6467,7 +6487,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Append_block_log_event::pack_info(Protocol *protocol)
++void Append_block_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ uint length;
+@@ -6619,7 +6639,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Delete_file_log_event::pack_info(Protocol *protocol)
++void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -6717,7 +6737,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_log_event::pack_info(Protocol *protocol)
++void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -6970,27 +6990,26 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_query_log_event::pack_info(Protocol *protocol)
++void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ char file_id_buf[22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len + 10 + 21);
+ if (db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
+- }
+- if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- pos= strmov(pos, " ;file_id=");
+- pos= int10_to_str((long) file_id, pos, 10);
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ if (buf.append("use ") ||
++ append_identifier(thd, &buf, db, db_len) ||
++ buf.append("; "))
++ return;
++ }
++ if (query && q_len && buf.append(query, q_len))
++ return;
++ int10_to_str((long) file_id, file_id_buf, 10);
++ if (buf.append(" ;file_id=") ||
++ buf.append(file_id_buf))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+
+
+@@ -7932,7 +7951,7 @@
+ #endif
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rows_log_event::pack_info(Protocol *protocol)
++void Rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+@@ -8533,7 +8552,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Table_map_log_event::pack_info(Protocol *protocol)
++void Table_map_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes= my_snprintf(buf, sizeof(buf),
+@@ -8554,7 +8573,7 @@
+ {
+ print_header(&print_event_info->head_cache, print_event_info, TRUE);
+ my_b_printf(&print_event_info->head_cache,
+- "\tTable_map: `%s`.`%s` mapped to number %lu\n",
++ "\tTable_map: %`s.%`s mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(&print_event_info->body_cache, print_event_info, TRUE);
+ }
+@@ -9747,7 +9766,7 @@
+
+
+ #ifndef MYSQL_CLIENT
+-void Incident_log_event::pack_info(Protocol *protocol)
++void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes;
+
+=== modified file 'sql/log_event.h'
+--- sql/log_event.h 2011-11-21 17:13:14 +0000
++++ sql/log_event.h 2012-08-24 08:06:16 +0000
+@@ -947,14 +947,15 @@
+ */
+ static void init_show_field_list(List<Item>* field_list);
+ #ifdef HAVE_REPLICATION
+- int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
++ int net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos);
+
+ /*
+ pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
+ a string to display to the user, so it resembles print().
+ */
+
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+
+ #endif /* HAVE_REPLICATION */
+ virtual const char* get_db()
+@@ -1649,7 +1650,7 @@
+ bool using_trans, bool suppress_use, int error);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -1779,7 +1780,7 @@
+
+ #ifndef MYSQL_CLIENT
+ Slave_log_event(THD* thd_arg, Relay_log_info* rli);
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2012,9 +2013,11 @@
+ const Format_description_log_event* description_event);
+
+ public:
+- uint get_query_buffer_length();
+- void print_query(bool need_db, const char *cs, char *buf, char **end,
+- char **fn_start, char **fn_end);
++#ifndef MYSQL_CLIENT
++ void print_query(THD *thd, bool need_db, const char *cs, String *buf,
++ my_off_t *fn_start, my_off_t *fn_end,
++ const char *qualify_db);
++#endif
+ ulong thread_id;
+ ulong slave_proxy_id;
+ uint32 table_name_len;
+@@ -2062,7 +2065,7 @@
+ Name_resolution_context *context);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2161,7 +2164,7 @@
+ #ifndef MYSQL_CLIENT
+ Start_log_event_v3();
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ Start_log_event_v3() {}
+@@ -2313,7 +2316,7 @@
+ :Log_event(thd_arg,0,0),val(val_arg),type(type_arg)
+ {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2389,7 +2392,7 @@
+ :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg)
+ {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2433,7 +2436,7 @@
+ #ifndef MYSQL_CLIENT
+ Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2482,7 +2485,7 @@
+ :Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
+ val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
+ { is_null= !val; }
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2613,7 +2616,7 @@
+ uint ident_len_arg,
+ ulonglong pos_arg, uint flags);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2673,7 +2676,7 @@
+ uchar* block_arg, uint block_len_arg,
+ bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2745,7 +2748,7 @@
+ Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
+ uint block_len_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ virtual int get_create_or_append() const;
+ #endif /* HAVE_REPLICATION */
+ #else
+@@ -2786,7 +2789,7 @@
+ #ifndef MYSQL_CLIENT
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2827,7 +2830,7 @@
+ #ifndef MYSQL_CLIENT
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2923,7 +2926,7 @@
+ bool using_trans, bool suppress_use,
+ int errcode);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3368,7 +3371,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3480,7 +3483,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3917,7 +3920,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+- void pack_info(Protocol*);
++ void pack_info(THD *thd, Protocol*);
+ #endif
+
+ Incident_log_event(const char *buf, uint event_len,
+
+=== modified file 'sql/log_event_old.cc'
+--- sql/log_event_old.cc 2011-11-21 17:13:14 +0000
++++ sql/log_event_old.cc 2012-08-24 08:06:16 +0000
+@@ -2003,7 +2003,7 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Old_rows_log_event::pack_info(Protocol *protocol)
++void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+
+=== modified file 'sql/log_event_old.h'
+--- sql/log_event_old.h 2011-02-20 16:51:43 +0000
++++ sql/log_event_old.h 2012-08-24 08:06:16 +0000
+@@ -108,7 +108,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+
+=== modified file 'sql/mysql_priv.h'
+--- sql/mysql_priv.h 2012-05-17 10:12:33 +0000
++++ sql/mysql_priv.h 2012-08-24 08:06:16 +0000
+@@ -1371,7 +1371,7 @@
+ /* sql_show.cc */
+ bool mysqld_show_open_tables(THD *thd,const char *wild);
+ bool mysqld_show_logs(THD *thd);
+-void append_identifier(THD *thd, String *packet, const char *name,
++bool append_identifier(THD *thd, String *packet, const char *name,
+ uint length);
+ #endif /* MYSQL_SERVER */
+ #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
+
+=== modified file 'sql/sql_base.cc'
+--- sql/sql_base.cc 2011-11-30 16:44:51 +0000
++++ sql/sql_base.cc 2012-08-24 08:06:16 +0000
+@@ -4172,22 +4172,22 @@
+ entry->file->implicit_emptied= 0;
+ if (mysql_bin_log.is_open())
+ {
+- char *query, *end;
+- uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
+- if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
++ char query_buf[2*FN_REFLEN + 21];
++ String query(query_buf, sizeof(query_buf), system_charset_info);
++ query.length(0);
++ if (query.ptr())
+ {
+ /* this DELETE FROM is needed even with row-based binlogging */
+- end = strxmov(strmov(query, "DELETE FROM `"),
+- share->db.str,"`.`",share->table_name.str,"`", NullS);
++ query.append("DELETE FROM ");
++ append_identifier(thd, &query, share->db.str, share->db.length);
++ query.append(".");
++ append_identifier(thd, &query, share->table_name.str,
++ share->table_name.length);
+ int errcode= query_error_code(thd, TRUE);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+- query, (ulong)(end-query),
++ query.ptr(), query.length(),
+ FALSE, FALSE, errcode))
+- {
+- my_free(query, MYF(0));
+ goto err;
+- }
+- my_free(query, MYF(0));
+ }
+ else
+ {
+@@ -4197,7 +4197,7 @@
+ because of MYF(MY_WME) in my_malloc() above).
+ */
+ sql_print_error("When opening HEAP table, could not allocate memory "
+- "to write 'DELETE FROM `%s`.`%s`' to the binary log",
++ "to write 'DELETE FROM %`s.%`s' to the binary log",
+ table_list->db, table_list->table_name);
+ delete entry->triggers;
+ closefrm(entry, 0);
+
+=== modified file 'sql/sql_db.cc'
+--- sql/sql_db.cc 2011-11-21 17:13:14 +0000
++++ sql/sql_db.cc 2012-08-24 08:06:16 +0000
+@@ -612,7 +612,6 @@
+ bool silent)
+ {
+ char path[FN_REFLEN+16];
+- char tmp_query[FN_REFLEN+16];
+ long result= 1;
+ int error= 0;
+ MY_STAT stat_info;
+@@ -719,17 +718,9 @@
+ char *query;
+ uint query_length;
+
+- if (!thd->query()) // Only in replication
+- {
+- query= tmp_query;
+- query_length= (uint) (strxmov(tmp_query,"create database `",
+- db, "`", NullS) - tmp_query);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
+
+ ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
+ query, query_length,
+@@ -989,18 +980,11 @@
+ {
+ const char *query;
+ ulong query_length;
+- if (!thd->query())
+- {
+- /* The client used the old obsolete mysql_drop_db() call */
+- query= path;
+- query_length= (uint) (strxmov(path, "drop database `", db, "`",
+- NullS) - path);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
++
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+@@ -1041,9 +1025,10 @@
+ for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
+ {
+ uint tbl_name_len;
++ char quoted_name[FN_REFLEN+3];
+
+- /* 3 for the quotes and the comma*/
+- tbl_name_len= strlen(tbl->table_name) + 3;
++ my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
++ tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
+ if (query_pos + tbl_name_len + 1 >= query_end)
+ {
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
+@@ -1055,9 +1040,7 @@
+ query_pos= query_data_start;
+ }
+
+- *query_pos++ = '`';
+- query_pos= strmov(query_pos,tbl->table_name);
+- *query_pos++ = '`';
++ query_pos= strmov(query_pos, quoted_name);
+ *query_pos++ = ',';
+ }
+
+
+=== modified file 'sql/sql_insert.cc'
+--- sql/sql_insert.cc 2011-11-23 17:32:14 +0000
++++ sql/sql_insert.cc 2012-08-24 08:06:16 +0000
+@@ -3457,16 +3457,16 @@
+ if (thd->lex->create_select_in_comment)
+ query.append(STRING_WITH_LEN("/*! "));
+ if (thd->lex->ignore)
+- query.append(STRING_WITH_LEN("INSERT IGNORE INTO `"));
++ query.append(STRING_WITH_LEN("INSERT IGNORE INTO "));
+ else if (thd->lex->duplicates == DUP_REPLACE)
+- query.append(STRING_WITH_LEN("REPLACE INTO `"));
++ query.append(STRING_WITH_LEN("REPLACE INTO "));
+ else
+- query.append(STRING_WITH_LEN("INSERT INTO `"));
++ query.append(STRING_WITH_LEN("INSERT INTO "));
+
+- query.append(create_table->db, db_len);
+- query.append(STRING_WITH_LEN("`.`"));
+- query.append(create_info->alias, table_len);
+- query.append(STRING_WITH_LEN("` "));
++ append_identifier(thd, &query, create_table->db, db_len);
++ query.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &query, create_info->alias, table_len);
++ query.append(STRING_WITH_LEN(" "));
+
+ /*
+ The insert items.
+
+=== modified file 'sql/sql_load.cc'
+--- sql/sql_load.cc 2012-04-05 08:49:38 +0000
++++ sql/sql_load.cc 2012-08-24 08:06:16 +0000
+@@ -24,6 +24,7 @@
+ #include "sql_repl.h"
+ #include "sp_head.h"
+ #include "sql_trigger.h"
++#include "sql_show.h"
+
+ class READ_INFO {
+ File file;
+@@ -606,20 +607,28 @@
+ bool transactional_table,
+ int errcode)
+ {
+- char *load_data_query,
+- *end,
+- *fname_start,
+- *fname_end,
+- *p= NULL;
+- size_t pl= 0;
++ char *load_data_query;
++ my_off_t fname_start,
++ fname_end;
+ List<Item> fv;
+ Item *item, *val;
+- String pfield, pfields;
+ int n;
+- const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
+- String string_buf;
+-
++ const char *qualify_db= NULL;
++ char command_buffer[1024];
++ String query_str(command_buffer, sizeof(command_buffer),
++ system_charset_info);
++
++ Load_log_event lle(thd, ex, tdb, table_name_arg, fv, duplicates,
++ ignore, transactional_table);
++
++ /*
++ force in a LOCAL if there was one in the original.
++ */
++ if (thd->lex->local_file)
++ lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++
++ query_str.length(0);
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+@@ -627,23 +636,10 @@
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+- string_buf.set_charset(system_charset_info);
+- string_buf.append(db_arg);
+- string_buf.append("`");
+- string_buf.append(".");
+- string_buf.append("`");
+- string_buf.append(table_name_arg);
+- tbl= string_buf.c_ptr_safe();
++ qualify_db= db_arg;
+ }
+-
+- Load_log_event lle(thd, ex, tdb, tbl, fv, duplicates,
+- ignore, transactional_table);
+-
+- /*
+- force in a LOCAL if there was one in the original.
+- */
+- if (thd->lex->local_file)
+- lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++ lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
++ &query_str, &fname_start, &fname_end, qualify_db);
+
+ /*
+ prepare fields-list and SET if needed; print_query won't do that for us.
+@@ -652,23 +648,19 @@
+ {
+ List_iterator<Item> li(thd->lex->field_list);
+
+- pfields.append(" (");
++ query_str.append(" (");
+ n= 0;
+
+ while ((item= li++))
+ {
+ if (n++)
+- pfields.append(", ");
++ query_str.append(", ");
+ if (item->name)
+- {
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- }
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
+ else
+- item->print(&pfields, QT_ORDINARY);
++ ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str);
+ }
+- pfields.append(")");
++ query_str.append(")");
+ }
+
+ if (!thd->lex->update_list.is_empty())
+@@ -676,39 +668,26 @@
+ List_iterator<Item> lu(thd->lex->update_list);
+ List_iterator<Item> lv(thd->lex->value_list);
+
+- pfields.append(" SET ");
++ query_str.append(" SET ");
+ n= 0;
+
+ while ((item= lu++))
+ {
+ val= lv++;
+ if (n++)
+- pfields.append(", ");
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- pfields.append("=");
+- val->print(&pfields, QT_ORDINARY);
++ query_str.append(", ");
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
++ query_str.append("=");
++ val->print(&query_str, QT_ORDINARY);
+ }
+ }
+
+- p= pfields.c_ptr_safe();
+- pl= strlen(p);
+-
+- if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length())))
+ return TRUE;
+
+- lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+- load_data_query, &end,
+- (char **)&fname_start, (char **)&fname_end);
+-
+- strcpy(end, p);
+- end += pl;
+-
+ Execute_load_query_log_event
+- e(thd, load_data_query, end-load_data_query,
+- (uint) ((char*) fname_start - load_data_query - 1),
+- (uint) ((char*) fname_end - load_data_query),
++ e(thd, load_data_query, query_str.length(),
++ (uint) (fname_start - 1), (uint) fname_end,
+ (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
+ (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
+ transactional_table, FALSE, errcode);
+
+=== modified file 'sql/sql_repl.cc'
+--- sql/sql_repl.cc 2011-11-21 17:13:14 +0000
++++ sql/sql_repl.cc 2012-08-24 08:06:16 +0000
+@@ -1554,7 +1554,7 @@
+ description_event)); )
+ {
+ if (event_count >= limit_start &&
+- ev->net_send(protocol, linfo.log_file_name, pos))
++ ev->net_send(thd, protocol, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+
+=== modified file 'sql/sql_show.cc'
+--- sql/sql_show.cc 2012-05-17 10:12:33 +0000
++++ sql/sql_show.cc 2012-08-24 08:06:16 +0000
+@@ -1019,9 +1019,13 @@
+ packet target string
+ name the identifier to be appended
+ name_length length of the appending identifier
++
++ RETURN VALUES
++ true Error
++ false Ok
+ */
+
+-void
++bool
+ append_identifier(THD *thd, String *packet, const char *name, uint length)
+ {
+ const char *name_end;
+@@ -1029,10 +1033,7 @@
+ int q= get_quote_char_for_identifier(thd, name, length);
+
+ if (q == EOF)
+- {
+- packet->append(name, length, packet->charset());
+- return;
+- }
++ return packet->append(name, length, packet->charset());
+
+ /*
+ The identifier must be quoted as it includes a quote character or
+@@ -1041,7 +1042,8 @@
+
+ VOID(packet->reserve(length*2 + 2));
+ quote_char= (char) q;
+- packet->append("e_char, 1, system_charset_info);
++ if (packet->append("e_char, 1, system_charset_info))
++ return true;
+
+ for (name_end= name+length ; name < name_end ; name+= length)
+ {
+@@ -1056,11 +1058,13 @@
+ */
+ if (!length)
+ length= 1;
+- if (length == 1 && chr == (uchar) quote_char)
+- packet->append("e_char, 1, system_charset_info);
+- packet->append(name, length, system_charset_info);
++ if (length == 1 && chr == (uchar) quote_char &&
++ packet->append("e_char, 1, system_charset_info))
++ return true;
++ if (packet->append(name, length, system_charset_info))
++ return true;
+ }
+- packet->append("e_char, 1, system_charset_info);
++ return packet->append("e_char, 1, system_charset_info);
+ }
+
+
+
+=== modified file 'sql/sql_string.cc'
+--- sql/sql_string.cc 2012-04-05 08:49:38 +0000
++++ sql/sql_string.cc 2012-08-24 08:06:16 +0000
+@@ -1157,39 +1157,47 @@
+
+
+
+-
+-void String::print(String *str)
++/*
++ Append characters to a single-quoted string '...', escaping special
++ characters as necessary.
++ Does not add the enclosing quotes, this is left up to caller.
++*/
++void String::append_for_single_quote(const char *st, uint len)
+ {
+- char *st= (char*)Ptr, *end= st+str_length;
++ const char *end= st+len;
+ for (; st < end; st++)
+ {
+ uchar c= *st;
+ switch (c)
+ {
+ case '\\':
+- str->append(STRING_WITH_LEN("\\\\"));
++ append(STRING_WITH_LEN("\\\\"));
+ break;
+ case '\0':
+- str->append(STRING_WITH_LEN("\\0"));
++ append(STRING_WITH_LEN("\\0"));
+ break;
+ case '\'':
+- str->append(STRING_WITH_LEN("\\'"));
++ append(STRING_WITH_LEN("\\'"));
+ break;
+ case '\n':
+- str->append(STRING_WITH_LEN("\\n"));
++ append(STRING_WITH_LEN("\\n"));
+ break;
+ case '\r':
+- str->append(STRING_WITH_LEN("\\r"));
++ append(STRING_WITH_LEN("\\r"));
+ break;
+ case '\032': // Ctrl-Z
+- str->append(STRING_WITH_LEN("\\Z"));
++ append(STRING_WITH_LEN("\\Z"));
+ break;
+ default:
+- str->append(c);
++ append(c);
+ }
+ }
+ }
+
++void String::print(String *str)
++{
++ str->append_for_single_quote(Ptr, str_length);
++}
+
+ /*
+ Exchange state of this object and argument.
+
+=== modified file 'sql/sql_string.h'
+--- sql/sql_string.h 2011-11-21 17:13:14 +0000
++++ sql/sql_string.h 2012-08-24 08:06:16 +0000
+@@ -385,6 +385,7 @@
+ return FALSE;
+ }
+ void print(String *print);
++ void append_for_single_quote(const char *st, uint len);
+
+ /* Swap two string objects. Efficient way to exchange data without memcpy. */
+ void swap(String &s);
+
+=== modified file 'sql/sql_table.cc'
+--- sql/sql_table.cc 2012-04-05 08:49:38 +0000
++++ sql/sql_table.cc 2012-08-24 08:06:16 +0000
+@@ -1945,6 +1945,7 @@
+ for (table= tables; table; table= table->next_local)
+ {
+ char *db=table->db;
++ size_t db_length= table->db_length;
+ handlerton *table_type;
+ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+
+@@ -1967,14 +1968,14 @@
+ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
+ }
+
+- built_tmp_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_tmp_query.append(db);
+- built_tmp_query.append("`.`");
++ append_identifier(thd, &built_tmp_query, db, db_length);
++ built_tmp_query.append(".");
+ }
+- built_tmp_query.append(table->table_name);
+- built_tmp_query.append("`,");
++ append_identifier(thd, &built_tmp_query, table->table_name,
++ table->table_name_length);
++ built_tmp_query.append(",");
+ }
+
+ continue;
+@@ -2000,15 +2001,15 @@
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+- built_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_query.append(db);
+- built_query.append("`.`");
++ append_identifier(thd, &built_query, db, db_length);
++ built_query.append(".");
+ }
+
+- built_query.append(table->table_name);
+- built_query.append("`,");
++ append_identifier(thd, &built_query, table->table_name,
++ table->table_name_length);
++ built_query.append(",");
+ }
+
+ if (!drop_temporary)
+
+=== modified file 'strings/my_vsnprintf.c'
+--- strings/my_vsnprintf.c 2011-11-21 17:13:14 +0000
++++ strings/my_vsnprintf.c 2012-08-24 08:06:16 +0000
+@@ -19,6 +19,57 @@
+ #include <m_ctype.h>
+ #include <stdarg.h>
+
++
++/**
++ Returns escaped string
++
++ @param cs string charset
++ @param to buffer where escaped string will be placed
++ @param end end of buffer
++ @param par string to escape
++ @param par_len string length
++ @param quote_char character for quoting
++
++ @retval
++ position in buffer which points on the end of escaped string
++*/
++
++static char *backtick_string(char *to, char *end, char *par,
++ size_t par_len, char quote_char)
++{
++ char *start= to;
++ char *par_end= par + par_len;
++ size_t buff_length= (size_t) (end - to);
++
++ if (buff_length <= par_len)
++ goto err;
++ *start++= quote_char;
++
++ for ( ; par < par_end; ++par)
++ {
++ char c= *par;
++ if (c == quote_char)
++ {
++ if (start + 1 >= end)
++ goto err;
++ *start++= quote_char;
++ }
++ if (start + 1 >= end)
++ goto err;
++ *start++= c;
++ }
++
++ if (start + 1 >= end)
++ goto err;
++ *start++= quote_char;
++ return start;
++
++err:
++ *to='\0';
++ return to;
++}
++
++
+ /*
+ Limited snprintf() implementations
+
+@@ -45,7 +96,7 @@
+ {
+ char *start=to, *end=to+n-1;
+ size_t length, width;
+- uint pre_zero, have_long;
++ uint pre_zero, have_long, escaped_arg;
+
+ for (; *fmt ; fmt++)
+ {
+@@ -61,7 +112,7 @@
+ if (*fmt == '-')
+ fmt++;
+ length= width= 0;
+- pre_zero= have_long= 0;
++ pre_zero= have_long= escaped_arg= 0;
+ if (*fmt == '*')
+ {
+ fmt++;
+@@ -93,6 +144,11 @@
+ fmt++;
+ have_long= 1;
+ }
++ if (*fmt == '`')
++ {
++ fmt++;
++ escaped_arg= 1;
++ }
+ if (*fmt == 's') /* String parameter */
+ {
+ reg2 char *par = va_arg(ap, char *);
+@@ -101,7 +157,10 @@
+ plen= (uint) strnlen(par, width);
+ if (left_len <= plen)
+ plen = left_len - 1;
+- to=strnmov(to,par,plen);
++ if (escaped_arg)
++ to= backtick_string(to, end, par, plen, '`');
++ else
++ to= strnmov(to,par,plen);
+ continue;
+ }
+ else if (*fmt == 'b') /* Buffer parameter */
+@@ -185,6 +244,70 @@
+ return result;
+ }
+
++/**
++ Writes output to the stream according to a format string.
++
++ @param stream file to write to
++ @param format string format
++ @param args list of parameters
++
++ @retval
++ number of the characters written.
++*/
++
++int my_vfprintf(FILE *stream, const char* format, va_list args)
++{
++ char cvtbuf[1024];
++ int alloc= 0;
++ char *p= cvtbuf;
++ size_t cur_len= sizeof(cvtbuf);
++ int ret;
++
++ /*
++ We do not know how much buffer we need.
++ So start with a reasonably-sized stack-allocated buffer, and increase
++ it exponentially until it is big enough.
++ */
++ for (;;)
++ {
++ size_t new_len;
++ size_t actual= my_vsnprintf(p, cur_len, format, args);
++ if (actual < cur_len - 1)
++ break;
++ /*
++ Not enough space (or just enough with nothing to spare - but we cannot
++ distinguish this case from the return value). Allocate a bigger buffer
++ and try again.
++ */
++ if (alloc)
++ (*my_str_free)(p);
++ else
++ alloc= 1;
++ new_len= cur_len*2;
++ if (new_len < cur_len)
++ return 0; /* Overflow */
++ cur_len= new_len;
++ p= (*my_str_malloc)(cur_len);
++ if (!p)
++ return 0;
++ }
++ ret= fprintf(stream, "%s", p);
++ if (alloc)
++ (*my_str_free)(p);
++ return ret;
++}
++
++int my_fprintf(FILE *stream, const char* format, ...)
++{
++ int result;
++ va_list args;
++ va_start(args, format);
++ result= my_vfprintf(stream, format, args);
++ va_end(args);
++ return result;
++}
++
++
+ #ifdef MAIN
+ #define OVERRUN_SENTRY 250
+ static void my_printf(const char * fmt, ...)
+
diff --git a/21000_sql-5.2.12.patch b/21000_sql-5.2.12.patch
new file mode 100644
index 0000000..fcbac0c
--- /dev/null
+++ b/21000_sql-5.2.12.patch
@@ -0,0 +1,3234 @@
+=== modified file 'client/mysqlbinlog.cc'
+--- client/mysqlbinlog.cc 2011-11-24 16:48:58 +0000
++++ client/mysqlbinlog.cc 2012-08-24 10:32:46 +0000
+@@ -664,7 +664,7 @@
+ return;
+
+ // In case of rewrite rule print USE statement for db_to
+- fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter);
++ my_fprintf(result_file, "use %`s%s\n", db_to, pinfo->delimiter);
+
+ // Copy the *original* db to pinfo to suppress emiting
+ // of USE stmts by log_event print-functions.
+
+=== modified file 'include/my_sys.h'
+--- include/my_sys.h 2011-11-24 16:48:58 +0000
++++ include/my_sys.h 2012-08-24 10:32:46 +0000
+@@ -676,6 +676,7 @@
+ extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
+ extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
+ extern int my_fclose(FILE *fd,myf MyFlags);
++extern int my_fprintf(FILE *stream, const char* format, ...);
+ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
+ extern int my_chmod(const char *name, mode_t mode, myf my_flags);
+ extern int my_sync(File fd, myf my_flags);
+@@ -811,6 +812,8 @@
+ extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+ extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
+ extern my_off_t my_b_filelength(IO_CACHE *info);
++extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
++ size_t len);
+ extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
+ extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
+ extern int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+
+=== modified file 'mysql-test/r/func_compress.result'
+--- mysql-test/r/func_compress.result 2009-06-19 09:29:21 +0000
++++ mysql-test/r/func_compress.result 2012-08-24 08:06:16 +0000
+@@ -11,7 +11,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select uncompress(compress((@test_compress_string))) AS `uncompress(compress(@test_compress_string))`
++Note 1003 select uncompress(compress((@`test_compress_string`))) AS `uncompress(compress(@test_compress_string))`
+ select uncompressed_length(compress(@test_compress_string))=length(@test_compress_string);
+ uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)
+ 1
+@@ -19,7 +19,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (uncompressed_length(compress((@test_compress_string))) = length((@test_compress_string))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
++Note 1003 select (uncompressed_length(compress((@`test_compress_string`))) = length((@`test_compress_string`))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
+ select uncompressed_length(compress(@test_compress_string));
+ uncompressed_length(compress(@test_compress_string))
+ 117
+
+=== modified file 'mysql-test/r/mysqlbinlog-innodb.result'
+--- mysql-test/r/mysqlbinlog-innodb.result 2011-01-13 12:28:36 +0000
++++ mysql-test/r/mysqlbinlog-innodb.result 2012-08-24 10:32:46 +0000
+@@ -34,7 +34,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+@@ -65,7 +65,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use foo/*!*/;
++use `foo`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog.result'
+--- mysql-test/r/mysqlbinlog.result 2011-03-25 14:16:13 +0000
++++ mysql-test/r/mysqlbinlog.result 2012-08-24 08:06:16 +0000
+@@ -18,7 +18,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -64,7 +64,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -97,7 +97,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -119,7 +119,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -165,7 +165,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -198,7 +198,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -220,7 +220,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844556/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+@@ -239,7 +239,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844556/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
+@@ -299,7 +299,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -349,7 +349,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -484,7 +484,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1253783037/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -581,22 +581,22 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+ /*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t1 VALUES(40)
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ ROLLBACK TO mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("after rollback to")
+ /*!*/;
+@@ -624,7 +624,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog2.result'
+--- mysql-test/r/mysqlbinlog2.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/mysqlbinlog2.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -62,7 +62,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -101,7 +101,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -127,7 +127,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -162,7 +162,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -185,7 +185,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -215,7 +215,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -246,7 +246,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -281,7 +281,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -304,7 +304,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -335,7 +335,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -358,7 +358,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -377,7 +377,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -399,7 +399,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -445,7 +445,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -468,7 +468,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -490,7 +490,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -520,7 +520,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -563,7 +563,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -601,7 +601,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -627,7 +627,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -661,7 +661,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -684,7 +684,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -714,7 +714,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -744,7 +744,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -779,7 +779,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -802,7 +802,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -833,7 +833,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -855,7 +855,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -874,7 +874,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -896,7 +896,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -942,7 +942,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -965,7 +965,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -987,7 +987,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1017,7 +1017,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row.result'
+--- mysql-test/r/mysqlbinlog_row.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row.result 2012-08-24 08:06:16 +0000
+@@ -336,7 +336,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_innodb.result'
+--- mysql-test/r/mysqlbinlog_row_innodb.result 2010-03-22 12:10:18 +0000
++++ mysql-test/r/mysqlbinlog_row_innodb.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3876,7 +3876,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4243,7 +4243,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4804,7 +4804,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_myisam.result'
+--- mysql-test/r/mysqlbinlog_row_myisam.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row_myisam.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3898,7 +3898,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4271,7 +4271,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4842,7 +4842,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_trans.result'
+--- mysql-test/r/mysqlbinlog_row_trans.result 2009-08-27 09:32:27 +0000
++++ mysql-test/r/mysqlbinlog_row_trans.result 2012-08-24 08:06:16 +0000
+@@ -132,7 +132,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/user_var-binlog.result'
+--- mysql-test/r/user_var-binlog.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/user_var-binlog.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/variables.result'
+--- mysql-test/r/variables.result 2011-09-13 15:46:47 +0000
++++ mysql-test/r/variables.result 2012-08-24 10:32:46 +0000
+@@ -77,7 +77,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@t1) AS `@t1`,(@t2) AS `@t2`,(@t3) AS `@t3`
++Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@`t1`) AS `@t1`,(@`t2`) AS `@t2`,(@`t3`) AS `@t3`
+ select @t5;
+ @t5
+ 1.23456
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
+--- mysql-test/suite/binlog/r/binlog_base64_flag.result 2011-02-23 09:31:37 +0000
++++ mysql-test/suite/binlog/r/binlog_base64_flag.result 2012-08-24 08:06:16 +0000
+@@ -35,7 +35,7 @@
+ # at 4
+ <#>ROLLBACK/*!*/;
+ # at 102
+-<#>use test/*!*/;
++<#>use `test`/*!*/;
+ SET TIMESTAMP=1196959712/*!*/;
+ <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+ SET @@session.sql_mode=0/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result'
+--- mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2011-01-13 12:28:36 +0000
++++ mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2012-08-24 10:32:46 +0000
+@@ -35,7 +35,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -72,7 +72,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -115,7 +115,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+@@ -229,7 +229,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -266,7 +266,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -309,7 +309,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result'
+--- mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2008-10-23 19:27:09 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2012-08-24 08:06:16 +0000
+@@ -13,7 +13,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result'
+--- mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2010-09-02 13:05:06 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2012-08-24 08:06:16 +0000
+@@ -631,7 +631,7 @@
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ /* the output must denote there is the query */;
+ drop trigger trg_del_t2;
+@@ -869,7 +869,7 @@
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ drop trigger trg_del_t2;
+ drop table t1,t2,t3,t4,t5;
+
+=== added file 'mysql-test/suite/rpl/r/rpl_mdev382.result'
+--- mysql-test/suite/rpl/r/rpl_mdev382.result 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/r/rpl_mdev382.result 2012-08-24 10:32:46 +0000
+@@ -0,0 +1,302 @@
++include/master-slave.inc
++[connection master]
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
++insert into t1 values (3);
++commit;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `test`; create table t1 (a int primary key) engine=innodb
++master-bin.000001 # Query # # use `test`; create table t2 (a int primary key) engine=myisam
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values (1)
++master-bin.000001 # Query # # SAVEPOINT "a`; create database couldbebadthingshere; savepoint `dummy"
++master-bin.000001 # Query # # use `test`; insert into t1 values (2)
++master-bin.000001 # Query # # use `test`; insert into t2 values (1)
++master-bin.000001 # Query # # ROLLBACK TO `a``; create database couldbebadthingshere; savepoint ``dummy`
++master-bin.000001 # Query # # use `test`; insert into t1 values (3)
++master-bin.000001 # Xid # # COMMIT /* XID */
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values(10)
++master-bin.000001 # Query # # SAVEPOINT "a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(11)
++master-bin.000001 # Query # # SAVEPOINT "a""a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(12)
++master-bin.000001 # Query # # SAVEPOINT b
++master-bin.000001 # Query # # use `test`; insert into t1 values(13)
++master-bin.000001 # Query # # SAVEPOINT "b""b"
++master-bin.000001 # Query # # use `test`; insert into t1 values(14)
++master-bin.000001 # Query # # SAVEPOINT `c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(15)
++master-bin.000001 # Query # # SAVEPOINT `c``c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(16)
++master-bin.000001 # Query # # SAVEPOINT d
++master-bin.000001 # Query # # use `test`; insert into t1 values(17)
++master-bin.000001 # Query # # SAVEPOINT `d``d`
++master-bin.000001 # Query # # use `test`; insert into t1 values(18)
++master-bin.000001 # Xid # # COMMIT /* XID */
++*** Test correct USE statement in SHOW BINLOG EVENTS ***
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (2)
++set sql_mode = '';
++set sql_quote_show_create = 0;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++DROP TABLE t1;
++use test;
++***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++use `db1``; SELECT 'oops!'`;
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++truncate `t``1`;
++use test;
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `db1``; SELECT 'oops!'`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!') ;file_id=#
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; truncate `t``1`
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!') ;file_id=#
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++truncate `t``1`
++/*!*/;
++use `test`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++drop table t1,t2;
++*** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE t1
++FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE `t1` FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=concat((@`b`),'| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|',(@`b`)) ;file_id=#
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++DROP TABLE t1;
++*** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++@`a``1`:=a1 @`a``2`:=a2 @`a``3`:=a3 @`a``4`:=a4 @`b```:=b @```c`:=c @```d```:=d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++master-bin.000001 # User var # # @`a``1`=-9223372036854775808
++master-bin.000001 # User var # # @`a``2`=42
++master-bin.000001 # User var # # @`a``3`=9223372036854775807
++master-bin.000001 # User var # # @`a``4`=-1
++master-bin.000001 # User var # # @`b```=-1.2345601234568e+125
++master-bin.000001 # User var # # @```c`=-1234501234567890123456789012345678901234567890123456789.0123456789
++master-bin.000001 # User var # # @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++/*!*/;
++SET @`a``1`:=-9223372036854775808/*!*/;
++SET @`a``2`:=42/*!*/;
++SET @`a``3`:=9223372036854775807/*!*/;
++SET @`a``4`:=-1/*!*/;
++SET @`b```:=-1.2345601234568e+125/*!*/;
++SET @```c`:=-1234501234567890123456789012345678901234567890123456789.0123456789/*!*/;
++SET @```d```:=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE `latin1_swedish_ci`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++a1 a2 a3 a4 b c d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++-9223372036854775807 4200 9223372036854775806 0 -6.17280061728394e+124 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++DROP TABLE t1;
++*** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++include/stop_slave.inc
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++a`
++1
++2
++5
++set timestamp=1000000000;
++# The table should be empty on the master.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++# The DELETE statement should be correctly quoted
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # use `test`; DELETE FROM `db1``; SELECT 'oops!'`.`t``1`
++include/start_slave.inc
++# The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++*** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++INSERT INTO t1 VALUES(1);
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES(1)
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `ts``et`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++INSERT INTO t1 VALUES(1)
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++DROP TABLE t1;
++include/rpl_end.inc
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
+--- mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2012-08-24 08:06:16 +0000
+@@ -153,7 +153,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -175,7 +175,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -284,7 +284,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -316,7 +316,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
+--- mysql-test/suite/rpl/r/rpl_sp.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_sp.result 2012-08-24 08:06:16 +0000
+@@ -627,7 +627,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest1
+ /*!*/;
+-use mysqltest1/*!*/;
++use `mysqltest1`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t1 (a varchar(100))
+ /*!*/;
+@@ -840,7 +840,7 @@
+ SET TIMESTAMP=t/*!*/;
+ drop user "zedjzlcsjhd"@127.0.0.1
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ drop function if exists f1
+ /*!*/;
+@@ -925,7 +925,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest2
+ /*!*/;
+-use mysqltest2/*!*/;
++use `mysqltest2`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t ( t integer )
+ /*!*/;
+@@ -943,7 +943,7 @@
+ return 0;
+ end
+ /*!*/;
+-use mysqltest/*!*/;
++use `mysqltest`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ SELECT `mysqltest2`.`f1`()
+ /*!*/;
+@@ -953,14 +953,14 @@
+ SET TIMESTAMP=t/*!*/;
+ drop database mysqltest2
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltestbug36570_p1`()
+ begin
+ select 1;
+ end
+ /*!*/;
+-use mysql/*!*/;
++use `mysql`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.` mysqltestbug36570_p2`( a int)
+ `label`:
+
+=== added file 'mysql-test/suite/rpl/t/rpl_mdev382.test'
+--- mysql-test/suite/rpl/t/rpl_mdev382.test 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/t/rpl_mdev382.test 2012-08-24 10:32:46 +0000
+@@ -0,0 +1,257 @@
++--source include/have_innodb.inc
++--source include/not_windows.inc
++--source include/have_binlog_format_statement.inc
++--source include/master-slave.inc
++
++# MDEV-382: multiple SQL injections in replication code.
++
++# Test previous SQL injection attack against binlog for SAVEPOINT statement.
++# The test would cause syntax error on slave due to improper quoting of
++# the savepoint name.
++connection master;
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (3);
++commit;
++
++--source include/show_binlog_events.inc
++
++# This failed due to syntax error in query when the bug was not fixed.
++sync_slave_with_master;
++connection slave;
++
++# Test some more combinations of ANSI_QUOTES and sql_quote_show_create
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++
++--source include/show_binlog_events.inc
++
++--echo *** Test correct USE statement in SHOW BINLOG EVENTS ***
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++--source include/show_binlog_events.inc
++set sql_mode = '';
++set sql_quote_show_create = 0;
++--source include/show_binlog_events.inc
++set sql_quote_show_create = 1;
++--source include/show_binlog_events.inc
++DROP TABLE t1;
++
++use test;
++
++--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++
++--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt
++--write_file $load_file
++'fo\\o','bar'
++EOF
++--exec chmod go+r "$load_file"
++
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++ `c``3` VARCHAR(7));
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++
++SELECT * FROM `t``1`;
++# Also test when code prefixes table name with database.
++truncate `t``1`;
++use test;
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++let $MYSQLD_DATADIR= `select @@datadir`;
++--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '<name>' INTO/
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++connection master;
++
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++--remove_file $load_file
++
++connection master;
++drop table t1,t2;
++
++
++--echo *** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++--let $load_file= $MYSQLTEST_VARDIR/tmp/file.txt
++--write_file $load_file
++1,X
++2,A
++EOF
++--exec chmod go+r "$load_file"
++
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++# The bug was that the SET expression was truncated to 256 bytes, so test with
++# an expression longer than that.
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$load_file' INTO TABLE t1
++ FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++
++SELECT * FROM t1 ORDER BY a;
++--source include/show_binlog_events.inc
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM t1 ORDER BY a;
++
++connection master;
++--remove_file $load_file
++DROP TABLE t1;
++
++
++--echo *** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++
++connection master;
++DROP TABLE t1;
++
++
++--echo *** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++
++# Let's keep the slave stopped during master restart, to avoid any potential
++# races between slave reconnect and master restart.
++connection slave;
++--source include/stop_slave.inc
++
++connection master;
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++
++# Restart the master mysqld.
++# This will cause an implicit truncation of the memory-based table, which will
++# cause logging of an explicit DELETE FROM to binlog.
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++wait-rpl_mdev382.test
++EOF
++
++--shutdown_server 30
++
++--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++restart-rpl_mdev382.test
++EOF
++
++connection default;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++# rpl_end.inc needs to use the connection server_1
++connection server_1;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++connection master;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++set timestamp=1000000000;
++
++--echo # The table should be empty on the master.
++let $binlog_file= master-bin.000002;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++--echo # The DELETE statement should be correctly quoted
++--source include/show_binlog_events.inc
++
++connection slave;
++--source include/start_slave.inc
++
++connection master;
++sync_slave_with_master;
++connection slave;
++--echo # The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++connection master;
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++sync_slave_with_master;
++
++
++connection master;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++
++--echo *** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++INSERT INTO t1 VALUES(1);
++--source include/show_binlog_events.inc
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 --rewrite-db='test->ts`et' $MYSQLD_DATADIR/master-bin.000002
++DROP TABLE t1;
++
++--source include/rpl_end.inc
+
+=== modified file 'mysys/mf_iocache2.c'
+--- mysys/mf_iocache2.c 2011-11-21 17:13:14 +0000
++++ mysys/mf_iocache2.c 2012-08-24 10:32:46 +0000
+@@ -284,6 +284,40 @@
+ }
+
+
++size_t
++my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
++{
++ const uchar *start;
++ const uchar *p= (const uchar *)str;
++ const uchar *end= p + len;
++ size_t count;
++ size_t total= 0;
++
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ for (;;)
++ {
++ start= p;
++ while (p < end && *p != '`')
++ ++p;
++ count= p - start;
++ if (count && my_b_write(info, start, count))
++ return (size_t)-1;
++ total+= count;
++ if (p >= end)
++ break;
++ if (my_b_write(info, (uchar *)"``", 2))
++ return (size_t)-1;
++ total+= 2;
++ ++p;
++ }
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ return total;
++}
++
+ /*
+ Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
+ Used for logging in MySQL
+@@ -308,6 +342,7 @@
+ uint minimum_width_sign;
+ uint precision; /* as yet unimplemented for anything but %b */
+ my_bool is_zero_padded;
++ my_bool backtick_quoting;
+
+ /*
+ Store the location of the beginning of a format directive, for the
+@@ -342,6 +377,7 @@
+ fmt++;
+
+ is_zero_padded= FALSE;
++ backtick_quoting= FALSE;
+ minimum_width_sign= 1;
+ minimum_width= 0;
+ precision= 0;
+@@ -354,6 +390,8 @@
+ minimum_width_sign= -1; fmt++; goto process_flags;
+ case '0':
+ is_zero_padded= TRUE; fmt++; goto process_flags;
++ case '`':
++ backtick_quoting= TRUE; fmt++; goto process_flags;
+ case '#':
+ /** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
+ case ' ':
+@@ -397,9 +435,19 @@
+ reg2 char *par = va_arg(args, char *);
+ size_t length2 = strlen(par);
+ /* TODO: implement precision */
+- out_length+= length2;
+- if (my_b_write(info, (uchar*) par, length2))
+- goto err;
++ if (backtick_quoting)
++ {
++ size_t total= my_b_write_backtick_quote(info, par, length2);
++ if (total == (size_t)-1)
++ goto err;
++ out_length+= total;
++ }
++ else
++ {
++ out_length+= length2;
++ if (my_b_write(info, (uchar*) par, length2))
++ goto err;
++ }
+ }
+ else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
+ {
+
+=== modified file 'sql/ha_ndbcluster_binlog.cc'
+--- sql/ha_ndbcluster_binlog.cc 2011-11-24 16:48:58 +0000
++++ sql/ha_ndbcluster_binlog.cc 2012-08-24 10:32:46 +0000
+@@ -1268,7 +1268,9 @@
+ DBUG_RETURN(0);
+ }
+
+- char tmp_buf2[FN_REFLEN];
++ char tmp_buf2_mem[FN_REFLEN];
++ String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info);
++ tmp_buf2.length(0);
+ const char *type_str;
+ switch (type)
+ {
+@@ -1277,17 +1279,24 @@
+ if (thd->lex->sql_command == SQLCOM_DROP_DB)
+ DBUG_RETURN(0);
+ /* redo the drop table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "drop table `",
+- table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("drop table "));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "drop table";
+ break;
+ case SOT_RENAME_TABLE:
+ /* redo the rename table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "rename table `",
+- db, ".", table_name, "` to `",
+- new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("rename table "));
++ append_identifier(thd, &tmp_buf2, db, strlen(db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ tmp_buf2.append(STRING_WITH_LEN(" to "));
++ append_identifier(thd, &tmp_buf2, new_db, strlen(new_db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "rename table";
+ break;
+ case SOT_CREATE_TABLE:
+
+=== modified file 'sql/item.cc'
+--- sql/item.cc 2012-05-18 12:23:05 +0000
++++ sql/item.cc 2012-08-24 10:32:46 +0000
+@@ -769,15 +769,31 @@
+ if (!my_charset_same(cs, system_charset_info))
+ {
+ size_t res_length;
+- name= sql_strmake_with_convert(str, name_length= length, cs,
++ name= sql_strmake_with_convert(str, length, cs,
+ MAX_ALIAS_NAME, system_charset_info,
+ &res_length);
++ name_length= res_length;
+ }
+ else
+ name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
+ }
+
+
++void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
++{
++ if (!my_charset_same(cs, system_charset_info))
++ {
++ size_t res_length;
++ name= sql_strmake_with_convert(str, length, cs,
++ UINT_MAX, system_charset_info,
++ &res_length);
++ name_length= res_length;
++ }
++ else
++ name= sql_strmake(str, (name_length= length));
++}
++
++
+ /**
+ @details
+ This function is called when:
+
+=== modified file 'sql/item.h'
+--- sql/item.h 2012-05-18 12:23:05 +0000
++++ sql/item.h 2012-08-24 10:32:46 +0000
+@@ -572,6 +572,7 @@
+ #endif
+ } /*lint -e1509 */
+ void set_name(const char *str, uint length, CHARSET_INFO *cs);
++ void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs);
+ void rename(char *new_name);
+ void init_make_field(Send_field *tmp_field,enum enum_field_types type);
+ virtual void cleanup();
+
+=== modified file 'sql/item_func.cc'
+--- sql/item_func.cc 2012-05-22 05:48:10 +0000
++++ sql/item_func.cc 2012-08-24 10:32:46 +0000
+@@ -4784,7 +4784,7 @@
+ void Item_func_get_user_var::print(String *str, enum_query_type query_type)
+ {
+ str->append(STRING_WITH_LEN("(@"));
+- str->append(name.str,name.length);
++ append_identifier(current_thd, str, name.str, name.length);
+ str->append(')');
+ }
+
+@@ -4882,10 +4882,10 @@
+ }
+
+
+-void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
++void Item_user_var_as_out_param::print_for_load(THD *thd, String *str)
+ {
+ str->append('@');
+- str->append(name.str,name.length);
++ append_identifier(thd, str, name.str, name.length);
+ }
+
+
+
+=== modified file 'sql/item_func.h'
+--- sql/item_func.h 2011-11-24 16:48:58 +0000
++++ sql/item_func.h 2012-08-24 10:32:46 +0000
+@@ -1541,7 +1541,7 @@
+ my_decimal *val_decimal(my_decimal *decimal_buffer);
+ /* fix_fields() binds variable name with its entry structure */
+ bool fix_fields(THD *thd, Item **ref);
+- virtual void print(String *str, enum_query_type query_type);
++ void print_for_load(THD *thd, String *str);
+ void set_null_value(CHARSET_INFO* cs);
+ void set_value(const char *str, uint length, CHARSET_INFO* cs);
+ };
+
+=== modified file 'sql/log.cc'
+--- sql/log.cc 2012-05-18 12:23:05 +0000
++++ sql/log.cc 2012-08-24 10:32:46 +0000
+@@ -38,6 +38,7 @@
+ #endif
+
+ #include <mysql/plugin.h>
++#include "sql_show.h"
+
+ /* max size of the log message */
+ #define MAX_LOG_BUFFER_SIZE 1024
+@@ -1769,9 +1770,8 @@
+
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+@@ -1793,9 +1793,8 @@
+ {
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == THD::NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+
+=== modified file 'sql/log_event.cc'
+--- sql/log_event.cc 2012-05-18 12:23:05 +0000
++++ sql/log_event.cc 2012-08-24 10:32:46 +0000
+@@ -34,6 +34,7 @@
+ #include "rpl_utility.h"
+ #include "rpl_record.h"
+ #include <my_dir.h>
++#include "sql_show.h"
+
+ #endif /* MYSQL_CLIENT */
+
+@@ -413,29 +414,28 @@
+ pretty_print_str()
+ */
+
+-static char *pretty_print_str(char *packet, const char *str, int len)
++static void
++pretty_print_str(String *packet, const char *str, int len)
+ {
+ const char *end= str + len;
+- char *pos= packet;
+- *pos++= '\'';
++ packet->append(STRING_WITH_LEN("'"));
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+- case '\n': *pos++= '\\'; *pos++= 'n'; break;
+- case '\r': *pos++= '\\'; *pos++= 'r'; break;
+- case '\\': *pos++= '\\'; *pos++= '\\'; break;
+- case '\b': *pos++= '\\'; *pos++= 'b'; break;
+- case '\t': *pos++= '\\'; *pos++= 't'; break;
+- case '\'': *pos++= '\\'; *pos++= '\''; break;
+- case 0 : *pos++= '\\'; *pos++= '0'; break;
++ case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
++ case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
++ case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
++ case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
++ case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
++ case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
++ case 0 : packet->append(STRING_WITH_LEN("\\0")); break;
+ default:
+- *pos++= c;
++ packet->append(&c, 1);
+ break;
+ }
+ }
+- *pos++= '\'';
+- return pos;
++ packet->append(STRING_WITH_LEN("'"));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -861,7 +861,7 @@
+ Log_event::pack_info()
+ */
+
+-void Log_event::pack_info(Protocol *protocol)
++void Log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ protocol->store("", &my_charset_bin);
+ }
+@@ -870,7 +870,8 @@
+ /**
+ Only called by SHOW BINLOG EVENTS
+ */
+-int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
++int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos)
+ {
+ const char *p= strrchr(log_name, FN_LIBCHAR);
+ const char *event_type;
+@@ -884,7 +885,7 @@
+ protocol->store(event_type, strlen(event_type), &my_charset_bin);
+ protocol->store((uint32) server_id);
+ protocol->store((ulonglong) log_pos);
+- pack_info(protocol);
++ pack_info(thd, protocol);
+ return protocol->write();
+ }
+ #endif /* HAVE_REPLICATION */
+@@ -2139,27 +2140,22 @@
+ show the catalog ??
+ */
+
+-void Query_log_event::pack_info(Protocol *protocol)
++void Query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ // TODO: show the catalog ??
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len);
+ if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
+ && db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf.append(STRING_WITH_LEN("use "));
++ append_identifier(thd, &buf, db, db_len);
++ buf.append("; ");
+ }
+ if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ buf.append(query, q_len);
++ protocol->store(&buf);
+ }
+ #endif
+
+@@ -2924,11 +2920,17 @@
+ }
+ else if (db)
+ {
++ /* Room for expand ` to `` + initial/final ` + \0 */
++ char buf[FN_REFLEN*2+3];
++
+ different_db= memcmp(print_event_info->db, db, db_len + 1);
+ if (different_db)
+ memcpy(print_event_info->db, db, db_len + 1);
+ if (db[0] && different_db)
+- my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
++ {
++ my_snprintf(buf, sizeof(buf), "%`s", db);
++ my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
++ }
+ }
+
+ end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
+@@ -3545,7 +3547,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Start_log_event_v3::pack_info(Protocol *protocol)
++void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
+ pos= strmov(buf, "Server ver: ");
+@@ -4194,131 +4196,115 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-uint Load_log_event::get_query_buffer_length()
+-{
+- return
+- 5 + db_len + 3 + // "use DB; "
+- 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+- 11 + // "CONCURRENT "
+- 7 + // LOCAL
+- 9 + // " REPLACE or IGNORE "
+- 13 + table_name_len*2 + // "INTO TABLE `table`"
+- 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
+- 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
+- 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
+- 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
+- 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
+- 15 + 22 + // " IGNORE xxx LINES"
+- 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
+-}
+-
+-
+-void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
+- char **end, char **fn_start, char **fn_end)
+-{
+- char *pos= buf;
+-
++void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
++ String *buf, my_off_t *fn_start,
++ my_off_t *fn_end, const char *qualify_db)
++{
+ if (need_db && db && db_len)
+ {
+- pos= strmov(pos, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf->append(STRING_WITH_LEN("use "));
++ append_identifier(thd, buf, db, db_len);
++ buf->append(STRING_WITH_LEN("; "));
+ }
+
+- pos= strmov(pos, "LOAD DATA ");
++ buf->append(STRING_WITH_LEN("LOAD DATA "));
+
+ if (thd->lex->lock_option == TL_WRITE_CONCURRENT_INSERT)
+- pos= strmov(pos, "CONCURRENT ");
++ buf->append(STRING_WITH_LEN("CONCURRENT "));
+
+ if (fn_start)
+- *fn_start= pos;
++ *fn_start= buf->length();
+
+ if (check_fname_outside_temp_buf())
+- pos= strmov(pos, "LOCAL ");
+- pos= strmov(pos, "INFILE '");
+- memcpy(pos, fname, fname_len);
+- pos= strmov(pos+fname_len, "' ");
++ buf->append(STRING_WITH_LEN("LOCAL "));
++ buf->append(STRING_WITH_LEN("INFILE '"));
++ buf->append_for_single_quote(fname, fname_len);
++ buf->append(STRING_WITH_LEN("' "));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+- pos= strmov(pos, "REPLACE ");
++ buf->append(STRING_WITH_LEN("REPLACE "));
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+- pos= strmov(pos, "IGNORE ");
++ buf->append(STRING_WITH_LEN("IGNORE "));
+
+- pos= strmov(pos ,"INTO");
++ buf->append(STRING_WITH_LEN("INTO"));
+
+ if (fn_end)
+- *fn_end= pos;
++ *fn_end= buf->length();
+
+- pos= strmov(pos ," TABLE `");
+- memcpy(pos, table_name, table_name_len);
+- pos+= table_name_len;
++ buf->append(STRING_WITH_LEN(" TABLE "));
++ if (qualify_db)
++ {
++ append_identifier(thd, buf, qualify_db, strlen(qualify_db));
++ buf->append(STRING_WITH_LEN("."));
++ }
++ append_identifier(thd, buf, table_name, table_name_len);
+
+ if (cs != NULL)
+ {
+- pos= strmov(pos ,"` CHARACTER SET ");
+- pos= strmov(pos , cs);
++ buf->append(STRING_WITH_LEN(" CHARACTER SET "));
++ buf->append(cs, strlen(cs));
+ }
+- else
+- pos= strmov(pos, "`");
+
+ /* We have to create all optional fields as the default is not empty */
+- pos= strmov(pos, " FIELDS TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
++ buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+- pos= strmov(pos, " OPTIONALLY ");
+- pos= strmov(pos, " ENCLOSED BY ");
+- pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
+-
+- pos= strmov(pos, " ESCAPED BY ");
+- pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+-
+- pos= strmov(pos, " LINES TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
++ buf->append(STRING_WITH_LEN(" OPTIONALLY "));
++ buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
++ pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
++
++ buf->append(STRING_WITH_LEN(" ESCAPED BY "));
++ pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
++
++ buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
+ if (sql_ex.line_start_len)
+ {
+- pos= strmov(pos, " STARTING BY ");
+- pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
++ buf->append(STRING_WITH_LEN(" STARTING BY "));
++ pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((long) skip_lines > 0)
+ {
+- pos= strmov(pos, " IGNORE ");
+- pos= longlong10_to_str((longlong) skip_lines, pos, 10);
+- pos= strmov(pos," LINES ");
++ char skipbuf[22];
++ buf->append(STRING_WITH_LEN(" IGNORE "));
++ longlong10_to_str((longlong) skip_lines, skipbuf, 10);
++ buf->append(skipbuf);
++ buf->append(STRING_WITH_LEN(" LINES "));
+ }
+
+ if (num_fields)
+ {
+ uint i;
+ const char *field= fields;
+- pos= strmov(pos, " (");
++ buf->append(STRING_WITH_LEN(" ("));
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ {
+- *pos++= ' ';
+- *pos++= ',';
++ /*
++ Yes, the space and comma is reversed here. But this is mostly dead
++ code, at most used when reading really old binlogs from old servers,
++ so better just leave it as is...
++ */
++ buf->append(STRING_WITH_LEN(" ,"));
+ }
+- memcpy(pos, field, field_lens[i]);
+- pos+= field_lens[i];
++ append_identifier(thd, buf, field, field_lens[i]);
+ field+= field_lens[i] + 1;
+ }
+- *pos++= ')';
++ buf->append(STRING_WITH_LEN(")"));
+ }
+-
+- *end= pos;
+ }
+
+
+-void Load_log_event::pack_info(Protocol *protocol)
++void Load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *end;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+
+- if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
+- return;
+- print_query(TRUE, NULL, buf, &end, 0, 0);
+- protocol->store(buf, end-buf, &my_charset_bin);
+- my_free(buf, MYF(0));
++ query_str.length(0);
++ print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL);
++ protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
+ }
+ #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+
+@@ -4585,7 +4571,7 @@
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ my_b_printf(&cache,"IGNORE ");
+
+- my_b_printf(&cache, "INTO TABLE `%s`", table_name);
++ my_b_printf(&cache, "INTO TABLE %`s", table_name);
+ my_b_printf(&cache, " FIELDS TERMINATED BY ");
+ pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
+
+@@ -4774,16 +4760,20 @@
+ else
+ {
+ char llbuff[22];
+- char *end;
+ enum enum_duplicates handle_dup;
+ bool ignore= 0;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+ char *load_data_query;
+
++ query_str.length(0);
+ /*
+ Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
+ and written to slave's binlog if binlogging is on.
+ */
+- if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
++ print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
++ query_str.length())))
+ {
+ /*
+ This will set thd->fatal_error in case of OOM. So we surely will notice
+@@ -4792,9 +4782,7 @@
+ goto error;
+ }
+
+- print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
+- *end= 0;
+- thd->set_query(load_data_query, (uint) (end - load_data_query));
++ thd->set_query(load_data_query, (uint) (query_str.length()));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ {
+@@ -4959,7 +4947,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rotate_log_event::pack_info(Protocol *protocol)
++void Rotate_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1), log_cs);
+@@ -5174,7 +5162,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Intvar_log_event::pack_info(Protocol *protocol)
++void Intvar_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256], *pos;
+ pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
+@@ -5323,7 +5311,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rand_log_event::pack_info(Protocol *protocol)
++void Rand_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], *pos;
+ pos= strmov(buf1,"rand_seed1=");
+@@ -5421,7 +5409,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Xid_log_event::pack_info(Protocol *protocol)
++void Xid_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[128], *pos;
+ pos= strmov(buf, "COMMIT /* xid=");
+@@ -5508,69 +5496,109 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void User_var_log_event::pack_info(Protocol* protocol)
++static bool
++user_var_append_name_part(THD *thd, String *buf,
++ const char *name, size_t name_len)
+ {
+- char *buf= 0;
+- uint val_offset= 4 + name_len;
+- uint event_len= val_offset;
++ return buf->append("@") ||
++ append_identifier(thd, buf, name, name_len) ||
++ buf->append("=");
++}
+
++void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
++{
+ if (is_null)
+ {
+- if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
++ char buf_mem[FN_REFLEN+7];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("NULL"))
+ return;
+- strmov(buf + val_offset, "NULL");
+- event_len= val_offset + 4;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+ else
+ {
+ switch (type) {
+ case REAL_RESULT:
++ {
+ double real_val;
++ char buf2[FLOATING_POINT_BUFFER];
++ char buf_mem[FN_REFLEN + FLOATING_POINT_BUFFER];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ float8get(real_val, val);
+- if (!(buf= (char*) my_malloc(val_offset + FLOATING_POINT_BUFFER,
+- MYF(MY_WME))))
+- return;
+- event_len+= my_sprintf(buf + val_offset,
+- (buf + val_offset, "%.14g", real_val));
++ buf.length(0);
++ my_sprintf(buf2, (buf2, "%.14g", real_val));
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case INT_RESULT:
+- if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
++ {
++ char buf2[22];
++ char buf_mem[FN_REFLEN + 22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2, longlong10_to_str(uint8korr(val), buf2, -10)-buf2))
+ return;
+- event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case DECIMAL_RESULT:
+ {
+- if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
+- MYF(MY_WME))))
+- return;
+- String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
++ char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ char buf2[DECIMAL_MAX_STR_LENGTH+1];
++ String str(buf2, sizeof(buf2), &my_charset_bin);
+ my_decimal dec;
++ buf.length(0);
+ binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
+ val[1]);
+ my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
+- event_len= str.length() + val_offset;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
+ }
+ case STRING_RESULT:
++ {
+ /* 15 is for 'COLLATE' and other chars */
+- buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
+- MYF(MY_WME));
++ char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ CHARSET_INFO *cs;
+- if (!buf)
+- return;
++ buf.length(0);
+ if (!(cs= get_charset(charset_number, MYF(0))))
+ {
+- strmov(buf+val_offset, "???");
+- event_len+= 3;
++ if (buf.append("???"))
++ return;
+ }
+ else
+ {
+- char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
+- p= str_to_hex(p, val, val_len);
+- p= strxmov(p, " COLLATE ", cs->name, NullS);
+- event_len= p-buf;
++ size_t old_len;
++ char *beg, *end;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("_") ||
++ buf.append(cs->csname) ||
++ buf.append(" "))
++ return;
++ old_len= buf.length();
++ if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") +
++ MY_CS_NAME_SIZE))
++ return;
++ beg= const_cast<char *>(buf.ptr()) + old_len;
++ end= str_to_hex(beg, val, val_len);
++ buf.length(old_len + (end - beg));
++ if (buf.append(" COLLATE ") ||
++ buf.append(cs->name))
++ return;
+ }
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
+ default:
+@@ -5578,13 +5606,6 @@
+ return;
+ }
+ }
+- buf[0]= '@';
+- buf[1]= '`';
+- memcpy(buf+2, name, name_len);
+- buf[2+name_len]= '`';
+- buf[3+name_len]= '=';
+- protocol->store(buf, event_len, &my_charset_bin);
+- my_free(buf, MYF(0));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -5700,9 +5721,8 @@
+ my_b_printf(&cache, "\tUser_var\n");
+ }
+
+- my_b_printf(&cache, "SET @`");
+- my_b_write(&cache, (uchar*) name, (uint) (name_len));
+- my_b_printf(&cache, "`");
++ my_b_printf(&cache, "SET @");
++ my_b_write_backtick_quote(&cache, name, name_len);
+
+ if (is_null)
+ {
+@@ -5775,7 +5795,7 @@
+ */
+ my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
+ else
+- my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
++ my_b_printf(&cache, ":=_%s %s COLLATE %`s%s\n",
+ cs->csname, hex_str, cs->name,
+ print_event_info->delimiter);
+ my_afree(hex_str);
+@@ -5914,7 +5934,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+-void Slave_log_event::pack_info(Protocol *protocol)
++void Slave_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256+HOSTNAME_LENGTH], *pos;
+ pos= strmov(buf, "host=");
+@@ -6286,7 +6306,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Create_file_log_event::pack_info(Protocol *protocol)
++void Create_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
+ pos= strmov(buf, "db=");
+@@ -6467,7 +6487,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Append_block_log_event::pack_info(Protocol *protocol)
++void Append_block_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ uint length;
+@@ -6619,7 +6639,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Delete_file_log_event::pack_info(Protocol *protocol)
++void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -6717,7 +6737,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_log_event::pack_info(Protocol *protocol)
++void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -6970,27 +6990,26 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_query_log_event::pack_info(Protocol *protocol)
++void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ char file_id_buf[22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len + 10 + 21);
+ if (db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
+- }
+- if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- pos= strmov(pos, " ;file_id=");
+- pos= int10_to_str((long) file_id, pos, 10);
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ if (buf.append("use ") ||
++ append_identifier(thd, &buf, db, db_len) ||
++ buf.append("; "))
++ return;
++ }
++ if (query && q_len && buf.append(query, q_len))
++ return;
++ int10_to_str((long) file_id, file_id_buf, 10);
++ if (buf.append(" ;file_id=") ||
++ buf.append(file_id_buf))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+
+
+@@ -7932,7 +7951,7 @@
+ #endif
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rows_log_event::pack_info(Protocol *protocol)
++void Rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+@@ -8638,7 +8657,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Table_map_log_event::pack_info(Protocol *protocol)
++void Table_map_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes= my_snprintf(buf, sizeof(buf),
+@@ -8659,7 +8678,7 @@
+ {
+ print_header(&print_event_info->head_cache, print_event_info, TRUE);
+ my_b_printf(&print_event_info->head_cache,
+- "\tTable_map: `%s`.`%s` mapped to number %lu\n",
++ "\tTable_map: %`s.%`s mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(&print_event_info->body_cache, print_event_info, TRUE);
+ }
+@@ -9859,7 +9878,7 @@
+
+
+ #ifndef MYSQL_CLIENT
+-void Incident_log_event::pack_info(Protocol *protocol)
++void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes;
+
+=== modified file 'sql/log_event.h'
+--- sql/log_event.h 2011-11-24 16:48:58 +0000
++++ sql/log_event.h 2012-08-24 10:32:46 +0000
+@@ -954,14 +954,15 @@
+ */
+ static void init_show_field_list(List<Item>* field_list);
+ #ifdef HAVE_REPLICATION
+- int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
++ int net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos);
+
+ /*
+ pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
+ a string to display to the user, so it resembles print().
+ */
+
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+
+ #endif /* HAVE_REPLICATION */
+ virtual const char* get_db()
+@@ -1661,7 +1662,7 @@
+ bool using_trans, bool suppress_use, int error);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -1791,7 +1792,7 @@
+
+ #ifndef MYSQL_CLIENT
+ Slave_log_event(THD* thd_arg, Relay_log_info* rli);
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2024,9 +2025,11 @@
+ const Format_description_log_event* description_event);
+
+ public:
+- uint get_query_buffer_length();
+- void print_query(bool need_db, const char *cs, char *buf, char **end,
+- char **fn_start, char **fn_end);
++#ifndef MYSQL_CLIENT
++ void print_query(THD *thd, bool need_db, const char *cs, String *buf,
++ my_off_t *fn_start, my_off_t *fn_end,
++ const char *qualify_db);
++#endif
+ ulong thread_id;
+ ulong slave_proxy_id;
+ uint32 table_name_len;
+@@ -2074,7 +2077,7 @@
+ Name_resolution_context *context);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2173,7 +2176,7 @@
+ #ifndef MYSQL_CLIENT
+ Start_log_event_v3();
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ Start_log_event_v3() {}
+@@ -2325,7 +2328,7 @@
+ :Log_event(thd_arg,0,0),val(val_arg),type(type_arg)
+ {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2401,7 +2404,7 @@
+ :Log_event(thd_arg,0,0),seed1(seed1_arg),seed2(seed2_arg)
+ {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2445,7 +2448,7 @@
+ #ifndef MYSQL_CLIENT
+ Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg,0,0), xid(x) {}
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2494,7 +2497,7 @@
+ :Log_event(), name(name_arg), name_len(name_len_arg), val(val_arg),
+ val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
+ { is_null= !val; }
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2625,7 +2628,7 @@
+ uint ident_len_arg,
+ ulonglong pos_arg, uint flags);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2685,7 +2688,7 @@
+ uchar* block_arg, uint block_len_arg,
+ bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2757,7 +2760,7 @@
+ Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
+ uint block_len_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ virtual int get_create_or_append() const;
+ #endif /* HAVE_REPLICATION */
+ #else
+@@ -2798,7 +2801,7 @@
+ #ifndef MYSQL_CLIENT
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2839,7 +2842,7 @@
+ #ifndef MYSQL_CLIENT
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2935,7 +2938,7 @@
+ bool using_trans, bool suppress_use,
+ int errcode);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3382,7 +3385,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3494,7 +3497,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3931,7 +3934,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+- void pack_info(Protocol*);
++ void pack_info(THD *thd, Protocol*);
+ #endif
+
+ Incident_log_event(const char *buf, uint event_len,
+
+=== modified file 'sql/log_event_old.cc'
+--- sql/log_event_old.cc 2011-11-24 16:48:58 +0000
++++ sql/log_event_old.cc 2012-08-24 10:32:46 +0000
+@@ -2008,7 +2008,7 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Old_rows_log_event::pack_info(Protocol *protocol)
++void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+
+=== modified file 'sql/log_event_old.h'
+--- sql/log_event_old.h 2011-02-20 16:51:43 +0000
++++ sql/log_event_old.h 2012-08-24 08:06:16 +0000
+@@ -108,7 +108,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+
+=== modified file 'sql/mysql_priv.h'
+--- sql/mysql_priv.h 2012-05-18 12:23:05 +0000
++++ sql/mysql_priv.h 2012-08-24 10:32:46 +0000
+@@ -1397,7 +1397,7 @@
+ /* sql_show.cc */
+ bool mysqld_show_open_tables(THD *thd,const char *wild);
+ bool mysqld_show_logs(THD *thd);
+-void append_identifier(THD *thd, String *packet, const char *name,
++bool append_identifier(THD *thd, String *packet, const char *name,
+ uint length);
+ #endif /* MYSQL_SERVER */
+ #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
+
+=== modified file 'sql/sql_base.cc'
+--- sql/sql_base.cc 2011-12-29 23:09:20 +0000
++++ sql/sql_base.cc 2012-08-24 10:32:46 +0000
+@@ -4195,22 +4195,22 @@
+ entry->file->implicit_emptied= 0;
+ if (mysql_bin_log.is_open())
+ {
+- char *query, *end;
+- uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
+- if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
++ char query_buf[2*FN_REFLEN + 21];
++ String query(query_buf, sizeof(query_buf), system_charset_info);
++ query.length(0);
++ if (query.ptr())
+ {
+ /* this DELETE FROM is needed even with row-based binlogging */
+- end = strxmov(strmov(query, "DELETE FROM `"),
+- share->db.str,"`.`",share->table_name.str,"`", NullS);
++ query.append("DELETE FROM ");
++ append_identifier(thd, &query, share->db.str, share->db.length);
++ query.append(".");
++ append_identifier(thd, &query, share->table_name.str,
++ share->table_name.length);
+ int errcode= query_error_code(thd, TRUE);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+- query, (ulong)(end-query),
++ query.ptr(), query.length(),
+ FALSE, FALSE, errcode))
+- {
+- my_free(query, MYF(0));
+ goto err;
+- }
+- my_free(query, MYF(0));
+ }
+ else
+ {
+@@ -4220,7 +4220,7 @@
+ because of MYF(MY_WME) in my_malloc() above).
+ */
+ sql_print_error("When opening HEAP table, could not allocate memory "
+- "to write 'DELETE FROM `%s`.`%s`' to the binary log",
++ "to write 'DELETE FROM %`s.%`s' to the binary log",
+ table_list->db, table_list->table_name);
+ delete entry->triggers;
+ closefrm(entry, 0);
+
+=== modified file 'sql/sql_db.cc'
+--- sql/sql_db.cc 2011-11-24 16:48:58 +0000
++++ sql/sql_db.cc 2012-08-24 10:32:46 +0000
+@@ -613,7 +613,6 @@
+ bool silent)
+ {
+ char path[FN_REFLEN+16];
+- char tmp_query[FN_REFLEN+16];
+ long result= 1;
+ int error= 0;
+ MY_STAT stat_info;
+@@ -720,17 +719,9 @@
+ char *query;
+ uint query_length;
+
+- if (!thd->query()) // Only in replication
+- {
+- query= tmp_query;
+- query_length= (uint) (strxmov(tmp_query,"create database `",
+- db, "`", NullS) - tmp_query);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
+
+ ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
+ query, query_length,
+@@ -990,18 +981,11 @@
+ {
+ const char *query;
+ ulong query_length;
+- if (!thd->query())
+- {
+- /* The client used the old obsolete mysql_drop_db() call */
+- query= path;
+- query_length= (uint) (strxmov(path, "drop database `", db, "`",
+- NullS) - path);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
++
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+@@ -1042,9 +1026,10 @@
+ for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
+ {
+ uint tbl_name_len;
++ char quoted_name[FN_REFLEN+3];
+
+- /* 3 for the quotes and the comma*/
+- tbl_name_len= strlen(tbl->table_name) + 3;
++ my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
++ tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
+ if (query_pos + tbl_name_len + 1 >= query_end)
+ {
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
+@@ -1056,9 +1041,7 @@
+ query_pos= query_data_start;
+ }
+
+- *query_pos++ = '`';
+- query_pos= strmov(query_pos,tbl->table_name);
+- *query_pos++ = '`';
++ query_pos= strmov(query_pos, quoted_name);
+ *query_pos++ = ',';
+ }
+
+
+=== modified file 'sql/sql_insert.cc'
+--- sql/sql_insert.cc 2012-02-03 08:28:23 +0000
++++ sql/sql_insert.cc 2012-08-24 10:32:46 +0000
+@@ -3480,16 +3480,16 @@
+ if (thd->lex->create_select_in_comment)
+ query.append(STRING_WITH_LEN("/*! "));
+ if (thd->lex->ignore)
+- query.append(STRING_WITH_LEN("INSERT IGNORE INTO `"));
++ query.append(STRING_WITH_LEN("INSERT IGNORE INTO "));
+ else if (thd->lex->duplicates == DUP_REPLACE)
+- query.append(STRING_WITH_LEN("REPLACE INTO `"));
++ query.append(STRING_WITH_LEN("REPLACE INTO "));
+ else
+- query.append(STRING_WITH_LEN("INSERT INTO `"));
++ query.append(STRING_WITH_LEN("INSERT INTO "));
+
+- query.append(create_table->db, db_len);
+- query.append(STRING_WITH_LEN("`.`"));
+- query.append(create_info->alias, table_len);
+- query.append(STRING_WITH_LEN("` "));
++ append_identifier(thd, &query, create_table->db, db_len);
++ query.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &query, create_info->alias, table_len);
++ query.append(STRING_WITH_LEN(" "));
+
+ /*
+ The insert items.
+
+=== modified file 'sql/sql_load.cc'
+--- sql/sql_load.cc 2012-04-05 10:01:52 +0000
++++ sql/sql_load.cc 2012-08-24 10:32:46 +0000
+@@ -24,6 +24,7 @@
+ #include "sql_repl.h"
+ #include "sp_head.h"
+ #include "sql_trigger.h"
++#include "sql_show.h"
+
+ class READ_INFO {
+ File file;
+@@ -606,24 +607,31 @@
+ bool transactional_table,
+ int errcode)
+ {
+- char *load_data_query,
+- *end,
+- *fname_start,
+- *fname_end,
+- *p= NULL;
+- size_t pl= 0;
++ char *load_data_query;
++ my_off_t fname_start,
++ fname_end;
+ List<Item> fv;
+ Item *item, *val;
+ int n;
+- const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
++ const char *qualify_db= NULL;
+ char name_buffer[SAFE_NAME_LEN*2];
+ char command_buffer[1024];
+ String string_buf(name_buffer, sizeof(name_buffer),
+ system_charset_info);
+- String pfields(command_buffer, sizeof(command_buffer),
++ String query_str(command_buffer, sizeof(command_buffer),
+ system_charset_info);
+
++ Load_log_event lle(thd, ex, tdb, table_name_arg, fv, duplicates,
++ ignore, transactional_table);
++
++ /*
++ force in a LOCAL if there was one in the original.
++ */
++ if (thd->lex->local_file)
++ lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++
++ query_str.length(0);
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+@@ -631,49 +639,31 @@
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+- string_buf.length(0);
+- string_buf.append(db_arg);
+- string_buf.append("`");
+- string_buf.append(".");
+- string_buf.append("`");
+- string_buf.append(table_name_arg);
+- tbl= string_buf.c_ptr_safe();
++ qualify_db= db_arg;
+ }
+-
+- Load_log_event lle(thd, ex, tdb, tbl, fv, duplicates,
+- ignore, transactional_table);
+-
+- /*
+- force in a LOCAL if there was one in the original.
+- */
+- if (thd->lex->local_file)
+- lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++ lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
++ &query_str, &fname_start, &fname_end, qualify_db);
+
+ /*
+ prepare fields-list and SET if needed; print_query won't do that for us.
+ */
+- pfields.length(0);
+ if (!thd->lex->field_list.is_empty())
+ {
+ List_iterator<Item> li(thd->lex->field_list);
+
+- pfields.append(" (");
++ query_str.append(" (");
+ n= 0;
+
+ while ((item= li++))
+ {
+ if (n++)
+- pfields.append(", ");
++ query_str.append(", ");
+ if (item->name)
+- {
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- }
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
+ else
+- item->print(&pfields, QT_ORDINARY);
++ ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str);
+ }
+- pfields.append(")");
++ query_str.append(")");
+ }
+
+ if (!thd->lex->update_list.is_empty())
+@@ -681,39 +671,26 @@
+ List_iterator<Item> lu(thd->lex->update_list);
+ List_iterator<Item> lv(thd->lex->value_list);
+
+- pfields.append(" SET ");
++ query_str.append(" SET ");
+ n= 0;
+
+ while ((item= lu++))
+ {
+ val= lv++;
+ if (n++)
+- pfields.append(", ");
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- pfields.append("=");
+- val->print(&pfields, QT_ORDINARY);
++ query_str.append(", ");
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
++ query_str.append("=");
++ val->print(&query_str, QT_ORDINARY);
+ }
+ }
+
+- p= pfields.c_ptr_safe();
+- pl= pfields.length();
+-
+- if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length())))
+ return TRUE;
+
+- lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+- load_data_query, &end,
+- (char **)&fname_start, (char **)&fname_end);
+-
+- strcpy(end, p);
+- end += pl;
+-
+ Execute_load_query_log_event
+- e(thd, load_data_query, end-load_data_query,
+- (uint) ((char*) fname_start - load_data_query - 1),
+- (uint) ((char*) fname_end - load_data_query),
++ e(thd, load_data_query, query_str.length(),
++ (uint) (fname_start - 1), (uint) fname_end,
+ (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
+ (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
+ transactional_table, FALSE, errcode);
+
+=== modified file 'sql/sql_repl.cc'
+--- sql/sql_repl.cc 2011-11-21 17:13:14 +0000
++++ sql/sql_repl.cc 2012-08-24 08:06:16 +0000
+@@ -1554,7 +1554,7 @@
+ description_event)); )
+ {
+ if (event_count >= limit_start &&
+- ev->net_send(protocol, linfo.log_file_name, pos))
++ ev->net_send(thd, protocol, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+
+=== modified file 'sql/sql_show.cc'
+--- sql/sql_show.cc 2012-05-18 12:23:05 +0000
++++ sql/sql_show.cc 2012-08-24 10:32:46 +0000
+@@ -1051,9 +1051,13 @@
+ packet target string
+ name the identifier to be appended
+ name_length length of the appending identifier
++
++ RETURN VALUES
++ true Error
++ false Ok
+ */
+
+-void
++bool
+ append_identifier(THD *thd, String *packet, const char *name, uint length)
+ {
+ const char *name_end;
+@@ -1061,10 +1065,7 @@
+ int q= get_quote_char_for_identifier(thd, name, length);
+
+ if (q == EOF)
+- {
+- packet->append(name, length, packet->charset());
+- return;
+- }
++ return packet->append(name, length, packet->charset());
+
+ /*
+ The identifier must be quoted as it includes a quote character or
+@@ -1073,7 +1074,8 @@
+
+ VOID(packet->reserve(length*2 + 2));
+ quote_char= (char) q;
+- packet->append("e_char, 1, system_charset_info);
++ if (packet->append("e_char, 1, system_charset_info))
++ return true;
+
+ for (name_end= name+length ; name < name_end ; name+= length)
+ {
+@@ -1088,11 +1090,13 @@
+ */
+ if (!length)
+ length= 1;
+- if (length == 1 && chr == (uchar) quote_char)
+- packet->append("e_char, 1, system_charset_info);
+- packet->append(name, length, system_charset_info);
++ if (length == 1 && chr == (uchar) quote_char &&
++ packet->append("e_char, 1, system_charset_info))
++ return true;
++ if (packet->append(name, length, system_charset_info))
++ return true;
+ }
+- packet->append("e_char, 1, system_charset_info);
++ return packet->append("e_char, 1, system_charset_info);
+ }
+
+
+
+=== modified file 'sql/sql_string.cc'
+--- sql/sql_string.cc 2012-04-05 10:01:52 +0000
++++ sql/sql_string.cc 2012-08-24 10:32:46 +0000
+@@ -1159,39 +1159,47 @@
+
+
+
+-
+-void String::print(String *str)
++/*
++ Append characters to a single-quoted string '...', escaping special
++ characters as necessary.
++ Does not add the enclosing quotes, this is left up to caller.
++*/
++void String::append_for_single_quote(const char *st, uint len)
+ {
+- char *st= (char*)Ptr, *end= st+str_length;
++ const char *end= st+len;
+ for (; st < end; st++)
+ {
+ uchar c= *st;
+ switch (c)
+ {
+ case '\\':
+- str->append(STRING_WITH_LEN("\\\\"));
++ append(STRING_WITH_LEN("\\\\"));
+ break;
+ case '\0':
+- str->append(STRING_WITH_LEN("\\0"));
++ append(STRING_WITH_LEN("\\0"));
+ break;
+ case '\'':
+- str->append(STRING_WITH_LEN("\\'"));
++ append(STRING_WITH_LEN("\\'"));
+ break;
+ case '\n':
+- str->append(STRING_WITH_LEN("\\n"));
++ append(STRING_WITH_LEN("\\n"));
+ break;
+ case '\r':
+- str->append(STRING_WITH_LEN("\\r"));
++ append(STRING_WITH_LEN("\\r"));
+ break;
+ case '\032': // Ctrl-Z
+- str->append(STRING_WITH_LEN("\\Z"));
++ append(STRING_WITH_LEN("\\Z"));
+ break;
+ default:
+- str->append(c);
++ append(c);
+ }
+ }
+ }
+
++void String::print(String *str)
++{
++ str->append_for_single_quote(Ptr, str_length);
++}
+
+ /*
+ Exchange state of this object and argument.
+
+=== modified file 'sql/sql_string.h'
+--- sql/sql_string.h 2011-11-24 16:48:58 +0000
++++ sql/sql_string.h 2012-08-24 10:32:46 +0000
+@@ -426,6 +426,7 @@
+ return FALSE;
+ }
+ void print(String *print);
++ void append_for_single_quote(const char *st, uint len);
+
+ /* Swap two string objects. Efficient way to exchange data without memcpy. */
+ void swap(String &s);
+
+=== modified file 'sql/sql_table.cc'
+--- sql/sql_table.cc 2012-04-05 10:01:52 +0000
++++ sql/sql_table.cc 2012-08-24 10:32:46 +0000
+@@ -1939,6 +1939,7 @@
+ for (table= tables; table; table= table->next_local)
+ {
+ char *db=table->db;
++ size_t db_length= table->db_length;
+ handlerton *table_type;
+ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+
+@@ -1961,14 +1962,14 @@
+ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
+ }
+
+- built_tmp_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_tmp_query.append(db);
+- built_tmp_query.append("`.`");
++ append_identifier(thd, &built_tmp_query, db, db_length);
++ built_tmp_query.append(".");
+ }
+- built_tmp_query.append(table->table_name);
+- built_tmp_query.append("`,");
++ append_identifier(thd, &built_tmp_query, table->table_name,
++ table->table_name_length);
++ built_tmp_query.append(",");
+ }
+
+ continue;
+@@ -1994,15 +1995,15 @@
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+- built_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_query.append(db);
+- built_query.append("`.`");
++ append_identifier(thd, &built_query, db, db_length);
++ built_query.append(".");
+ }
+
+- built_query.append(table->table_name);
+- built_query.append("`,");
++ append_identifier(thd, &built_query, table->table_name,
++ table->table_name_length);
++ built_query.append(",");
+ }
+
+ if (!drop_temporary)
+
+=== modified file 'strings/my_vsnprintf.c'
+--- strings/my_vsnprintf.c 2011-11-24 16:48:58 +0000
++++ strings/my_vsnprintf.c 2012-08-24 10:32:46 +0000
+@@ -636,3 +636,66 @@
+ return result;
+ }
+
++
++/**
++ Writes output to the stream according to a format string.
++
++ @param stream file to write to
++ @param format string format
++ @param args list of parameters
++
++ @retval
++ number of the characters written.
++*/
++
++int my_vfprintf(FILE *stream, const char* format, va_list args)
++{
++ char cvtbuf[1024];
++ int alloc= 0;
++ char *p= cvtbuf;
++ size_t cur_len= sizeof(cvtbuf);
++ int ret;
++
++ /*
++ We do not know how much buffer we need.
++ So start with a reasonably-sized stack-allocated buffer, and increase
++ it exponentially until it is big enough.
++ */
++ for (;;)
++ {
++ size_t new_len;
++ size_t actual= my_vsnprintf(p, cur_len, format, args);
++ if (actual < cur_len - 1)
++ break;
++ /*
++ Not enough space (or just enough with nothing to spare - but we cannot
++ distinguish this case from the return value). Allocate a bigger buffer
++ and try again.
++ */
++ if (alloc)
++ (*my_str_free)(p);
++ else
++ alloc= 1;
++ new_len= cur_len*2;
++ if (new_len < cur_len)
++ return 0; /* Overflow */
++ cur_len= new_len;
++ p= (*my_str_malloc)(cur_len);
++ if (!p)
++ return 0;
++ }
++ ret= fprintf(stream, "%s", p);
++ if (alloc)
++ (*my_str_free)(p);
++ return ret;
++}
++
++int my_fprintf(FILE *stream, const char* format, ...)
++{
++ int result;
++ va_list args;
++ va_start(args, format);
++ result= my_vfprintf(stream, format, args);
++ va_end(args);
++ return result;
++}
+
diff --git a/21000_sql-5.3.7.patch b/21000_sql-5.3.7.patch
new file mode 100644
index 0000000..feff133
--- /dev/null
+++ b/21000_sql-5.3.7.patch
@@ -0,0 +1,3258 @@
+=== modified file 'client/mysqlbinlog.cc'
+--- client/mysqlbinlog.cc 2011-12-11 09:34:44 +0000
++++ client/mysqlbinlog.cc 2012-08-24 12:02:32 +0000
+@@ -731,7 +731,7 @@
+ return;
+
+ // In case of rewrite rule print USE statement for db_to
+- fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter);
++ my_fprintf(result_file, "use %`s%s\n", db_to, pinfo->delimiter);
+
+ // Copy the *original* db to pinfo to suppress emiting
+ // of USE stmts by log_event print-functions.
+
+=== modified file 'include/my_sys.h'
+--- include/my_sys.h 2011-12-11 09:34:44 +0000
++++ include/my_sys.h 2012-08-24 12:02:32 +0000
+@@ -686,6 +686,7 @@
+ extern FILE *my_fdopen(File Filedes,const char *name, int Flags,myf MyFlags);
+ extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
+ extern int my_fclose(FILE *fd,myf MyFlags);
++extern int my_fprintf(FILE *stream, const char* format, ...);
+ extern File my_fileno(FILE *fd);
+ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
+ extern int my_chmod(const char *name, mode_t mode, myf my_flags);
+@@ -822,6 +823,8 @@
+ extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+ extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
+ extern my_off_t my_b_filelength(IO_CACHE *info);
++extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
++ size_t len);
+ extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
+ extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
+ extern int init_strvar_from_file(char *var, int max_size, IO_CACHE *f,
+
+=== modified file 'mysql-test/r/func_compress.result'
+--- mysql-test/r/func_compress.result 2011-11-21 16:00:55 +0000
++++ mysql-test/r/func_compress.result 2012-08-24 12:02:32 +0000
+@@ -11,7 +11,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select uncompress(compress((@test_compress_string))) AS `uncompress(compress(@test_compress_string))`
++Note 1003 select uncompress(compress((@`test_compress_string`))) AS `uncompress(compress(@test_compress_string))`
+ select uncompressed_length(compress(@test_compress_string))=length(@test_compress_string);
+ uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)
+ 1
+@@ -19,7 +19,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (uncompressed_length(compress((@test_compress_string))) = length((@test_compress_string))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
++Note 1003 select (uncompressed_length(compress((@`test_compress_string`))) = length((@`test_compress_string`))) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
+ select uncompressed_length(compress(@test_compress_string));
+ uncompressed_length(compress(@test_compress_string))
+ 117
+
+=== modified file 'mysql-test/r/func_time_hires.result'
+--- mysql-test/r/func_time_hires.result 2011-06-07 16:13:02 +0000
++++ mysql-test/r/func_time_hires.result 2012-08-24 12:02:32 +0000
+@@ -156,12 +156,12 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select cast(cast((@a) as datetime(4)) as time) AS `cast(cast(@a as datetime(4)) as time(0))`
++Note 1003 select cast(cast((@`a`) as datetime(4)) as time) AS `cast(cast(@a as datetime(4)) as time(0))`
+ select cast(cast(@a as time(2)) as time(6));
+ cast(cast(@a as time(2)) as time(6))
+ 12:13:14.120000
+ select CAST(@a AS DATETIME(7));
+-ERROR 42000: Too big precision 7 specified for '(@a)'. Maximum is 6.
++ERROR 42000: Too big precision 7 specified for '(@`a`)'. Maximum is 6.
+ SELECT CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00');
+ CONVERT_TZ('2011-01-02 12:00:00', '+00:00', '+03:00')
+ 2011-01-02 15:00:00
+
+=== modified file 'mysql-test/r/mysqlbinlog-innodb.result'
+--- mysql-test/r/mysqlbinlog-innodb.result 2011-01-13 12:28:36 +0000
++++ mysql-test/r/mysqlbinlog-innodb.result 2012-08-24 10:32:46 +0000
+@@ -34,7 +34,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+@@ -65,7 +65,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use foo/*!*/;
++use `foo`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog.result'
+--- mysql-test/r/mysqlbinlog.result 2011-05-10 15:17:43 +0000
++++ mysql-test/r/mysqlbinlog.result 2012-08-24 12:02:32 +0000
+@@ -20,7 +20,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -66,7 +66,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -99,7 +99,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -121,7 +121,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -167,7 +167,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -200,7 +200,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -229,7 +229,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844555/*!*/;
+ insert t1 values (1)
+ /*!*/;
+@@ -248,7 +248,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844555/*!*/;
+ insert t1 values (1)
+ /*!*/;
+@@ -302,7 +302,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -352,7 +352,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -487,7 +487,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1253783037/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -587,7 +587,7 @@
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog2.result'
+--- mysql-test/r/mysqlbinlog2.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/mysqlbinlog2.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -62,7 +62,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -101,7 +101,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -127,7 +127,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -162,7 +162,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -185,7 +185,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -215,7 +215,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -246,7 +246,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -281,7 +281,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -304,7 +304,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -335,7 +335,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -358,7 +358,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -377,7 +377,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -399,7 +399,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -445,7 +445,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -468,7 +468,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -490,7 +490,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -520,7 +520,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -563,7 +563,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -601,7 +601,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -627,7 +627,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -661,7 +661,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -684,7 +684,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -714,7 +714,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -744,7 +744,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -779,7 +779,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -802,7 +802,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -833,7 +833,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -855,7 +855,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ SET INSERT_ID=4/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609946/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -874,7 +874,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -896,7 +896,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -942,7 +942,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -965,7 +965,7 @@
+ DELIMITER ;
+ DELIMITER /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -987,7 +987,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1017,7 +1017,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row.result'
+--- mysql-test/r/mysqlbinlog_row.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row.result 2012-08-24 08:06:16 +0000
+@@ -336,7 +336,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_innodb.result'
+--- mysql-test/r/mysqlbinlog_row_innodb.result 2010-03-22 12:10:18 +0000
++++ mysql-test/r/mysqlbinlog_row_innodb.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3876,7 +3876,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4243,7 +4243,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4804,7 +4804,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_myisam.result'
+--- mysql-test/r/mysqlbinlog_row_myisam.result 2008-09-06 04:49:43 +0000
++++ mysql-test/r/mysqlbinlog_row_myisam.result 2012-08-24 08:06:16 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3898,7 +3898,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4271,7 +4271,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4842,7 +4842,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_trans.result'
+--- mysql-test/r/mysqlbinlog_row_trans.result 2009-08-27 09:32:27 +0000
++++ mysql-test/r/mysqlbinlog_row_trans.result 2012-08-24 08:06:16 +0000
+@@ -132,7 +132,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/user_var-binlog.result'
+--- mysql-test/r/user_var-binlog.result 2008-04-02 09:49:22 +0000
++++ mysql-test/r/user_var-binlog.result 2012-08-24 08:06:16 +0000
+@@ -19,7 +19,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/variables.result'
+--- mysql-test/r/variables.result 2011-12-11 09:34:44 +0000
++++ mysql-test/r/variables.result 2012-08-24 12:02:32 +0000
+@@ -78,7 +78,7 @@
+ id select_type table type possible_keys key key_len ref rows filtered Extra
+ 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+ Warnings:
+-Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@t1) AS `@t1`,(@t2) AS `@t2`,(@t3) AS `@t3`
++Note 1003 select (@t1:=((@t2:=1) + (@t3:=4))) AS `@t1:=(@t2:=1)+@t3:=4`,(@`t1`) AS `@t1`,(@`t2`) AS `@t2`,(@`t3`) AS `@t3`
+ select @t5;
+ @t5
+ 1.23456
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
+--- mysql-test/suite/binlog/r/binlog_base64_flag.result 2011-02-23 09:31:37 +0000
++++ mysql-test/suite/binlog/r/binlog_base64_flag.result 2012-08-24 08:06:16 +0000
+@@ -35,7 +35,7 @@
+ # at 4
+ <#>ROLLBACK/*!*/;
+ # at 102
+-<#>use test/*!*/;
++<#>use `test`/*!*/;
+ SET TIMESTAMP=1196959712/*!*/;
+ <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+ SET @@session.sql_mode=0/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result'
+--- mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2011-01-13 12:28:36 +0000
++++ mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2012-08-24 10:32:46 +0000
+@@ -35,7 +35,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -72,7 +72,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -115,7 +115,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+@@ -229,7 +229,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -266,7 +266,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -309,7 +309,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result'
+--- mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2008-10-23 19:27:09 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2012-08-24 08:06:16 +0000
+@@ -13,7 +13,7 @@
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result'
+--- mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2010-09-02 13:05:06 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2012-08-24 08:06:16 +0000
+@@ -631,7 +631,7 @@
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ /* the output must denote there is the query */;
+ drop trigger trg_del_t2;
+@@ -869,7 +869,7 @@
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`=((@b) + `bug27417`(2)) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=((@`b`) + `bug27417`(2)) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ drop trigger trg_del_t2;
+ drop table t1,t2,t3,t4,t5;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_hrtime.result'
+--- mysql-test/suite/rpl/r/rpl_hrtime.result 2011-05-28 02:11:32 +0000
++++ mysql-test/suite/rpl/r/rpl_hrtime.result 2012-08-24 12:02:32 +0000
+@@ -30,7 +30,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1293832861/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== added file 'mysql-test/suite/rpl/r/rpl_mdev382.result'
+--- mysql-test/suite/rpl/r/rpl_mdev382.result 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/r/rpl_mdev382.result 2012-08-24 10:32:46 +0000
+@@ -0,0 +1,302 @@
++include/master-slave.inc
++[connection master]
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
++insert into t1 values (3);
++commit;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `test`; create table t1 (a int primary key) engine=innodb
++master-bin.000001 # Query # # use `test`; create table t2 (a int primary key) engine=myisam
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values (1)
++master-bin.000001 # Query # # SAVEPOINT "a`; create database couldbebadthingshere; savepoint `dummy"
++master-bin.000001 # Query # # use `test`; insert into t1 values (2)
++master-bin.000001 # Query # # use `test`; insert into t2 values (1)
++master-bin.000001 # Query # # ROLLBACK TO `a``; create database couldbebadthingshere; savepoint ``dummy`
++master-bin.000001 # Query # # use `test`; insert into t1 values (3)
++master-bin.000001 # Xid # # COMMIT /* XID */
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values(10)
++master-bin.000001 # Query # # SAVEPOINT "a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(11)
++master-bin.000001 # Query # # SAVEPOINT "a""a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(12)
++master-bin.000001 # Query # # SAVEPOINT b
++master-bin.000001 # Query # # use `test`; insert into t1 values(13)
++master-bin.000001 # Query # # SAVEPOINT "b""b"
++master-bin.000001 # Query # # use `test`; insert into t1 values(14)
++master-bin.000001 # Query # # SAVEPOINT `c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(15)
++master-bin.000001 # Query # # SAVEPOINT `c``c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(16)
++master-bin.000001 # Query # # SAVEPOINT d
++master-bin.000001 # Query # # use `test`; insert into t1 values(17)
++master-bin.000001 # Query # # SAVEPOINT `d``d`
++master-bin.000001 # Query # # use `test`; insert into t1 values(18)
++master-bin.000001 # Xid # # COMMIT /* XID */
++*** Test correct USE statement in SHOW BINLOG EVENTS ***
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (2)
++set sql_mode = '';
++set sql_quote_show_create = 0;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++DROP TABLE t1;
++use test;
++***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++use `db1``; SELECT 'oops!'`;
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++truncate `t``1`;
++use test;
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `db1``; SELECT 'oops!'`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!') ;file_id=#
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; truncate `t``1`
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!') ;file_id=#
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`=(@`b```), `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++truncate `t``1`
++/*!*/;
++use `test`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`=concat('|','b"a\'z','!')
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++drop table t1,t2;
++*** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE t1
++FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE `t1` FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`=concat((@`b`),'| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|',(@`b`)) ;file_id=#
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++DROP TABLE t1;
++*** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++@`a``1`:=a1 @`a``2`:=a2 @`a``3`:=a3 @`a``4`:=a4 @`b```:=b @```c`:=c @```d```:=d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++master-bin.000001 # User var # # @`a``1`=-9223372036854775808
++master-bin.000001 # User var # # @`a``2`=42
++master-bin.000001 # User var # # @`a``3`=9223372036854775807
++master-bin.000001 # User var # # @`a``4`=-1
++master-bin.000001 # User var # # @`b```=-1.2345601234568e+125
++master-bin.000001 # User var # # @```c`=-1234501234567890123456789012345678901234567890123456789.0123456789
++master-bin.000001 # User var # # @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++/*!*/;
++SET @`a``1`:=-9223372036854775808/*!*/;
++SET @`a``2`:=42/*!*/;
++SET @`a``3`:=9223372036854775807/*!*/;
++SET @`a``4`:=-1/*!*/;
++SET @`b```:=-1.2345601234568e+125/*!*/;
++SET @```c`:=-1234501234567890123456789012345678901234567890123456789.0123456789/*!*/;
++SET @```d```:=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE `latin1_swedish_ci`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++a1 a2 a3 a4 b c d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.23456012345679e+125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++-9223372036854775807 4200 9223372036854775806 0 -6.17280061728394e+124 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++DROP TABLE t1;
++*** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++include/stop_slave.inc
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++a`
++1
++2
++5
++set timestamp=1000000000;
++# The table should be empty on the master.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++# The DELETE statement should be correctly quoted
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # use `test`; DELETE FROM `db1``; SELECT 'oops!'`.`t``1`
++include/start_slave.inc
++# The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++*** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++INSERT INTO t1 VALUES(1);
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES(1)
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `ts``et`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++INSERT INTO t1 VALUES(1)
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++DROP TABLE t1;
++include/rpl_end.inc
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
+--- mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2012-08-24 08:06:16 +0000
+@@ -153,7 +153,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -175,7 +175,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -284,7 +284,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -316,7 +316,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
+--- mysql-test/suite/rpl/r/rpl_sp.result 2010-12-19 17:07:28 +0000
++++ mysql-test/suite/rpl/r/rpl_sp.result 2012-08-24 08:06:16 +0000
+@@ -627,7 +627,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest1
+ /*!*/;
+-use mysqltest1/*!*/;
++use `mysqltest1`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t1 (a varchar(100))
+ /*!*/;
+@@ -840,7 +840,7 @@
+ SET TIMESTAMP=t/*!*/;
+ drop user "zedjzlcsjhd"@127.0.0.1
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ drop function if exists f1
+ /*!*/;
+@@ -925,7 +925,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest2
+ /*!*/;
+-use mysqltest2/*!*/;
++use `mysqltest2`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t ( t integer )
+ /*!*/;
+@@ -943,7 +943,7 @@
+ return 0;
+ end
+ /*!*/;
+-use mysqltest/*!*/;
++use `mysqltest`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ SELECT `mysqltest2`.`f1`()
+ /*!*/;
+@@ -953,14 +953,14 @@
+ SET TIMESTAMP=t/*!*/;
+ drop database mysqltest2
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltestbug36570_p1`()
+ begin
+ select 1;
+ end
+ /*!*/;
+-use mysql/*!*/;
++use `mysql`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.` mysqltestbug36570_p2`( a int)
+ `label`:
+
+=== added file 'mysql-test/suite/rpl/t/rpl_mdev382.test'
+--- mysql-test/suite/rpl/t/rpl_mdev382.test 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/t/rpl_mdev382.test 2012-08-24 10:32:46 +0000
+@@ -0,0 +1,257 @@
++--source include/have_innodb.inc
++--source include/not_windows.inc
++--source include/have_binlog_format_statement.inc
++--source include/master-slave.inc
++
++# MDEV-382: multiple SQL injections in replication code.
++
++# Test previous SQL injection attack against binlog for SAVEPOINT statement.
++# The test would cause syntax error on slave due to improper quoting of
++# the savepoint name.
++connection master;
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (3);
++commit;
++
++--source include/show_binlog_events.inc
++
++# This failed due to syntax error in query when the bug was not fixed.
++sync_slave_with_master;
++connection slave;
++
++# Test some more combinations of ANSI_QUOTES and sql_quote_show_create
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++
++--source include/show_binlog_events.inc
++
++--echo *** Test correct USE statement in SHOW BINLOG EVENTS ***
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++--source include/show_binlog_events.inc
++set sql_mode = '';
++set sql_quote_show_create = 0;
++--source include/show_binlog_events.inc
++set sql_quote_show_create = 1;
++--source include/show_binlog_events.inc
++DROP TABLE t1;
++
++use test;
++
++--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++
++--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt
++--write_file $load_file
++'fo\\o','bar'
++EOF
++--exec chmod go+r "$load_file"
++
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++ `c``3` VARCHAR(7));
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++
++SELECT * FROM `t``1`;
++# Also test when code prefixes table name with database.
++truncate `t``1`;
++use test;
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++let $MYSQLD_DATADIR= `select @@datadir`;
++--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '<name>' INTO/
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++connection master;
++
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++--remove_file $load_file
++
++connection master;
++drop table t1,t2;
++
++
++--echo *** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++--let $load_file= $MYSQLTEST_VARDIR/tmp/file.txt
++--write_file $load_file
++1,X
++2,A
++EOF
++--exec chmod go+r "$load_file"
++
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++# The bug was that the SET expression was truncated to 256 bytes, so test with
++# an expression longer than that.
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$load_file' INTO TABLE t1
++ FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++
++SELECT * FROM t1 ORDER BY a;
++--source include/show_binlog_events.inc
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM t1 ORDER BY a;
++
++connection master;
++--remove_file $load_file
++DROP TABLE t1;
++
++
++--echo *** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++
++connection master;
++DROP TABLE t1;
++
++
++--echo *** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++
++# Let's keep the slave stopped during master restart, to avoid any potential
++# races between slave reconnect and master restart.
++connection slave;
++--source include/stop_slave.inc
++
++connection master;
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++
++# Restart the master mysqld.
++# This will cause an implicit truncation of the memory-based table, which will
++# cause logging of an explicit DELETE FROM to binlog.
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++wait-rpl_mdev382.test
++EOF
++
++--shutdown_server 30
++
++--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++restart-rpl_mdev382.test
++EOF
++
++connection default;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++# rpl_end.inc needs to use the connection server_1
++connection server_1;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++connection master;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++set timestamp=1000000000;
++
++--echo # The table should be empty on the master.
++let $binlog_file= master-bin.000002;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++--echo # The DELETE statement should be correctly quoted
++--source include/show_binlog_events.inc
++
++connection slave;
++--source include/start_slave.inc
++
++connection master;
++sync_slave_with_master;
++connection slave;
++--echo # The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++connection master;
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++sync_slave_with_master;
++
++
++connection master;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++
++--echo *** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++INSERT INTO t1 VALUES(1);
++--source include/show_binlog_events.inc
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 --rewrite-db='test->ts`et' $MYSQLD_DATADIR/master-bin.000002
++DROP TABLE t1;
++
++--source include/rpl_end.inc
+
+=== modified file 'mysys/mf_iocache2.c'
+--- mysys/mf_iocache2.c 2011-11-21 17:13:14 +0000
++++ mysys/mf_iocache2.c 2012-08-24 10:32:46 +0000
+@@ -284,6 +284,40 @@
+ }
+
+
++size_t
++my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
++{
++ const uchar *start;
++ const uchar *p= (const uchar *)str;
++ const uchar *end= p + len;
++ size_t count;
++ size_t total= 0;
++
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ for (;;)
++ {
++ start= p;
++ while (p < end && *p != '`')
++ ++p;
++ count= p - start;
++ if (count && my_b_write(info, start, count))
++ return (size_t)-1;
++ total+= count;
++ if (p >= end)
++ break;
++ if (my_b_write(info, (uchar *)"``", 2))
++ return (size_t)-1;
++ total+= 2;
++ ++p;
++ }
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ return total;
++}
++
+ /*
+ Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
+ Used for logging in MySQL
+@@ -308,6 +342,7 @@
+ uint minimum_width_sign;
+ uint precision; /* as yet unimplemented for anything but %b */
+ my_bool is_zero_padded;
++ my_bool backtick_quoting;
+
+ /*
+ Store the location of the beginning of a format directive, for the
+@@ -342,6 +377,7 @@
+ fmt++;
+
+ is_zero_padded= FALSE;
++ backtick_quoting= FALSE;
+ minimum_width_sign= 1;
+ minimum_width= 0;
+ precision= 0;
+@@ -354,6 +390,8 @@
+ minimum_width_sign= -1; fmt++; goto process_flags;
+ case '0':
+ is_zero_padded= TRUE; fmt++; goto process_flags;
++ case '`':
++ backtick_quoting= TRUE; fmt++; goto process_flags;
+ case '#':
+ /** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
+ case ' ':
+@@ -397,9 +435,19 @@
+ reg2 char *par = va_arg(args, char *);
+ size_t length2 = strlen(par);
+ /* TODO: implement precision */
+- out_length+= length2;
+- if (my_b_write(info, (uchar*) par, length2))
+- goto err;
++ if (backtick_quoting)
++ {
++ size_t total= my_b_write_backtick_quote(info, par, length2);
++ if (total == (size_t)-1)
++ goto err;
++ out_length+= total;
++ }
++ else
++ {
++ out_length+= length2;
++ if (my_b_write(info, (uchar*) par, length2))
++ goto err;
++ }
+ }
+ else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
+ {
+
+=== modified file 'sql/ha_ndbcluster_binlog.cc'
+--- sql/ha_ndbcluster_binlog.cc 2011-12-11 09:34:44 +0000
++++ sql/ha_ndbcluster_binlog.cc 2012-08-24 12:02:32 +0000
+@@ -1268,7 +1268,9 @@
+ DBUG_RETURN(0);
+ }
+
+- char tmp_buf2[FN_REFLEN];
++ char tmp_buf2_mem[FN_REFLEN];
++ String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info);
++ tmp_buf2.length(0);
+ const char *type_str;
+ switch (type)
+ {
+@@ -1277,17 +1279,24 @@
+ if (thd->lex->sql_command == SQLCOM_DROP_DB)
+ DBUG_RETURN(0);
+ /* redo the drop table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "drop table `",
+- table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("drop table "));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "drop table";
+ break;
+ case SOT_RENAME_TABLE:
+ /* redo the rename table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "rename table `",
+- db, ".", table_name, "` to `",
+- new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("rename table "));
++ append_identifier(thd, &tmp_buf2, db, strlen(db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ tmp_buf2.append(STRING_WITH_LEN(" to "));
++ append_identifier(thd, &tmp_buf2, new_db, strlen(new_db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "rename table";
+ break;
+ case SOT_CREATE_TABLE:
+
+=== modified file 'sql/item.cc'
+--- sql/item.cc 2012-06-08 17:15:01 +0000
++++ sql/item.cc 2012-08-24 12:02:32 +0000
+@@ -942,15 +942,31 @@
+ if (!my_charset_same(cs, system_charset_info))
+ {
+ size_t res_length;
+- name= sql_strmake_with_convert(str, name_length= length, cs,
++ name= sql_strmake_with_convert(str, length, cs,
+ MAX_ALIAS_NAME, system_charset_info,
+ &res_length);
++ name_length= res_length;
+ }
+ else
+ name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
+ }
+
+
++void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
++{
++ if (!my_charset_same(cs, system_charset_info))
++ {
++ size_t res_length;
++ name= sql_strmake_with_convert(str, length, cs,
++ UINT_MAX, system_charset_info,
++ &res_length);
++ name_length= res_length;
++ }
++ else
++ name= sql_strmake(str, (name_length= length));
++}
++
++
+ void Item::set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs)
+ {
+
+=== modified file 'sql/item.h'
+--- sql/item.h 2012-05-20 12:57:29 +0000
++++ sql/item.h 2012-08-24 12:02:32 +0000
+@@ -620,6 +620,7 @@
+ #endif
+ } /*lint -e1509 */
+ void set_name(const char *str, uint length, CHARSET_INFO *cs);
++ void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs);
+ void set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs);
+ void rename(char *new_name);
+
+=== modified file 'sql/item_func.cc'
+--- sql/item_func.cc 2012-06-18 18:38:11 +0000
++++ sql/item_func.cc 2012-08-24 12:02:32 +0000
+@@ -4913,7 +4913,7 @@
+ void Item_func_get_user_var::print(String *str, enum_query_type query_type)
+ {
+ str->append(STRING_WITH_LEN("(@"));
+- str->append(name.str,name.length);
++ append_identifier(current_thd, str, name.str, name.length);
+ str->append(')');
+ }
+
+@@ -5011,10 +5011,10 @@
+ }
+
+
+-void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
++void Item_user_var_as_out_param::print_for_load(THD *thd, String *str)
+ {
+ str->append('@');
+- str->append(name.str,name.length);
++ append_identifier(thd, str, name.str, name.length);
+ }
+
+
+
+=== modified file 'sql/item_func.h'
+--- sql/item_func.h 2011-12-19 20:55:32 +0000
++++ sql/item_func.h 2012-08-24 12:02:32 +0000
+@@ -1582,7 +1582,7 @@
+ my_decimal *val_decimal(my_decimal *decimal_buffer);
+ /* fix_fields() binds variable name with its entry structure */
+ bool fix_fields(THD *thd, Item **ref);
+- virtual void print(String *str, enum_query_type query_type);
++ void print_for_load(THD *thd, String *str);
+ void set_null_value(CHARSET_INFO* cs);
+ void set_value(const char *str, uint length, CHARSET_INFO* cs);
+ };
+
+=== modified file 'sql/log.cc'
+--- sql/log.cc 2012-05-20 12:57:29 +0000
++++ sql/log.cc 2012-08-24 12:02:32 +0000
+@@ -39,6 +39,7 @@
+
+ #include <mysql/plugin.h>
+ #include "debug_sync.h"
++#include "sql_show.h"
+
+ /* max size of the log message */
+ #define MAX_LOG_BUFFER_SIZE 1024
+@@ -1794,9 +1795,8 @@
+
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+@@ -1818,9 +1818,8 @@
+ {
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+
+=== modified file 'sql/log_event.cc'
+--- sql/log_event.cc 2012-06-01 12:56:47 +0000
++++ sql/log_event.cc 2012-08-24 12:02:32 +0000
+@@ -34,6 +34,7 @@
+ #include "rpl_utility.h"
+ #include "rpl_record.h"
+ #include <my_dir.h>
++#include "sql_show.h"
+
+ #endif /* MYSQL_CLIENT */
+
+@@ -457,29 +458,28 @@
+ pretty_print_str()
+ */
+
+-static char *pretty_print_str(char *packet, const char *str, int len)
++static void
++pretty_print_str(String *packet, const char *str, int len)
+ {
+ const char *end= str + len;
+- char *pos= packet;
+- *pos++= '\'';
++ packet->append(STRING_WITH_LEN("'"));
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+- case '\n': *pos++= '\\'; *pos++= 'n'; break;
+- case '\r': *pos++= '\\'; *pos++= 'r'; break;
+- case '\\': *pos++= '\\'; *pos++= '\\'; break;
+- case '\b': *pos++= '\\'; *pos++= 'b'; break;
+- case '\t': *pos++= '\\'; *pos++= 't'; break;
+- case '\'': *pos++= '\\'; *pos++= '\''; break;
+- case 0 : *pos++= '\\'; *pos++= '0'; break;
++ case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
++ case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
++ case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
++ case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
++ case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
++ case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
++ case 0 : packet->append(STRING_WITH_LEN("\\0")); break;
+ default:
+- *pos++= c;
++ packet->append(&c, 1);
+ break;
+ }
+ }
+- *pos++= '\'';
+- return pos;
++ packet->append(STRING_WITH_LEN("'"));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -904,7 +904,7 @@
+ Log_event::pack_info()
+ */
+
+-void Log_event::pack_info(Protocol *protocol)
++void Log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ protocol->store("", &my_charset_bin);
+ }
+@@ -913,7 +913,8 @@
+ /**
+ Only called by SHOW BINLOG EVENTS
+ */
+-int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
++int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos)
+ {
+ const char *p= strrchr(log_name, FN_LIBCHAR);
+ const char *event_type;
+@@ -927,7 +928,7 @@
+ protocol->store(event_type, strlen(event_type), &my_charset_bin);
+ protocol->store((uint32) server_id);
+ protocol->store((ulonglong) log_pos);
+- pack_info(protocol);
++ pack_info(thd, protocol);
+ return protocol->write();
+ }
+ #endif /* HAVE_REPLICATION */
+@@ -2428,27 +2429,22 @@
+ show the catalog ??
+ */
+
+-void Query_log_event::pack_info(Protocol *protocol)
++void Query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ // TODO: show the catalog ??
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len);
+ if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
+ && db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf.append(STRING_WITH_LEN("use "));
++ append_identifier(thd, &buf, db, db_len);
++ buf.append("; ");
+ }
+ if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ buf.append(query, q_len);
++ protocol->store(&buf);
+ }
+ #endif
+
+@@ -3233,11 +3229,17 @@
+ }
+ else if (db)
+ {
++ /* Room for expand ` to `` + initial/final ` + \0 */
++ char buf[FN_REFLEN*2+3];
++
+ different_db= memcmp(print_event_info->db, db, db_len + 1);
+ if (different_db)
+ memcpy(print_event_info->db, db, db_len + 1);
+ if (db[0] && different_db)
+- my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
++ {
++ my_snprintf(buf, sizeof(buf), "%`s", db);
++ my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
++ }
+ }
+
+ end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
+@@ -3859,7 +3861,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Start_log_event_v3::pack_info(Protocol *protocol)
++void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
+ pos= strmov(buf, "Server ver: ");
+@@ -4635,131 +4637,115 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-uint Load_log_event::get_query_buffer_length()
+-{
+- return
+- 5 + db_len + 3 + // "use DB; "
+- 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+- 11 + // "CONCURRENT "
+- 7 + // LOCAL
+- 9 + // " REPLACE or IGNORE "
+- 13 + table_name_len*2 + // "INTO TABLE `table`"
+- 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
+- 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
+- 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
+- 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
+- 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
+- 15 + 22 + // " IGNORE xxx LINES"
+- 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
+-}
+-
+-
+-void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
+- char **end, char **fn_start, char **fn_end)
+-{
+- char *pos= buf;
+-
++void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
++ String *buf, my_off_t *fn_start,
++ my_off_t *fn_end, const char *qualify_db)
++{
+ if (need_db && db && db_len)
+ {
+- pos= strmov(pos, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf->append(STRING_WITH_LEN("use "));
++ append_identifier(thd, buf, db, db_len);
++ buf->append(STRING_WITH_LEN("; "));
+ }
+
+- pos= strmov(pos, "LOAD DATA ");
++ buf->append(STRING_WITH_LEN("LOAD DATA "));
+
+ if (thd->lex->lock_option == TL_WRITE_CONCURRENT_INSERT)
+- pos= strmov(pos, "CONCURRENT ");
++ buf->append(STRING_WITH_LEN("CONCURRENT "));
+
+ if (fn_start)
+- *fn_start= pos;
++ *fn_start= buf->length();
+
+ if (check_fname_outside_temp_buf())
+- pos= strmov(pos, "LOCAL ");
+- pos= strmov(pos, "INFILE '");
+- memcpy(pos, fname, fname_len);
+- pos= strmov(pos+fname_len, "' ");
++ buf->append(STRING_WITH_LEN("LOCAL "));
++ buf->append(STRING_WITH_LEN("INFILE '"));
++ buf->append_for_single_quote(fname, fname_len);
++ buf->append(STRING_WITH_LEN("' "));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+- pos= strmov(pos, "REPLACE ");
++ buf->append(STRING_WITH_LEN("REPLACE "));
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+- pos= strmov(pos, "IGNORE ");
++ buf->append(STRING_WITH_LEN("IGNORE "));
+
+- pos= strmov(pos ,"INTO");
++ buf->append(STRING_WITH_LEN("INTO"));
+
+ if (fn_end)
+- *fn_end= pos;
++ *fn_end= buf->length();
+
+- pos= strmov(pos ," TABLE `");
+- memcpy(pos, table_name, table_name_len);
+- pos+= table_name_len;
++ buf->append(STRING_WITH_LEN(" TABLE "));
++ if (qualify_db)
++ {
++ append_identifier(thd, buf, qualify_db, strlen(qualify_db));
++ buf->append(STRING_WITH_LEN("."));
++ }
++ append_identifier(thd, buf, table_name, table_name_len);
+
+ if (cs != NULL)
+ {
+- pos= strmov(pos ,"` CHARACTER SET ");
+- pos= strmov(pos , cs);
++ buf->append(STRING_WITH_LEN(" CHARACTER SET "));
++ buf->append(cs, strlen(cs));
+ }
+- else
+- pos= strmov(pos, "`");
+
+ /* We have to create all optional fields as the default is not empty */
+- pos= strmov(pos, " FIELDS TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
++ buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+- pos= strmov(pos, " OPTIONALLY ");
+- pos= strmov(pos, " ENCLOSED BY ");
+- pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
+-
+- pos= strmov(pos, " ESCAPED BY ");
+- pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+-
+- pos= strmov(pos, " LINES TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
++ buf->append(STRING_WITH_LEN(" OPTIONALLY "));
++ buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
++ pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
++
++ buf->append(STRING_WITH_LEN(" ESCAPED BY "));
++ pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
++
++ buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
+ if (sql_ex.line_start_len)
+ {
+- pos= strmov(pos, " STARTING BY ");
+- pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
++ buf->append(STRING_WITH_LEN(" STARTING BY "));
++ pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((long) skip_lines > 0)
+ {
+- pos= strmov(pos, " IGNORE ");
+- pos= longlong10_to_str((longlong) skip_lines, pos, 10);
+- pos= strmov(pos," LINES ");
++ char skipbuf[22];
++ buf->append(STRING_WITH_LEN(" IGNORE "));
++ longlong10_to_str((longlong) skip_lines, skipbuf, 10);
++ buf->append(skipbuf);
++ buf->append(STRING_WITH_LEN(" LINES "));
+ }
+
+ if (num_fields)
+ {
+ uint i;
+ const char *field= fields;
+- pos= strmov(pos, " (");
++ buf->append(STRING_WITH_LEN(" ("));
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ {
+- *pos++= ' ';
+- *pos++= ',';
++ /*
++ Yes, the space and comma is reversed here. But this is mostly dead
++ code, at most used when reading really old binlogs from old servers,
++ so better just leave it as is...
++ */
++ buf->append(STRING_WITH_LEN(" ,"));
+ }
+- memcpy(pos, field, field_lens[i]);
+- pos+= field_lens[i];
++ append_identifier(thd, buf, field, field_lens[i]);
+ field+= field_lens[i] + 1;
+ }
+- *pos++= ')';
++ buf->append(STRING_WITH_LEN(")"));
+ }
+-
+- *end= pos;
+ }
+
+
+-void Load_log_event::pack_info(Protocol *protocol)
++void Load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *end;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+
+- if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
+- return;
+- print_query(TRUE, NULL, buf, &end, 0, 0);
+- protocol->store(buf, end-buf, &my_charset_bin);
+- my_free(buf, MYF(0));
++ query_str.length(0);
++ print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL);
++ protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
+ }
+ #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+
+@@ -5026,7 +5012,7 @@
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+ my_b_printf(&cache,"IGNORE ");
+
+- my_b_printf(&cache, "INTO TABLE `%s`", table_name);
++ my_b_printf(&cache, "INTO TABLE %`s", table_name);
+ my_b_printf(&cache, " FIELDS TERMINATED BY ");
+ pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
+
+@@ -5215,16 +5201,20 @@
+ else
+ {
+ char llbuff[22];
+- char *end;
+ enum enum_duplicates handle_dup;
+ bool ignore= 0;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+ char *load_data_query;
+
++ query_str.length(0);
+ /*
+ Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
+ and written to slave's binlog if binlogging is on.
+ */
+- if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
++ print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
++ query_str.length())))
+ {
+ /*
+ This will set thd->fatal_error in case of OOM. So we surely will notice
+@@ -5233,9 +5223,7 @@
+ goto error;
+ }
+
+- print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
+- *end= 0;
+- thd->set_query(load_data_query, (uint) (end - load_data_query));
++ thd->set_query(load_data_query, (uint) (query_str.length()));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ {
+@@ -5400,7 +5388,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rotate_log_event::pack_info(Protocol *protocol)
++void Rotate_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1), log_cs);
+@@ -5618,7 +5606,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Intvar_log_event::pack_info(Protocol *protocol)
++void Intvar_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256], *pos;
+ pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
+@@ -5768,7 +5756,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rand_log_event::pack_info(Protocol *protocol)
++void Rand_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], *pos;
+ pos= strmov(buf1,"rand_seed1=");
+@@ -5867,7 +5855,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Xid_log_event::pack_info(Protocol *protocol)
++void Xid_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[128], *pos;
+ pos= strmov(buf, "COMMIT /* xid=");
+@@ -5955,69 +5943,109 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void User_var_log_event::pack_info(Protocol* protocol)
++static bool
++user_var_append_name_part(THD *thd, String *buf,
++ const char *name, size_t name_len)
+ {
+- char *buf= 0;
+- uint val_offset= 4 + name_len;
+- uint event_len= val_offset;
++ return buf->append("@") ||
++ append_identifier(thd, buf, name, name_len) ||
++ buf->append("=");
++}
+
++void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
++{
+ if (is_null)
+ {
+- if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
++ char buf_mem[FN_REFLEN+7];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("NULL"))
+ return;
+- strmov(buf + val_offset, "NULL");
+- event_len= val_offset + 4;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+ else
+ {
+ switch (type) {
+ case REAL_RESULT:
++ {
+ double real_val;
++ char buf2[FLOATING_POINT_BUFFER];
++ char buf_mem[FN_REFLEN + FLOATING_POINT_BUFFER];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ float8get(real_val, val);
+- if (!(buf= (char*) my_malloc(val_offset + FLOATING_POINT_BUFFER,
+- MYF(MY_WME))))
+- return;
+- event_len+= my_sprintf(buf + val_offset,
+- (buf + val_offset, "%.14g", real_val));
++ buf.length(0);
++ my_sprintf(buf2, (buf2, "%.14g", real_val));
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case INT_RESULT:
+- if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
++ {
++ char buf2[22];
++ char buf_mem[FN_REFLEN + 22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2, longlong10_to_str(uint8korr(val), buf2, -10)-buf2))
+ return;
+- event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case DECIMAL_RESULT:
+ {
+- if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
+- MYF(MY_WME))))
+- return;
+- String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
++ char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ char buf2[DECIMAL_MAX_STR_LENGTH+1];
++ String str(buf2, sizeof(buf2), &my_charset_bin);
+ my_decimal dec;
++ buf.length(0);
+ binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
+ val[1]);
+ my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
+- event_len= str.length() + val_offset;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
+ }
+ case STRING_RESULT:
++ {
+ /* 15 is for 'COLLATE' and other chars */
+- buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
+- MYF(MY_WME));
++ char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ CHARSET_INFO *cs;
+- if (!buf)
+- return;
++ buf.length(0);
+ if (!(cs= get_charset(charset_number, MYF(0))))
+ {
+- strmov(buf+val_offset, "???");
+- event_len+= 3;
++ if (buf.append("???"))
++ return;
+ }
+ else
+ {
+- char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
+- p= str_to_hex(p, val, val_len);
+- p= strxmov(p, " COLLATE ", cs->name, NullS);
+- event_len= p-buf;
++ size_t old_len;
++ char *beg, *end;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("_") ||
++ buf.append(cs->csname) ||
++ buf.append(" "))
++ return;
++ old_len= buf.length();
++ if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") +
++ MY_CS_NAME_SIZE))
++ return;
++ beg= const_cast<char *>(buf.ptr()) + old_len;
++ end= str_to_hex(beg, val, val_len);
++ buf.length(old_len + (end - beg));
++ if (buf.append(" COLLATE ") ||
++ buf.append(cs->name))
++ return;
+ }
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case ROW_RESULT:
+ case IMPOSSIBLE_RESULT:
+ default:
+@@ -6025,13 +6053,6 @@
+ return;
+ }
+ }
+- buf[0]= '@';
+- buf[1]= '`';
+- memcpy(buf+2, name, name_len);
+- buf[2+name_len]= '`';
+- buf[3+name_len]= '=';
+- protocol->store(buf, event_len, &my_charset_bin);
+- my_free(buf, MYF(0));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -6148,9 +6169,8 @@
+ my_b_printf(&cache, "\tUser_var\n");
+ }
+
+- my_b_printf(&cache, "SET @`");
+- my_b_write(&cache, (uchar*) name, (uint) (name_len));
+- my_b_printf(&cache, "`");
++ my_b_printf(&cache, "SET @");
++ my_b_write_backtick_quote(&cache, name, name_len);
+
+ if (is_null)
+ {
+@@ -6223,7 +6243,7 @@
+ */
+ my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
+ else
+- my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
++ my_b_printf(&cache, ":=_%s %s COLLATE %`s%s\n",
+ cs->csname, hex_str, cs->name,
+ print_event_info->delimiter);
+ my_afree(hex_str);
+@@ -6362,7 +6382,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+-void Slave_log_event::pack_info(Protocol *protocol)
++void Slave_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256+HOSTNAME_LENGTH], *pos;
+ pos= strmov(buf, "host=");
+@@ -6734,7 +6754,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Create_file_log_event::pack_info(Protocol *protocol)
++void Create_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
+ pos= strmov(buf, "db=");
+@@ -6916,7 +6936,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Append_block_log_event::pack_info(Protocol *protocol)
++void Append_block_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ uint length;
+@@ -7069,7 +7089,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Delete_file_log_event::pack_info(Protocol *protocol)
++void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -7168,7 +7188,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_log_event::pack_info(Protocol *protocol)
++void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -7422,27 +7442,26 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_query_log_event::pack_info(Protocol *protocol)
++void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ char file_id_buf[22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len + 10 + 21);
+ if (db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
+- }
+- if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- pos= strmov(pos, " ;file_id=");
+- pos= int10_to_str((long) file_id, pos, 10);
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
++ if (buf.append("use ") ||
++ append_identifier(thd, &buf, db, db_len) ||
++ buf.append("; "))
++ return;
++ }
++ if (query && q_len && buf.append(query, q_len))
++ return;
++ int10_to_str((long) file_id, file_id_buf, 10);
++ if (buf.append(" ;file_id=") ||
++ buf.append(file_id_buf))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+
+
+@@ -8386,7 +8405,7 @@
+ #endif
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rows_log_event::pack_info(Protocol *protocol)
++void Rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+@@ -8488,7 +8507,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+-void Annotate_rows_log_event::pack_info(Protocol* protocol)
++void Annotate_rows_log_event::pack_info(THD *thd, Protocol* protocol)
+ {
+ if (m_query_txt && m_query_len)
+ protocol->store(m_query_txt, m_query_len, &my_charset_bin);
+@@ -9230,7 +9249,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Table_map_log_event::pack_info(Protocol *protocol)
++void Table_map_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes= my_snprintf(buf, sizeof(buf),
+@@ -9251,7 +9270,7 @@
+ {
+ print_header(&print_event_info->head_cache, print_event_info, TRUE);
+ my_b_printf(&print_event_info->head_cache,
+- "\tTable_map: `%s`.`%s` mapped to number %lu\n",
++ "\tTable_map: %`s.%`s mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(&print_event_info->body_cache, print_event_info, TRUE);
+ }
+@@ -10531,7 +10550,7 @@
+
+
+ #ifndef MYSQL_CLIENT
+-void Incident_log_event::pack_info(Protocol *protocol)
++void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes;
+
+=== modified file 'sql/log_event.h'
+--- sql/log_event.h 2012-03-13 14:38:43 +0000
++++ sql/log_event.h 2012-08-24 12:02:32 +0000
+@@ -1008,14 +1008,15 @@
+ */
+ static void init_show_field_list(List<Item>* field_list);
+ #ifdef HAVE_REPLICATION
+- int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
++ int net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos);
+
+ /*
+ pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
+ a string to display to the user, so it resembles print().
+ */
+
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+
+ #endif /* HAVE_REPLICATION */
+ virtual const char* get_db()
+@@ -1741,7 +1742,7 @@
+ bool using_trans, bool suppress_use, int error);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -1871,7 +1872,7 @@
+
+ #ifndef MYSQL_CLIENT
+ Slave_log_event(THD* thd_arg, Relay_log_info* rli);
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2104,9 +2105,11 @@
+ const Format_description_log_event* description_event);
+
+ public:
+- uint get_query_buffer_length();
+- void print_query(bool need_db, const char *cs, char *buf, char **end,
+- char **fn_start, char **fn_end);
++#ifndef MYSQL_CLIENT
++ void print_query(THD *thd, bool need_db, const char *cs, String *buf,
++ my_off_t *fn_start, my_off_t *fn_end,
++ const char *qualify_db);
++#endif
+ ulong thread_id;
+ ulong slave_proxy_id;
+ uint32 table_name_len;
+@@ -2154,7 +2157,7 @@
+ Name_resolution_context *context);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2253,7 +2256,7 @@
+ #ifndef MYSQL_CLIENT
+ Start_log_event_v3();
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ Start_log_event_v3() {}
+@@ -2414,7 +2417,7 @@
+ :Log_event(thd_arg,0,0), val(val_arg), type(type_arg)
+ { cache_type= cache_type_arg; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2491,7 +2494,7 @@
+ :Log_event(thd_arg, 0, 0), seed1(seed1_arg), seed2(seed2_arg)
+ { cache_type= cache_type_arg; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2536,7 +2539,7 @@
+ Xid_log_event(THD* thd_arg, my_xid x): Log_event(thd_arg, 0, 0), xid(x)
+ { cache_type= EVENT_NO_CACHE; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2586,7 +2589,7 @@
+ :Log_event(thd_arg, 0, 0), name(name_arg), name_len(name_len_arg), val(val_arg),
+ val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg)
+ { is_null= !val; cache_type= cache_type_arg; }
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2717,7 +2720,7 @@
+ uint ident_len_arg,
+ ulonglong pos_arg, uint flags);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2777,7 +2780,7 @@
+ uchar* block_arg, uint block_len_arg,
+ bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2849,7 +2852,7 @@
+ Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
+ uint block_len_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ virtual int get_create_or_append() const;
+ #endif /* HAVE_REPLICATION */
+ #else
+@@ -2890,7 +2893,7 @@
+ #ifndef MYSQL_CLIENT
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2931,7 +2934,7 @@
+ #ifndef MYSQL_CLIENT
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3027,7 +3030,7 @@
+ bool using_trans, bool suppress_use,
+ int errcode);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3113,7 +3116,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol*);
++ virtual void pack_info(THD *thd, Protocol*);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3527,7 +3530,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3639,7 +3642,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -4080,7 +4083,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+- void pack_info(Protocol*);
++ void pack_info(THD *thd, Protocol*);
+ #endif
+
+ Incident_log_event(const char *buf, uint event_len,
+
+=== modified file 'sql/log_event_old.cc'
+--- sql/log_event_old.cc 2012-03-13 14:38:43 +0000
++++ sql/log_event_old.cc 2012-08-24 12:02:32 +0000
+@@ -2012,7 +2012,7 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Old_rows_log_event::pack_info(Protocol *protocol)
++void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+
+=== modified file 'sql/log_event_old.h'
+--- sql/log_event_old.h 2012-03-13 14:38:43 +0000
++++ sql/log_event_old.h 2012-08-24 12:02:32 +0000
+@@ -108,7 +108,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+
+=== modified file 'sql/mysql_priv.h'
+--- sql/mysql_priv.h 2012-05-21 14:37:46 +0000
++++ sql/mysql_priv.h 2012-08-24 12:02:32 +0000
+@@ -1549,7 +1549,7 @@
+ /* sql_show.cc */
+ bool mysqld_show_open_tables(THD *thd,const char *wild);
+ bool mysqld_show_logs(THD *thd);
+-void append_identifier(THD *thd, String *packet, const char *name,
++bool append_identifier(THD *thd, String *packet, const char *name,
+ uint length);
+ #endif /* MYSQL_SERVER */
+ #if defined MYSQL_SERVER || defined INNODB_COMPATIBILITY_HOOKS
+
+=== modified file 'sql/sql_base.cc'
+--- sql/sql_base.cc 2012-05-21 14:37:46 +0000
++++ sql/sql_base.cc 2012-08-24 12:02:32 +0000
+@@ -4254,22 +4254,22 @@
+ entry->file->implicit_emptied= 0;
+ if (mysql_bin_log.is_open())
+ {
+- char *query, *end;
+- uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
+- if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
++ char query_buf[2*FN_REFLEN + 21];
++ String query(query_buf, sizeof(query_buf), system_charset_info);
++ query.length(0);
++ if (query.ptr())
+ {
+ /* this DELETE FROM is needed even with row-based binlogging */
+- end = strxmov(strmov(query, "DELETE FROM `"),
+- share->db.str,"`.`",share->table_name.str,"`", NullS);
++ query.append("DELETE FROM ");
++ append_identifier(thd, &query, share->db.str, share->db.length);
++ query.append(".");
++ append_identifier(thd, &query, share->table_name.str,
++ share->table_name.length);
+ int errcode= query_error_code(thd, TRUE);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+- query, (ulong)(end-query),
++ query.ptr(), query.length(),
+ FALSE, FALSE, errcode))
+- {
+- my_free(query, MYF(0));
+ goto err;
+- }
+- my_free(query, MYF(0));
+ }
+ else
+ {
+@@ -4279,7 +4279,7 @@
+ because of MYF(MY_WME) in my_malloc() above).
+ */
+ sql_print_error("When opening HEAP table, could not allocate memory "
+- "to write 'DELETE FROM `%s`.`%s`' to the binary log",
++ "to write 'DELETE FROM %`s.%`s' to the binary log",
+ table_list->db, table_list->table_name);
+ delete entry->triggers;
+ closefrm(entry, 0);
+
+=== modified file 'sql/sql_db.cc'
+--- sql/sql_db.cc 2011-12-11 09:34:44 +0000
++++ sql/sql_db.cc 2012-08-24 12:02:32 +0000
+@@ -614,7 +614,6 @@
+ bool silent)
+ {
+ char path[FN_REFLEN+16];
+- char tmp_query[FN_REFLEN+16];
+ long result= 1;
+ int error= 0;
+ MY_STAT stat_info;
+@@ -721,17 +720,9 @@
+ char *query;
+ uint query_length;
+
+- if (!thd->query()) // Only in replication
+- {
+- query= tmp_query;
+- query_length= (uint) (strxmov(tmp_query,"create database `",
+- db, "`", NullS) - tmp_query);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
+
+ ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
+ query, query_length,
+@@ -991,18 +982,11 @@
+ {
+ const char *query;
+ ulong query_length;
+- if (!thd->query())
+- {
+- /* The client used the old obsolete mysql_drop_db() call */
+- query= path;
+- query_length= (uint) (strxmov(path, "drop database `", db, "`",
+- NullS) - path);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
++
+ if (mysql_bin_log.is_open())
+ {
+ thd->clear_error();
+@@ -1043,9 +1027,10 @@
+ for (tbl= dropped_tables; tbl; tbl= tbl->next_local)
+ {
+ uint tbl_name_len;
++ char quoted_name[FN_REFLEN+3];
+
+- /* 3 for the quotes and the comma*/
+- tbl_name_len= strlen(tbl->table_name) + 3;
++ my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
++ tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
+ if (query_pos + tbl_name_len + 1 >= query_end)
+ {
+ /* These DDL methods and logging protected with LOCK_mysql_create_db */
+@@ -1057,9 +1042,7 @@
+ query_pos= query_data_start;
+ }
+
+- *query_pos++ = '`';
+- query_pos= strmov(query_pos,tbl->table_name);
+- *query_pos++ = '`';
++ query_pos= strmov(query_pos, quoted_name);
+ *query_pos++ = ',';
+ }
+
+
+=== modified file 'sql/sql_insert.cc'
+--- sql/sql_insert.cc 2012-02-03 11:32:29 +0000
++++ sql/sql_insert.cc 2012-08-24 12:02:32 +0000
+@@ -3543,16 +3543,16 @@
+ if (thd->lex->create_select_in_comment)
+ query.append(STRING_WITH_LEN("/*! "));
+ if (thd->lex->ignore)
+- query.append(STRING_WITH_LEN("INSERT IGNORE INTO `"));
++ query.append(STRING_WITH_LEN("INSERT IGNORE INTO "));
+ else if (thd->lex->duplicates == DUP_REPLACE)
+- query.append(STRING_WITH_LEN("REPLACE INTO `"));
++ query.append(STRING_WITH_LEN("REPLACE INTO "));
+ else
+- query.append(STRING_WITH_LEN("INSERT INTO `"));
++ query.append(STRING_WITH_LEN("INSERT INTO "));
+
+- query.append(create_table->db, db_len);
+- query.append(STRING_WITH_LEN("`.`"));
+- query.append(create_info->alias, table_len);
+- query.append(STRING_WITH_LEN("` "));
++ append_identifier(thd, &query, create_table->db, db_len);
++ query.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &query, create_info->alias, table_len);
++ query.append(STRING_WITH_LEN(" "));
+
+ /*
+ The insert items.
+
+=== modified file 'sql/sql_load.cc'
+--- sql/sql_load.cc 2012-04-05 21:07:18 +0000
++++ sql/sql_load.cc 2012-08-24 12:02:32 +0000
+@@ -24,6 +24,7 @@
+ #include "sql_repl.h"
+ #include "sp_head.h"
+ #include "sql_trigger.h"
++#include "sql_show.h"
+
+ class READ_INFO {
+ File file;
+@@ -615,24 +616,31 @@
+ bool transactional_table,
+ int errcode)
+ {
+- char *load_data_query,
+- *end,
+- *fname_start,
+- *fname_end,
+- *p= NULL;
+- size_t pl= 0;
++ char *load_data_query;
++ my_off_t fname_start,
++ fname_end;
+ List<Item> fv;
+ Item *item, *val;
+ int n;
+- const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
++ const char *qualify_db= NULL;
+ char name_buffer[SAFE_NAME_LEN*2];
+ char command_buffer[1024];
+ String string_buf(name_buffer, sizeof(name_buffer),
+ system_charset_info);
+- String pfields(command_buffer, sizeof(command_buffer),
++ String query_str(command_buffer, sizeof(command_buffer),
+ system_charset_info);
+
++ Load_log_event lle(thd, ex, tdb, table_name_arg, fv, duplicates,
++ ignore, transactional_table);
++
++ /*
++ force in a LOCAL if there was one in the original.
++ */
++ if (thd->lex->local_file)
++ lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++
++ query_str.length(0);
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+@@ -640,49 +648,31 @@
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+- string_buf.length(0);
+- string_buf.append(db_arg);
+- string_buf.append("`");
+- string_buf.append(".");
+- string_buf.append("`");
+- string_buf.append(table_name_arg);
+- tbl= string_buf.c_ptr_safe();
++ qualify_db= db_arg;
+ }
+-
+- Load_log_event lle(thd, ex, tdb, tbl, fv, duplicates,
+- ignore, transactional_table);
+-
+- /*
+- force in a LOCAL if there was one in the original.
+- */
+- if (thd->lex->local_file)
+- lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++ lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
++ &query_str, &fname_start, &fname_end, qualify_db);
+
+ /*
+ prepare fields-list and SET if needed; print_query won't do that for us.
+ */
+- pfields.length(0);
+ if (!thd->lex->field_list.is_empty())
+ {
+ List_iterator<Item> li(thd->lex->field_list);
+
+- pfields.append(" (");
++ query_str.append(" (");
+ n= 0;
+
+ while ((item= li++))
+ {
+ if (n++)
+- pfields.append(", ");
++ query_str.append(", ");
+ if (item->name)
+- {
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- }
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
+ else
+- item->print(&pfields, QT_ORDINARY);
++ ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str);
+ }
+- pfields.append(")");
++ query_str.append(")");
+ }
+
+ if (!thd->lex->update_list.is_empty())
+@@ -690,39 +680,26 @@
+ List_iterator<Item> lu(thd->lex->update_list);
+ List_iterator<Item> lv(thd->lex->value_list);
+
+- pfields.append(" SET ");
++ query_str.append(" SET ");
+ n= 0;
+
+ while ((item= lu++))
+ {
+ val= lv++;
+ if (n++)
+- pfields.append(", ");
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- pfields.append("=");
+- val->print(&pfields, QT_ORDINARY);
++ query_str.append(", ");
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
++ query_str.append("=");
++ val->print(&query_str, QT_ORDINARY);
+ }
+ }
+
+- p= pfields.c_ptr_safe();
+- pl= pfields.length();
+-
+- if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length())))
+ return TRUE;
+
+- lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+- load_data_query, &end,
+- (char **)&fname_start, (char **)&fname_end);
+-
+- strcpy(end, p);
+- end += pl;
+-
+ Execute_load_query_log_event
+- e(thd, load_data_query, end-load_data_query,
+- (uint) ((char*) fname_start - load_data_query - 1),
+- (uint) ((char*) fname_end - load_data_query),
++ e(thd, load_data_query, query_str.length(),
++ (uint) (fname_start - 1), (uint) fname_end,
+ (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
+ (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
+ transactional_table, FALSE, errcode);
+
+=== modified file 'sql/sql_repl.cc'
+--- sql/sql_repl.cc 2011-12-11 09:34:44 +0000
++++ sql/sql_repl.cc 2012-08-24 12:02:32 +0000
+@@ -1721,7 +1721,7 @@
+ description_event->checksum_alg= ev->checksum_alg;
+
+ if (event_count >= limit_start &&
+- ev->net_send(protocol, linfo.log_file_name, pos))
++ ev->net_send(thd, protocol, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+
+=== modified file 'sql/sql_show.cc'
+--- sql/sql_show.cc 2012-05-20 12:57:29 +0000
++++ sql/sql_show.cc 2012-08-24 12:02:32 +0000
+@@ -1053,9 +1053,13 @@
+ packet target string
+ name the identifier to be appended
+ name_length length of the appending identifier
++
++ RETURN VALUES
++ true Error
++ false Ok
+ */
+
+-void
++bool
+ append_identifier(THD *thd, String *packet, const char *name, uint length)
+ {
+ const char *name_end;
+@@ -1063,10 +1067,7 @@
+ int q= get_quote_char_for_identifier(thd, name, length);
+
+ if (q == EOF)
+- {
+- packet->append(name, length, packet->charset());
+- return;
+- }
++ return packet->append(name, length, packet->charset());
+
+ /*
+ The identifier must be quoted as it includes a quote character or
+@@ -1075,7 +1076,8 @@
+
+ VOID(packet->reserve(length*2 + 2));
+ quote_char= (char) q;
+- packet->append("e_char, 1, system_charset_info);
++ if (packet->append("e_char, 1, system_charset_info))
++ return true;
+
+ for (name_end= name+length ; name < name_end ; name+= length)
+ {
+@@ -1090,11 +1092,13 @@
+ */
+ if (!length)
+ length= 1;
+- if (length == 1 && chr == (uchar) quote_char)
+- packet->append("e_char, 1, system_charset_info);
+- packet->append(name, length, system_charset_info);
++ if (length == 1 && chr == (uchar) quote_char &&
++ packet->append("e_char, 1, system_charset_info))
++ return true;
++ if (packet->append(name, length, system_charset_info))
++ return true;
+ }
+- packet->append("e_char, 1, system_charset_info);
++ return packet->append("e_char, 1, system_charset_info);
+ }
+
+
+
+=== modified file 'sql/sql_string.cc'
+--- sql/sql_string.cc 2012-04-05 21:07:18 +0000
++++ sql/sql_string.cc 2012-08-24 12:02:32 +0000
+@@ -1159,39 +1159,47 @@
+
+
+
+-
+-void String::print(String *str)
++/*
++ Append characters to a single-quoted string '...', escaping special
++ characters as necessary.
++ Does not add the enclosing quotes, this is left up to caller.
++*/
++void String::append_for_single_quote(const char *st, uint len)
+ {
+- char *st= (char*)Ptr, *end= st+str_length;
++ const char *end= st+len;
+ for (; st < end; st++)
+ {
+ uchar c= *st;
+ switch (c)
+ {
+ case '\\':
+- str->append(STRING_WITH_LEN("\\\\"));
++ append(STRING_WITH_LEN("\\\\"));
+ break;
+ case '\0':
+- str->append(STRING_WITH_LEN("\\0"));
++ append(STRING_WITH_LEN("\\0"));
+ break;
+ case '\'':
+- str->append(STRING_WITH_LEN("\\'"));
++ append(STRING_WITH_LEN("\\'"));
+ break;
+ case '\n':
+- str->append(STRING_WITH_LEN("\\n"));
++ append(STRING_WITH_LEN("\\n"));
+ break;
+ case '\r':
+- str->append(STRING_WITH_LEN("\\r"));
++ append(STRING_WITH_LEN("\\r"));
+ break;
+ case '\032': // Ctrl-Z
+- str->append(STRING_WITH_LEN("\\Z"));
++ append(STRING_WITH_LEN("\\Z"));
+ break;
+ default:
+- str->append(c);
++ append(c);
+ }
+ }
+ }
+
++void String::print(String *str)
++{
++ str->append_for_single_quote(Ptr, str_length);
++}
+
+ /*
+ Exchange state of this object and argument.
+
+=== modified file 'sql/sql_string.h'
+--- sql/sql_string.h 2011-12-11 09:34:44 +0000
++++ sql/sql_string.h 2012-08-24 12:02:32 +0000
+@@ -438,6 +438,7 @@
+ return FALSE;
+ }
+ void print(String *print);
++ void append_for_single_quote(const char *st, uint len);
+
+ /* Swap two string objects. Efficient way to exchange data without memcpy. */
+ void swap(String &s);
+
+=== modified file 'sql/sql_table.cc'
+--- sql/sql_table.cc 2012-04-05 21:07:18 +0000
++++ sql/sql_table.cc 2012-08-24 12:02:32 +0000
+@@ -1939,6 +1939,7 @@
+ for (table= tables; table; table= table->next_local)
+ {
+ char *db=table->db;
++ size_t db_length= table->db_length;
+ handlerton *table_type;
+ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+
+@@ -1961,14 +1962,14 @@
+ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
+ }
+
+- built_tmp_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_tmp_query.append(db);
+- built_tmp_query.append("`.`");
++ append_identifier(thd, &built_tmp_query, db, db_length);
++ built_tmp_query.append(".");
+ }
+- built_tmp_query.append(table->table_name);
+- built_tmp_query.append("`,");
++ append_identifier(thd, &built_tmp_query, table->table_name,
++ table->table_name_length);
++ built_tmp_query.append(",");
+ }
+
+ continue;
+@@ -1994,15 +1995,15 @@
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+- built_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_query.append(db);
+- built_query.append("`.`");
++ append_identifier(thd, &built_query, db, db_length);
++ built_query.append(".");
+ }
+
+- built_query.append(table->table_name);
+- built_query.append("`,");
++ append_identifier(thd, &built_query, table->table_name,
++ table->table_name_length);
++ built_query.append(",");
+ }
+
+ if (!drop_temporary)
+
+=== modified file 'strings/my_vsnprintf.c'
+--- strings/my_vsnprintf.c 2011-12-11 09:34:44 +0000
++++ strings/my_vsnprintf.c 2012-08-24 12:02:32 +0000
+@@ -635,3 +635,67 @@
+ va_end(args);
+ return result;
+ }
++
++
++/**
++ Writes output to the stream according to a format string.
++
++ @param stream file to write to
++ @param format string format
++ @param args list of parameters
++
++ @retval
++ number of the characters written.
++*/
++
++int my_vfprintf(FILE *stream, const char* format, va_list args)
++{
++ char cvtbuf[1024];
++ int alloc= 0;
++ char *p= cvtbuf;
++ size_t cur_len= sizeof(cvtbuf);
++ int ret;
++
++ /*
++ We do not know how much buffer we need.
++ So start with a reasonably-sized stack-allocated buffer, and increase
++ it exponentially until it is big enough.
++ */
++ for (;;)
++ {
++ size_t new_len;
++ size_t actual= my_vsnprintf(p, cur_len, format, args);
++ if (actual < cur_len - 1)
++ break;
++ /*
++ Not enough space (or just enough with nothing to spare - but we cannot
++ distinguish this case from the return value). Allocate a bigger buffer
++ and try again.
++ */
++ if (alloc)
++ (*my_str_free)(p);
++ else
++ alloc= 1;
++ new_len= cur_len*2;
++ if (new_len < cur_len)
++ return 0; /* Overflow */
++ cur_len= new_len;
++ p= (*my_str_malloc)(cur_len);
++ if (!p)
++ return 0;
++ }
++ ret= fprintf(stream, "%s", p);
++ if (alloc)
++ (*my_str_free)(p);
++ return ret;
++}
++
++int my_fprintf(FILE *stream, const char* format, ...)
++{
++ int result;
++ va_list args;
++ va_start(args, format);
++ result= my_vfprintf(stream, format, args);
++ va_end(args);
++ return result;
++}
+
diff --git a/21000_sql-5.5.25.patch b/21000_sql-5.5.25.patch
new file mode 100644
index 0000000..d904491
--- /dev/null
+++ b/21000_sql-5.5.25.patch
@@ -0,0 +1,3338 @@
+=== modified file 'client/mysqlbinlog.cc'
+--- client/mysqlbinlog.cc 2012-08-09 15:22:00 +0000
++++ client/mysqlbinlog.cc 2012-08-24 13:29:01 +0000
+@@ -743,7 +743,7 @@
+ return;
+
+ // In case of rewrite rule print USE statement for db_to
+- fprintf(result_file, "use %s%s\n", db_to, pinfo->delimiter);
++ my_fprintf(result_file, "use %`s%s\n", db_to, pinfo->delimiter);
+
+ // Copy the *original* db to pinfo to suppress emiting
+ // of USE stmts by log_event print-functions.
+
+=== modified file 'include/my_sys.h'
+--- include/my_sys.h 2012-03-28 17:26:00 +0000
++++ include/my_sys.h 2012-08-24 13:29:01 +0000
+@@ -627,6 +627,7 @@
+ extern FILE *my_freopen(const char *path, const char *mode, FILE *stream);
+ extern int my_fclose(FILE *fd,myf MyFlags);
+ extern int my_vfprintf(FILE *stream, const char* format, va_list args);
++extern int my_fprintf(FILE *stream, const char* format, ...);
+ extern File my_fileno(FILE *fd);
+ extern int my_chsize(File fd,my_off_t newlength, int filler, myf MyFlags);
+ extern int my_chmod(const char *name, mode_t mode, myf my_flags);
+@@ -751,6 +752,8 @@
+ extern void my_b_seek(IO_CACHE *info,my_off_t pos);
+ extern size_t my_b_gets(IO_CACHE *info, char *to, size_t max_length);
+ extern my_off_t my_b_filelength(IO_CACHE *info);
++extern size_t my_b_write_backtick_quote(IO_CACHE *info, const char *str,
++ size_t len);
+ extern size_t my_b_printf(IO_CACHE *info, const char* fmt, ...);
+ extern size_t my_b_vprintf(IO_CACHE *info, const char* fmt, va_list ap);
+ extern my_bool open_cached_file(IO_CACHE *cache,const char *dir,
+
+=== modified file 'mysql-test/r/mysqlbinlog-innodb.result'
+--- mysql-test/r/mysqlbinlog-innodb.result 2011-10-19 19:45:18 +0000
++++ mysql-test/r/mysqlbinlog-innodb.result 2012-08-24 13:29:01 +0000
+@@ -34,7 +34,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+@@ -65,7 +65,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use foo/*!*/;
++use `foo`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ INSERT INTO t1 VALUES (1)
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog.result'
+--- mysql-test/r/mysqlbinlog.result 2011-10-19 19:45:18 +0000
++++ mysql-test/r/mysqlbinlog.result 2012-08-24 13:29:01 +0000
+@@ -18,7 +18,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -111,7 +111,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
+ /*!*/;
+@@ -202,7 +202,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ insert into t1 values ("Alas")
+ /*!*/;
+@@ -219,7 +219,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -312,7 +312,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-#-#' INTO TABLE `t1` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`word`)
+ /*!*/;
+@@ -403,7 +403,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ insert into t1 values ("Alas")
+ /*!*/;
+@@ -427,7 +427,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844555/*!*/;
+ insert t1 values (1)
+ /*!*/;
+@@ -445,7 +445,7 @@
+ SET @@session.collation_database=DEFAULT/*!*/;
+ BEGIN
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1108844555/*!*/;
+ insert t1 values (1)
+ /*!*/;
+@@ -498,7 +498,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -548,7 +548,7 @@
+ /*!40019 SET @@session.max_insert_delayed_threads=0*/;
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -725,7 +725,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1253783037/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -825,7 +825,7 @@
+ SET TIMESTAMP=1266652094/*!*/;
+ SavePoint mixed_cases
+ /*!*/;
+-use db1/*!*/;
++use `db1`/*!*/;
+ SET TIMESTAMP=1266652094/*!*/;
+ INSERT INTO db1.t2 VALUES("in savepoint mixed_cases")
+ /*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog2.result'
+--- mysql-test/r/mysqlbinlog2.result 2010-01-07 15:39:11 +0000
++++ mysql-test/r/mysqlbinlog2.result 2012-08-24 13:29:01 +0000
+@@ -19,7 +19,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -103,7 +103,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ insert into t1 values(null, "a")
+ /*!*/;
+@@ -172,7 +172,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -209,7 +209,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -263,7 +263,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -289,7 +289,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -326,7 +326,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -369,7 +369,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -445,7 +445,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -474,7 +474,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ insert into t1 values(null, "a")
+ /*!*/;
+@@ -535,7 +535,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -564,7 +564,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -605,7 +605,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -622,7 +622,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -720,7 +720,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -761,7 +761,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -778,7 +778,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -820,7 +820,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -904,7 +904,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ insert into t1 values(null, "a")
+ /*!*/;
+@@ -972,7 +972,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -1009,7 +1009,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1062,7 +1062,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -1088,7 +1088,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -1125,7 +1125,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1167,7 +1167,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1243,7 +1243,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -1272,7 +1272,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=1/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ insert into t1 values(null, "a")
+ /*!*/;
+@@ -1333,7 +1333,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -1361,7 +1361,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -1402,7 +1402,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -1419,7 +1419,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1516,7 +1516,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=3/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609944/*!*/;
+ insert into t1 values(null, "c")
+ /*!*/;
+@@ -1557,7 +1557,7 @@
+ BEGIN
+ /*!*/;
+ SET INSERT_ID=6/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609943/*!*/;
+ insert into t1 values(null, "f")
+ /*!*/;
+@@ -1574,7 +1574,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -1616,7 +1616,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1579609942/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row.result'
+--- mysql-test/r/mysqlbinlog_row.result 2010-08-23 22:31:12 +0000
++++ mysql-test/r/mysqlbinlog_row.result 2012-08-24 13:29:01 +0000
+@@ -336,7 +336,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_innodb.result'
+--- mysql-test/r/mysqlbinlog_row_innodb.result 2010-03-24 15:03:44 +0000
++++ mysql-test/r/mysqlbinlog_row_innodb.result 2012-08-24 13:29:01 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3876,7 +3876,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4243,7 +4243,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4804,7 +4804,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_myisam.result'
+--- mysql-test/r/mysqlbinlog_row_myisam.result 2010-03-12 12:42:30 +0000
++++ mysql-test/r/mysqlbinlog_row_myisam.result 2012-08-24 13:29:01 +0000
+@@ -2253,7 +2253,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -3898,7 +3898,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4271,7 +4271,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -4842,7 +4842,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/mysqlbinlog_row_trans.result'
+--- mysql-test/r/mysqlbinlog_row_trans.result 2010-01-07 15:39:11 +0000
++++ mysql-test/r/mysqlbinlog_row_trans.result 2012-08-24 13:29:01 +0000
+@@ -132,7 +132,7 @@
+ ROLLBACK/*!*/;
+ # at #
+ #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/r/user_var-binlog.result'
+--- mysql-test/r/user_var-binlog.result 2010-01-07 15:39:11 +0000
++++ mysql-test/r/user_var-binlog.result 2012-08-24 13:29:01 +0000
+@@ -34,7 +34,7 @@
+ BEGIN
+ /*!*/;
+ SET @`a b`:=_latin1 0x68656C6C6F COLLATE `latin1_swedish_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ INSERT INTO t1 VALUES(@`a b`)
+ /*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_base64_flag.result'
+--- mysql-test/suite/binlog/r/binlog_base64_flag.result 2011-12-12 22:58:40 +0000
++++ mysql-test/suite/binlog/r/binlog_base64_flag.result 2012-08-24 13:29:01 +0000
+@@ -35,7 +35,7 @@
+ # at 4
+ <#>ROLLBACK/*!*/;
+ # at 102
+-<#>use test/*!*/;
++<#>use `test`/*!*/;
+ SET TIMESTAMP=1196959712/*!*/;
+ <#>SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+ SET @@session.sql_mode=0/*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result'
+--- mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2011-10-19 19:45:18 +0000
++++ mysql-test/suite/binlog/r/binlog_row_mysqlbinlog_options.result 2012-08-24 13:29:01 +0000
+@@ -35,7 +35,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -72,7 +72,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -115,7 +115,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+@@ -229,7 +229,7 @@
+ #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup
+ ROLLBACK/*!*/;
+ # at #
+-use new_test1/*!*/;
++use `new_test1`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=#/*!*/;
+@@ -266,7 +266,7 @@
+ /*!*/;
+ # at #
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+-use test2/*!*/;
++use `test2`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t2 (a INT)
+ /*!*/;
+@@ -309,7 +309,7 @@
+ COMMIT
+ /*!*/;
+ # at #
+-use new_test3/*!*/;
++use `new_test3`/*!*/;
+ #010909 4:46:40 server id # end_log_pos # Query thread_id=# exec_time=# error_code=0
+ SET TIMESTAMP=1000000000/*!*/;
+ CREATE TABLE t3 (a INT)
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result'
+--- mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2010-01-07 15:39:11 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_ctype_ucs.result 2012-08-24 13:29:01 +0000
+@@ -26,7 +26,7 @@
+ BEGIN
+ /*!*/;
+ SET @`v`:=_ucs2 0x006100620063 COLLATE `ucs2_general_ci`/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=10000/*!*/;
+ insert into t2 values (@v)
+ /*!*/;
+
+=== modified file 'mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result'
+--- mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2011-05-12 04:56:41 +0000
++++ mysql-test/suite/binlog/r/binlog_stm_mix_innodb_myisam.result 2012-08-24 13:29:01 +0000
+@@ -698,7 +698,7 @@
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`= @b + bug27417(2) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`= @b + bug27417(2) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ /* the output must denote there is the query */;
+ drop trigger trg_del_t2;
+@@ -950,7 +950,7 @@
+ master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
+ master-bin.000001 # Intvar # # INSERT_ID=10
+ master-bin.000001 # User var # # @`b`=_latin1 0x3135 COLLATE latin1_swedish_ci
+-master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @b) SET `b`= @b + bug27417(2) ;file_id=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE '../../std_data/rpl_loaddata.dat' INTO TABLE `t4` FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`= @b + bug27417(2) ;file_id=#
+ master-bin.000001 # Query # # ROLLBACK
+ drop trigger trg_del_t2;
+ drop table t1,t2,t3,t4,t5;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_hrtime.result'
+--- mysql-test/suite/rpl/r/rpl_hrtime.result 2011-10-19 19:45:18 +0000
++++ mysql-test/suite/rpl/r/rpl_hrtime.result 2012-08-24 13:29:01 +0000
+@@ -30,7 +30,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1293832861/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== added file 'mysql-test/suite/rpl/r/rpl_mdev382.result'
+--- mysql-test/suite/rpl/r/rpl_mdev382.result 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/r/rpl_mdev382.result 2012-08-24 13:29:01 +0000
+@@ -0,0 +1,369 @@
++include/master-slave.inc
++[connection master]
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++Warnings:
++Warning 1196 Some non-transactional changed tables couldn't be rolled back
++insert into t1 values (3);
++commit;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `test`; create table t1 (a int primary key) engine=innodb
++master-bin.000001 # Query # # use `test`; create table t2 (a int primary key) engine=myisam
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t2 values (1)
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values (1)
++master-bin.000001 # Query # # SAVEPOINT "a`; create database couldbebadthingshere; savepoint `dummy"
++master-bin.000001 # Query # # use `test`; insert into t1 values (2)
++master-bin.000001 # Query # # ROLLBACK TO `a``; create database couldbebadthingshere; savepoint ``dummy`
++master-bin.000001 # Query # # use `test`; insert into t1 values (3)
++master-bin.000001 # Xid # # COMMIT /* XID */
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `test`; insert into t1 values(10)
++master-bin.000001 # Query # # SAVEPOINT "a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(11)
++master-bin.000001 # Query # # SAVEPOINT "a""a"
++master-bin.000001 # Query # # use `test`; insert into t1 values(12)
++master-bin.000001 # Query # # SAVEPOINT b
++master-bin.000001 # Query # # use `test`; insert into t1 values(13)
++master-bin.000001 # Query # # SAVEPOINT "b""b"
++master-bin.000001 # Query # # use `test`; insert into t1 values(14)
++master-bin.000001 # Query # # SAVEPOINT `c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(15)
++master-bin.000001 # Query # # SAVEPOINT `c``c`
++master-bin.000001 # Query # # use `test`; insert into t1 values(16)
++master-bin.000001 # Query # # SAVEPOINT d
++master-bin.000001 # Query # # use `test`; insert into t1 values(17)
++master-bin.000001 # Query # # SAVEPOINT `d``d`
++master-bin.000001 # Query # # use `test`; insert into t1 values(18)
++master-bin.000001 # Xid # # COMMIT /* XID */
++*** Test correct USE statement in SHOW BINLOG EVENTS ***
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use "db1`; SELECT 'oops!'"; INSERT INTO t1 VALUES (2)
++master-bin.000001 # Query # # COMMIT
++set sql_mode = '';
++set sql_quote_show_create = 0;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++master-bin.000001 # Query # # COMMIT
++set sql_quote_show_create = 1;
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # CREATE DATABASE "db1`; SELECT 'oops!'"
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (1)
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (2)
++master-bin.000001 # Query # # COMMIT
++DROP TABLE t1;
++use test;
++***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++use `db1``; SELECT 'oops!'`;
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++truncate `t``1`;
++use test;
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `db1``; SELECT 'oops!'`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`= @`b```, `c``3`= concat('|', "b""a'z", "!") ;file_id=#
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; truncate `t``1`
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/f\'le.txt' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!") ;file_id=#
++master-bin.000001 # Query # # COMMIT
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++`c``3` VARCHAR(7))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++BEGIN
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, @`b```) SET `b``2`= @`b```, `c``3`= concat('|', "b""a'z", "!")
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++COMMIT
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++truncate `t``1`
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++BEGIN
++/*!*/;
++use `test`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++LOAD DATA LOCAL INFILE '<name>' INTO TABLE `db1``; SELECT 'oops!'`.`t``1` FIELDS TERMINATED BY ',' ENCLOSED BY '\'' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a``1`, `b``2`) SET `c``3`= concat('|', "b""a'z", "!")
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++COMMIT
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`1 b`2 c`3
++fo\o bar |b"a'z!
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++drop table t1,t2;
++*** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE t1
++FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Begin_load_query # # ;file_id=#;block_len=#
++master-bin.000001 # Execute_load_query # # use `test`; LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/file.txt' INTO TABLE `t1` FIELDS TERMINATED BY ',' ENCLOSED BY '' ESCAPED BY '\\' LINES TERMINATED BY '\n' (`a`, @`b`) SET `b`= CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b) ;file_id=#
++master-bin.000001 # Query # # COMMIT
++SELECT * FROM t1 ORDER BY a;
++a b
++1 X| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|X
++2 A| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|A
++DROP TABLE t1;
++*** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++@`a``1`:=a1 @`a``2`:=a2 @`a``3`:=a3 @`a``4`:=a4 @`b```:=b @```c`:=c @```d```:=d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.234560123456789e125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++show binlog events from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++master-bin.000001 # Query # # COMMIT
++master-bin.000001 # Query # # BEGIN
++master-bin.000001 # User var # # @`a``1`=-9223372036854775808
++master-bin.000001 # User var # # @`a``2`=42
++master-bin.000001 # User var # # @`a``3`=9223372036854775807
++master-bin.000001 # User var # # @`a``4`=18446744073709551615
++master-bin.000001 # User var # # @`b```=-1.234560123456789e125
++master-bin.000001 # User var # # @```c`=-1234501234567890123456789012345678901234567890123456789.0123456789
++master-bin.000001 # User var # # @```d```=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE latin1_swedish_ci
++master-bin.000001 # Query # # use `db1``; SELECT 'oops!'`; INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++master-bin.000001 # Query # # COMMIT
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++use `db1``; SELECT 'oops!'`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++BEGIN
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++COMMIT
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++BEGIN
++/*!*/;
++SET @`a``1`:=-9223372036854775808/*!*/;
++SET @`a``2`:=42/*!*/;
++SET @`a``3`:=9223372036854775807/*!*/;
++SET @`a``4`:=18446744073709551615/*!*/;
++SET @`b```:=-1.2345601234568e+125/*!*/;
++SET @```c`:=-1234501234567890123456789012345678901234567890123456789.0123456789/*!*/;
++SET @```d```:=_latin1 0x78787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878787878 COLLATE `latin1_swedish_ci`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98))
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++COMMIT
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++a1 a2 a3 a4 b c d
++-9223372036854775808 42 9223372036854775807 18446744073709551615 -1.234560123456789e125 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++-9223372036854775807 4200 9223372036854775806 18446744073709551614 -6.172800617283945e124 -1234501234567890123456789012345678901234567890123456789.0123456789 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
++DROP TABLE t1;
++*** Test correct quoting in foreign key error message ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE `t``1` ( `a``` INT PRIMARY KEY) ENGINE=innodb;
++CREATE TABLE `t``2` ( `b``` INT PRIMARY KEY, `c``` INT NOT NULL,
++FOREIGN KEY fk (`c```) REFERENCES `t``1`(`a```)) ENGINE=innodb;
++TRUNCATE `t``1`;
++ERROR 42000: Cannot truncate a table referenced in a foreign key constraint (`db1``; SELECT 'oops!'`.`t``2`, CONSTRAINT `INNODB_FOREIGN_KEY_NAME` FOREIGN KEY (`c```) REFERENCES `db1``; SELECT 'oops!'`.`t``1` (`a```))
++DROP TABLE `t``2`;
++DROP TABLE `t``1`;
++*** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++include/stop_slave.inc
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++a`
++1
++2
++5
++set timestamp=1000000000;
++# The table should be empty on the master.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++# The DELETE statement should be correctly quoted
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # BEGIN
++master-bin.000002 # Query # # use `test`; DELETE FROM `db1``; SELECT 'oops!'`.`t``1`
++master-bin.000002 # Query # # COMMIT
++include/start_slave.inc
++# The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++a`
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++*** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++INSERT INTO t1 VALUES(1);
++show binlog events in 'master-bin.000002' from <binlog_start>;
++Log_name Pos Event_type Server_id End_log_pos Info
++master-bin.000002 # Query # # BEGIN
++master-bin.000002 # Query # # use `test`; INSERT INTO t1 VALUES(1)
++master-bin.000002 # Query # # COMMIT
++/*!40019 SET @@session.max_insert_delayed_threads=0*/;
++/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
++DELIMITER /*!*/;
++ROLLBACK/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++SET @@session.pseudo_thread_id=999999999/*!*/;
++SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
++SET @@session.sql_mode=0/*!*/;
++SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/;
++/*!\C latin1 *//*!*/;
++SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/;
++SET @@session.lc_time_names=0/*!*/;
++SET @@session.collation_database=DEFAULT/*!*/;
++BEGIN
++/*!*/;
++use `ts``et`/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++INSERT INTO t1 VALUES(1)
++/*!*/;
++SET TIMESTAMP=1000000000/*!*/;
++COMMIT
++/*!*/;
++DELIMITER ;
++# End of log file
++ROLLBACK /* added by mysqlbinlog */;
++/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
++DROP TABLE t1;
++include/rpl_end.inc
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result'
+--- mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2010-12-19 17:15:12 +0000
++++ mysql-test/suite/rpl/r/rpl_row_mysqlbinlog.result 2012-08-24 13:29:01 +0000
+@@ -154,7 +154,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -176,7 +176,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -287,7 +287,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+@@ -318,7 +318,7 @@
+ /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
+ DELIMITER /*!*/;
+ ROLLBACK/*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=1000000000/*!*/;
+ SET @@session.pseudo_thread_id=999999999/*!*/;
+ SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
+
+=== modified file 'mysql-test/suite/rpl/r/rpl_sp.result'
+--- mysql-test/suite/rpl/r/rpl_sp.result 2010-12-19 17:15:12 +0000
++++ mysql-test/suite/rpl/r/rpl_sp.result 2012-08-24 13:29:01 +0000
+@@ -670,7 +670,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest1
+ /*!*/;
+-use mysqltest1/*!*/;
++use `mysqltest1`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t1 (a varchar(100))
+ /*!*/;
+@@ -1015,7 +1015,7 @@
+ SET TIMESTAMP=t/*!*/;
+ drop user "zedjzlcsjhd"@127.0.0.1
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ drop function if exists f1
+ /*!*/;
+@@ -1112,7 +1112,7 @@
+ SET TIMESTAMP=t/*!*/;
+ create database mysqltest2
+ /*!*/;
+-use mysqltest2/*!*/;
++use `mysqltest2`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ create table t ( t integer )
+ /*!*/;
+@@ -1139,7 +1139,7 @@
+ SET TIMESTAMP=t/*!*/;
+ BEGIN
+ /*!*/;
+-use mysqltest/*!*/;
++use `mysqltest`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ SELECT `mysqltest2`.`f1`()
+ /*!*/;
+@@ -1152,14 +1152,14 @@
+ SET TIMESTAMP=t/*!*/;
+ drop database mysqltest2
+ /*!*/;
+-use test/*!*/;
++use `test`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `mysqltestbug36570_p1`()
+ begin
+ select 1;
+ end
+ /*!*/;
+-use mysql/*!*/;
++use `mysql`/*!*/;
+ SET TIMESTAMP=t/*!*/;
+ CREATE DEFINER=`root`@`localhost` PROCEDURE `test`.` mysqltestbug36570_p2`( a int)
+ `label`:
+
+=== added file 'mysql-test/suite/rpl/t/rpl_mdev382.test'
+--- mysql-test/suite/rpl/t/rpl_mdev382.test 1970-01-01 00:00:00 +0000
++++ mysql-test/suite/rpl/t/rpl_mdev382.test 2012-08-24 13:29:01 +0000
+@@ -0,0 +1,265 @@
++--source include/have_innodb.inc
++--source include/have_binlog_format_statement.inc
++--source include/master-slave.inc
++
++# MDEV-382: multiple SQL injections in replication code.
++
++# Test previous SQL injection attack against binlog for SAVEPOINT statement.
++# The test would cause syntax error on slave due to improper quoting of
++# the savepoint name.
++connection master;
++create table t1 (a int primary key) engine=innodb;
++create table t2 (a int primary key) engine=myisam;
++
++begin;
++insert into t1 values (1);
++SET sql_mode = 'ANSI_QUOTES';
++savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (2);
++insert into t2 values (1);
++SET sql_mode = '';
++rollback to savepoint `a``; create database couldbebadthingshere; savepoint ``dummy`;
++insert into t1 values (3);
++commit;
++
++--source include/show_binlog_events.inc
++
++# This failed due to syntax error in query when the bug was not fixed.
++sync_slave_with_master;
++connection slave;
++
++# Test some more combinations of ANSI_QUOTES and sql_quote_show_create
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++BEGIN;
++insert into t1 values(10);
++set sql_mode = 'ANSI_QUOTES';
++set sql_quote_show_create = 1;
++savepoint a;
++insert into t1 values(11);
++savepoint "a""a";
++insert into t1 values(12);
++set sql_quote_show_create = 0;
++savepoint b;
++insert into t1 values(13);
++savepoint "b""b";
++insert into t1 values(14);
++set sql_mode = '';
++set sql_quote_show_create = 1;
++savepoint c;
++insert into t1 values(15);
++savepoint `c``c`;
++insert into t1 values(16);
++set sql_quote_show_create = 0;
++savepoint d;
++insert into t1 values(17);
++savepoint `d``d`;
++insert into t1 values(18);
++COMMIT;
++set sql_quote_show_create = 1;
++
++--source include/show_binlog_events.inc
++
++--echo *** Test correct USE statement in SHOW BINLOG EVENTS ***
++connection master;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set sql_mode = 'ANSI_QUOTES';
++CREATE DATABASE "db1`; SELECT 'oops!'";
++use "db1`; SELECT 'oops!'";
++CREATE TABLE t1 (a INT PRIMARY KEY) engine=MyISAM;
++INSERT INTO t1 VALUES (1);
++set sql_mode = '';
++INSERT INTO t1 VALUES (2);
++set sql_mode = 'ANSI_QUOTES';
++--source include/show_binlog_events.inc
++set sql_mode = '';
++set sql_quote_show_create = 0;
++--source include/show_binlog_events.inc
++set sql_quote_show_create = 1;
++--source include/show_binlog_events.inc
++DROP TABLE t1;
++
++use test;
++
++--echo ***Test LOAD DATA INFILE with various identifiers that need correct quoting ***
++
++--let $load_file= $MYSQLTEST_VARDIR/tmp/f'le.txt
++--write_file $load_file
++'fo\\o','bar'
++EOF
++
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++set timestamp=1000000000;
++CREATE TABLE `t``1` (`a``1` VARCHAR(4) PRIMARY KEY, `b``2` VARCHAR(3),
++ `c``3` VARCHAR(7));
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt' INTO TABLE `t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, @`b```) SET `b``2` = @`b```, `c``3` = concat('|', "b""a'z", "!");
++
++SELECT * FROM `t``1`;
++# Also test when code prefixes table name with database.
++truncate `t``1`;
++use test;
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$MYSQLTEST_VARDIR/tmp/f''le.txt'
++ INTO TABLE `db1``; SELECT 'oops!'`.`t``1`
++ FIELDS TERMINATED BY ',' ESCAPED BY '\\\\' ENCLOSED BY ''''
++ LINES TERMINATED BY '\\n'
++ (`a``1`, `b``2`) SET `c``3` = concat('|', "b""a'z", "!");
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++let $MYSQLD_DATADIR= `select @@datadir`;
++--replace_regex /LOCAL INFILE '.*SQL_LOAD.*' INTO/LOCAL INFILE '<name>' INTO/
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++connection master;
++
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++--remove_file $load_file
++
++connection master;
++drop table t1,t2;
++
++
++--echo *** Test truncation of long SET expression in LOAD DATA ***
++CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(1000));
++--let $load_file= $MYSQLTEST_VARDIR/tmp/file.txt
++--write_file $load_file
++1,X
++2,A
++EOF
++
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++# The bug was that the SET expression was truncated to 256 bytes, so test with
++# an expression longer than that.
++--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
++eval LOAD DATA INFILE '$load_file' INTO TABLE t1
++ FIELDS TERMINATED BY ','
++ (a, @b) SET b = CONCAT(@b, '| 123456789A123456789B123456789C123456789D123456789E123456789F123456789G123456789H123456789I123456789J123456789K123456789L123456789M123456789N123456789O123456789P123456789Q123456789R123456789123456789T123456789U123456789V123456789W123456789X123456789Y123456789Z123456789|', @b);
++
++SELECT * FROM t1 ORDER BY a;
++--source include/show_binlog_events.inc
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM t1 ORDER BY a;
++
++connection master;
++--remove_file $load_file
++DROP TABLE t1;
++
++
++--echo *** Test user variables whose names require correct quoting ***
++use `db1``; SELECT 'oops!'`;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++CREATE TABLE t1 (a1 BIGINT PRIMARY KEY, a2 BIGINT, a3 BIGINT, a4 BIGINT UNSIGNED, b DOUBLE, c DECIMAL(65,10), d VARCHAR(100));
++INSERT INTO t1 VALUES (-9223372036854775808,42,9223372036854775807,18446744073709551615,-1234560123456789e110, -1234501234567890123456789012345678901234567890123456789.0123456789, REPEAT("x", 100));
++SELECT @`a``1`:=a1, @`a``2`:=a2, @`a``3`:=a3, @`a``4`:=a4, @`b```:=b, @```c`:=c, @```d```:=d FROM t1;
++INSERT INTO t1 VALUES (@`a``1`+1, @`a``2`*100, @`a``3`-1, @`a``4`-1, @`b```/2, @```c`, substr(@```d```, 2, 98));
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++
++--source include/show_binlog_events.inc
++
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 $MYSQLD_DATADIR/master-bin.000001
++
++sync_slave_with_master;
++connection slave;
++SELECT * FROM `db1``; SELECT 'oops!'`.t1 ORDER BY a1;
++
++connection master;
++DROP TABLE t1;
++
++--echo *** Test correct quoting in foreign key error message ***
++use `db1``; SELECT 'oops!'`;
++CREATE TABLE `t``1` ( `a``` INT PRIMARY KEY) ENGINE=innodb;
++CREATE TABLE `t``2` ( `b``` INT PRIMARY KEY, `c``` INT NOT NULL,
++ FOREIGN KEY fk (`c```) REFERENCES `t``1`(`a```)) ENGINE=innodb;
++--replace_regex /t@[0-9]+_ibfk_[0-9]+/INNODB_FOREIGN_KEY_NAME/
++--error ER_TRUNCATE_ILLEGAL_FK
++TRUNCATE `t``1`;
++DROP TABLE `t``2`;
++DROP TABLE `t``1`;
++
++
++--echo *** Test correct quoting of DELETE FROM statement binlogged for HEAP table that is emptied due to server restart
++
++# Let's keep the slave stopped during master restart, to avoid any potential
++# races between slave reconnect and master restart.
++connection slave;
++--source include/stop_slave.inc
++
++connection master;
++CREATE TABLE `db1``; SELECT 'oops!'`.`t``1` (`a``` INT PRIMARY KEY) ENGINE=heap;
++INSERT INTO `db1``; SELECT 'oops!'`.`t``1` VALUES (1), (2), (5);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1` ORDER BY 1;
++
++# Restart the master mysqld.
++# This will cause an implicit truncation of the memory-based table, which will
++# cause logging of an explicit DELETE FROM to binlog.
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++wait-rpl_mdev382.test
++EOF
++
++--shutdown_server 30
++
++--remove_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
++restart-rpl_mdev382.test
++EOF
++
++connection default;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++# rpl_end.inc needs to use the connection server_1
++connection server_1;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++connection master;
++--enable_reconnect
++--source include/wait_until_connected_again.inc
++set timestamp=1000000000;
++
++--echo # The table should be empty on the master.
++let $binlog_file= master-bin.000002;
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++--echo # The DELETE statement should be correctly quoted
++--source include/show_binlog_events.inc
++
++connection slave;
++--source include/start_slave.inc
++
++connection master;
++sync_slave_with_master;
++connection slave;
++--echo # The table should be empty on the slave also.
++SELECT * FROM `db1``; SELECT 'oops!'`.`t``1`;
++
++connection master;
++DROP TABLE `db1``; SELECT 'oops!'`.`t``1`;
++sync_slave_with_master;
++
++
++connection master;
++use test;
++DROP DATABASE `db1``; SELECT 'oops!'`;
++
++--echo *** Test correct quoting of mysqlbinlog --rewrite-db option ***
++CREATE TABLE t1 (a INT PRIMARY KEY);
++let $binlog_start= query_get_value(SHOW MASTER STATUS, Position, 1);
++INSERT INTO t1 VALUES(1);
++--source include/show_binlog_events.inc
++let $pos2= query_get_value(SHOW MASTER STATUS, Position, 1);
++--exec $MYSQL_BINLOG --short-form --start-position=$binlog_start --stop-position=$pos2 --rewrite-db='test->ts`et' $MYSQLD_DATADIR/master-bin.000002
++DROP TABLE t1;
++
++--source include/rpl_end.inc
+
+=== modified file 'mysys/mf_iocache2.c'
+--- mysys/mf_iocache2.c 2012-08-09 15:22:00 +0000
++++ mysys/mf_iocache2.c 2012-08-24 13:29:01 +0000
+@@ -287,6 +287,40 @@
+ }
+
+
++size_t
++my_b_write_backtick_quote(IO_CACHE *info, const char *str, size_t len)
++{
++ const uchar *start;
++ const uchar *p= (const uchar *)str;
++ const uchar *end= p + len;
++ size_t count;
++ size_t total= 0;
++
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ for (;;)
++ {
++ start= p;
++ while (p < end && *p != '`')
++ ++p;
++ count= p - start;
++ if (count && my_b_write(info, start, count))
++ return (size_t)-1;
++ total+= count;
++ if (p >= end)
++ break;
++ if (my_b_write(info, (uchar *)"``", 2))
++ return (size_t)-1;
++ total+= 2;
++ ++p;
++ }
++ if (my_b_write(info, (uchar *)"`", 1))
++ return (size_t)-1;
++ ++total;
++ return total;
++}
++
+ /*
+ Simple printf version. Supports '%s', '%d', '%u', "%ld" and "%lu"
+ Used for logging in MySQL
+@@ -311,6 +345,7 @@
+ uint minimum_width_sign;
+ uint precision; /* as yet unimplemented for anything but %b */
+ my_bool is_zero_padded;
++ my_bool backtick_quoting;
+
+ /*
+ Store the location of the beginning of a format directive, for the
+@@ -345,6 +380,7 @@
+ fmt++;
+
+ is_zero_padded= FALSE;
++ backtick_quoting= FALSE;
+ minimum_width_sign= 1;
+ minimum_width= 0;
+ precision= 0;
+@@ -357,6 +393,8 @@
+ minimum_width_sign= -1; fmt++; goto process_flags;
+ case '0':
+ is_zero_padded= TRUE; fmt++; goto process_flags;
++ case '`':
++ backtick_quoting= TRUE; fmt++; goto process_flags;
+ case '#':
+ /** @todo Implement "#" conversion flag. */ fmt++; goto process_flags;
+ case ' ':
+@@ -400,9 +438,19 @@
+ reg2 char *par = va_arg(args, char *);
+ size_t length2 = strlen(par);
+ /* TODO: implement precision */
+- out_length+= length2;
+- if (my_b_write(info, (uchar*) par, length2))
+- goto err;
++ if (backtick_quoting)
++ {
++ size_t total= my_b_write_backtick_quote(info, (uchar *) par, length2);
++ if (total == (size_t)-1)
++ goto err;
++ out_length+= total;
++ }
++ else
++ {
++ out_length+= length2;
++ if (my_b_write(info, (uchar*) par, length2))
++ goto err;
++ }
+ }
+ else if (*fmt == 'b') /* Sized buffer parameter, only precision makes sense */
+ {
+
+=== modified file 'sql/ha_ndbcluster_binlog.cc'
+--- sql/ha_ndbcluster_binlog.cc 2012-01-13 14:50:02 +0000
++++ sql/ha_ndbcluster_binlog.cc 2012-08-24 13:29:01 +0000
+@@ -1295,7 +1295,9 @@
+ DBUG_RETURN(0);
+ }
+
+- char tmp_buf2[FN_REFLEN];
++ char tmp_buf2_mem[FN_REFLEN];
++ String tmp_buf2(tmp_buf2_mem, sizeof(tmp_buf2_mem), system_charset_info);
++ tmp_buf2.length(0);
+ const char *type_str;
+ switch (type)
+ {
+@@ -1304,17 +1306,24 @@
+ if (thd->lex->sql_command == SQLCOM_DROP_DB)
+ DBUG_RETURN(0);
+ /* redo the drop table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "drop table `",
+- table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("drop table "));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "drop table";
+ break;
+ case SOT_RENAME_TABLE:
+ /* redo the rename table query as is may contain several tables */
+- query= tmp_buf2;
+- query_length= (uint) (strxmov(tmp_buf2, "rename table `",
+- db, ".", table_name, "` to `",
+- new_db, ".", new_table_name, "`", NullS) - tmp_buf2);
++ tmp_buf2.append(STRING_WITH_LEN("rename table "));
++ append_identifier(thd, &tmp_buf2, db, strlen(db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, table_name, strlen(table_name));
++ tmp_buf2.append(STRING_WITH_LEN(" to "));
++ append_identifier(thd, &tmp_buf2, new_db, strlen(new_db));
++ tmp_buf2.append(STRING_WITH_LEN("."));
++ append_identifier(thd, &tmp_buf2, new_table_name, strlen(new_table_name));
++ query= tmp_buf2.c_ptr_safe();
++ query_length= tmp_buf2.length();
+ type_str= "rename table";
+ break;
+ case SOT_CREATE_TABLE:
+
+=== modified file 'sql/item.cc'
+--- sql/item.cc 2012-08-09 15:22:00 +0000
++++ sql/item.cc 2012-08-24 13:29:01 +0000
+@@ -992,15 +992,31 @@
+ if (!my_charset_same(cs, system_charset_info))
+ {
+ size_t res_length;
+- name= sql_strmake_with_convert(str, name_length= length, cs,
++ name= sql_strmake_with_convert(str, length, cs,
+ MAX_ALIAS_NAME, system_charset_info,
+ &res_length);
++ name_length= res_length;
+ }
+ else
+ name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
+ }
+
+
++void Item::set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs)
++{
++ if (!my_charset_same(cs, system_charset_info))
++ {
++ size_t res_length;
++ name= sql_strmake_with_convert(str, length, cs,
++ UINT_MAX, system_charset_info,
++ &res_length);
++ name_length= res_length;
++ }
++ else
++ name= sql_strmake(str, (name_length= length));
++}
++
++
+ void Item::set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs)
+ {
+
+=== modified file 'sql/item.h'
+--- sql/item.h 2012-06-06 19:26:40 +0000
++++ sql/item.h 2012-08-24 13:29:01 +0000
+@@ -656,6 +656,7 @@
+ #endif
+ } /*lint -e1509 */
+ void set_name(const char *str, uint length, CHARSET_INFO *cs);
++ void set_name_no_truncate(const char *str, uint length, CHARSET_INFO *cs);
+ void set_name_for_rollback(THD *thd, const char *str, uint length,
+ CHARSET_INFO *cs);
+ void rename(char *new_name);
+
+=== modified file 'sql/item_func.cc'
+--- sql/item_func.cc 2012-06-20 11:01:28 +0000
++++ sql/item_func.cc 2012-08-24 13:29:01 +0000
+@@ -5443,10 +5443,10 @@
+ }
+
+
+-void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
++void Item_user_var_as_out_param::print_for_load(THD *thd, String *str)
+ {
+ str->append('@');
+- str->append(name.str,name.length);
++ append_identifier(thd, str, name.str, name.length);
+ }
+
+
+
+=== modified file 'sql/item_func.h'
+--- sql/item_func.h 2012-06-15 07:01:20 +0000
++++ sql/item_func.h 2012-08-24 13:29:01 +0000
+@@ -1670,7 +1670,7 @@
+ my_decimal *val_decimal(my_decimal *decimal_buffer);
+ /* fix_fields() binds variable name with its entry structure */
+ bool fix_fields(THD *thd, Item **ref);
+- virtual void print(String *str, enum_query_type query_type);
++ void print_for_load(THD *thd, String *str);
+ void set_null_value(CHARSET_INFO* cs);
+ void set_value(const char *str, uint length, CHARSET_INFO* cs);
+ };
+
+=== modified file 'sql/log.cc'
+--- sql/log.cc 2012-08-09 15:22:00 +0000
++++ sql/log.cc 2012-08-24 13:29:01 +0000
+@@ -52,6 +52,7 @@
+ #include "sql_plugin.h"
+ #include "rpl_handler.h"
+ #include "debug_sync.h"
++#include "sql_show.h"
+
+ /* max size of the log message */
+ #define MAX_LOG_BUFFER_SIZE 1024
+@@ -2073,9 +2074,8 @@
+
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("SAVEPOINT ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+@@ -2097,9 +2097,8 @@
+ {
+ String log_query;
+ if (log_query.append(STRING_WITH_LEN("ROLLBACK TO ")) ||
+- log_query.append("`") ||
+- log_query.append(thd->lex->ident.str, thd->lex->ident.length) ||
+- log_query.append("`"))
++ append_identifier(thd, &log_query,
++ thd->lex->ident.str, thd->lex->ident.length))
+ DBUG_RETURN(1);
+ int errcode= query_error_code(thd, thd->killed == NOT_KILLED);
+ Query_log_event qinfo(thd, log_query.ptr(), log_query.length(),
+
+=== modified file 'sql/log_event.cc'
+--- sql/log_event.cc 2012-08-22 15:03:31 +0000
++++ sql/log_event.cc 2012-08-24 13:29:01 +0000
+@@ -46,6 +46,7 @@
+ #include "rpl_record.h"
+ #include "transaction.h"
+ #include <my_dir.h>
++#include "sql_show.h"
+
+ #endif /* MYSQL_CLIENT */
+
+@@ -471,29 +472,28 @@
+ pretty_print_str()
+ */
+
+-static char *pretty_print_str(char *packet, const char *str, int len)
++static void
++pretty_print_str(String *packet, const char *str, int len)
+ {
+ const char *end= str + len;
+- char *pos= packet;
+- *pos++= '\'';
++ packet->append(STRING_WITH_LEN("'"));
+ while (str < end)
+ {
+ char c;
+ switch ((c=*str++)) {
+- case '\n': *pos++= '\\'; *pos++= 'n'; break;
+- case '\r': *pos++= '\\'; *pos++= 'r'; break;
+- case '\\': *pos++= '\\'; *pos++= '\\'; break;
+- case '\b': *pos++= '\\'; *pos++= 'b'; break;
+- case '\t': *pos++= '\\'; *pos++= 't'; break;
+- case '\'': *pos++= '\\'; *pos++= '\''; break;
+- case 0 : *pos++= '\\'; *pos++= '0'; break;
++ case '\n': packet->append(STRING_WITH_LEN("\\n")); break;
++ case '\r': packet->append(STRING_WITH_LEN("\\r")); break;
++ case '\\': packet->append(STRING_WITH_LEN("\\\\")); break;
++ case '\b': packet->append(STRING_WITH_LEN("\\b")); break;
++ case '\t': packet->append(STRING_WITH_LEN("\\t")); break;
++ case '\'': packet->append(STRING_WITH_LEN("\\'")); break;
++ case 0 : packet->append(STRING_WITH_LEN("\\0")); break;
+ default:
+- *pos++= c;
++ packet->append(&c, 1);
+ break;
+ }
+ }
+- *pos++= '\'';
+- return pos;
++ packet->append(STRING_WITH_LEN("'"));
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -926,7 +926,7 @@
+ Log_event::pack_info()
+ */
+
+-void Log_event::pack_info(Protocol *protocol)
++void Log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ protocol->store("", &my_charset_bin);
+ }
+@@ -935,7 +935,8 @@
+ /**
+ Only called by SHOW BINLOG EVENTS
+ */
+-int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
++int Log_event::net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos)
+ {
+ const char *p= strrchr(log_name, FN_LIBCHAR);
+ const char *event_type;
+@@ -949,7 +950,7 @@
+ protocol->store(event_type, strlen(event_type), &my_charset_bin);
+ protocol->store((uint32) server_id);
+ protocol->store((ulonglong) log_pos);
+- pack_info(protocol);
++ pack_info(thd, protocol);
+ return protocol->write();
+ }
+ #endif /* HAVE_REPLICATION */
+@@ -2448,27 +2449,22 @@
+ show the catalog ??
+ */
+
+-void Query_log_event::pack_info(Protocol *protocol)
++void Query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ // TODO: show the catalog ??
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len);
+ if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
+ && db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf.append(STRING_WITH_LEN("use "));
++ append_identifier(thd, &buf, db, db_len);
++ buf.append("; ");
+ }
+ if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf);
++ buf.append(query, q_len);
++ protocol->store(&buf);
+ }
+ #endif
+
+@@ -3334,11 +3330,17 @@
+ }
+ else if (db)
+ {
++ /* Room for expand ` to `` + initial/final ` + \0 */
++ char buf[FN_REFLEN*2+3];
++
+ different_db= memcmp(print_event_info->db, db, db_len + 1);
+ if (different_db)
+ memcpy(print_event_info->db, db, db_len + 1);
+ if (db[0] && different_db)
+- my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
++ {
++ my_snprintf(buf, sizeof(buf), "%`s", db);
++ my_b_printf(file, "use %s%s\n", buf, print_event_info->delimiter);
++ }
+ }
+
+ end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
+@@ -4003,7 +4005,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Start_log_event_v3::pack_info(Protocol *protocol)
++void Start_log_event_v3::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
+ pos= strmov(buf, "Server ver: ");
+@@ -4779,131 +4781,113 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-uint Load_log_event::get_query_buffer_length()
+-{
+- return
+- 5 + db_len + 3 + // "use DB; "
+- 18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
+- 11 + // "CONCURRENT "
+- 7 + // LOCAL
+- 9 + // " REPLACE or IGNORE "
+- 13 + table_name_len*2 + // "INTO TABLE `table`"
+- 21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
+- 23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
+- 12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
+- 21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
+- 19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
+- 15 + 22 + // " IGNORE xxx LINES"
+- 3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
+-}
+-
+-
+-void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
+- char **end, char **fn_start, char **fn_end)
+-{
+- char *pos= buf;
+-
++void Load_log_event::print_query(THD *thd, bool need_db, const char *cs,
++ String *buf, my_off_t *fn_start,
++ my_off_t *fn_end, const char *qualify_db)
++{
+ if (need_db && db && db_len)
+ {
+- pos= strmov(pos, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
++ buf->append(STRING_WITH_LEN("use "));
++ append_identifier(thd, buf, db, db_len);
++ buf->append(STRING_WITH_LEN("; "));
+ }
+
+- pos= strmov(pos, "LOAD DATA ");
++ buf->append(STRING_WITH_LEN("LOAD DATA "));
+
+ if (is_concurrent)
+- pos= strmov(pos, "CONCURRENT ");
++ buf->append(STRING_WITH_LEN("CONCURRENT "));
+
+ if (fn_start)
+- *fn_start= pos;
++ *fn_start= buf->length();
+
+ if (check_fname_outside_temp_buf())
+- pos= strmov(pos, "LOCAL ");
+- pos= strmov(pos, "INFILE '");
+- memcpy(pos, fname, fname_len);
+- pos= strmov(pos+fname_len, "' ");
++ buf->append(STRING_WITH_LEN("LOCAL "));
++ buf->append(STRING_WITH_LEN("INFILE '"));
++ buf->append_for_single_quote(fname, fname_len);
++ buf->append(STRING_WITH_LEN("' "));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+- pos= strmov(pos, "REPLACE ");
++ buf->append(STRING_WITH_LEN("REPLACE "));
+ else if (sql_ex.opt_flags & IGNORE_FLAG)
+- pos= strmov(pos, "IGNORE ");
++ buf->append(STRING_WITH_LEN("IGNORE "));
+
+- pos= strmov(pos ,"INTO");
++ buf->append(STRING_WITH_LEN("INTO"));
+
+ if (fn_end)
+- *fn_end= pos;
++ *fn_end= buf->length();
+
+- pos= strmov(pos ," TABLE `");
+- memcpy(pos, table_name, table_name_len);
+- pos+= table_name_len;
++ buf->append(STRING_WITH_LEN(" TABLE "));
++ if (qualify_db)
++ {
++ append_identifier(thd, buf, qualify_db, strlen(qualify_db));
++ buf->append(STRING_WITH_LEN("."));
++ }
++ append_identifier(thd, buf, table_name, table_name_len);
+
+ if (cs != NULL)
+ {
+- pos= strmov(pos ,"` CHARACTER SET ");
+- pos= strmov(pos , cs);
++ buf->append(STRING_WITH_LEN(" CHARACTER SET "));
++ buf->append(cs, strlen(cs));
+ }
+- else
+- pos= strmov(pos, "`");
+
+ /* We have to create all optional fields as the default is not empty */
+- pos= strmov(pos, " FIELDS TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
++ buf->append(STRING_WITH_LEN(" FIELDS TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.field_term, sql_ex.field_term_len);
+ if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
+- pos= strmov(pos, " OPTIONALLY ");
+- pos= strmov(pos, " ENCLOSED BY ");
+- pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
+-
+- pos= strmov(pos, " ESCAPED BY ");
+- pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
+-
+- pos= strmov(pos, " LINES TERMINATED BY ");
+- pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
++ buf->append(STRING_WITH_LEN(" OPTIONALLY "));
++ buf->append(STRING_WITH_LEN(" ENCLOSED BY "));
++ pretty_print_str(buf, sql_ex.enclosed, sql_ex.enclosed_len);
++
++ buf->append(STRING_WITH_LEN(" ESCAPED BY "));
++ pretty_print_str(buf, sql_ex.escaped, sql_ex.escaped_len);
++
++ buf->append(STRING_WITH_LEN(" LINES TERMINATED BY "));
++ pretty_print_str(buf, sql_ex.line_term, sql_ex.line_term_len);
+ if (sql_ex.line_start_len)
+ {
+- pos= strmov(pos, " STARTING BY ");
+- pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
++ buf->append(STRING_WITH_LEN(" STARTING BY "));
++ pretty_print_str(buf, sql_ex.line_start, sql_ex.line_start_len);
+ }
+
+ if ((long) skip_lines > 0)
+ {
+- pos= strmov(pos, " IGNORE ");
+- pos= longlong10_to_str((longlong) skip_lines, pos, 10);
+- pos= strmov(pos," LINES ");
++ buf->append(STRING_WITH_LEN(" IGNORE "));
++ buf->append_ulonglong(skip_lines);
++ buf->append(STRING_WITH_LEN(" LINES "));
+ }
+
+ if (num_fields)
+ {
+ uint i;
+ const char *field= fields;
+- pos= strmov(pos, " (");
++ buf->append(STRING_WITH_LEN(" ("));
+ for (i = 0; i < num_fields; i++)
+ {
+ if (i)
+ {
+- *pos++= ' ';
+- *pos++= ',';
++ /*
++ Yes, the space and comma is reversed here. But this is mostly dead
++ code, at most used when reading really old binlogs from old servers,
++ so better just leave it as is...
++ */
++ buf->append(STRING_WITH_LEN(" ,"));
+ }
+- memcpy(pos, field, field_lens[i]);
+- pos+= field_lens[i];
++ append_identifier(thd, buf, field, field_lens[i]);
+ field+= field_lens[i] + 1;
+ }
+- *pos++= ')';
++ buf->append(STRING_WITH_LEN(")"));
+ }
+-
+- *end= pos;
+ }
+
+
+-void Load_log_event::pack_info(Protocol *protocol)
++void Load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *end;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+
+- if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
+- return;
+- print_query(TRUE, NULL, buf, &end, 0, 0);
+- protocol->store(buf, end-buf, &my_charset_bin);
+- my_free(buf);
++ query_str.length(0);
++ print_query(thd, TRUE, NULL, &query_str, 0, 0, NULL);
++ protocol->store(query_str.ptr(), query_str.length(), &my_charset_bin);
+ }
+ #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
+
+@@ -5361,16 +5345,20 @@
+ else
+ {
+ char llbuff[22];
+- char *end;
+ enum enum_duplicates handle_dup;
+ bool ignore= 0;
++ char query_buffer[1024];
++ String query_str(query_buffer, sizeof(query_buffer), system_charset_info);
+ char *load_data_query;
+
++ query_str.length(0);
+ /*
+ Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
+ and written to slave's binlog if binlogging is on.
+ */
+- if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
++ print_query(thd, FALSE, NULL, &query_str, NULL, NULL, NULL);
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(),
++ query_str.length())))
+ {
+ /*
+ This will set thd->fatal_error in case of OOM. So we surely will notice
+@@ -5379,9 +5367,7 @@
+ goto error;
+ }
+
+- print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
+- *end= 0;
+- thd->set_query(load_data_query, (uint) (end - load_data_query));
++ thd->set_query(load_data_query, (uint) (query_str.length()));
+
+ if (sql_ex.opt_flags & REPLACE_FLAG)
+ handle_dup= DUP_REPLACE;
+@@ -5559,7 +5545,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rotate_log_event::pack_info(Protocol *protocol)
++void Rotate_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], buf[22];
+ String tmp(buf1, sizeof(buf1), log_cs);
+@@ -5777,7 +5763,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Intvar_log_event::pack_info(Protocol *protocol)
++void Intvar_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256], *pos;
+ pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
+@@ -5931,7 +5917,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rand_log_event::pack_info(Protocol *protocol)
++void Rand_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf1[256], *pos;
+ pos= strmov(buf1,"rand_seed1=");
+@@ -6056,7 +6042,7 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Xid_log_event::pack_info(Protocol *protocol)
++void Xid_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[128], *pos;
+ pos= strmov(buf, "COMMIT /* xid=");
+@@ -6153,84 +6139,117 @@
+ **************************************************************************/
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void User_var_log_event::pack_info(Protocol* protocol)
++static bool
++user_var_append_name_part(THD *thd, String *buf,
++ const char *name, size_t name_len)
+ {
+- char *buf= 0;
+- uint val_offset= 4 + name_len;
+- uint event_len= val_offset;
++ return buf->append("@") ||
++ append_identifier(thd, buf, name, name_len) ||
++ buf->append("=");
++}
+
++void User_var_log_event::pack_info(THD *thd, Protocol* protocol)
++{
+ if (is_null)
+ {
+- if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
++ char buf_mem[FN_REFLEN+7];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("NULL"))
+ return;
+- strmov(buf + val_offset, "NULL");
+- event_len= val_offset + 4;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+ else
+ {
+ switch (type) {
+ case REAL_RESULT:
++ {
+ double real_val;
++ char buf2[MY_GCVT_MAX_FIELD_WIDTH+1];
++ char buf_mem[FN_REFLEN + MY_GCVT_MAX_FIELD_WIDTH + 1];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ float8get(real_val, val);
+- if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
+- MYF(MY_WME))))
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2, my_gcvt(real_val, MY_GCVT_ARG_DOUBLE,
++ MY_GCVT_MAX_FIELD_WIDTH, buf2, NULL)))
+ return;
+- event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
+- buf + val_offset, NULL);
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case INT_RESULT:
+- if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
++ {
++ char buf2[22];
++ char buf_mem[FN_REFLEN + 22];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.length(0);
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2,
++ longlong10_to_str(uint8korr(val), buf2,
++ ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10))-buf2))
+ return;
+- event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
+- ((flags & User_var_log_event::UNSIGNED_F) ?
+- 10 : -10))-buf;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case DECIMAL_RESULT:
+ {
+- if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
+- MYF(MY_WME))))
+- return;
+- String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
++ char buf_mem[FN_REFLEN + DECIMAL_MAX_STR_LENGTH];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ char buf2[DECIMAL_MAX_STR_LENGTH+1];
++ String str(buf2, sizeof(buf2), &my_charset_bin);
+ my_decimal dec;
++ buf.length(0);
+ binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
+ val[1]);
+ my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
+- event_len= str.length() + val_offset;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append(buf2))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
+- }
++ }
+ case STRING_RESULT:
++ {
+ /* 15 is for 'COLLATE' and other chars */
+- buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
+- MYF(MY_WME));
++ char buf_mem[FN_REFLEN + 512 + 1 + 2*MY_CS_NAME_SIZE+15];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
+ CHARSET_INFO *cs;
+- if (!buf)
+- return;
++ buf.length(0);
+ if (!(cs= get_charset(charset_number, MYF(0))))
+ {
+- strmov(buf+val_offset, "???");
+- event_len+= 3;
++ if (buf.append("???"))
++ return;
+ }
+ else
+ {
+- char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
+- p= str_to_hex(p, val, val_len);
+- p= strxmov(p, " COLLATE ", cs->name, NullS);
+- event_len= p-buf;
++ size_t old_len;
++ char *beg, *end;
++ if (user_var_append_name_part(thd, &buf, name, name_len) ||
++ buf.append("_") ||
++ buf.append(cs->csname) ||
++ buf.append(" "))
++ return;
++ old_len= buf.length();
++ if (buf.reserve(old_len + val_len*2 + 2 + sizeof(" COLLATE ") +
++ MY_CS_NAME_SIZE))
++ return;
++ beg= const_cast<char *>(buf.ptr()) + old_len;
++ end= str_to_hex(beg, val, val_len);
++ buf.length(old_len + (end - beg));
++ if (buf.append(" COLLATE ") ||
++ buf.append(cs->name))
++ return;
+ }
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ break;
++ }
+ case ROW_RESULT:
+ default:
+ DBUG_ASSERT(0);
+ return;
+ }
+ }
+- buf[0]= '@';
+- buf[1]= '`';
+- memcpy(buf+2, name, name_len);
+- buf[2+name_len]= '`';
+- buf[3+name_len]= '=';
+- protocol->store(buf, event_len, &my_charset_bin);
+- my_free(buf);
+ }
+ #endif /* !MYSQL_CLIENT */
+
+@@ -6388,9 +6407,8 @@
+ my_b_printf(&cache, "\tUser_var\n");
+ }
+
+- my_b_printf(&cache, "SET @`");
+- my_b_write(&cache, (uchar*) name, (uint) (name_len));
+- my_b_printf(&cache, "`");
++ my_b_printf(&cache, "SET @");
++ my_b_write_backtick_quote(&cache, name, name_len);
+
+ if (is_null)
+ {
+@@ -6613,7 +6631,7 @@
+ #endif
+
+ #ifndef MYSQL_CLIENT
+-void Slave_log_event::pack_info(Protocol *protocol)
++void Slave_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256+HOSTNAME_LENGTH], *pos;
+ pos= strmov(buf, "host=");
+@@ -6995,7 +7013,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Create_file_log_event::pack_info(Protocol *protocol)
++void Create_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[SAFE_NAME_LEN*2 + 30 + 21*2], *pos;
+ pos= strmov(buf, "db=");
+@@ -7181,7 +7199,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Append_block_log_event::pack_info(Protocol *protocol)
++void Append_block_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ uint length;
+@@ -7338,7 +7356,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Delete_file_log_event::pack_info(Protocol *protocol)
++void Delete_file_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -7437,7 +7455,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_log_event::pack_info(Protocol *protocol)
++void Execute_load_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[64];
+ uint length;
+@@ -7699,27 +7717,24 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Execute_load_query_log_event::pack_info(Protocol *protocol)
++void Execute_load_query_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+- char *buf, *pos;
+- if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
+- return;
+- pos= buf;
++ char buf_mem[1024];
++ String buf(buf_mem, sizeof(buf_mem), system_charset_info);
++ buf.real_alloc(9 + db_len + q_len + 10 + 21);
+ if (db && db_len)
+ {
+- pos= strmov(buf, "use `");
+- memcpy(pos, db, db_len);
+- pos= strmov(pos+db_len, "`; ");
+- }
+- if (query && q_len)
+- {
+- memcpy(pos, query, q_len);
+- pos+= q_len;
+- }
+- pos= strmov(pos, " ;file_id=");
+- pos= int10_to_str((long) file_id, pos, 10);
+- protocol->store(buf, pos-buf, &my_charset_bin);
+- my_free(buf);
++ if (buf.append("use ") ||
++ append_identifier(thd, &buf, db, db_len) ||
++ buf.append("; "))
++ return;
++ }
++ if (query && q_len && buf.append(query, q_len))
++ return;
++ if (buf.append(" ;file_id=") ||
++ buf.append_ulonglong(file_id))
++ return;
++ protocol->store(buf.ptr(), buf.length(), &my_charset_bin);
+ }
+
+
+@@ -8682,7 +8697,7 @@
+ #endif
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Rows_log_event::pack_info(Protocol *protocol)
++void Rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+@@ -8786,7 +8801,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+-void Annotate_rows_log_event::pack_info(Protocol* protocol)
++void Annotate_rows_log_event::pack_info(THD *thd, Protocol* protocol)
+ {
+ if (m_query_txt && m_query_len)
+ protocol->store(m_query_txt, m_query_len, &my_charset_bin);
+@@ -9530,7 +9545,7 @@
+ */
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Table_map_log_event::pack_info(Protocol *protocol)
++void Table_map_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes= my_snprintf(buf, sizeof(buf),
+@@ -9551,7 +9566,7 @@
+ {
+ print_header(&print_event_info->head_cache, print_event_info, TRUE);
+ my_b_printf(&print_event_info->head_cache,
+- "\tTable_map: `%s`.`%s` mapped to number %lu\n",
++ "\tTable_map: %`s.%`s mapped to number %lu\n",
+ m_dbnam, m_tblnam, m_table_id);
+ print_base64(&print_event_info->body_cache, print_event_info, TRUE);
+ }
+@@ -10884,7 +10899,7 @@
+
+
+ #ifndef MYSQL_CLIENT
+-void Incident_log_event::pack_info(Protocol *protocol)
++void Incident_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ size_t bytes;
+
+=== modified file 'sql/log_event.h'
+--- sql/log_event.h 2012-08-09 15:22:00 +0000
++++ sql/log_event.h 2012-08-24 13:29:01 +0000
+@@ -1065,14 +1065,15 @@
+ */
+ static void init_show_field_list(List<Item>* field_list);
+ #ifdef HAVE_REPLICATION
+- int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
++ int net_send(THD *thd, Protocol *protocol, const char* log_name,
++ my_off_t pos);
+
+ /*
+ pack_info() is used by SHOW BINLOG EVENTS; as print() it prepares and sends
+ a string to display to the user, so it resembles print().
+ */
+
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+
+ #endif /* HAVE_REPLICATION */
+ virtual const char* get_db()
+@@ -1809,7 +1810,7 @@
+ bool using_trans, bool direct, bool suppress_use, int error);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -1939,7 +1940,7 @@
+
+ #ifdef MYSQL_SERVER
+ Slave_log_event(THD* thd_arg, Relay_log_info* rli);
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2172,9 +2173,9 @@
+ const Format_description_log_event* description_event);
+
+ public:
+- uint get_query_buffer_length();
+- void print_query(bool need_db, const char *cs, char *buf, char **end,
+- char **fn_start, char **fn_end);
++ void print_query(THD *thd, bool need_db, const char *cs, String *buf,
++ my_off_t *fn_start, my_off_t *fn_end,
++ const char *qualify_db);
+ ulong thread_id;
+ ulong slave_proxy_id;
+ uint32 table_name_len;
+@@ -2235,7 +2236,7 @@
+ Name_resolution_context *context);
+ const char* get_db() { return db; }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2332,7 +2333,7 @@
+ #ifdef MYSQL_SERVER
+ Start_log_event_v3();
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ Start_log_event_v3() {}
+@@ -2496,7 +2497,7 @@
+ cache_type= Log_event::EVENT_NO_CACHE;
+ }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2576,7 +2577,7 @@
+ cache_type= Log_event::EVENT_NO_CACHE;
+ }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2625,7 +2626,7 @@
+ cache_type= Log_event::EVENT_NO_CACHE;
+ }
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2687,7 +2688,7 @@
+ if (direct)
+ cache_type= Log_event::EVENT_NO_CACHE;
+ }
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+ #endif
+@@ -2825,7 +2826,7 @@
+ uint ident_len_arg,
+ ulonglong pos_arg, uint flags);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2886,7 +2887,7 @@
+ uchar* block_arg, uint block_len_arg,
+ bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -2958,7 +2959,7 @@
+ Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
+ uint block_len_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ virtual int get_create_or_append() const;
+ #endif /* HAVE_REPLICATION */
+ #else
+@@ -2999,7 +3000,7 @@
+ #ifdef MYSQL_SERVER
+ Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3040,7 +3041,7 @@
+ #ifdef MYSQL_SERVER
+ Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3136,7 +3137,7 @@
+ bool using_trans, bool direct,
+ bool suppress_use, int errcode);
+ #ifdef HAVE_REPLICATION
+- void pack_info(Protocol* protocol);
++ void pack_info(THD *thd, Protocol* protocol);
+ #endif /* HAVE_REPLICATION */
+ #else
+ void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
+@@ -3222,7 +3223,7 @@
+ #endif
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol*);
++ virtual void pack_info(THD *thd, Protocol*);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3636,7 +3637,7 @@
+ #endif
+
+ #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -3748,7 +3749,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+@@ -4195,7 +4196,7 @@
+ #endif
+
+ #ifdef MYSQL_SERVER
+- void pack_info(Protocol*);
++ void pack_info(THD *thd, Protocol*);
+ #endif
+
+ Incident_log_event(const char *buf, uint event_len,
+
+=== modified file 'sql/log_event_old.cc'
+--- sql/log_event_old.cc 2012-06-14 18:05:31 +0000
++++ sql/log_event_old.cc 2012-08-24 13:29:01 +0000
+@@ -1935,7 +1935,7 @@
+
+
+ #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
+-void Old_rows_log_event::pack_info(Protocol *protocol)
++void Old_rows_log_event::pack_info(THD *thd, Protocol *protocol)
+ {
+ char buf[256];
+ char const *const flagstr=
+
+=== modified file 'sql/log_event_old.h'
+--- sql/log_event_old.h 2012-03-13 14:38:43 +0000
++++ sql/log_event_old.h 2012-08-24 12:02:32 +0000
+@@ -108,7 +108,7 @@
+ flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
+
+ #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
+- virtual void pack_info(Protocol *protocol);
++ virtual void pack_info(THD *thd, Protocol *protocol);
+ #endif
+
+ #ifdef MYSQL_CLIENT
+
+=== modified file 'sql/repl_failsafe.cc'
+--- sql/repl_failsafe.cc 2012-01-13 14:50:02 +0000
++++ sql/repl_failsafe.cc 2012-08-24 13:29:01 +0000
+@@ -35,7 +35,6 @@
+ #include "rpl_mi.h"
+ #include "rpl_filter.h"
+ #include "log_event.h"
+-#include "sql_db.h" // mysql_create_db
+ #include <mysql.h>
+
+ #define SLAVE_LIST_CHUNK 128
+
+=== modified file 'sql/rpl_record.cc'
+--- sql/rpl_record.cc 2012-03-17 08:26:58 +0000
++++ sql/rpl_record.cc 2012-08-24 13:29:01 +0000
+@@ -314,7 +314,7 @@
+ if (!pack_ptr)
+ {
+ rli->report(ERROR_LEVEL, ER_SLAVE_CORRUPT_EVENT,
+- "Could not read field `%s` of table `%s`.`%s`",
++ "Could not read field %`s of table %`s.%`s",
+ f->field_name, table->s->db.str,
+ table->s->table_name.str);
+ DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
+
+=== modified file 'sql/sql_base.cc'
+--- sql/sql_base.cc 2012-08-09 15:22:00 +0000
++++ sql/sql_base.cc 2012-08-24 13:29:01 +0000
+@@ -3887,22 +3887,22 @@
+ entry->file->implicit_emptied= 0;
+ if (mysql_bin_log.is_open())
+ {
+- char *query, *end;
+- uint query_buf_size= 20 + share->db.length + share->table_name.length +1;
+- if ((query= (char*) my_malloc(query_buf_size,MYF(MY_WME))))
++ char query_buf[2*FN_REFLEN + 21];
++ String query(query_buf, sizeof(query_buf), system_charset_info);
++ query.length(0);
++ if (query.ptr())
+ {
+ /* this DELETE FROM is needed even with row-based binlogging */
+- end = strxmov(strmov(query, "DELETE FROM `"),
+- share->db.str,"`.`",share->table_name.str,"`", NullS);
++ query.append("DELETE FROM ");
++ append_identifier(thd, &query, share->db.str, share->db.length);
++ query.append(".");
++ append_identifier(thd, &query, share->table_name.str,
++ share->table_name.length);
+ int errcode= query_error_code(thd, TRUE);
+ if (thd->binlog_query(THD::STMT_QUERY_TYPE,
+- query, (ulong)(end-query),
++ query.ptr(), query.length(),
+ FALSE, FALSE, FALSE, errcode))
+- {
+- my_free(query);
+ return TRUE;
+- }
+- my_free(query);
+ }
+ else
+ {
+@@ -3912,7 +3912,7 @@
+ because of MYF(MY_WME) in my_malloc() above).
+ */
+ sql_print_error("When opening HEAP table, could not allocate memory "
+- "to write 'DELETE FROM `%s`.`%s`' to the binary log",
++ "to write 'DELETE FROM %`s.%`s' to the binary log",
+ share->db.str, share->table_name.str);
+ delete entry->triggers;
+ return TRUE;
+
+=== modified file 'sql/sql_db.cc'
+--- sql/sql_db.cc 2012-01-13 14:50:02 +0000
++++ sql/sql_db.cc 2012-08-24 13:29:01 +0000
+@@ -544,7 +544,6 @@
+ bool silent)
+ {
+ char path[FN_REFLEN+16];
+- char tmp_query[FN_REFLEN+16];
+ long result= 1;
+ int error= 0;
+ MY_STAT stat_info;
+@@ -622,17 +621,9 @@
+ char *query;
+ uint query_length;
+
+- if (!thd->query()) // Only in replication
+- {
+- query= tmp_query;
+- query_length= (uint) (strxmov(tmp_query,"create database `",
+- db, "`", NullS) - tmp_query);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
+
+ ha_binlog_log_query(thd, 0, LOGCOM_CREATE_DB,
+ query, query_length,
+@@ -885,18 +876,11 @@
+ {
+ const char *query;
+ ulong query_length;
+- if (!thd->query())
+- {
+- /* The client used the old obsolete mysql_drop_db() call */
+- query= path;
+- query_length= (uint) (strxmov(path, "drop database `", db, "`",
+- NullS) - path);
+- }
+- else
+- {
+- query= thd->query();
+- query_length= thd->query_length();
+- }
++
++ query= thd->query();
++ query_length= thd->query_length();
++ DBUG_ASSERT(query);
++
+ if (mysql_bin_log.is_open())
+ {
+ int errcode= query_error_code(thd, TRUE);
+@@ -940,6 +924,7 @@
+ {
+ uint tbl_name_len;
+ bool exists;
++ char quoted_name[FN_REFLEN+3];
+
+ // Only write drop table to the binlog for tables that no longer exist.
+ if (check_if_table_exists(thd, tbl, &exists))
+@@ -950,8 +935,8 @@
+ if (exists)
+ continue;
+
+- /* 3 for the quotes and the comma*/
+- tbl_name_len= strlen(tbl->table_name) + 3;
++ my_snprintf(quoted_name, sizeof(quoted_name), "%`s", tbl->table_name);
++ tbl_name_len= strlen(quoted_name) + 1; /* +1 for the comma */
+ if (query_pos + tbl_name_len + 1 >= query_end)
+ {
+ /*
+@@ -966,9 +951,7 @@
+ query_pos= query_data_start;
+ }
+
+- *query_pos++ = '`';
+- query_pos= strmov(query_pos,tbl->table_name);
+- *query_pos++ = '`';
++ query_pos= strmov(query_pos, quoted_name);
+ *query_pos++ = ',';
+ }
+
+
+=== modified file 'sql/sql_load.cc'
+--- sql/sql_load.cc 2012-04-07 13:58:46 +0000
++++ sql/sql_load.cc 2012-08-24 13:29:01 +0000
+@@ -39,6 +39,7 @@
+ #include "sp_head.h"
+ #include "sql_trigger.h"
+ #include "sql_derived.h"
++#include "sql_show.h"
+
+ class XML_TAG {
+ public:
+@@ -675,24 +676,28 @@
+ bool transactional_table,
+ int errcode)
+ {
+- char *load_data_query,
+- *end,
+- *fname_start,
+- *fname_end,
+- *p= NULL;
+- size_t pl= 0;
++ char *load_data_query;
++ my_off_t fname_start,
++ fname_end;
+ List<Item> fv;
+ Item *item, *val;
+ int n;
+- const char *tbl= table_name_arg;
+ const char *tdb= (thd->db != NULL ? thd->db : db_arg);
+- char name_buffer[SAFE_NAME_LEN*2];
++ const char *qualify_db= NULL;
+ char command_buffer[1024];
+- String string_buf(name_buffer, sizeof(name_buffer),
+- system_charset_info);
+- String pfields(command_buffer, sizeof(command_buffer),
++ String query_str(command_buffer, sizeof(command_buffer),
+ system_charset_info);
+
++ Load_log_event lle(thd, ex, tdb, table_name_arg, fv, is_concurrent,
++ duplicates, ignore, transactional_table);
++
++ /*
++ force in a LOCAL if there was one in the original.
++ */
++ if (thd->lex->local_file)
++ lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++
++ query_str.length(0);
+ if (!thd->db || strcmp(db_arg, thd->db))
+ {
+ /*
+@@ -700,49 +705,35 @@
+ prefix table name with database name so that it
+ becomes a FQ name.
+ */
+- string_buf.length(0);
+- string_buf.append(db_arg);
+- string_buf.append("`");
+- string_buf.append(".");
+- string_buf.append("`");
+- string_buf.append(table_name_arg);
+- tbl= string_buf.c_ptr_safe();
++ qualify_db= db_arg;
+ }
+-
+- Load_log_event lle(thd, ex, tdb, tbl, fv, is_concurrent,
+- duplicates, ignore, transactional_table);
+-
+- /*
+- force in a LOCAL if there was one in the original.
+- */
+- if (thd->lex->local_file)
+- lle.set_fname_outside_temp_buf(ex->file_name, strlen(ex->file_name));
++ lle.print_query(thd, FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
++ &query_str, &fname_start, &fname_end, qualify_db);
+
+ /*
+ prepare fields-list and SET if needed; print_query won't do that for us.
+ */
+- pfields.length(0);
+ if (!thd->lex->field_list.is_empty())
+ {
+ List_iterator<Item> li(thd->lex->field_list);
+
+- pfields.append(" (");
++ query_str.append(" (");
+ n= 0;
+
+ while ((item= li++))
+ {
+ if (n++)
+- pfields.append(", ");
++ query_str.append(", ");
+ if (item->type() == Item::FIELD_ITEM)
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
++ else
+ {
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
++ /* Actually Item_user_var_as_out_param despite claiming STRING_ITEM. */
++ DBUG_ASSERT(item->type() == Item::STRING_ITEM);
++ ((Item_user_var_as_out_param *)item)->print_for_load(thd, &query_str);
+ }
+- else
+- item->print(&pfields, QT_ORDINARY);
+ }
+- pfields.append(")");
++ query_str.append(")");
+ }
+
+ if (!thd->lex->update_list.is_empty())
+@@ -750,38 +741,25 @@
+ List_iterator<Item> lu(thd->lex->update_list);
+ List_iterator<Item> lv(thd->lex->value_list);
+
+- pfields.append(" SET ");
++ query_str.append(" SET ");
+ n= 0;
+
+ while ((item= lu++))
+ {
+ val= lv++;
+ if (n++)
+- pfields.append(", ");
+- pfields.append("`");
+- pfields.append(item->name);
+- pfields.append("`");
+- pfields.append(val->name);
++ query_str.append(", ");
++ append_identifier(thd, &query_str, item->name, strlen(item->name));
++ query_str.append(val->name);
+ }
+ }
+
+- p= pfields.c_ptr_safe();
+- pl= pfields.length();
+-
+- if (!(load_data_query= (char *)thd->alloc(lle.get_query_buffer_length() + 1 + pl)))
++ if (!(load_data_query= (char *)thd->strmake(query_str.ptr(), query_str.length())))
+ return TRUE;
+
+- lle.print_query(FALSE, (const char *) ex->cs?ex->cs->csname:NULL,
+- load_data_query, &end,
+- (char **)&fname_start, (char **)&fname_end);
+-
+- strcpy(end, p);
+- end += pl;
+-
+ Execute_load_query_log_event
+- e(thd, load_data_query, end-load_data_query,
+- (uint) ((char*) fname_start - load_data_query - 1),
+- (uint) ((char*) fname_end - load_data_query),
++ e(thd, load_data_query, query_str.length(),
++ (uint) (fname_start - 1), (uint) fname_end,
+ (duplicates == DUP_REPLACE) ? LOAD_DUP_REPLACE :
+ (ignore ? LOAD_DUP_IGNORE : LOAD_DUP_ERROR),
+ transactional_table, FALSE, FALSE, errcode);
+
+=== modified file 'sql/sql_repl.cc'
+--- sql/sql_repl.cc 2012-08-09 15:22:00 +0000
++++ sql/sql_repl.cc 2012-08-24 13:29:01 +0000
+@@ -2000,7 +2000,7 @@
+ description_event->checksum_alg= ev->checksum_alg;
+
+ if (event_count >= limit_start &&
+- ev->net_send(protocol, linfo.log_file_name, pos))
++ ev->net_send(thd, protocol, linfo.log_file_name, pos))
+ {
+ errmsg = "Net error";
+ delete ev;
+
+=== modified file 'sql/sql_select.cc'
+--- sql/sql_select.cc 2012-08-21 12:24:43 +0000
++++ sql/sql_select.cc 2012-08-24 13:29:01 +0000
+@@ -16481,7 +16481,7 @@
+ && !table->in_use->killed)
+ {
+ push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error,
+- "Got error %d when reading table `%s`.`%s`",
++ "Got error %d when reading table %`s.%`s",
+ error, table->s->db.str, table->s->table_name.str);
+ sql_print_error("Got error %d when reading table '%s'",
+ error, table->s->path.str);
+
+=== modified file 'sql/sql_show.cc'
+--- sql/sql_show.cc 2012-08-09 15:22:00 +0000
++++ sql/sql_show.cc 2012-08-24 13:29:01 +0000
+@@ -992,9 +992,13 @@
+ packet target string
+ name the identifier to be appended
+ name_length length of the appending identifier
++
++ RETURN VALUES
++ true Error
++ false Ok
+ */
+
+-void
++bool
+ append_identifier(THD *thd, String *packet, const char *name, uint length)
+ {
+ const char *name_end;
+@@ -1002,10 +1006,7 @@
+ int q= get_quote_char_for_identifier(thd, name, length);
+
+ if (q == EOF)
+- {
+- packet->append(name, length, packet->charset());
+- return;
+- }
++ return packet->append(name, length, packet->charset());
+
+ /*
+ The identifier must be quoted as it includes a quote character or
+@@ -1014,7 +1015,8 @@
+
+ (void) packet->reserve(length*2 + 2);
+ quote_char= (char) q;
+- packet->append("e_char, 1, system_charset_info);
++ if (packet->append("e_char, 1, system_charset_info))
++ return true;
+
+ for (name_end= name+length ; name < name_end ; name+= length)
+ {
+@@ -1029,11 +1031,13 @@
+ */
+ if (!length)
+ length= 1;
+- if (length == 1 && chr == (uchar) quote_char)
+- packet->append("e_char, 1, system_charset_info);
+- packet->append(name, length, system_charset_info);
++ if (length == 1 && chr == (uchar) quote_char &&
++ packet->append("e_char, 1, system_charset_info))
++ return true;
++ if (packet->append(name, length, system_charset_info))
++ return true;
+ }
+- packet->append("e_char, 1, system_charset_info);
++ return packet->append("e_char, 1, system_charset_info);
+ }
+
+
+
+=== modified file 'sql/sql_show.h'
+--- sql/sql_show.h 2011-06-30 15:46:53 +0000
++++ sql/sql_show.h 2012-08-24 13:29:01 +0000
+@@ -90,7 +90,7 @@
+
+ int copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table);
+
+-void append_identifier(THD *thd, String *packet, const char *name,
++bool append_identifier(THD *thd, String *packet, const char *name,
+ uint length);
+ void mysqld_list_fields(THD *thd,TABLE_LIST *table, const char *wild);
+ int mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd);
+
+=== modified file 'sql/sql_string.cc'
+--- sql/sql_string.cc 2012-04-07 13:58:46 +0000
++++ sql/sql_string.cc 2012-08-24 13:29:01 +0000
+@@ -1121,39 +1121,47 @@
+
+
+
+-
+-void String::print(String *str)
++/*
++ Append characters to a single-quoted string '...', escaping special
++ characters as necessary.
++ Does not add the enclosing quotes, this is left up to caller.
++*/
++void String::append_for_single_quote(const char *st, uint len)
+ {
+- char *st= (char*)Ptr, *end= st+str_length;
++ const char *end= st+len;
+ for (; st < end; st++)
+ {
+ uchar c= *st;
+ switch (c)
+ {
+ case '\\':
+- str->append(STRING_WITH_LEN("\\\\"));
++ append(STRING_WITH_LEN("\\\\"));
+ break;
+ case '\0':
+- str->append(STRING_WITH_LEN("\\0"));
++ append(STRING_WITH_LEN("\\0"));
+ break;
+ case '\'':
+- str->append(STRING_WITH_LEN("\\'"));
++ append(STRING_WITH_LEN("\\'"));
+ break;
+ case '\n':
+- str->append(STRING_WITH_LEN("\\n"));
++ append(STRING_WITH_LEN("\\n"));
+ break;
+ case '\r':
+- str->append(STRING_WITH_LEN("\\r"));
++ append(STRING_WITH_LEN("\\r"));
+ break;
+ case '\032': // Ctrl-Z
+- str->append(STRING_WITH_LEN("\\Z"));
++ append(STRING_WITH_LEN("\\Z"));
+ break;
+ default:
+- str->append(c);
++ append(c);
+ }
+ }
+ }
+
++void String::print(String *str)
++{
++ str->append_for_single_quote(Ptr, str_length);
++}
+
+ /*
+ Exchange state of this object and argument.
+
+=== modified file 'sql/sql_string.h'
+--- sql/sql_string.h 2012-01-13 14:50:02 +0000
++++ sql/sql_string.h 2012-08-24 13:29:01 +0000
+@@ -459,6 +459,7 @@
+ return FALSE;
+ }
+ void print(String *print);
++ void append_for_single_quote(const char *st, uint len);
+
+ /* Swap two string objects. Efficient way to exchange data without memcpy. */
+ void swap(String &s);
+
+=== modified file 'sql/sql_table.cc'
+--- sql/sql_table.cc 2012-08-15 11:37:55 +0000
++++ sql/sql_table.cc 2012-08-24 13:29:01 +0000
+@@ -2104,6 +2104,7 @@
+ {
+ bool is_trans;
+ char *db=table->db;
++ size_t db_length= table->db_length;
+ handlerton *table_type;
+ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
+
+@@ -2165,14 +2166,14 @@
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+- built_ptr_query->append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_ptr_query->append(db);
+- built_ptr_query->append("`.`");
++ append_identifier(thd, built_ptr_query, db, db_length);
++ built_ptr_query->append(".");
+ }
+- built_ptr_query->append(table->table_name);
+- built_ptr_query->append("`,");
++ append_identifier(thd, built_ptr_query, table->table_name,
++ table->table_name_length);
++ built_ptr_query->append(",");
+ }
+ /*
+ This means that a temporary table was droped and as such there
+@@ -2228,15 +2229,15 @@
+ Don't write the database name if it is the current one (or if
+ thd->db is NULL).
+ */
+- built_query.append("`");
+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
+ {
+- built_query.append(db);
+- built_query.append("`.`");
++ append_identifier(thd, &built_query, db, db_length);
++ built_query.append(".");
+ }
+
+- built_query.append(table->table_name);
+- built_query.append("`,");
++ append_identifier(thd, &built_query, table->table_name,
++ table->table_name_length);
++ built_query.append(",");
+ }
+ }
+ DEBUG_SYNC(thd, "rm_table_no_locks_before_delete_table");
+
+=== modified file 'sql/sql_truncate.cc'
+--- sql/sql_truncate.cc 2012-05-16 22:47:28 +0000
++++ sql/sql_truncate.cc 2012-08-24 13:29:01 +0000
+@@ -24,6 +24,7 @@
+ #include "sql_acl.h" // DROP_ACL
+ #include "sql_parse.h" // check_one_table_access()
+ #include "sql_truncate.h"
++#include "sql_show.h"
+
+
+ /**
+@@ -35,7 +36,8 @@
+ @return TRUE on failure, FALSE otherwise.
+ */
+
+-static bool fk_info_append_fields(String *str, List<LEX_STRING> *fields)
++static bool fk_info_append_fields(THD *thd, String *str,
++ List<LEX_STRING> *fields)
+ {
+ bool res= FALSE;
+ LEX_STRING *field;
+@@ -43,9 +45,8 @@
+
+ while ((field= it++))
+ {
+- res|= str->append("`");
+- res|= str->append(field);
+- res|= str->append("`, ");
++ res|= append_identifier(thd, str, field->str, field->length);
++ res|= str->append(", ");
+ }
+
+ str->chop();
+@@ -76,20 +77,24 @@
+ `db`.`tbl`, CONSTRAINT `id` FOREIGN KEY (`fk`) REFERENCES `db`.`tbl` (`fk`)
+ */
+
+- res|= str.append('`');
+- res|= str.append(fk_info->foreign_db);
+- res|= str.append("`.`");
+- res|= str.append(fk_info->foreign_table);
+- res|= str.append("`, CONSTRAINT `");
+- res|= str.append(fk_info->foreign_id);
+- res|= str.append("` FOREIGN KEY (");
+- res|= fk_info_append_fields(&str, &fk_info->foreign_fields);
+- res|= str.append(") REFERENCES `");
+- res|= str.append(fk_info->referenced_db);
+- res|= str.append("`.`");
+- res|= str.append(fk_info->referenced_table);
+- res|= str.append("` (");
+- res|= fk_info_append_fields(&str, &fk_info->referenced_fields);
++ res|= append_identifier(thd, &str, fk_info->foreign_db->str,
++ fk_info->foreign_db->length);
++ res|= str.append(".");
++ res|= append_identifier(thd, &str, fk_info->foreign_table->str,
++ fk_info->foreign_table->length);
++ res|= str.append(", CONSTRAINT ");
++ res|= append_identifier(thd, &str, fk_info->foreign_id->str,
++ fk_info->foreign_id->length);
++ res|= str.append(" FOREIGN KEY (");
++ res|= fk_info_append_fields(thd, &str, &fk_info->foreign_fields);
++ res|= str.append(") REFERENCES ");
++ res|= append_identifier(thd, &str, fk_info->referenced_db->str,
++ fk_info->referenced_db->length);
++ res|= str.append(".");
++ res|= append_identifier(thd, &str, fk_info->referenced_table->str,
++ fk_info->referenced_table->length);
++ res|= str.append(" (");
++ res|= fk_info_append_fields(thd, &str, &fk_info->referenced_fields);
+ res|= str.append(')');
+
+ return res ? NULL : thd->strmake(str.ptr(), str.length());
+
+=== modified file 'sql/sql_yacc.yy'
+--- sql/sql_yacc.yy 2012-08-09 15:22:00 +0000
++++ sql/sql_yacc.yy 2012-08-24 13:29:01 +0000
+@@ -12144,7 +12144,7 @@
+ if (lex->update_list.push_back($1) ||
+ lex->value_list.push_back($4))
+ MYSQL_YYABORT;
+- $4->set_name($3, (uint) ($5 - $3), YYTHD->charset());
++ $4->set_name_no_truncate($3, (uint) ($5 - $3), YYTHD->charset());
+ }
+ ;
+
+
+=== modified file 'strings/my_vsnprintf.c'
+--- strings/my_vsnprintf.c 2012-03-13 20:55:56 +0000
++++ strings/my_vsnprintf.c 2012-08-24 13:29:01 +0000
+@@ -694,6 +694,51 @@
+ int my_vfprintf(FILE *stream, const char* format, va_list args)
+ {
+ char cvtbuf[1024];
+- (void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args);
+- return fprintf(stream, "%s\n", cvtbuf);
++ int alloc= 0;
++ char *p= cvtbuf;
++ size_t cur_len= sizeof(cvtbuf);
++ int ret;
++
++ /*
++ We do not know how much buffer we need.
++ So start with a reasonably-sized stack-allocated buffer, and increase
++ it exponentially until it is big enough.
++ */
++ for (;;)
++ {
++ size_t new_len;
++ size_t actual= my_vsnprintf(p, cur_len, format, args);
++ if (actual < cur_len - 1)
++ break;
++ /*
++ Not enough space (or just enough with nothing to spare - but we cannot
++ distinguish this case from the return value). Allocate a bigger buffer
++ and try again.
++ */
++ if (alloc)
++ (*my_str_free)(p);
++ else
++ alloc= 1;
++ new_len= cur_len*2;
++ if (new_len < cur_len)
++ return 0; /* Overflow */
++ cur_len= new_len;
++ p= (*my_str_malloc)(cur_len);
++ if (!p)
++ return 0;
++ }
++ ret= fprintf(stream, "%s", p);
++ if (alloc)
++ (*my_str_free)(p);
++ return ret;
++}
++
++int my_fprintf(FILE *stream, const char* format, ...)
++{
++ int result;
++ va_list args;
++ va_start(args, format);
++ result= my_vfprintf(stream, format, args);
++ va_end(args);
++ return result;
+ }
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2012-09-06 13:45 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2012-09-06 13:45 UTC (permalink / raw
To: gentoo-commits
commit: 28664e798c942ccb71c42c05039508a72a5a0f1d
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Thu Sep 6 13:44:17 2012 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Thu Sep 6 13:44:17 2012 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=28664e79
Fix patches names.
---
00000_index.txt | 8 ++++----
..._sql-5.1.62.patch => 21000_all_sql-5.1.62.patch | 0
..._sql-5.2.12.patch => 21000_all_sql-5.2.12.patch | 0
21000_sql-5.3.7.patch => 21000_all_sql-5.3.7.patch | 0
..._sql-5.5.25.patch => 21000_all_sql-5.5.25.patch | 0
5 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 073e8ed..a9a46a0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1432,22 +1432,22 @@
@pn mariadb
@@ Fix the minimal build by reordering CMakeLists.txt
-@patch 21000_sql-5.1.62.patch
+@patch 21000_all_sql-5.1.62.patch
@ver 5.01.62.00 to 5.01.64.99
@pn mariadb
@@ Fix sql
-@patch 21000_sql-5.2.12.patch
+@patch 21000_all_sql-5.2.12.patch
@ver 5.02.12.00 to 5.02.12.99
@pn mariadb
@@ Fix sql
-@patch 21000_sql-5.3.7.patch
+@patch 21000_all_sql-5.3.7.patch
@ver 5.03.07.00 to 5.03.07.99
@pn mariadb
@@ Fix sql
-@patch 21000_sql-5.5.25.patch
+@patch 21000_all_sql-5.5.25.patch
@ver 5.05.25.00 to 5.05.26.99
@pn mariadb
@@ Fix sql
diff --git a/21000_sql-5.1.62.patch b/21000_all_sql-5.1.62.patch
similarity index 100%
rename from 21000_sql-5.1.62.patch
rename to 21000_all_sql-5.1.62.patch
diff --git a/21000_sql-5.2.12.patch b/21000_all_sql-5.2.12.patch
similarity index 100%
rename from 21000_sql-5.2.12.patch
rename to 21000_all_sql-5.2.12.patch
diff --git a/21000_sql-5.3.7.patch b/21000_all_sql-5.3.7.patch
similarity index 100%
rename from 21000_sql-5.3.7.patch
rename to 21000_all_sql-5.3.7.patch
diff --git a/21000_sql-5.5.25.patch b/21000_all_sql-5.5.25.patch
similarity index 100%
rename from 21000_sql-5.5.25.patch
rename to 21000_all_sql-5.5.25.patch
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-01-18 18:10 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-01-18 18:10 UTC (permalink / raw
To: gentoo-commits
commit: 53acc8aee942f6f75461d449f6c11bcebfe87deb
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Fri Jan 18 18:10:24 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Fri Jan 18 18:10:24 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=53acc8ae
20001_all_fix-minimal-build-cmake-mysql.patch is not applicable to >=5.5.29. It causes cmake to fail, as the macros need to defined earlier.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index a9a46a0..3afe364 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1423,7 +1423,7 @@
@@ Fix bad index in the ma_test2 unit test binary
@patch 20001_all_fix-minimal-build-cmake-mysql.patch
-@ver 5.05.00.00 to 5.99.99.99
+@ver 5.05.00.00 to 5.05.28.99
@pn mysql
@@ Fix the minimal build by reordering CMakeLists.txt
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-01-19 22:38 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-01-19 22:38 UTC (permalink / raw
To: gentoo-commits
commit: f79a31d108f36388f85a7e6bcc8fc9d5c0e2504d
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Mon Sep 10 20:47:25 2012 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jan 19 01:32:03 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f79a31d1
Set maximum version on 20001_all_fix-minimal-build-cmake-mariadb.patch which was fixed upstream.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3afe364..132a663 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1428,7 +1428,7 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
-@ver 5.05.00.00 to 5.99.99.99
+@ver 5.05.00.00 to 5.05.26.99
@pn mariadb
@@ Fix the minimal build by reordering CMakeLists.txt
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-01-19 22:38 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-01-19 22:38 UTC (permalink / raw
To: gentoo-commits
commit: 8f0a7d31fef23582d4f3000d649d84ecba76ec9d
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Sat Jan 19 03:00:00 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Jan 19 03:00:00 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=8f0a7d31
Respin minimal patch for 5.5.29
---
00000_index.txt | 5 ++
..._all_fix-minimal-build-cmake-mysql-5.5.29.patch | 49 ++++++++++++++++++++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 132a663..dbee56e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1427,6 +1427,11 @@
@pn mysql
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
+@ver 5.05.29.00 to 5.05.99.99
+@pn mysql
+@@ Fix the minimal build by reordering CMakeLists.txt
+
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
@ver 5.05.00.00 to 5.05.26.99
@pn mariadb
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch b/20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
new file mode 100644
index 0000000..8c63678
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
@@ -0,0 +1,49 @@
+--- CMakeLists.orig.txt 2013-01-18 16:58:34.701624830 -0500
++++ CMakeLists.txt 2013-01-18 17:00:51.479636903 -0500
+@@ -294,7 +294,11 @@
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+@@ -307,10 +311,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -319,18 +320,17 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
+ ADD_SUBDIRECTORY(packaging/rpm-uln)
+ ENDIF()
+
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
++
+ INCLUDE(cmake/abi_check.cmake)
+ INCLUDE(cmake/tags.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-01-20 23:03 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-01-20 23:03 UTC (permalink / raw
To: gentoo-commits
commit: cff00b7bef9779f996077e340d8336eb636718a1
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Sun Jan 20 03:45:03 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sun Jan 20 04:10:25 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=cff00b7b
Patch for bug 442000. Use empty va_list across all arches.
---
00000_index.txt | 5 ++++
20002_all_mysql-va-list.patch | 49 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index dbee56e..ab3621f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1456,3 +1456,8 @@
@ver 5.05.25.00 to 5.05.26.99
@pn mariadb
@@ Fix sql
+
+@patch 20002_all_mysql-va-list.patch
+@ver 5.05.00.00 to 5.99.99.99
+@pn mysql
+@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
diff --git a/20002_all_mysql-va-list.patch b/20002_all_mysql-va-list.patch
new file mode 100644
index 0000000..2375aa1
--- /dev/null
+++ b/20002_all_mysql-va-list.patch
@@ -0,0 +1,49 @@
+diff -Naur mysql-5.5.16.orig/sql-common/client_plugin.c mysql-5.5.16/sql-common/client_plugin.c
+--- mysql-5.5.16.orig/sql-common/client_plugin.c 2011-09-09 11:56:39.000000000 -0400
++++ mysql-5.5.16/sql-common/client_plugin.c 2011-10-16 23:00:00.708799138 -0400
+@@ -228,11 +228,13 @@
+ {
+ MYSQL mysql;
+ struct st_mysql_client_plugin **builtin;
++ va_list unused;
+
+ if (initialized)
+ return 0;
+
+ bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
++ bzero(&unused, sizeof(unused)); /* suppress uninitialized-value warnings */
+
+ pthread_mutex_init(&LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
+ init_alloc_root(&mem_root, 128, 128);
+@@ -244,7 +246,7 @@
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ for (builtin= mysql_client_builtins; *builtin; builtin++)
+- add_plugin(&mysql, *builtin, 0, 0, 0);
++ add_plugin(&mysql, *builtin, 0, 0, unused);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+
+@@ -288,9 +290,13 @@
+ mysql_client_register_plugin(MYSQL *mysql,
+ struct st_mysql_client_plugin *plugin)
+ {
++ va_list unused;
++
+ if (is_not_initialized(mysql, plugin->name))
+ return NULL;
+
++ bzero(&unused, sizeof(unused)); /* suppress uninitialized-value warnings */
++
+ pthread_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+@@ -302,7 +308,7 @@
+ plugin= NULL;
+ }
+ else
+- plugin= add_plugin(mysql, plugin, 0, 0, 0);
++ plugin= add_plugin(mysql, plugin, 0, 0, unused);
+
+ pthread_mutex_unlock(&LOCK_load_client_plugin);
+ return plugin;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-01-28 17:27 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-01-28 17:27 UTC (permalink / raw
To: gentoo-commits
commit: d7795a46c2c51a9e95f90b1eafbdec25ef482d8f
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 28 17:27:42 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jan 28 17:27:42 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d7795a46
Port 20002_all_mysql-va-list.patch for 5.6.
---
00000_index.txt | 7 ++++-
20002_all_mysql-va-list-5.6.patch | 49 +++++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index ab3621f..5829392 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1458,6 +1458,11 @@
@@ Fix sql
@patch 20002_all_mysql-va-list.patch
-@ver 5.05.00.00 to 5.99.99.99
+@ver 5.05.00.00 to 5.05.99.99
+@pn mysql
+@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+
+@patch 20002_all_mysql-va-list-5.6.patch
+@ver 5.06.00.00 to 5.99.99.99
@pn mysql
@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
diff --git a/20002_all_mysql-va-list-5.6.patch b/20002_all_mysql-va-list-5.6.patch
new file mode 100644
index 0000000..1c06ed3
--- /dev/null
+++ b/20002_all_mysql-va-list-5.6.patch
@@ -0,0 +1,49 @@
+diff -Nuar --exclude '*.orig' --exclude '*.rej' mysql.orig/sql-common/client_plugin.c mysql/sql-common/client_plugin.c
+--- mysql.orig/sql-common/client_plugin.c 2012-11-22 14:39:01.000000000 +0000
++++ mysql/sql-common/client_plugin.c 2013-01-28 17:26:20.534550104 +0000
+@@ -233,11 +233,13 @@
+ {
+ MYSQL mysql;
+ struct st_mysql_client_plugin **builtin;
++ va_list unused;
+
+ if (initialized)
+ return 0;
+
+ memset(&mysql, 0, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */
++ memset(&unused, 0, sizeof(unused)); /* suppress uninitialized-value warnings */
+
+ mysql_mutex_init(0, &LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW);
+ init_alloc_root(&mem_root, 128, 128);
+@@ -249,7 +251,7 @@
+ mysql_mutex_lock(&LOCK_load_client_plugin);
+
+ for (builtin= mysql_client_builtins; *builtin; builtin++)
+- add_plugin(&mysql, *builtin, 0, 0, 0);
++ add_plugin(&mysql, *builtin, 0, 0, unused);
+
+ mysql_mutex_unlock(&LOCK_load_client_plugin);
+
+@@ -293,9 +295,13 @@
+ mysql_client_register_plugin(MYSQL *mysql,
+ struct st_mysql_client_plugin *plugin)
+ {
++ va_list unused;
++
+ if (is_not_initialized(mysql, plugin->name))
+ return NULL;
+
++ memset(&unused, 0, sizeof(unused)); /* suppress uninitialized-value warnings */
++
+ mysql_mutex_lock(&LOCK_load_client_plugin);
+
+ /* make sure the plugin wasn't loaded meanwhile */
+@@ -307,7 +313,7 @@
+ plugin= NULL;
+ }
+ else
+- plugin= add_plugin(mysql, plugin, 0, 0, 0);
++ plugin= add_plugin(mysql, plugin, 0, 0, unused);
+
+ mysql_mutex_unlock(&LOCK_load_client_plugin);
+ return plugin;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-03-01 2:47 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-03-01 2:47 UTC (permalink / raw
To: gentoo-commits
commit: f15bfea3c776a0feee358c29ffa0859b75ba9ed7
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Wed Feb 27 17:48:53 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Wed Feb 27 17:48:53 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f15bfea3
Fix bad CMake references to zlib and readline in 5.6
---
00000_index.txt | 5 +++++
20003_all_fix-5.6-library.patch | 26 ++++++++++++++++++++++++++
2 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 5829392..25a2422 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1466,3 +1466,8 @@
@ver 5.06.00.00 to 5.99.99.99
@pn mysql
@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+
+@patch 20003_all_fix-5.6-library.patch
+@ver 5.06.00.00 to 5.99.99.99
+@pn mysql
+@@ Fix bad references to zlib and readline upstream bugs 68277 and 68087
diff --git a/20003_all_fix-5.6-library.patch b/20003_all_fix-5.6-library.patch
new file mode 100644
index 0000000..ab207e5
--- /dev/null
+++ b/20003_all_fix-5.6-library.patch
@@ -0,0 +1,26 @@
+--- mysql-5.6-5.6.9-rc+dfsg.orig/cmake/readline.cmake
++++ mysql-5.6-5.6.9-rc+dfsg/cmake/readline.cmake
+@@ -192,9 +192,9 @@ MACRO (MYSQL_CHECK_READLINE)
+ IF(WITH_LIBEDIT)
+ MYSQL_USE_BUNDLED_LIBEDIT()
+ ELSE()
+- FIND_SYSTEM_LIBEDIT(edit)
+- IF(NOT_LIBEDIT_FOUND)
+- MESSAGE(FATAL_ERROR "Cannot find system libedit libraries.Use WITH_LIBEDIT")
++ FIND_SYSTEM_LIBEDIT(readline)
++ IF(NOT_LIBREADLINE_FOUND)
++ MESSAGE(FATAL_ERROR "Cannot find system libreadline libraries.Use WITH_LIBREADLINE")
+ ENDIF()
+ ENDIF()
+ ENDIF(NOT WIN32)
+--- a/storage/perfschema/unittest/CMakeLists.txt 2013-02-27 10:45:29.559846643 -0500
++++ b/storage/perfschema/unittest/CMakeLists.txt 2013-02-27 10:45:59.459430483 -0500
+@@ -63,7 +63,7 @@
+ TARGET_LINK_LIBRARIES(pfs_connect_attr-t sql binlog rpl master slave sql)
+ TARGET_LINK_LIBRARIES(pfs_connect_attr-t mysys mysys_ssl)
+ TARGET_LINK_LIBRARIES(pfs_connect_attr-t vio ${SSL_LIBRARIES})
+-TARGET_LINK_LIBRARIES(pfs_connect_attr-t strings dbug regex mysys zlib)
++TARGET_LINK_LIBRARIES(pfs_connect_attr-t strings dbug regex mysys ${ZLIB_LIBRARY})
+ ADD_TEST(pfs_connect_attr pfs_connect_attr-t)
+
+ # On windows, pfs_connect_attr-t may depend on openssl dlls.
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-04-23 23:26 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-04-23 23:26 UTC (permalink / raw
To: gentoo-commits
commit: 0f1674fc0494d50b7c49f14a65fab81ff69568a0
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Tue Apr 23 23:14:16 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Tue Apr 23 23:14:16 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0f1674fc
Reworked Brian Evans patch for fixing bad CMake references for readline for mysql-5.7.
---
00000_index.txt | 9 +++++++--
20003_all_fix-5.7-library.patch | 15 +++++++++++++++
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 25a2422..95633b9 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1468,6 +1468,11 @@
@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20003_all_fix-5.6-library.patch
-@ver 5.06.00.00 to 5.99.99.99
+@ver 5.06.00.00 to 5.06.99.99
+@pn mysql
+@@ Fix bad references to zlib and readline upstream bugs 68277 and 63130
+
+@patch 20003_all_fix-5.7-library.patch
+@ver 5.07.00.00 to 5.99.99.99
@pn mysql
-@@ Fix bad references to zlib and readline upstream bugs 68277 and 68087
+@@ Fix readline upstream bug 63130
diff --git a/20003_all_fix-5.7-library.patch b/20003_all_fix-5.7-library.patch
new file mode 100644
index 0000000..8f0c938
--- /dev/null
+++ b/20003_all_fix-5.7-library.patch
@@ -0,0 +1,15 @@
+--- mysql-5.6-5.6.9-rc+dfsg.orig/cmake/readline.cmake
++++ mysql-5.6-5.6.9-rc+dfsg/cmake/readline.cmake
+@@ -192,9 +192,9 @@ MACRO (MYSQL_CHECK_READLINE)
+ IF(WITH_LIBEDIT)
+ MYSQL_USE_BUNDLED_LIBEDIT()
+ ELSE()
+- FIND_SYSTEM_LIBEDIT(edit)
+- IF(NOT_LIBEDIT_FOUND)
+- MESSAGE(FATAL_ERROR "Cannot find system libedit libraries.Use WITH_LIBEDIT")
++ FIND_SYSTEM_LIBEDIT(readline)
++ IF(NOT_LIBREADLINE_FOUND)
++ MESSAGE(FATAL_ERROR "Cannot find system libreadline libraries.Use WITH_LIBREADLINE")
+ ENDIF()
+ ENDIF()
+ ENDIF(NOT WIN32)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-04-24 19:49 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-04-24 19:49 UTC (permalink / raw
To: gentoo-commits
commit: f25e83830d50ea2f7eb4526246669889392d983e
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 24 19:22:17 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Wed Apr 24 19:22:17 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f25e8383
Make sure the 02040 embedded lib patch is applied to mysql-5.7 as well.
---
00000_index.txt | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 95633b9..e1f1229 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -306,7 +306,7 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.5.10.patch
-@ver 5.05.10.00 to 5.06.99.99
+@ver 5.05.10.00 to 5.07.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-01 0:07 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-05-01 0:07 UTC (permalink / raw
To: gentoo-commits
commit: 052dfb4036b0cb5e1ebaed9bf222f53702e5cb3a
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Wed May 1 00:07:08 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Wed May 1 00:07:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=052dfb40
Apply mysql-5.5 patches to percona-server-5.5.
---
00000_index.txt | 15 +++++++++++++++
1 files changed, 15 insertions(+), 0 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index e1f1229..585ccbf 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -310,6 +310,11 @@
@pn mysql
@@ Take libmysqld to be a proper shared library.
+@patch 02040_all_embedded-library-shared-5.5.10.patch
+@ver 5.05.10.00 to 5.07.99.99
+@pn percona-server
+@@ Take libmysqld to be a proper shared library.
+
@patch 02040_all_embedded-library-shared-maria-5.1.50.patch
@ver 5.01.50.00 to 5.01.52.99
@pn mariadb
@@ -1432,6 +1437,11 @@
@pn mysql
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
+@ver 5.05.29.00 to 5.05.99.99
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
@ver 5.05.00.00 to 5.05.26.99
@pn mariadb
@@ -1462,6 +1472,11 @@
@pn mysql
@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+@patch 20002_all_mysql-va-list.patch
+@ver 5.05.00.00 to 5.05.99.99
+@pn percona-server
+@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+
@patch 20002_all_mysql-va-list-5.6.patch
@ver 5.06.00.00 to 5.99.99.99
@pn mysql
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:16 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:16 UTC (permalink / raw
To: gentoo-commits
commit: 28c61c3141efe139494ab81f135963b6b04408d8
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:15:38 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:16:28 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=28c61c31
Tweak shared patch for 5.1.69.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
00000_index.txt | 7 +-
02040_all_embedded-library-shared-5.1.69.patch | 2298 ++++++++++++++++++++++++
2 files changed, 2304 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 585ccbf..22de958 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -301,7 +301,12 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.1.60.patch
-@ver 5.01.60.00 to 5.01.99.99
+@ver 5.01.60.00 to 5.01.68.99
+@pn mysql
+@@ Take libmysqld to be a proper shared library.
+
+@patch 02040_all_embedded-library-shared-5.1.69.patch
+@ver 5.01.69.00 to 5.01.99.99
@pn mysql
@@ Take libmysqld to be a proper shared library.
diff --git a/02040_all_embedded-library-shared-5.1.69.patch b/02040_all_embedded-library-shared-5.1.69.patch
new file mode 100644
index 0000000..60ea554
--- /dev/null
+++ b/02040_all_embedded-library-shared-5.1.69.patch
@@ -0,0 +1,2298 @@
+Convert all of the static libraries for the embedded libmysqld to build as
+shared.
+
+This enables amarok's mysql extension to properly build as a shared object,
+without statically including libmysqld or nor forcing libmysqld to be built
+with -fPIC.
+
+Thanks to <pageexec@freemail.hu> for the @plt fixes.
+Thanks to Diego Elio Pettenò <flameeyes@gentoo.org> for all the extensive build
+system help with libtool conversions.
+Thanks to Maciej Mrozowski <reavertm@gentoo.org> for working in the redo of the
+patch for mysql-5.1.
+
+Gentoo-Bug: 238487
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=238487
+MySQL-Bug-URL: http://bugs.mysql.com/bug.php?id=39288
+MySQL-Bug: 39288
+MySQL-Lists-URL: http://lists.mysql.com/internals/35947
+X-Patch-URL: http://bugs.gentoo.org/attachment.cgi?id=188019&action=view
+Signed-off-by: Jorge Manuel B. S. Vicetto <jmbsvicetto@gentoo.org>
+Signed-off-by: Robin H. Johnson <robbat2@gentoo.org>
+Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
+
+=== modified file 'client/Makefile.am'
+---
+ client/Makefile.am | 11 -
+ config/ac-macros/plugins.m4 | 107 ++++++++-----
+ configure.in | 8 -
+ dbug/Makefile.am | 6
+ extra/Makefile.am | 4
+ libmysqld/Makefile.am | 184 ++++++++---------------
+ libmysqld/examples/Makefile.am | 10 -
+ mysys/Makefile.am | 42 ++---
+ netware/BUILD/compile-linux-tools | 16 +-
+ netware/Makefile.am | 4
+ regex/Makefile.am | 6
+ server-tools/instance-manager/Makefile.am | 8 -
+ sql/Makefile.am | 12 -
+ storage/archive/Makefile.am | 23 +-
+ storage/archive/plug.in | 2
+ storage/blackhole/Makefile.am | 11 -
+ storage/blackhole/plug.in | 2
+ storage/csv/Makefile.am | 9 -
+ storage/csv/plug.in | 2
+ storage/example/Makefile.am | 11 -
+ storage/federated/Makefile.am | 15 +
+ storage/federated/plug.in | 3
+ storage/heap/Makefile.am | 37 +++-
+ storage/heap/plug.in | 3
+ storage/innobase/Makefile.am | 40 ++---
+ storage/innobase/plug.in | 2
+ storage/innodb_plugin/Makefile.am | 13 -
+ storage/myisam/Makefile.am | 118 ++++++++------
+ storage/myisam/plug.in | 4
+ storage/myisammrg/Makefile.am | 20 ++
+ storage/myisammrg/plug.in | 3
+ storage/ndb/config/type_ndbapitest.mk.am | 31 ++-
+ storage/ndb/config/type_ndbapitools.mk.am | 33 ++--
+ storage/ndb/config/win-libraries | 2
+ storage/ndb/src/common/util/Makefile.am | 6
+ storage/ndb/src/cw/cpcd/Makefile.am | 6
+ storage/ndb/src/kernel/Makefile.am | 7
+ storage/ndb/src/kernel/blocks/Makefile.am | 10 -
+ storage/ndb/src/kernel/blocks/backup/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dbdict/Makefile.am | 12 -
+ storage/ndb/src/kernel/blocks/dbdih/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dblqh/Makefile.am | 6
+ storage/ndb/src/kernel/blocks/dbtup/Makefile.am | 6
+ storage/ndb/src/kernel/vm/Makefile.am | 82 +++++-----
+ storage/ndb/src/mgmclient/Makefile.am | 65 ++++----
+ storage/ndb/src/mgmsrv/Makefile.am | 70 ++++----
+ storage/ndb/src/ndbapi/Makefile.am | 98 ++++++------
+ storage/ndb/test/run-test/Makefile.am | 6
+ strings/Makefile.am | 16 +-
+ unittest/mysys/Makefile.am | 15 +
+ unittest/strings/Makefile.am | 9 -
+ unittest/unit.pl | 2
+ vio/Makefile.am | 4
+ 53 files changed, 622 insertions(+), 612 deletions(-)
+
+Index: client/Makefile.am
+===================================================================
+--- client/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ client/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -75,7 +75,8 @@ mysqlimport_CFLAGS= -DTHREAD -UUNDEF_TH
+ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ mysqlshow_SOURCES= mysqlshow.c
+
+@@ -84,15 +85,17 @@ mysqlslap_CFLAGS= -DTHREAD -UMYSQL_CLIE
+ mysqlslap_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ mysqltest_SOURCES= mysqltest.cc
+ mysqltest_CXXFLAGS= -DTHREAD -UMYSQL_CLIENT_NO_THREADS
+ mysqltest_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \
+ @CLIENT_EXTRA_LDFLAGS@ \
+ $(LIBMYSQLCLIENT_LA) \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/regex/libregex.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/strings/libmystrings.la \
+ $(CLIENT_THREAD_LIBS)
+
+ mysql_upgrade_SOURCES= mysql_upgrade.c \
+Index: config/ac-macros/plugins.m4
+===================================================================
+--- config/ac-macros/plugins.m4.orig 2010-11-27 15:02:45.000000000 +0100
++++ config/ac-macros/plugins.m4 2010-11-27 15:02:49.000000000 +0100
+@@ -115,18 +115,32 @@ dnl ------------------------------------
+ dnl Macro: MYSQL_PLUGIN_STATIC
+ dnl
+ dnl SYNOPSIS
+-dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a])
++dnl MYSQL_PLUGIN_STATIC([name],[libmyplugin.a],[libmyplugin_embedded.a])
+ dnl
+ dnl DESCRIPTION
+-dnl Declare the name for the static library
++dnl Declare the name for the static library
++dnl
++dnl Third argument is optional, only needed for special plugins that depend
++dnl on server internals and have source files that must be compiled specially
++dnl with -DEMBEDDED_LIBRARY for embedded server. If specified, the third
++dnl argument is used to link embedded server instead of the second.
+ dnl
+ dnl ---------------------------------------------------------------------------
+
+ AC_DEFUN([MYSQL_PLUGIN_STATIC],[
+ MYSQL_REQUIRE_PLUGIN([$1])
+ m4_define([MYSQL_PLUGIN_STATIC_]AS_TR_CPP([$1]), [$2])
++ ifelse($#, 3, [
++ m4_define([MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]), [$3])
++ ])
+ ])
+
++dnl ---------------------------------------------------------------------------
++dnl Substitution variable to use to compile source files specially for
++dnl embedded server.
++dnl To be used by plugins that have sources that depend on server internals.
++dnl ---------------------------------------------------------------------------
++AC_SUBST([plugin_embedded_defs], ["-DEMBEDDED_LIBRARY -DMYSQL_SERVER"])
+
+ dnl ---------------------------------------------------------------------------
+ dnl Macro: MYSQL_PLUGIN_DYNAMIC
+@@ -254,29 +268,6 @@ AC_DEFUN([MYSQL_PLUGIN_ACTIONS],[
+ ])
+
+ dnl ---------------------------------------------------------------------------
+-dnl Macro: MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS
+-dnl
+-dnl SYNOPSIS
+-dnl MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS([name],[file name])
+-dnl
+-dnl DESCRIPTION
+-dnl Some modules in plugins keep dependance on structures
+-dnl declared in sql/ (THD class usually)
+-dnl That has to be fixed in the future, but until then
+-dnl we have to recompile these modules when we want to
+-dnl to compile server parts with the different #defines
+-dnl Normally it happens when we compile the embedded server
+-dnl Thus one should mark such files in his handler using this macro
+-dnl (currently only one such a file per plugin is supported)
+-dnl
+-dnl ---------------------------------------------------------------------------
+-
+-AC_DEFUN([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS],[
+- MYSQL_REQUIRE_PLUGIN([$1])
+- m4_define([MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]), [$2])
+-])
+-
+-dnl ---------------------------------------------------------------------------
+ dnl Macro: MYSQL_CONFIGURE_PLUGINS
+ dnl
+ dnl SYNOPSIS
+@@ -336,11 +327,25 @@ AC_DEFUN([_MYSQL_EMIT_CHECK_PLUGIN],[
+ [MYSQL_PLUGIN_DYNAMIC_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_MANDATORY_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_DISABLED_]AS_TR_CPP([$1]),
+- [MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS_]AS_TR_CPP([$1]),
++ [MYSQL_PLUGIN_EMBEDDED_]AS_TR_CPP([$1]),
+ [MYSQL_PLUGIN_ACTIONS_]AS_TR_CPP([$1])
+ )
+ ])
+
++# __MYSQL_EMIT_CHECK_PLUGIN arguments:
++#
++# 1 - plugin identifying name
++# 2 - plugin identifying name, with `-' replaced by `_'
++# 3 - plugin long name
++# 4 - plugin description
++# 5 - mysql_plugin_define (eg. WITH_xxx_STORAGE_ENGINE)
++# 6 - directory
++# 7 - static target (if supports static build)
++# 8 - dynamic target (if supports dynamic build)
++# 9 - mandatory flag
++# 10 - disabled flag
++# 11 - static target for libmysqld (if different from mysqld)
++# 12 - actions
+ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ m4_ifdef([$5],[
+ AH_TEMPLATE($5, [Include ]$4[ into mysqld])
+@@ -407,6 +412,7 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ ])
+ AC_SUBST([plugin_]$2[_shared_target], "$8")
+ AC_SUBST([plugin_]$2[_static_target], [""])
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
+ [with_plugin_]$2=yes
+ AC_MSG_RESULT([plugin])
+ m4_ifdef([$6],[
+@@ -421,32 +427,47 @@ AC_DEFUN([__MYSQL_EMIT_CHECK_PLUGIN],[
+ ])
+ else
+ m4_ifdef([$7],[
+- ifelse(m4_bregexp($7, [^lib[^.]+\.a$]), -2, [
+-dnl change above "-2" to "0" to enable this section
+-dnl Although this is "pretty", it breaks libmysqld build
+- m4_ifdef([$6],[
+- mysql_use_plugin_dir="$6"
+- mysql_plugin_libs="$mysql_plugin_libs -L[\$(top_builddir)]/$6"
+- ])
+- mysql_plugin_libs="$mysql_plugin_libs dnl
+-[-l]m4_bregexp($7, [^lib\([^.]+\)], [\1])"
+- ], m4_bregexp($7, [^\\\$]), 0, [
++ ifelse(m4_bregexp($7, [^\\\$]), 0, [
+ m4_ifdef([$6],[
+ mysql_use_plugin_dir="$6"
+ ])
+ mysql_plugin_libs="$mysql_plugin_libs $7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7"
++ ])
+ ], [
+ m4_ifdef([$6],[
+ mysql_use_plugin_dir="$6"
+ mysql_plugin_libs="$mysql_plugin_libs \$(top_builddir)/$6/$7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs \$(top_builddir)/$6/$7"
++ ])
+ ],[
+ mysql_plugin_libs="$mysql_plugin_libs $7"
++ m4_ifdef([$11],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $11"
++ ],[
++ mysql_embedded_plugin_libs="$mysql_embedded_plugin_libs $7"
++ ])
+ ])
+ ])
+ m4_ifdef([$5],[
+ AC_DEFINE($5)
+ ])
+ AC_SUBST([plugin_]$2[_static_target], "$7")
++ m4_ifdef([$11], [
++ if test "$with_embedded_server" = "yes"; then
++ AC_SUBST([plugin_]$2[_embedded_static_target], "$11")
++ else
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
++ fi
++ ], [
++ AC_SUBST([plugin_]$2[_embedded_static_target], [""])
++ ])
+ AC_SUBST([plugin_]$2[_shared_target], [""])
+ ],[
+ m4_ifdef([$6],[
+@@ -463,12 +484,6 @@ dnl Although this is "pretty", it breaks
+ mysql_plugin_defs="$mysql_plugin_defs, [builtin_]$2[_plugin]"
+ [with_plugin_]$2=yes
+ AC_MSG_RESULT([yes])
+- m4_ifdef([$11],[
+- condition_dependent_plugin_modules="$condition_dependent_plugin_modules m4_bregexp($11, [[^/]+$], [\&])"
+- condition_dependent_plugin_objects="$condition_dependent_plugin_objects m4_bregexp($11, [[^/]+\.], [\&o])"
+- condition_dependent_plugin_links="$condition_dependent_plugin_links $6/$11"
+- condition_dependent_plugin_includes="$condition_dependent_plugin_includes -I[\$(top_srcdir)]/$6/m4_bregexp($11, [^.+[/$]], [\&])"
+- ])
+ fi
+ fi
+
+@@ -516,6 +531,14 @@ dnl
+ ])
+ ])
+
++dnl If not building libmysqld embedded server, then there is no need to build
++dnl shared object versions of static plugins.
++if test "$with_embedded_server" = "yes"; then
++ AC_SUBST([plugin_static_if_no_embedded], "")
++else
++ AC_SUBST([plugin_static_if_no_embedded], "-static")
++fi
++
+ AC_DEFUN([_MYSQL_EMIT_PLUGIN_ACTIONS],[
+ ifelse($#, 0, [], $#, 1, [
+ _MYSQL_EMIT_PLUGIN_ACTION([$1])
+Index: configure.in
+===================================================================
+--- configure.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ configure.in 2010-11-27 19:41:49.000000000 +0100
+@@ -2483,8 +2483,6 @@ MYSQL_STORAGE_ENGINE(partition, partitio
+
+ dnl -- ndbcluster requires partition to be enabled
+
+-MYSQL_CONFIGURE_PLUGINS([none])
+-
+ # Only build client code?
+ AC_ARG_WITH(server,
+ [ --without-server Only build the client.],
+@@ -2498,6 +2496,8 @@ AC_ARG_WITH(embedded-server,
+ [with_embedded_server=no]
+ )
+
++MYSQL_CONFIGURE_PLUGINS([none])
++
+ AC_ARG_WITH(query_cache,
+ [ --without-query-cache Do not build query cache.],
+ [with_query_cache=$withval],
+@@ -2801,9 +2801,6 @@ if test "$with_server" != "no" -o "$THRE
+ then
+ AC_DEFINE([THREAD], [1],
+ [Define if you want to have threaded code. This may be undef on client code])
+- # Avoid _PROGRAMS names
+- THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
+- AC_SUBST(THREAD_LOBJECTS)
+ fi
+ AM_CONDITIONAL(NEED_THREAD, test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no")
+
+@@ -2831,6 +2828,7 @@ AC_SUBST(server_scripts)
+
+ AC_SUBST(mysql_plugin_dirs)
+ AC_SUBST(mysql_plugin_libs)
++AC_SUBST(mysql_embedded_plugin_libs)
+ AC_SUBST(mysql_plugin_defs)
+
+
+Index: dbug/Makefile.am
+===================================================================
+--- dbug/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ dbug/Makefile.am 2010-11-27 19:42:26.000000000 +0100
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-LDADD = libdbug.a ../mysys/libmysys.a ../strings/libmystrings.a
+-pkglib_LIBRARIES = libdbug.a
++LDADD = libdbug.la ../mysys/libmysys.la ../strings/libmystrings.la $(ZLIB_LIBS)
++noinst_LTLIBRARIES = libdbug.la
+ noinst_HEADERS = dbug_long.h
+-libdbug_a_SOURCES = dbug.c sanity.c
++libdbug_la_SOURCES = dbug.c sanity.c
+ EXTRA_DIST = CMakeLists.txt example1.c example2.c example3.c \
+ user.r monty.doc dbug_add_tags.pl \
+ my_main.c main.c factorial.c dbug_analyze.c \
+Index: extra/Makefile.am
+===================================================================
+--- extra/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ extra/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -15,8 +15,8 @@
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_srcdir)/sql
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a \
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
++ ../dbug/libdbug.la ../strings/libmystrings.la \
+ $(ZLIB_LIBS)
+ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
+ $(top_builddir)/include/sql_state.h \
+Index: libmysqld/Makefile.am
+===================================================================
+--- libmysqld/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ libmysqld/Makefile.am 2010-11-27 20:58:00.000000000 +0100
+@@ -17,95 +17,91 @@
+ #
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+-MYSQLDATAdir = $(localstatedir)
+-MYSQLSHAREdir = $(pkgdatadir)
+-MYSQLBASEdir= $(prefix)
+-MYSQLLIBdir= $(libdir)
+-pkgplugindir = $(pkglibdir)/plugin
++MYSQLDATAdir = $(localstatedir)
++MYSQLSHAREdir = $(pkgdatadir)
++MYSQLBASEdir = $(prefix)
++MYSQLLIBdir = $(libdir)
++pkgplugindir = $(pkglibdir)/plugin
+
+-EXTRA_DIST = libmysqld.def CMakeLists.txt
+-DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
++EXTRA_DIST = libmysqld.def CMakeLists.txt
++DEFS = -DEMBEDDED_LIBRARY -DMYSQL_SERVER \
+ -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+ -DPLUGINDIR="\"$(pkgplugindir)\""
+-INCLUDES= -I$(top_builddir)/include -I$(top_srcdir)/include \
++INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ -I$(top_builddir)/sql -I$(top_srcdir)/sql \
+ -I$(top_srcdir)/sql/examples \
+ -I$(top_srcdir)/regex \
+- $(openssl_includes) @ZLIB_INCLUDES@ \
+- @condition_dependent_plugin_includes@
++ $(openssl_includes) $(ZLIB_INCLUDES) \
++ @condition_dependent_plugin_includes@ \
++ $(ndbcluster_includes)
+
+-noinst_LIBRARIES = libmysqld_int.a
+-pkglib_LIBRARIES = libmysqld.a
+-SUBDIRS = . examples
++pkglib_LTLIBRARIES = libmysqld.la
++SUBDIRS = . examples
+ libmysqld_sources= libmysqld.c lib_sql.cc emb_qcache.cc
+ libmysqlsources = errmsg.c get_password.c libmysql.c client.c pack.c \
+- my_time.c
++ my_time.c
+
+ noinst_HEADERS = embedded_priv.h emb_qcache.h
+
+-sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
+- ha_ndbcluster.cc ha_ndbcluster_cond.cc \
+- ha_ndbcluster_binlog.cc ha_partition.cc \
+- handler.cc sql_handler.cc \
+- hostname.cc init.cc password.c \
+- item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
+- item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
+- item_geofunc.cc item_subselect.cc item_row.cc\
+- item_xmlfunc.cc \
+- key.cc lock.cc log.cc sql_state.c \
+- log_event.cc rpl_record.cc \
+- log_event_old.cc rpl_record_old.cc \
+- protocol.cc net_serv.cc opt_range.cc \
+- opt_sum.cc procedure.cc records.cc sql_acl.cc \
+- sql_load.cc discover.cc sql_locale.cc \
+- sql_profile.cc \
+- sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
+- sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
+- sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
+- scheduler.cc sql_connect.cc sql_parse.cc \
+- sql_prepare.cc sql_derived.cc sql_rename.cc \
+- sql_select.cc sql_do.cc sql_show.cc set_var.cc \
+- sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
+- sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
+- unireg.cc uniques.cc sql_union.cc hash_filo.cc \
+- spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
+- sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
+- parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
+- rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
+- debug_sync.cc \
+- sql_tablespace.cc \
+- rpl_injector.cc my_user.c partition_info.cc \
+- sql_servers.cc event_parse_data.cc
+-
+-libmysqld_int_a_SOURCES= $(libmysqld_sources)
+-nodist_libmysqld_int_a_SOURCES= $(libmysqlsources) $(sqlsources)
+-libmysqld_a_SOURCES=
+-
+-sqlstoragesources = $(EXTRA_libmysqld_a_SOURCES)
+-storagesources = @condition_dependent_plugin_modules@
+-storageobjects = @condition_dependent_plugin_objects@
+-storagesourceslinks = @condition_dependent_plugin_links@
++sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
++ ha_ndbcluster.cc ha_ndbcluster_cond.cc \
++ ha_ndbcluster_binlog.cc ha_partition.cc \
++ handler.cc sql_handler.cc \
++ hostname.cc init.cc password.c \
++ item.cc item_buff.cc item_cmpfunc.cc item_create.cc \
++ item_func.cc item_strfunc.cc item_sum.cc item_timefunc.cc \
++ item_geofunc.cc item_subselect.cc item_row.cc\
++ item_xmlfunc.cc \
++ key.cc lock.cc log.cc sql_state.c \
++ log_event.cc rpl_record.cc \
++ log_event_old.cc rpl_record_old.cc \
++ protocol.cc net_serv.cc opt_range.cc \
++ opt_sum.cc procedure.cc records.cc sql_acl.cc \
++ sql_load.cc discover.cc sql_locale.cc \
++ sql_profile.cc \
++ sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
++ sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
++ sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc \
++ scheduler.cc sql_connect.cc sql_parse.cc \
++ sql_prepare.cc sql_derived.cc sql_rename.cc \
++ sql_select.cc sql_do.cc sql_show.cc set_var.cc \
++ sql_string.cc sql_table.cc sql_test.cc sql_udf.cc \
++ sql_update.cc sql_yacc.cc table.cc thr_malloc.cc time.cc \
++ unireg.cc uniques.cc sql_union.cc hash_filo.cc \
++ spatial.cc gstream.cc sql_help.cc tztime.cc sql_cursor.cc \
++ sp_head.cc sp_pcontext.cc sp.cc sp_cache.cc sp_rcontext.cc \
++ parse_file.cc sql_view.cc sql_trigger.cc my_decimal.cc \
++ rpl_filter.cc sql_partition.cc sql_builtin.cc sql_plugin.cc \
++ debug_sync.cc \
++ sql_tablespace.cc \
++ rpl_injector.cc my_user.c partition_info.cc \
++ sql_servers.cc event_parse_data.cc
+
+ # automake misses these
+ sql_yacc.cc sql_yacc.$(YACC_HEXT): $(top_srcdir)/sql/sql_yacc.yy
+
+ # The following libraries should be included in libmysqld.a
+-INC_LIB= $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/vio/libvio.a \
+- @NDB_SCI_LIBS@ \
+- @mysql_plugin_libs@ \
+- $(yassl_inc_libs)
++INC_LIB= $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/vio/libvio.la \
++ @ZLIB_LIBS@ @LIBDL@ \
++ $(NDB_SCI_LIBS) \
++ $(mysql_embedded_plugin_libs) \
++ $(yassl_inc_libs)
+
+ if HAVE_YASSL
+-yassl_inc_libs= $(top_builddir)/extra/yassl/src/.libs/libyassl.a \
+- $(top_builddir)/extra/yassl/taocrypt/src/.libs/libtaocrypt.a
++yassl_inc_libs= $(top_builddir)/extra/yassl/src/libyassl.la \
++ $(top_builddir)/extra/yassl/taocrypt/src/libtaocrypt.la
+ endif
+
++libmysqld_la_SOURCES= $(libmysqld_sources)
++nodist_libmysqld_la_SOURCES= $(libmysqlsources) $(sqlsources)
++libmysqld_la_LIBADD = $(INC_LIB)
++
+ # Storage engine specific compilation options
+ ha_ndbcluster.o:ha_ndbcluster.cc
+ $(CXXCOMPILE) @ndbcluster_includes@ $(LM_CFLAGS) -c $<
+@@ -139,44 +135,6 @@ ha_myisam.o:ha_myisam.cc
+ ha_myisammrg.o:ha_myisammrg.cc
+ $(CXXCOMPILE) $(LM_CFLAGS) -c $<
+
+-#
+-# 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) $(libmysqld_a_DEPENDENCIES) $(storageobjects)
+-if DARWIN_MWCC
+- mwld -lib -o $@ libmysqld_int.a `echo $(INC_LIB) | sort -u` $(storageobjects)
+-else
+- -rm -f libmysqld.a
+- if test "$(host_os)" = "netware" ; \
+- then \
+- $(libmysqld_a_AR) libmysqld.a $(INC_LIB) libmysqld_int.a $(storageobjects); \
+- else \
+- current_dir=`pwd`; \
+- rm -rf tmp; mkdir tmp; \
+- (for arc in $(INC_LIB) ./libmysqld_int.a; do \
+- arpath=`echo $$arc|sed 's|[^/]*$$||'|sed 's|\.libs/$$||'`; \
+- artmp=`echo $$arc|sed 's|^.*/|tmp/lib-|'`; \
+- for F in `$(AR) t $$arc | grep -v SYMDEF`; do \
+- if test -e "$$arpath/$$F" ; then echo "$$arpath/$$F"; else \
+- mkdir $$artmp; cd $$artmp > /dev/null; \
+- $(AR) x ../../$$arc; \
+- cd $$current_dir > /dev/null; \
+- ls $$artmp/* | grep -v SYMDEF; \
+- continue 2; fi; done; \
+- done; echo $(libmysqld_a_DEPENDENCIES) ) | sort -u | xargs $(AR) cq libmysqld.a ; \
+- $(AR) r libmysqld.a $(storageobjects); \
+- $(RANLIB) libmysqld.a ; \
+- rm -rf tmp; \
+- fi
+-endif
+-
+ ## XXX: any time the client interface changes, we'll need to bump
+ ## the version info for libmysqld; however, it's possible for the
+ ## libmysqld interface to change without affecting the standard
+@@ -187,7 +145,7 @@ endif
+
+ BUILT_SOURCES = link_sources
+
+-CLEANFILES = $(BUILT_SOURCES)
++CLEANFILES = libmysqld.la
+
+ link_sources:
+ for f in $(sqlsources); do \
+@@ -208,20 +166,6 @@ link_sources:
+ @LN_CP_F@ $(top_builddir)/libmysql/$$f $$f; \
+ fi ; \
+ done; \
+- if test -n "$(sqlstoragesources)" ; \
+- then \
+- for f in "$(sqlstoragesources)"; do \
+- rm -f "$$f"; \
+- @LN_CP_F@ `find $(srcdir)/../sql -name "$$f"` "$$f"; \
+- done; \
+- fi; \
+- if test -n "$(storagesources)" ; \
+- then \
+- rm -f $(storagesources); \
+- for f in $(storagesourceslinks); do \
+- @LN_CP_F@ $(top_srcdir)/$$f . ; \
+- done; \
+- fi; \
+ rm -f client_settings.h; \
+ @LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h \
+ client_settings.h; \
+@@ -229,7 +173,7 @@ link_sources:
+
+
+ clean-local:
+- rm -f `echo $(sqlsources) $(libmysqlsources) $(sqlstoragesources) $(storagesources) | sed "s;\.lo;.c;g"`; \
++ rm -f `echo $(sqlsources) $(libmysqlsources) | sed "s;\.lo;.c;g"`; \
+ rm -f client_settings.h
+
+ # Don't update the files from bitkeeper
+Index: libmysqld/examples/Makefile.am
+===================================================================
+--- libmysqld/examples/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ libmysqld/examples/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -37,12 +37,16 @@ INCLUDES = -I$(top_builddir)/include -I$
+ -I$(top_srcdir) -I$(top_srcdir)/client -I$(top_srcdir)/regex \
+ $(openssl_includes)
+ LIBS = @LIBS@ @WRAPLIBS@ @CLIENT_LIBS@ $(yassl_libs)
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.a @LIBDL@ $(CXXLDFLAGS) \
+- @NDB_SCI_LIBS@
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../libmysqld.la @LIBDL@ $(CXXLDFLAGS) \
++ @NDB_SCI_LIBS@ \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(ZLIB_LIBS)
+
+ mysqltest_embedded_LINK = $(CXXLINK)
+ nodist_mysqltest_embedded_SOURCES = mysqltest.cc
+-mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.a \
++mysqltest_embedded_LDADD = $(LDADD) $(top_builddir)/regex/libregex.la \
+ @MYSQLD_EXTRA_LDFLAGS@
+
+ nodist_mysql_SOURCES = mysql.cc readline.cc completion_hash.cc \
+Index: mysys/Makefile.am
+===================================================================
+--- mysys/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ mysys/Makefile.am 2010-11-27 19:42:49.000000000 +0100
+@@ -18,10 +18,10 @@ MYSQLSHAREdir = $(pkgdatadir)
+ MYSQLBASEdir= $(prefix)
+ INCLUDES = @ZLIB_INCLUDES@ -I$(top_builddir)/include \
+ -I$(top_srcdir)/include -I$(srcdir)
+-pkglib_LIBRARIES = libmysys.a
+-LDADD = libmysys.a $(top_builddir)/strings/libmystrings.a $(top_builddir)/dbug/libdbug.a
++noinst_LTLIBRARIES = libmysys.la
++LDADD = libmysys.la $(top_builddir)/strings/libmystrings.la $(top_builddir)/dbug/libdbug.la
+ noinst_HEADERS = mysys_priv.h my_static.h my_handler_errors.h
+-libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
++libmysys_la_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \
+ mf_path.c mf_loadpath.c my_file.c \
+ my_open.c my_create.c my_dup.c my_seek.c my_read.c \
+ my_pread.c my_write.c my_getpagesize.c \
+@@ -57,18 +57,18 @@ if NEED_THREAD
+ # mf_keycache is used only in the server, so it is safe to leave the file
+ # out of the non-threaded library.
+ # In fact, it will currently not compile without thread support.
+-libmysys_a_SOURCES += mf_keycache.c
++libmysys_la_SOURCES += thr_alarm.c thr_lock.c thr_mutex.c thr_rwlock.c \
++ my_pthread.c my_thr_init.c mf_keycache.c
+ endif
+
+ EXTRA_DIST = thr_alarm.c thr_lock.c my_pthread.c my_thr_init.c \
+ thr_mutex.c thr_rwlock.c \
+ CMakeLists.txt mf_soundex.c \
+ my_conio.c my_wincond.c my_winthread.c
+-libmysys_a_LIBADD = @THREAD_LOBJECTS@
+-# test_dir_DEPENDENCIES= $(LIBRARIES)
+-# testhash_DEPENDENCIES= $(LIBRARIES)
+-# test_charset_DEPENDENCIES= $(LIBRARIES)
+-# charset2html_DEPENDENCIES= $(LIBRARIES)
++# test_dir_DEPENDENCIES= $(LTLIBRARIES)
++# testhash_DEPENDENCIES= $(LTLIBRARIES)
++# test_charset_DEPENDENCIES= $(LTLIBRARIES)
++# charset2html_DEPENDENCIES= $(LTLIBRARIES)
+ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\" \
+ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+ -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
+@@ -78,8 +78,6 @@ DEFS = -DDEFAULT_BASEDIR=\"$(prefix)\"
+ -DDEFAULT_SYSCONFDIR="\"$(sysconfdir)\"" \
+ @DEFS@
+
+-libmysys_a_DEPENDENCIES= @THREAD_LOBJECTS@
+-
+ # I hope this always does the right thing. Otherwise this is only test programs
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+@@ -88,47 +86,47 @@ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(
+ # which automaticly removes the object files you use to compile a final program
+ #
+
+-test_bitmap$(EXEEXT): my_bitmap.c $(LIBRARIES)
++test_bitmap$(EXEEXT): my_bitmap.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./my_bitmap.c $(LDADD) $(LIBS)
+
+-test_priority_queue$(EXEEXT): queues.c $(LIBRARIES)
++test_priority_queue$(EXEEXT): queues.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN ./queues.c $(LDADD) $(LIBS)
+
+-test_thr_alarm$(EXEEXT): thr_alarm.c $(LIBRARIES)
++test_thr_alarm$(EXEEXT): thr_alarm.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_alarm.c ./test_thr_alarm.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_alarm.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_alarm.c
+
+-test_thr_lock$(EXEEXT): thr_lock.c $(LIBRARIES)
++test_thr_lock$(EXEEXT): thr_lock.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/thr_lock.c test_thr_lock.c
+ $(LINK) $(FLAGS) -DMAIN ./test_thr_lock.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_thr_lock.c
+
+-test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LIBRARIES)
++test_vsnprintf$(EXEEXT): my_vsnprintf.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_vsnprintf.c test_vsnprintf.c
+ $(LINK) $(FLAGS) -DMAIN ./test_vsnprintf.c $(LDADD) $(LIBS)
+ $(RM) -f test_vsnprintf.c
+
+-test_io_cache$(EXEEXT): mf_iocache.c $(LIBRARIES)
++test_io_cache$(EXEEXT): mf_iocache.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/mf_iocache.c test_io_cache.c
+ $(LINK) $(FLAGS) -DMAIN ./test_io_cache.c $(LDADD) $(LIBS)
+ $(RM) -f test_io_cache.c
+
+-test_dir$(EXEEXT): test_dir.c $(LIBRARIES)
++test_dir$(EXEEXT): test_dir.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_dir.c $(LDADD) $(LIBS)
+
+-test_charset$(EXEEXT): test_charset.c $(LIBRARIES)
++test_charset$(EXEEXT): test_charset.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/test_charset.c $(LDADD) $(LIBS)
+
+-testhash$(EXEEXT): testhash.c $(LIBRARIES)
++testhash$(EXEEXT): testhash.c $(LTLIBRARIES)
+ $(LINK) $(FLAGS) -DMAIN $(srcdir)/testhash.c $(LDADD) $(LIBS)
+
+-test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LIBRARIES)
++test_gethwaddr$(EXEEXT): my_gethwaddr.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/my_gethwaddr.c ./test_gethwaddr.c
+ $(LINK) $(FLAGS) -DMAIN ./test_gethwaddr.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_gethwaddr.c
+
+-test_base64$(EXEEXT): base64.c $(LIBRARIES)
++test_base64$(EXEEXT): base64.c $(LTLIBRARIES)
+ $(CP) $(srcdir)/base64.c ./test_base64.c
+ $(LINK) $(FLAGS) -DMAIN ./test_base64.c $(LDADD) $(LIBS)
+ $(RM) -f ./test_base64.c
+Index: netware/BUILD/compile-linux-tools
+===================================================================
+--- netware/BUILD/compile-linux-tools.orig 2010-11-27 15:02:45.000000000 +0100
++++ netware/BUILD/compile-linux-tools 2010-11-27 15:02:49.000000000 +0100
+@@ -34,14 +34,14 @@ make
+ # Create mysql_version.h which was deleted my previous step
+ ./config.status include/mysql_version.h
+
+-(cd dbug; make libdbug.a)
+-(cd strings; make libmystrings.a)
+-(cd mysys; make libmysys.a)
+-(cd storage/heap; make libheap.a)
+-(cd vio; make libvio.a)
+-(cd regex; make libregex.a)
+-(cd storage/myisam; make libmyisam.a)
+-(cd storage/myisammrg; make libmyisammrg.a)
++(cd dbug; make libdbug.la)
++(cd strings; make libmystrings.la)
++(cd mysys; make libmysys.la)
++(cd storage/heap; make libheap.la)
++(cd vio; make libvio.la)
++(cd regex; make libregex.la)
++(cd storage/myisam; make libmyisam.la)
++(cd storage/myisammrg; make libmyisammrg.la)
+ (cd extra; make comp_err)
+ (cd libmysql; make conf_to_src)
+ (cd libmysql_r; make conf_to_src)
+Index: netware/Makefile.am
+===================================================================
+--- netware/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ netware/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,8 +16,8 @@
+
+ if HAVE_NETWARE
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I..
+-LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.a \
+- ../dbug/libdbug.a ../strings/libmystrings.a
++LDADD = @CLIENT_EXTRA_LDFLAGS@ ../mysys/libmysys.la \
++ ../dbug/libdbug.la ../strings/libmystrings.la
+ bin_PROGRAMS = mysqld_safe mysql_install_db mysql_test_run libmysql
+ mysqld_safe_SOURCES= mysqld_safe.c my_manage.c
+ mysql_install_db_SOURCES= mysql_install_db.c my_manage.c
+Index: regex/Makefile.am
+===================================================================
+--- regex/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ regex/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,10 +16,10 @@
+ # MA 02111-1307, USA
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-noinst_LIBRARIES = libregex.a
+-LDADD= libregex.a $(top_builddir)/strings/libmystrings.a
++noinst_LTLIBRARIES = libregex.la
++LDADD= libregex.la $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = cclass.h cname.h regex2.h utils.h engine.c my_regex.h
+-libregex_a_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
++libregex_la_SOURCES = regerror.c regcomp.c regexec.c regfree.c reginit.c
+ noinst_PROGRAMS = re
+ re_SOURCES = split.c debug.c main.c
+ re_LDFLAGS= @NOINST_LDFLAGS@
+Index: server-tools/instance-manager/Makefile.am
+===================================================================
+--- server-tools/instance-manager/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ server-tools/instance-manager/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -87,10 +87,10 @@ mysqlmanager_SOURCES= command.cc command
+ mysqlmanager_LDADD= @CLIENT_EXTRA_LDFLAGS@ \
+ liboptions.la \
+ libnet.a \
+- $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
++ $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
+ @openssl_libs@ @yassl_libs@ @ZLIB_LIBS@
+
+ EXTRA_DIST = WindowsService.cpp WindowsService.h IMService.cpp \
+Index: sql/Makefile.am
+===================================================================
+--- sql/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ sql/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,13 +32,13 @@ bin_PROGRAMS = mysql_tzinfo_to_sql
+ noinst_LTLIBRARIES= libndb.la \
+ udf_example.la
+
+-SUPPORTING_LIBS = $(top_builddir)/vio/libvio.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/regex/libregex.a \
+- $(top_builddir)/strings/libmystrings.a
++SUPPORTING_LIBS = $(top_builddir)/vio/libvio.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/regex/libregex.la \
++ $(top_builddir)/strings/libmystrings.la
+ mysqld_DEPENDENCIES= @mysql_plugin_libs@ $(SUPPORTING_LIBS) libndb.la
+-LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@
++LDADD = $(SUPPORTING_LIBS) @ZLIB_LIBS@ @NDB_SCI_LIBS@ $(openssl_libs) $(yassl_libs)
+ mysqld_LDADD = libndb.la \
+ @MYSQLD_EXTRA_LDFLAGS@ \
+ @pstack_libs@ \
+Index: storage/archive/Makefile.am
+===================================================================
+--- storage/archive/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/archive/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -33,7 +33,7 @@ DEFS = @DEFS@
+ noinst_HEADERS = ha_archive.h azlib.h
+ noinst_PROGRAMS = archive_test archive_reader
+
+-EXTRA_LTLIBRARIES = ha_archive.la
++EXTRA_LTLIBRARIES = libarchive.la ha_archive.la
+ pkgplugin_LTLIBRARIES = @plugin_archive_shared_target@
+ ha_archive_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_archive_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -41,26 +41,25 @@ ha_archive_la_CFLAGS = $(AM_CFLAGS) -DMY
+ ha_archive_la_SOURCES = ha_archive.cc azio.c
+
+
+-EXTRA_LIBRARIES = libarchive.a
+-noinst_LIBRARIES = @plugin_archive_static_target@
+-libarchive_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libarchive_a_CFLAGS = $(AM_CFLAGS)
+-libarchive_a_SOURCES = ha_archive.cc azio.c
++noinst_LTLIBRARIES = @plugin_archive_static_target@
++libarchive_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libarchive_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libarchive_la_SOURCES = ha_archive.cc azio.c
+
+
+ archive_test_SOURCES = archive_test.c azio.c
+ archive_test_CFLAGS = $(AM_CFLAGS)
+-archive_test_LDADD = $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a \
++archive_test_LDADD = $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @ZLIB_LIBS@
+ archive_test_LDFLAGS = @NOINST_LDFLAGS@
+
+ archive_reader_SOURCES = archive_reader.c azio.c
+ archive_reader_CFLAGS = $(AM_CFLAGS)
+-archive_reader_LDADD = $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a \
++archive_reader_LDADD = $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
+ @ZLIB_LIBS@
+ archive_reader_LDFLAGS = @NOINST_LDFLAGS@
+
+Index: storage/archive/plug.in
+===================================================================
+--- storage/archive/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/archive/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,4 +1,4 @@
+ MYSQL_STORAGE_ENGINE(archive,, [Archive Storage Engine],
+ [Archive Storage Engine], [max,max-no-ndb])
+-MYSQL_PLUGIN_STATIC(archive, [libarchive.a])
++MYSQL_PLUGIN_STATIC(archive, [libarchive.la])
+ MYSQL_PLUGIN_DYNAMIC(archive, [ha_archive.la])
+Index: storage/blackhole/Makefile.am
+===================================================================
+--- storage/blackhole/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/blackhole/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_blackhole.h
+
+-EXTRA_LTLIBRARIES = ha_blackhole.la
++EXTRA_LTLIBRARIES = libblackhole.la ha_blackhole.la
+ pkgplugin_LTLIBRARIES = @plugin_blackhole_shared_target@
+ ha_blackhole_la_LDFLAGS=-module -rpath $(pkgplugindir)
+ ha_blackhole_la_CXXFLAGS=$(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,10 @@ ha_blackhole_la_CFLAGS= $(AM_CFLAGS) -DM
+ ha_blackhole_la_SOURCES=ha_blackhole.cc
+
+
+-EXTRA_LIBRARIES = libblackhole.a
+-noinst_LIBRARIES = @plugin_blackhole_static_target@
+-libblackhole_a_CXXFLAGS=$(AM_CXXFLAGS)
+-libblackhole_a_CFLAGS = $(AM_CFLAGS)
+-libblackhole_a_SOURCES= ha_blackhole.cc
++noinst_LTLIBRARIES = @plugin_blackhole_static_target@
++libblackhole_la_CXXFLAGS=$(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libblackhole_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libblackhole_la_SOURCES= ha_blackhole.cc
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/blackhole/plug.in
+===================================================================
+--- storage/blackhole/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/blackhole/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,6 +1,6 @@
+ MYSQL_STORAGE_ENGINE(blackhole,,[Blackhole Storage Engine],
+ [Basic Write-only Read-never tables], [max,max-no-ndb])
+ MYSQL_PLUGIN_DIRECTORY(blackhole, [storage/blackhole])
+-MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.a])
++MYSQL_PLUGIN_STATIC(blackhole, [libblackhole.la])
+ MYSQL_PLUGIN_DYNAMIC(blackhole, [ha_blackhole.la])
+
+Index: storage/csv/Makefile.am
+===================================================================
+--- storage/csv/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/csv/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -29,16 +29,15 @@ LDADD =
+ DEFS = @DEFS@
+ noinst_HEADERS = ha_tina.h transparent_file.h
+
+-EXTRA_LTLIBRARIES = ha_csv.la
++EXTRA_LTLIBRARIES = libcsv.la ha_csv.la
+ pkglib_LTLIBRARIES = @plugin_csv_shared_target@
+ ha_csv_la_LDFLAGS = -module -rpath $(MYSQLLIBdir)
+ ha_csv_la_CXXFLAGS = $(AM_CXXFLAGS) -DMYSQL_PLUGIN
+ ha_csv_la_SOURCES = transparent_file.cc ha_tina.cc
+
+-EXTRA_LIBRARIES = libcsv.a
+-noinst_LIBRARIES = @plugin_csv_static_target@
+-libcsv_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libcsv_a_SOURCES = transparent_file.cc ha_tina.cc
++noinst_LTLIBRARIES = @plugin_csv_static_target@
++libcsv_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libcsv_la_SOURCES = transparent_file.cc ha_tina.cc
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+ # Don't update the files from bitkeeper
+Index: storage/csv/plug.in
+===================================================================
+--- storage/csv/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/csv/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,5 +1,5 @@
+ MYSQL_STORAGE_ENGINE(csv,, [CSV Storage Engine],
+ [Stores tables in text CSV format])
+ MYSQL_PLUGIN_DIRECTORY(csv, [storage/csv])
+-MYSQL_PLUGIN_STATIC(csv, [libcsv.a])
++MYSQL_PLUGIN_STATIC(csv, [libcsv.la])
+ MYSQL_PLUGIN_MANDATORY(csv) dnl Used for logging
+Index: storage/example/Makefile.am
+===================================================================
+--- storage/example/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/example/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_example.h
+
+-EXTRA_LTLIBRARIES = ha_example.la
++EXTRA_LTLIBRARIES = libexample.la ha_example.la
+ pkgplugin_LTLIBRARIES = @plugin_example_shared_target@
+ ha_example_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_example_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,10 @@ ha_example_la_CFLAGS = $(AM_CFLAGS) -DMY
+ ha_example_la_SOURCES = ha_example.cc
+
+
+-EXTRA_LIBRARIES = libexample.a
+-noinst_LIBRARIES = @plugin_example_static_target@
+-libexample_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libexample_a_CFLAGS = $(AM_CFLAGS)
+-libexample_a_SOURCES= ha_example.cc
++noinst_LTLIBRARIES = @plugin_example_static_target@
++libexample_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libexample_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libexample_la_SOURCES= ha_example.cc
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/federated/Makefile.am
+===================================================================
+--- storage/federated/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/federated/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -32,7 +32,7 @@ DEFS = @DEFS@
+
+ noinst_HEADERS = ha_federated.h
+
+-EXTRA_LTLIBRARIES = ha_federated.la
++EXTRA_LTLIBRARIES = libfederated.la libfederated_embedded.la ha_federated.la
+ pkgplugin_LTLIBRARIES = @plugin_federated_shared_target@
+ ha_federated_la_LDFLAGS = -module -rpath $(pkgplugindir)
+ ha_federated_la_CXXFLAGS= $(AM_CXXFLAGS) -DMYSQL_DYNAMIC_PLUGIN
+@@ -40,11 +40,14 @@ ha_federated_la_CFLAGS = $(AM_CFLAGS) -D
+ ha_federated_la_SOURCES = ha_federated.cc $(top_srcdir)/mysys/string.c
+
+
+-EXTRA_LIBRARIES = libfederated.a
+-noinst_LIBRARIES = @plugin_federated_static_target@
+-libfederated_a_CXXFLAGS = $(AM_CXXFLAGS)
+-libfederated_a_CFLAGS = $(AM_CFLAGS)
+-libfederated_a_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
++noinst_LTLIBRARIES = @plugin_federated_static_target@ @plugin_federated_embedded_static_target@
++libfederated_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libfederated_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libfederated_la_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
++
++libfederated_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++libfederated_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@
++libfederated_embedded_la_SOURCES= ha_federated.cc $(top_srcdir)/mysys/string.c
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/federated/plug.in
+===================================================================
+--- storage/federated/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/federated/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,5 +1,4 @@
+ MYSQL_STORAGE_ENGINE(federated,,[Federated Storage Engine],
+ [Connects to tables on remote MySQL servers], [max,max-no-ndb])
+-MYSQL_PLUGIN_STATIC(federated, [libfederated.a])
++MYSQL_PLUGIN_STATIC(federated, [libfederated.la], [libfederated_embedded.la])
+ MYSQL_PLUGIN_DYNAMIC(federated, [ha_federated.la])
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(federated, [ha_federated.cc])
+Index: storage/heap/Makefile.am
+===================================================================
+--- storage/heap/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/heap/Makefile.am 2010-11-27 19:44:23.000000000 +0100
+@@ -26,27 +26,40 @@ WRAPLIBS=
+ LDADD =
+
+ DEFS = @DEFS@
+-pkglib_LIBRARIES = libheap.a
++noinst_LTLIBRARIES = libheap.la libheap_s.la libheap_common.la \
++ @plugin_heap_embedded_static_target@
++EXTRA_LTLIBRARIES = libheap_embedded.la
++
+ noinst_PROGRAMS = hp_test1 hp_test2
+-noinst_LIBRARIES = libheap.a
+ hp_test1_LDFLAGS = @NOINST_LDFLAGS@
+-hp_test1_LDADD = libheap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++hp_test1_LDADD = libheap.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+ hp_test2_LDFLAGS = @NOINST_LDFLAGS@
+-hp_test2_LDADD = libheap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++hp_test2_LDADD = libheap.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+ noinst_HEADERS = heapdef.h ha_heap.h
+-libheap_a_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
++libheap_common_la_SOURCES = hp_open.c hp_extra.c hp_close.c hp_panic.c hp_info.c \
+ hp_rrnd.c hp_scan.c hp_update.c hp_write.c hp_delete.c \
+ hp_rsame.c hp_create.c hp_rename.c hp_rfirst.c \
+ hp_rnext.c hp_rlast.c hp_rprev.c hp_clear.c \
+ hp_rkey.c hp_block.c \
+- ha_heap.cc \
+ hp_hash.c _check.c _rectest.c hp_static.c
++libheap_common_la_CFLAGS = $(AM_LDFLAGS) @plugin_static_if_no_embedded@
++
++libheap_s_la_SOURCES = ha_heap.cc
++libheap_s_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libheap_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libheap_s_la_LIBADD = libheap_common.la
++libheap_embedded_la_SOURCES = ha_heap.cc
++libheap_embedded_la_LIBADD = libheap_common.la
++libheap_embedded_la_CXXFLAGS = @plugin_embedded_defs@
++libheap_la_SOURCES =
++libheap_la_LIBADD = libheap_s.la
++libheap_la_LDFLAGS = -static
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/heap/plug.in
+===================================================================
+--- storage/heap/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/heap/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,6 @@
+ MYSQL_STORAGE_ENGINE(heap,no, [Memory Storage Engine],
+ [Volatile memory based tables])
+ MYSQL_PLUGIN_DIRECTORY(heap, [storage/heap])
+-MYSQL_PLUGIN_STATIC(heap, [libheap.a])
++MYSQL_PLUGIN_STATIC(heap, [libheap_s.la], [libheap_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(heap) dnl Memory tables
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(heap, [ha_heap.cc])
+
+Index: storage/innobase/Makefile.am
+===================================================================
+--- storage/innobase/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innobase/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -15,21 +15,20 @@
+
+ # Process this file with automake to create Makefile.in
+
+-MYSQLDATAdir= $(localstatedir)
+-MYSQLSHAREdir= $(pkgdatadir)
+-MYSQLBASEdir= $(prefix)
+-MYSQLLIBdir= $(pkglibdir)
+-pkgplugindir= $(pkglibdir)/plugin
+-INCLUDES= -I$(top_srcdir)/include -I$(top_builddir)/include \
++MYSQLDATAdir = $(localstatedir)
++MYSQLSHAREdir = $(pkgdatadir)
++MYSQLBASEdir = $(prefix)
++MYSQLLIBdir = $(pkglibdir)
++pkgplugindir = $(pkglibdir)/plugin
++INCLUDES = -I$(top_srcdir)/include -I$(top_builddir)/include \
+ -I$(top_srcdir)/regex \
+ -I$(top_srcdir)/storage/innobase/include \
+ -I$(top_srcdir)/sql \
+ -I$(srcdir)
+
+-DEFS= @DEFS@
++DEFS= @DEFS@
+
+-
+-noinst_HEADERS= include/btr0btr.h include/btr0btr.ic \
++noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
+ include/btr0cur.h include/btr0cur.ic \
+ include/btr0pcur.h include/btr0pcur.ic \
+ include/btr0sea.h include/btr0sea.ic \
+@@ -122,9 +121,8 @@ noinst_HEADERS= include/btr0btr.h inclu
+ include/ut0list.ic include/ut0wqueue.h \
+ include/ha_prototypes.h handler/ha_innodb.h
+
+-EXTRA_LIBRARIES= libinnobase.a
+-noinst_LIBRARIES= @plugin_innobase_static_target@
+-libinnobase_a_SOURCES= btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
++noinst_LTLIBRARIES = @plugin_innobase_static_target@
++libinnobase_la_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
+ btr/btr0sea.c buf/buf0buf.c buf/buf0flu.c \
+ buf/buf0lru.c buf/buf0rea.c data/data0data.c \
+ data/data0type.c dict/dict0boot.c \
+@@ -156,18 +154,18 @@ libinnobase_a_SOURCES= btr/btr0btr.c btr
+ ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
+ handler/ha_innodb.cc
+
+-libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
+-libinnobase_a_CFLAGS= $(AM_CFLAGS)
++libinnobase_la_CXXFLAGS = $(AM_CXXFLAGS)
++libinnobase_la_CFLAGS = $(AM_CFLAGS)
+
+-EXTRA_LTLIBRARIES= ha_innodb.la
+-pkgplugin_LTLIBRARIES= @plugin_innobase_shared_target@
++EXTRA_LTLIBRARIES = libinnobase.la ha_innodb.la
++pkgplugin_LTLIBRARIES = @plugin_innobase_shared_target@
+
+-ha_innodb_la_LDFLAGS= -module -rpath $(pkgplugindir)
+-ha_innodb_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_la_SOURCES= $(libinnobase_a_SOURCES)
++ha_innodb_la_LDFLAGS = -module -rpath $(pkgplugindir)
++ha_innodb_la_CXXFLAGS = $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
++ha_innodb_la_CFLAGS = $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
++ha_innodb_la_SOURCES = $(libinnobase_la_SOURCES)
+
+-EXTRA_DIST= CMakeLists.txt plug.in \
++EXTRA_DIST = CMakeLists.txt plug.in \
+ pars/make_bison.sh pars/make_flex.sh \
+ pars/pars0grm.y pars/pars0lex.l
+
+Index: storage/innobase/plug.in
+===================================================================
+--- storage/innobase/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innobase/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,7 @@
+ MYSQL_STORAGE_ENGINE(innobase, innodb, [InnoDB Storage Engine],
+ [Transactional Tables using InnoDB], [max,max-no-ndb])
+ MYSQL_PLUGIN_DIRECTORY(innobase, [storage/innobase])
+-MYSQL_PLUGIN_STATIC(innobase, [libinnobase.a])
++MYSQL_PLUGIN_STATIC(innobase, [libinnobase.la])
+ MYSQL_PLUGIN_DYNAMIC(innobase, [ha_innodb.la])
+ MYSQL_PLUGIN_ACTIONS(innobase, [
+ AC_CHECK_LIB(rt, aio_read, [innodb_system_libs="-lrt"])
+Index: storage/innodb_plugin/Makefile.am
+===================================================================
+--- storage/innodb_plugin/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/innodb_plugin/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -228,9 +228,8 @@ noinst_HEADERS= \
+ include/ut0wqueue.h \
+ mem/mem0dbg.c
+
+-EXTRA_LIBRARIES= libinnobase.a
+-noinst_LIBRARIES= @plugin_innodb_plugin_static_target@
+-libinnobase_a_SOURCES= \
++noinst_LTLIBRARIES= @plugin_innodb_plugin_static_target@
++libinnobase_la_SOURCES= \
+ btr/btr0btr.c \
+ btr/btr0cur.c \
+ btr/btr0pcur.c \
+@@ -325,16 +324,16 @@ libinnobase_a_SOURCES= \
+ ut/ut0vec.c \
+ ut/ut0wqueue.c
+
+-libinnobase_a_CXXFLAGS= $(AM_CXXFLAGS)
+-libinnobase_a_CFLAGS= $(AM_CFLAGS)
++libinnobase_la_CXXFLAGS= $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libinnobase_la_CFLAGS= $(AM_CFLAGS) @plugin_static_if_no_embedded@
+
+-EXTRA_LTLIBRARIES= ha_innodb_plugin.la
++EXTRA_LTLIBRARIES= libinnobase.la ha_innodb_plugin.la
+ pkgplugin_LTLIBRARIES= @plugin_innodb_plugin_shared_target@
+
+ ha_innodb_plugin_la_LDFLAGS= -module -rpath $(pkgplugindir)
+ ha_innodb_plugin_la_CXXFLAGS= $(AM_CXXFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+ ha_innodb_plugin_la_CFLAGS= $(AM_CFLAGS) $(INNODB_DYNAMIC_CFLAGS)
+-ha_innodb_plugin_la_SOURCES= $(libinnobase_a_SOURCES)
++ha_innodb_plugin_la_SOURCES= $(libinnobase_la_SOURCES)
+
+ EXTRA_DIST= CMakeLists.txt plug.in \
+ pars/make_bison.sh pars/make_flex.sh \
+Index: storage/myisam/Makefile.am
+===================================================================
+--- storage/myisam/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisam/Makefile.am 2010-11-27 19:44:01.000000000 +0100
+@@ -30,60 +30,63 @@ DEFS = @DEFS@
+ EXTRA_DIST = mi_test_all.sh mi_test_all.res ft_stem.c CMakeLists.txt plug.in
+ pkgdata_DATA = mi_test_all mi_test_all.res
+
+-pkglib_LIBRARIES = libmyisam.a
++noinst_LTLIBRARIES = libmyisam.la libmyisam_common.la libmyisam_s.la \
++ @plugin_myisam_embedded_static_target@
++EXTRA_LTLIBRARIES = libmyisam_embedded.la
++
+ bin_PROGRAMS = myisamchk myisamlog myisampack myisam_ftdump
+-myisamchk_DEPENDENCIES= $(LIBRARIES)
+-myisamchk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-myisamlog_DEPENDENCIES= $(LIBRARIES)
+-myisamlog_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-myisampack_DEPENDENCIES=$(LIBRARIES)
+-myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
++myisamchk_DEPENDENCIES= $(LTLIBRARIES)
++myisamchk_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++myisamlog_DEPENDENCIES= $(LTLIBRARIES)
++myisamlog_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++myisampack_DEPENDENCIES=$(LTLIBRARIES)
++myisampack_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
+ noinst_PROGRAMS = mi_test1 mi_test2 mi_test3 rt_test sp_test #ft_test1 ft_eval
+ noinst_HEADERS = myisamdef.h rt_index.h rt_key.h rt_mbr.h sp_defs.h \
+ fulltext.h ftdefs.h ft_test1.h ft_eval.h \
+ ha_myisam.h
+-mi_test1_DEPENDENCIES= $(LIBRARIES)
+-mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-mi_test2_DEPENDENCIES= $(LIBRARIES)
+-mi_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-mi_test3_DEPENDENCIES= $(LIBRARIES)
+-mi_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-#ft_test1_DEPENDENCIES= $(LIBRARIES)
+-#ft_eval_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_DEPENDENCIES= $(LIBRARIES)
+-myisam_ftdump_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-rt_test_DEPENDENCIES= $(LIBRARIES)
+-rt_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-sp_test_DEPENDENCIES= $(LIBRARIES)
+-sp_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a @ZLIB_LIBS@
+-libmyisam_a_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
++mi_test1_DEPENDENCIES= $(LTLIBRARIES)
++mi_test1_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++mi_test2_DEPENDENCIES= $(LTLIBRARIES)
++mi_test2_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++mi_test3_DEPENDENCIES= $(LTLIBRARIES)
++mi_test3_LDADD= @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++#ft_test1_DEPENDENCIES= $(LTLIBRARIES)
++#ft_eval_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_DEPENDENCIES= $(LTLIBRARIES)
++myisam_ftdump_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++rt_test_DEPENDENCIES= $(LTLIBRARIES)
++rt_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++sp_test_DEPENDENCIES= $(LTLIBRARIES)
++sp_test_LDADD = @CLIENT_EXTRA_LDFLAGS@ libmyisam.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la @ZLIB_LIBS@
++libmyisam_common_la_SOURCES = mi_open.c mi_extra.c mi_info.c mi_rkey.c \
+ mi_rnext.c mi_rnext_same.c \
+ mi_search.c mi_page.c mi_key.c mi_locking.c \
+ mi_rrnd.c mi_scan.c mi_cache.c \
+@@ -98,8 +101,23 @@ libmyisam_a_SOURCES = mi_open.c mi_extra
+ mi_keycache.c mi_preload.c \
+ ft_parser.c ft_stopwords.c ft_static.c \
+ ft_update.c ft_boolean_search.c ft_nlq_search.c sort.c \
+- ha_myisam.cc \
+ rt_index.c rt_key.c rt_mbr.c rt_split.c sp_key.c
++libmyisam_common_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libmyisam_s_la_SOURCES = ha_myisam.cc
++libmyisam_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libmyisam_s_la_LIBADD = libmyisam_common.la
++libmyisam_embedded_la_SOURCES = ha_myisam.cc
++libmyisam_embedded_la_LIBADD = libmyisam_common.la
++libmyisam_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++# libmyisam references symbols inside mysqld.
++# This means we cannot use it as shared library, as these references causes
++# undefined symbol errors at load time.
++# But a static library works (as long as those parts that references
++# problematic symbols are not linked).
++libmyisam_la_LDFLAGS = -static
++libmyisam_la_SOURCES =
++libmyisam_la_LIBADD = libmyisam_s.la
++
+ CLEANFILES = test?.MY? FT?.MY? isam.log mi_test_all rt_test.MY? sp_test.MY?
+
+ # Move to automake rules ?
+Index: storage/myisam/plug.in
+===================================================================
+--- storage/myisam/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisam/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,7 +1,5 @@
+ MYSQL_STORAGE_ENGINE(myisam,no, [MyISAM Storage Engine],
+ [Traditional non-transactional MySQL tables])
+ MYSQL_PLUGIN_DIRECTORY(myisam, [storage/myisam])
+-MYSQL_PLUGIN_STATIC(myisam, [libmyisam.a])
++MYSQL_PLUGIN_STATIC(myisam, [libmyisam_s.la], [libmyisam_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(myisam) dnl Default
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisam, [ha_myisam.cc])
+-
+Index: storage/myisammrg/Makefile.am
+===================================================================
+--- storage/myisammrg/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisammrg/Makefile.am 2010-11-27 19:43:39.000000000 +0100
+@@ -26,16 +26,28 @@ WRAPLIBS=
+ LDADD =
+
+ DEFS = @DEFS@
+-pkglib_LIBRARIES = libmyisammrg.a
++noinst_LTLIBRARIES = libmyisammrg.la libmyisammrg_s.la libmyisammrg_common.la \
++ @plugin_myisammrg_embedded_static_target@
++EXTRA_LTLIBRARIES = libmyisammrg_embedded.la
+ noinst_HEADERS = myrg_def.h ha_myisammrg.h
+-noinst_LIBRARIES = libmyisammrg.a
+-libmyisammrg_a_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
++libmyisammrg_common_la_SOURCES = myrg_open.c myrg_extra.c myrg_info.c myrg_locking.c \
+ myrg_rrnd.c myrg_update.c myrg_delete.c myrg_rsame.c \
+ myrg_panic.c myrg_close.c myrg_create.c myrg_static.c \
+ myrg_rkey.c myrg_rfirst.c myrg_rlast.c myrg_rnext.c \
+ myrg_rprev.c myrg_queue.c myrg_write.c myrg_range.c \
+- ha_myisammrg.cc \
+ myrg_rnext_same.c myrg_records.c
++libmyisammrg_common_la_CFLAGS = $(AM_CFLAGS) @plugin_static_if_no_embedded@
++libmyisammrg_s_la_SOURCES = ha_myisammrg.cc
++libmyisammrg_s_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_static_if_no_embedded@
++libmyisammrg_s_la_LIBADD = libmyisammrg_common.la
++libmyisammrg_embedded_la_SOURCES = ha_myisammrg.cc
++libmyisammrg_embedded_la_CFLAGS = $(AM_CFLAGS) @plugin_embedded_defs@
++libmyisammrg_embedded_la_LIBADD = libmyisammrg_common.la
++libmyisammrg_embedded_la_CXXFLAGS = $(AM_CXXFLAGS) @plugin_embedded_defs@
++libmyisammrg_la_SOURCES =
++libmyisammrg_la_LIBADD = libmyisammrg_s.la
++libmyisammrg_la_LDFLAGS = -static
++
+
+
+ EXTRA_DIST = CMakeLists.txt plug.in
+Index: storage/myisammrg/plug.in
+===================================================================
+--- storage/myisammrg/plug.in.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/myisammrg/plug.in 2010-11-27 15:02:49.000000000 +0100
+@@ -1,6 +1,5 @@
+ MYSQL_STORAGE_ENGINE(myisammrg,no,[MyISAM MERGE Engine],
+ [Merge multiple MySQL tables into one])
+ MYSQL_PLUGIN_DIRECTORY(myisammrg,[storage/myisammrg])
+-MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg.a])
++MYSQL_PLUGIN_STATIC(myisammrg, [libmyisammrg_s.la], [libmyisammrg_embedded.la])
+ MYSQL_PLUGIN_MANDATORY(myisammrg)
+-MYSQL_PLUGIN_DEPENDS_ON_MYSQL_INTERNALS(myisammrg, [ha_myisammrg.cc])
+Index: storage/ndb/src/common/util/Makefile.am
+===================================================================
+--- storage/ndb/src/common/util/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/common/util/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -31,9 +31,9 @@ EXTRA_PROGRAMS = testBitmask
+ testBitmask_SOURCES = testBitmask.cpp
+ testBitmask_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testBitmask.cpp : Bitmask.cpp
+ rm -f testBitmask.cpp
+Index: storage/ndb/config/type_ndbapitest.mk.am
+===================================================================
+--- storage/ndb/config/type_ndbapitest.mk.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/type_ndbapitest.mk.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,19 +13,20 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-LDADD += $(top_builddir)/storage/ndb/test/src/libNDBT.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++LDADD += $(top_builddir)/storage/ndb/test/src/libNDBT.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+-INCLUDES += -I$(top_srcdir) \
+- -I$(top_builddir)/include \
+- -I$(top_builddir)/storage/ndb/include \
+- -I$(top_srcdir)/include \
+- -I$(top_srcdir)/storage/ndb/include \
+- -I$(top_srcdir)/storage/ndb/include/ndbapi \
+- -I$(top_srcdir)/storage/ndb/include/util \
+- -I$(top_srcdir)/storage/ndb/include/portlib \
+- -I$(top_srcdir)/storage/ndb/test/include \
+- -I$(top_srcdir)/storage/ndb/include/mgmapi
++INCLUDES += -I$(top_srcdir) \
++ -I$(top_builddir)/include \
++ -I$(top_builddir)/storage/ndb/include \
++ -I$(top_srcdir)/include \
++ -I$(top_srcdir)/storage/ndb/include \
++ -I$(top_srcdir)/storage/ndb/include/ndbapi \
++ -I$(top_srcdir)/storage/ndb/include/util \
++ -I$(top_srcdir)/storage/ndb/include/portlib \
++ -I$(top_srcdir)/storage/ndb/test/include \
++ -I$(top_srcdir)/storage/ndb/include/mgmapi
+Index: storage/ndb/config/type_ndbapitools.mk.am
+===================================================================
+--- storage/ndb/config/type_ndbapitools.mk.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/type_ndbapitools.mk.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,20 +13,21 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-LDADD += \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@ @ZLIB_LIBS@
++LDADD += \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+-INCLUDES += -I$(srcdir) \
+- -I$(top_builddir)/include \
+- -I$(top_builddir)/storage/ndb/include \
+- -I$(top_srcdir)/include \
+- -I$(top_srcdir)/storage/ndb/include \
+- -I$(top_srcdir)/storage/ndb/include/ndbapi \
+- -I$(top_srcdir)/storage/ndb/include/util \
+- -I$(top_srcdir)/storage/ndb/include/portlib \
+- -I$(top_srcdir)/storage/ndb/test/include \
+- -I$(top_srcdir)/storage/ndb/include/mgmapi \
+- -I$(top_srcdir)/storage/ndb/include/kernel
++INCLUDES += -I$(srcdir) \
++ -I$(top_builddir)/include \
++ -I$(top_builddir)/storage/ndb/include \
++ -I$(top_srcdir)/include \
++ -I$(top_srcdir)/storage/ndb/include \
++ -I$(top_srcdir)/storage/ndb/include/ndbapi \
++ -I$(top_srcdir)/storage/ndb/include/util \
++ -I$(top_srcdir)/storage/ndb/include/portlib \
++ -I$(top_srcdir)/storage/ndb/test/include \
++ -I$(top_srcdir)/storage/ndb/include/mgmapi \
++ -I$(top_srcdir)/storage/ndb/include/kernel
+Index: storage/ndb/config/win-libraries
+===================================================================
+--- storage/ndb/config/win-libraries.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/config/win-libraries 2010-11-27 15:02:49.000000000 +0100
+@@ -21,7 +21,7 @@ do
+ # the same goes for mysys and strings
+ lib=$i
+ case $i in
+- *libdbug.a | *libmysys.a | *libmystrings.a)
++ *libdbug.la | *libmysys.la | *libmystrings.la)
+ lib=`echo $i | sed s'!dbug\/lib!!' | sed 's!mysys\/lib!!' | sed 's!strings\/libmy!!'`
+ echo "Changing from $i to $lib"
+ ;;
+Index: storage/ndb/src/cw/cpcd/Makefile.am
+===================================================================
+--- storage/ndb/src/cw/cpcd/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/cw/cpcd/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -19,9 +19,9 @@ ndb_cpcd_SOURCES = main.cpp CPCD.cpp Pro
+
+ LDADD_LOC = \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_util.mk.am
+Index: storage/ndb/src/kernel/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -53,9 +53,10 @@ LDADD += \
+ $(top_builddir)/storage/ndb/src/mgmapi/libmgmapi.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@ \
++ $(ZLIB_LIBS)
+
+ windoze-dsp: ndbd.dsp
+
+Index: storage/ndb/src/kernel/blocks/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -18,7 +18,7 @@ SUBDIRS = \
+ dbdih \
+ dblqh \
+ dbtup \
+- backup
++ backup
+
+ noinst_LIBRARIES = libblocks.a
+
+@@ -56,10 +56,10 @@ libblocks_a_SOURCES = tsman.cpp lgman.cp
+ EXTRA_PROGRAMS = ndb_print_file
+ ndb_print_file_SOURCES = print_file.cpp diskpage.cpp dbtup/tuppage.cpp
+ ndb_print_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+Index: storage/ndb/src/kernel/blocks/backup/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/backup/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/backup/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -17,9 +17,9 @@ ndbtools_PROGRAMS = ndb_print_backup_fil
+ ndb_print_backup_file_SOURCES = read.cpp
+ ndb_print_backup_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_kernel.mk.am
+Index: storage/ndb/src/kernel/blocks/dbdict/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbdict/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbdict/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -19,17 +19,17 @@ include $(top_srcdir)/storage/ndb/config
+ LDADD += \
+ $(top_builddir)/storage/ndb/src/common/util/libgeneral.la \
+ $(top_builddir)/storage/ndb/src/common/portlib/libportlib.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ ndbtools_PROGRAMS = ndb_print_schema_file
+ ndb_print_schema_file_SOURCES = printSchemaFile.cpp
+ ndb_print_schema_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/blocks/dbdih/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbdih/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbdih/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -17,9 +17,9 @@ ndbtools_PROGRAMS = ndb_print_sys_file
+ ndb_print_sys_file_SOURCES = printSysfile.cpp
+ ndb_print_sys_file_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+Index: storage/ndb/src/kernel/blocks/dblqh/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dblqh/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dblqh/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -23,9 +23,9 @@ include $(top_srcdir)/storage/ndb/config
+
+ ndbd_redo_log_reader_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/blocks/dbtup/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/blocks/dbtup/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/blocks/dbtup/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -20,9 +20,9 @@ EXTRA_PROGRAMS = test_varpage
+ test_varpage_SOURCES = test_varpage.cpp tuppage.cpp
+ test_varpage_LDFLAGS = @ndb_bin_am_ldflags@ \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: storage/ndb/src/kernel/vm/Makefile.am
+===================================================================
+--- storage/ndb/src/kernel/vm/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/kernel/vm/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -21,22 +21,22 @@
+ noinst_LIBRARIES = libkernel.a
+
+ libkernel_a_SOURCES = \
+- SimulatedBlock.cpp \
+- FastScheduler.cpp \
+- TimeQueue.cpp \
+- VMSignal.cpp \
+- ThreadConfig.cpp \
+- TransporterCallback.cpp \
+- Emulator.cpp \
+- Configuration.cpp \
+- WatchDog.cpp \
+- SimplePropertiesSection.cpp \
+- SectionReader.cpp \
+- Mutex.cpp SafeCounter.cpp \
+- Rope.cpp \
+- ndbd_malloc.cpp ndbd_malloc_impl.cpp \
+- Pool.cpp WOPool.cpp RWPool.cpp \
+- DynArr256.cpp
++ SimulatedBlock.cpp \
++ FastScheduler.cpp \
++ TimeQueue.cpp \
++ VMSignal.cpp \
++ ThreadConfig.cpp \
++ TransporterCallback.cpp \
++ Emulator.cpp \
++ Configuration.cpp \
++ WatchDog.cpp \
++ SimplePropertiesSection.cpp \
++ SectionReader.cpp \
++ Mutex.cpp SafeCounter.cpp \
++ Rope.cpp \
++ ndbd_malloc.cpp ndbd_malloc_impl.cpp \
++ Pool.cpp WOPool.cpp RWPool.cpp \
++ DynArr256.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
+
+@@ -49,40 +49,40 @@ include $(top_srcdir)/storage/ndb/config
+ windoze-dsp: libkernel.dsp
+
+ libkernel.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libkernel_a_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
+
+ EXTRA_PROGRAMS = ndbd_malloc_impl_test bench_pool testDynArr256
+ ndbd_malloc_impl_test_CXXFLAGS = -DUNIT_TEST
+ ndbd_malloc_impl_test_SOURCES = ndbd_malloc_impl.cpp
+ ndbd_malloc_impl_test_LDFLAGS = @ndb_bin_am_ldflags@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ bench_pool_SOURCES = bench_pool.cpp
+-bench_pool_LDFLAGS = @ndb_bin_am_ldflags@\
+- libkernel.a ../error/liberror.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++bench_pool_LDFLAGS = @ndb_bin_am_ldflags@ \
++ libkernel.a ../error/liberror.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ testDynArr256_CXXFLAGS = -DUNIT_TEST
+ testDynArr256_SOURCES = DynArr256.cpp
+ testDynArr256_LDFLAGS = @ndb_bin_am_ldflags@ \
+- libkernel.a ../error/liberror.a \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++ libkernel.a ../error/liberror.a \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la
+
+Index: storage/ndb/src/mgmclient/Makefile.am
+===================================================================
+--- storage/ndb/src/mgmclient/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/mgmclient/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -18,12 +18,11 @@ ndbtools_PROGRAMS = ndb_mgm
+
+ libndbmgmclient_la_SOURCES = CommandInterpreter.cpp
+ libndbmgmclient_la_LIBADD = ../mgmapi/libmgmapi.la \
+- ../common/logger/liblogger.la \
+- ../common/portlib/libportlib.la \
+- ../common/util/libgeneral.la \
+- ../common/portlib/libportlib.la \
+- ../common/debugger/libtrace.la
+-
++ ../common/logger/liblogger.la \
++ ../common/portlib/libportlib.la \
++ ../common/util/libgeneral.la \
++ ../common/portlib/libportlib.la \
++ ../common/debugger/libtrace.la
+
+ ndb_mgm_SOURCES = main.cpp
+
+@@ -34,13 +33,13 @@ INCLUDES += -I$(top_srcdir)/storage/ndb/
+ -I$(top_srcdir)/storage/ndb/src/common/mgmcommon
+
+ LDADD_LOC = $(noinst_LTLIBRARIES) \
+- ../common/portlib/libportlib.la \
+- @readline_link@ \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- @TERMCAP_LIB@ @NDB_SCI_LIBS@
++ ../common/portlib/libportlib.la \
++ @readline_link@ \
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ @TERMCAP_LIB@ @NDB_SCI_LIBS@
+
+ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+
+@@ -50,25 +49,25 @@ ndb_mgm_LDFLAGS = @ndb_bin_am_ldflags@
+ windoze-dsp: ndb_mgm.dsp libndbmgmclient.dsp
+
+ ndb_mgm.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-prg.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbtools_PROGRAMS)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgm_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-prg.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbtools_PROGRAMS)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgm_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
+
+ libndbmgmclient.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbmgmclient_la_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbmgmclient_la_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB
+Index: storage/ndb/src/mgmsrv/Makefile.am
+===================================================================
+--- storage/ndb/src/mgmsrv/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/mgmsrv/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -22,35 +22,35 @@ MYSQLCLUSTERdir= .
+ ndbbin_PROGRAMS = ndb_mgmd
+
+ ndb_mgmd_SOURCES = \
+- MgmtSrvr.cpp \
+- MgmtSrvrGeneralSignalHandling.cpp \
+- main.cpp \
+- Services.cpp \
+- convertStrToInt.cpp \
+- SignalQueue.cpp \
+- MgmtSrvrConfig.cpp \
+- ConfigInfo.cpp \
+- InitConfigFileParser.cpp \
+- Config.cpp
++ MgmtSrvr.cpp \
++ MgmtSrvrGeneralSignalHandling.cpp \
++ main.cpp \
++ Services.cpp \
++ convertStrToInt.cpp \
++ SignalQueue.cpp \
++ MgmtSrvrConfig.cpp \
++ ConfigInfo.cpp \
++ InitConfigFileParser.cpp \
++ Config.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/ndbapi \
+- -I$(top_srcdir)/storage/ndb/src/mgmapi \
+- -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \
+- -I$(top_srcdir)/storage/ndb/src/mgmclient
++ -I$(top_srcdir)/storage/ndb/src/mgmapi \
++ -I$(top_srcdir)/storage/ndb/src/common/mgmcommon \
++ -I$(top_srcdir)/storage/ndb/src/mgmclient
+
+ LDADD_LOC = $(top_builddir)/storage/ndb/src/mgmclient/CommandInterpreter.lo \
+- $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- @readline_link@ \
+- @NDB_SCI_LIBS@ \
+- @TERMCAP_LIB@
+-
+-DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
+- -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
+- -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
+- -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\""
++ $(top_builddir)/storage/ndb/src/libndbclient.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ @readline_link@ \
++ @NDB_SCI_LIBS@ \
++ @TERMCAP_LIB@
++
++DEFS_LOC = -DDEFAULT_MYSQL_HOME="\"$(MYSQLBASEdir)\"" \
++ -DMYSQL_DATADIR="\"$(MYSQLDATAdir)\"" \
++ -DSHAREDIR="\"$(MYSQLSHAREdir)\"" \
++ -DMYSQLCLUSTERDIR="\"$(MYSQLCLUSTERdir)\""
+
+ include $(top_srcdir)/storage/ndb/config/common.mk.am
+ include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
+@@ -63,13 +63,13 @@ ndb_mgmd_LDFLAGS = @ndb_bin_am_ldflags@
+ windoze-dsp: ndb_mgmd.dsp
+
+ ndb_mgmd.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-prg.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-prg.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-prg.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(ndbbin_PROGRAMS)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(ndb_mgmd_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LINK $(LDADD)
+Index: storage/ndb/src/ndbapi/Makefile.am
+===================================================================
+--- storage/ndb/src/ndbapi/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/src/ndbapi/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -22,41 +22,42 @@ ndberror_check_SOURCES = ndberror_check.
+ noinst_LTLIBRARIES = libndbapi.la
+
+ libndbapi_la_SOURCES = \
+- TransporterFacade.cpp \
+- ClusterMgr.cpp \
+- Ndb.cpp \
+- NdbPoolImpl.cpp \
+- NdbPool.cpp \
+- Ndblist.cpp \
+- Ndbif.cpp \
+- Ndbinit.cpp \
+- Ndberr.cpp \
+- ndberror.c \
+- NdbErrorOut.cpp \
+- NdbTransaction.cpp \
+- NdbTransactionScan.cpp \
+- NdbOperation.cpp \
+- NdbOperationSearch.cpp \
+- NdbOperationScan.cpp \
+- NdbOperationInt.cpp \
+- NdbOperationDefine.cpp \
+- NdbOperationExec.cpp \
+- NdbScanOperation.cpp NdbScanFilter.cpp \
+- NdbIndexOperation.cpp \
+- NdbEventOperation.cpp \
+- NdbEventOperationImpl.cpp \
+- NdbApiSignal.cpp \
+- NdbRecAttr.cpp \
+- NdbUtil.cpp \
+- NdbReceiver.cpp \
+- NdbDictionary.cpp \
+- NdbDictionaryImpl.cpp \
+- DictCache.cpp \
+- ndb_cluster_connection.cpp \
+- NdbBlob.cpp \
+- NdbIndexStat.cpp \
+- SignalSender.cpp \
+- ObjectMap.cpp
++ TransporterFacade.cpp \
++ ClusterMgr.cpp \
++ Ndb.cpp \
++ NdbPoolImpl.cpp \
++ NdbPool.cpp \
++ Ndblist.cpp \
++ Ndbif.cpp \
++ Ndbinit.cpp \
++ Ndberr.cpp \
++ ndberror.c \
++ NdbErrorOut.cpp \
++ NdbTransaction.cpp \
++ NdbTransactionScan.cpp \
++ NdbOperation.cpp \
++ NdbOperationSearch.cpp \
++ NdbOperationScan.cpp \
++ NdbOperationInt.cpp \
++ NdbOperationDefine.cpp \
++ NdbOperationExec.cpp \
++ NdbScanOperation.cpp \
++ NdbScanFilter.cpp \
++ NdbIndexOperation.cpp \
++ NdbEventOperation.cpp \
++ NdbEventOperationImpl.cpp \
++ NdbApiSignal.cpp \
++ NdbRecAttr.cpp \
++ NdbUtil.cpp \
++ NdbReceiver.cpp \
++ NdbDictionary.cpp \
++ NdbDictionaryImpl.cpp \
++ DictCache.cpp \
++ ndb_cluster_connection.cpp \
++ NdbBlob.cpp \
++ NdbIndexStat.cpp \
++ SignalSender.cpp \
++ ObjectMap.cpp
+
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/src/mgmapi
+
+@@ -67,9 +68,10 @@ include $(top_srcdir)/storage/ndb/config
+ include $(top_srcdir)/storage/ndb/config/type_ndbapi.mk.am
+
+ ndberror_check_LDFLAGS = \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+@@ -77,13 +79,13 @@ ndberror_check_LDFLAGS = \
+ windoze-dsp: libndbapi.dsp
+
+ libndbapi.dsp: Makefile \
+- $(top_srcdir)/storage/ndb/config/win-lib.am \
+- $(top_srcdir)/storage/ndb/config/win-name \
+- $(top_srcdir)/storage/ndb/config/win-includes \
+- $(top_srcdir)/storage/ndb/config/win-sources \
+- $(top_srcdir)/storage/ndb/config/win-libraries
+- cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
+- @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
+- @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
+- @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbapi_la_SOURCES)
+- @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
++ $(top_srcdir)/storage/ndb/config/win-lib.am \
++ $(top_srcdir)/storage/ndb/config/win-name \
++ $(top_srcdir)/storage/ndb/config/win-includes \
++ $(top_srcdir)/storage/ndb/config/win-sources \
++ $(top_srcdir)/storage/ndb/config/win-libraries
++ cat $(top_srcdir)/storage/ndb/config/win-lib.am > $@
++ @$(top_srcdir)/storage/ndb/config/win-name $@ $(noinst_LTLIBRARIES)
++ @$(top_srcdir)/storage/ndb/config/win-includes $@ $(INCLUDES)
++ @$(top_srcdir)/storage/ndb/config/win-sources $@ $(libndbapi_la_SOURCES)
++ @$(top_srcdir)/storage/ndb/config/win-libraries $@ LIB $(LDADD)
+Index: storage/ndb/test/run-test/Makefile.am
+===================================================================
+--- storage/ndb/test/run-test/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ storage/ndb/test/run-test/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -34,9 +34,9 @@ atrt_SOURCES = main.cpp setup.cpp files.
+ INCLUDES_LOC = -I$(top_srcdir)/storage/ndb/test/include
+ LDADD_LOC = $(top_builddir)/storage/ndb/test/src/libNDBT.a \
+ $(top_builddir)/storage/ndb/src/libndbclient.la \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a @NDB_SCI_LIBS@
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la @NDB_SCI_LIBS@
+
+ atrt_CXXFLAGS = -I$(top_srcdir)/ndb/src/mgmapi \
+ -I$(top_srcdir)/ndb/src/mgmsrv \
+Index: strings/Makefile.am
+===================================================================
+--- strings/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ strings/Makefile.am 2010-11-27 19:42:38.000000000 +0100
+@@ -16,7 +16,7 @@
+ # This file is public domain and comes with NO WARRANTY of any kind
+
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
+-pkglib_LIBRARIES = libmystrings.a
++noinst_LTLIBRARIES = libmystrings.la
+
+ # Exact one of ASSEMBLER_X
+ if ASSEMBLER_x86
+@@ -37,7 +37,7 @@ CSRCS = strxmov.c bmove_upp.c strappend
+ endif
+ endif
+
+-libmystrings_a_SOURCES = $(ASRCS) $(CSRCS)
++libmystrings_la_SOURCES = $(ASRCS) $(CSRCS)
+ noinst_PROGRAMS = conf_to_src
+ CLEANFILES = str_test uctypedump test_decimal
+ # Default charset definitions
+@@ -56,9 +56,9 @@ EXTRA_DIST = ctype-big5.c ctype-cp932.c
+ t_ctype.h my_strchr.c CMakeLists.txt \
+ CHARSET_INFO.txt
+
+-libmystrings_a_LIBADD=
+-conf_to_src_SOURCES = conf_to_src.c xml.c ctype.c
+-conf_to_src_LDADD=
++libmystrings_la_LIBADD=
++conf_to_src_SOURCES = conf_to_src.c
++conf_to_src_LDADD = libmystrings.la
+ #force static linking of conf_to_src - essential when linking against
+ #custom installation of libc
+ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+@@ -69,15 +69,15 @@ conf_to_src_LDFLAGS= @NOINST_LDFLAGS@
+
+ FLAGS=$(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) @NOINST_LDFLAGS@
+
+-str_test: str_test.c $(pkglib_LIBRARIES)
+- $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LIBRARIES)
++str_test: str_test.c $(pkglib_LTLIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN $(INCLUDES) $(srcdir)/str_test.c $(LDADD) $(pkglib_LTLIBRARIES)
+
+ uctypedump: uctypedump.c
+ $(LINK) $(INCLUDES) $(srcdir)/uctypedump.c
+
+ test_decimal$(EXEEXT): decimal.c $(pkglib_LIBRARIES)
+ $(CP) $(srcdir)/decimal.c ./test_decimal.c
+- $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LIBRARIES)
++ $(LINK) $(FLAGS) -DMAIN ./test_decimal.c $(LDADD) $(pkglib_LTLIBRARIES)
+ $(RM) -f ./test_decimal.c
+
+ # Don't update the files from bitkeeper
+Index: unittest/unit.pl
+===================================================================
+--- unittest/unit.pl.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/unit.pl 2010-11-27 15:02:49.000000000 +0100
+@@ -55,7 +55,7 @@ sub _find_test_files (@) {
+ my @dirs = @_;
+ my @files;
+ find sub {
+- $File::Find::prune = 1 if /^SCCS$/;
++ $File::Find::prune = 1 if /^(SCCS|\.libs)$/;
+ push(@files, $File::Find::name) if -x _ && /-t\z/;
+ }, @dirs;
+ return @files;
+Index: unittest/mysys/Makefile.am
+===================================================================
+--- unittest/mysys/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/mysys/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -13,15 +13,16 @@
+ # along with this program; if not, write to the Free Software
+ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
+-AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
++AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
++AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
+
+-LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+-noinst_PROGRAMS = bitmap-t base64-t
++noinst_PROGRAMS = bitmap-t base64-t
+
+ # Don't update the files from bitkeeper
+ %::SCCS/s.%
+Index: unittest/strings/Makefile.am
+===================================================================
+--- unittest/strings/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ unittest/strings/Makefile.am 2010-11-27 15:02:49.000000000 +0100
+@@ -16,10 +16,11 @@
+ AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include
+ AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap
+
+-LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/strings/libmystrings.a
++LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(ZLIB_LIBS)
+
+ noinst_PROGRAMS = strings-t
+
+Index: vio/Makefile.am
+===================================================================
+--- vio/Makefile.am.orig 2010-11-27 15:02:45.000000000 +0100
++++ vio/Makefile.am 2010-11-27 19:43:02.000000000 +0100
+@@ -16,11 +16,11 @@
+ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
+ $(openssl_includes)
+ LDADD = @CLIENT_EXTRA_LDFLAGS@ $(openssl_libs) $(yassl_libs)
+-pkglib_LIBRARIES = libvio.a
++noinst_LTLIBRARIES = libvio.la
+
+ noinst_HEADERS = vio_priv.h
+
+-libvio_a_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
++libvio_la_SOURCES = vio.c viosocket.c viossl.c viosslfactories.c
+
+ EXTRA_DIST= CMakeLists.txt
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:34 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:34 UTC (permalink / raw
To: gentoo-commits
commit: f66ac9d05911addce2b0e0c289cfe4f340d57c6e
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:33:50 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:33:50 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f66ac9d0
Add tracking.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
07110_all_mysql_gcc-4.2_5.1.65.patch | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/07110_all_mysql_gcc-4.2_5.1.65.patch b/07110_all_mysql_gcc-4.2_5.1.65.patch
index 89abf1a..9755a95 100644
--- a/07110_all_mysql_gcc-4.2_5.1.65.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.65.patch
@@ -1,3 +1,8 @@
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
diff -ur mysql-orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
--- mysql-orig/client/mysqlbinlog.cc 2012-08-14 01:12:29.733435005 +0000
+++ mysql/client/mysqlbinlog.cc 2012-08-14 01:14:59.292197574 +0000
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:34 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:34 UTC (permalink / raw
To: gentoo-commits
commit: 0e606bcb2c2a1e99e6184c9c9c6e74b1631e1393
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:34:07 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:34:07 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0e606bcb
Port min/max patch.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
00000_index.txt | 9 +-
07110_all_mysql_gcc-4.2_5.1.69.patch | 3838 ++++++++++++++++++++++++++++++++++
2 files changed, 3846 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 22de958..ebf5c95 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -573,11 +573,18 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.65.patch
-@ver 5.01.65.00 to 5.01.99.99
+@ver 5.01.65.00 to 5.01.68.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
+@patch 07110_all_mysql_gcc-4.2_5.1.69.patch
+@ver 5.01.69.00 to 5.01.99.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+
@patch 07120_all_openssl_handshake_mybug_33050.patch
@ver 5.00.50.00 to 5.00.54.99
@pn mysql
diff --git a/07110_all_mysql_gcc-4.2_5.1.69.patch b/07110_all_mysql_gcc-4.2_5.1.69.patch
new file mode 100644
index 0000000..e5919c4
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.69.patch
@@ -0,0 +1,3838 @@
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -ur mysql-orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql-orig/client/mysqlbinlog.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqlbinlog.cc 2012-08-14 01:14:59.292197574 +0000
+@@ -1978,7 +1978,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -ur mysql-orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql-orig/client/mysql.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -3334,9 +3334,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3356,7 +3356,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -ur mysql-orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql-orig/client/mysqldump.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqldump.c 2012-08-14 01:14:59.322198687 +0000
+@@ -849,7 +849,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4769,7 +4769,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -ur mysql-orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql-orig/client/mysqltest.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqltest.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -5666,9 +5666,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -ur mysql-orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql-orig/client/mysql_upgrade.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql_upgrade.c 2012-08-14 01:14:59.332198575 +0000
+@@ -533,7 +533,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -ur mysql-orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql-orig/client/sql_string.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/sql_string.cc 2012-08-14 01:14:59.332198575 +0000
+@@ -665,7 +665,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -751,7 +751,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -768,7 +768,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -ur mysql-orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql-orig/dbug/dbug.c 2012-08-14 01:12:29.743434923 +0000
++++ mysql/dbug/dbug.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -ur mysql-orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql-orig/extra/yassl/src/ssl.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -39,6 +39,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -114,7 +115,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -ur mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:14:59.332198575 +0000
+@@ -68,7 +68,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -ur mysql-orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-orig/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -ur mysql-orig/include/my_global.h mysql/include/my_global.h
+--- mysql-orig/include/my_global.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/include/my_global.h 2012-08-14 01:14:59.332198575 +0000
+@@ -586,10 +586,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -ur mysql-orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql-orig/libmysql/libmysql.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/libmysql/libmysql.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -ur mysql-orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql-orig/libmysqld/lib_sql.cc 2012-08-14 01:12:29.723435087 +0000
++++ mysql/libmysqld/lib_sql.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -844,7 +844,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -ur mysql-orig/mysys/array.c mysql/mysys/array.c
+--- mysql-orig/mysys/array.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/array.c 2012-08-14 01:14:59.372198019 +0000
+@@ -50,7 +50,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -344,7 +344,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -ur mysql-orig/mysys/default.c mysql/mysys/default.c
+--- mysql-orig/mysys/default.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/default.c 2012-08-14 01:14:59.372198019 +0000
+@@ -796,7 +796,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -ur mysql-orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql-orig/mysys/mf_format.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_format.c 2012-08-14 01:14:59.372198019 +0000
+@@ -86,7 +86,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -ur mysql-orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql-orig/mysys/mf_iocache.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_iocache.c 2012-08-14 01:14:59.372198019 +0000
+@@ -1099,7 +1099,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1258,7 +1258,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1367,7 +1367,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1401,7 +1401,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -ur mysql-orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql-orig/mysys/my_alloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_alloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -214,7 +214,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -ur mysql-orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql-orig/mysys/my_bitmap.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_bitmap.c 2012-08-14 01:14:59.372198019 +0000
+@@ -425,7 +425,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -ur mysql-orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql-orig/mysys/my_compare.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compare.c 2012-08-14 01:14:59.372198019 +0000
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -ur mysql-orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql-orig/mysys/my_compress.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compress.c 2012-08-14 01:14:59.372198019 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -ur mysql-orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql-orig/mysys/my_conio.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_conio.c 2012-08-14 01:14:59.372198019 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -ur mysql-orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql-orig/mysys/my_file.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_file.c 2012-08-14 01:14:59.372198019 +0000
+@@ -77,7 +77,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -99,7 +99,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -109,9 +109,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -ur mysql-orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql-orig/mysys/my_getopt.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_getopt.c 2012-08-14 01:14:59.372198019 +0000
+@@ -985,7 +985,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -ur mysql-orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql-orig/mysys/my_static.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_static.h 2012-08-14 01:14:59.372198019 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -ur mysql-orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql-orig/mysys/safemalloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/safemalloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -250,7 +250,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -ur mysql-orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql-orig/mysys/stacktrace.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/stacktrace.c 2012-08-14 01:14:59.372198019 +0000
+@@ -98,7 +98,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -328,7 +328,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
+ my_safe_printf_stderr("Cannot determine thread, fp=%p, "
+diff -ur mysql-orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql-orig/server-tools/instance-manager/buffer.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -86,8 +86,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -ur mysql-orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql-orig/server-tools/instance-manager/listener.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -106,7 +106,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -ur mysql-orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql-orig/sql/debug_sync.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/debug_sync.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -ur mysql-orig/sql/field.cc mysql/sql/field.cc
+--- mysql-orig/sql/field.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/field.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -55,7 +55,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2073,7 +2073,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2081,7 +2081,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2506,7 +2506,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2522,7 +2522,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3092,7 +3092,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3304,7 +3304,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3521,7 +3521,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3740,7 +3740,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3981,7 +3981,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4204,7 +4204,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6443,13 +6443,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6457,7 +6457,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6715,7 +6715,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7709,7 +7709,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7869,7 +7869,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8065,7 +8065,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9112,7 +9112,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9198,7 +9198,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9326,7 +9326,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9783,7 +9783,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -ur mysql-orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql-orig/sql/filesort.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/filesort.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -194,7 +194,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -216,12 +216,12 @@
+ goto err;
+
+ memavl= thd->variables.sortbuff_size;
+- min_sort_memory= max(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
++ min_sort_memory= MYSQL_MAX(MIN_SORT_MEMORY, param.sort_length*MERGEBUFF2);
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+
+ if (table_sort.sort_keys &&
+ table_sort.sort_keys_size != char_array_size(param.keys,
+@@ -1133,7 +1133,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1396,7 +1396,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -ur mysql-orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql-orig/sql/ha_ndbcluster.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/ha_ndbcluster.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -ur mysql-orig/sql/handler.h mysql/sql/handler.h
+--- mysql-orig/sql/handler.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/handler.h 2012-08-14 01:14:59.382197947 +0000
+@@ -1607,15 +1607,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -ur mysql-orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql-orig/sql/ha_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/ha_partition.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -6138,7 +6138,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -ur mysql-orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql-orig/sql/item_buff.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_buff.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -61,7 +61,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -71,7 +71,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -ur mysql-orig/sql/item.cc mysql/sql/item.cc
+--- mysql-orig/sql/item.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -76,7 +76,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -444,9 +444,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -752,7 +752,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5417,7 +5417,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5472,7 +5472,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7554,14 +7554,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7592,7 +7592,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7614,7 +7614,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7632,7 +7632,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -ur mysql-orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql-orig/sql/item_cmpfunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_cmpfunc.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -ur mysql-orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql-orig/sql/item_func.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -ur mysql-orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql-orig/sql/item_func.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.h 2012-08-14 01:14:59.402197785 +0000
+@@ -421,7 +421,7 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length, MY_INT64_NUM_DECIMAL_DIGITS);
++ max_length= MYSQL_MIN(args[0]->max_length, MY_INT64_NUM_DECIMAL_DIGITS);
+ unsigned_flag=1;
+ }
+ longlong val_int();
+diff -ur mysql-orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql-orig/sql/item_strfunc.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -389,7 +389,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -750,7 +750,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1251,7 +1251,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1271,7 +1271,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1962,7 +1962,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3114,11 +3114,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3582,7 +3582,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -ur mysql-orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql-orig/sql/item_strfunc.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.h 2012-08-14 01:14:59.402197785 +0000
+@@ -709,7 +709,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -ur mysql-orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql-orig/sql/item_sum.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_sum.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -ur mysql-orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql-orig/sql/item_timefunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_timefunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -310,14 +310,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -326,7 +326,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -343,15 +343,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -362,14 +362,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -377,7 +377,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -429,7 +429,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -441,7 +441,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -453,7 +453,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -598,7 +598,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1830,7 +1830,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -ur mysql-orig/sql/key.cc mysql/sql/key.cc
+--- mysql-orig/sql/key.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/key.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -128,13 +128,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -218,7 +218,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -227,7 +227,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -288,7 +288,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -354,7 +354,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -ur mysql-orig/sql/log.cc mysql/sql/log.cc
+--- mysql-orig/sql/log.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2432,7 +2432,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5238,7 +5238,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -ur mysql-orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql-orig/sql/log_event.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/log_event.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1099,7 +1099,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2695,7 +2695,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5676,7 +5676,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7426,7 +7426,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql-orig/sql/log_event_old.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log_event_old.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1434,7 +1434,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql-orig/sql/mysqld.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/mysqld.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -3241,7 +3241,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3253,15 +3253,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -4947,7 +4947,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -ur mysql-orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql-orig/sql/net_serv.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/net_serv.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -ur mysql-orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql-orig/sql/opt_range.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -ur mysql-orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql-orig/sql/opt_range.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.h 2012-08-14 01:14:59.422197616 +0000
+@@ -85,7 +85,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -123,7 +123,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -ur mysql-orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql-orig/sql/protocol.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/protocol.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -168,7 +168,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -263,7 +263,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -ur mysql-orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql-orig/sql/rpl_record.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/rpl_record.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -287,7 +287,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -ur mysql-orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql-orig/sql/rpl_rli.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_rli.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -690,7 +690,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -700,7 +700,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -ur mysql-orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql-orig/sql/rpl_utility.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -182,7 +182,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -ur mysql-orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql-orig/sql/rpl_utility.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.h 2012-08-14 01:14:59.422197616 +0000
+@@ -315,7 +315,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -ur mysql-orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql-orig/sql/set_var.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/set_var.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1849,7 +1849,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4034,7 +4034,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -ur mysql-orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql-orig/sql/slave.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/slave.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1791,7 +1791,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2408,7 +2408,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4112,7 +4112,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -ur mysql-orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql-orig/sql/spatial.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/spatial.h 2012-08-14 01:14:59.432197532 +0000
+@@ -182,8 +182,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -ur mysql-orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql-orig/sql/sp_head.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sp_head.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -2481,7 +2481,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2682,7 +2682,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql-orig/sql/sql_acl.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_acl.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -ur mysql-orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql-orig/sql/sql_analyse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_analyse.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -282,16 +282,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1045,7 +1045,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1070,7 +1070,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1187,7 +1187,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -ur mysql-orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql-orig/sql/sql_cache.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_cache.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -1006,7 +1006,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2451,7 +2451,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2506,7 +2506,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2534,7 +2534,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2622,8 +2622,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2655,7 +2655,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2664,7 +2664,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3087,7 +3087,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -ur mysql-orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql-orig/sql/sql_class.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_class.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -418,7 +418,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -433,7 +433,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2116,7 +2116,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -ur mysql-orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql-orig/sql/sql_client.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_client.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -ur mysql-orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql-orig/sql/sql_connect.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_connect.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -845,7 +845,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -ur mysql-orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql-orig/sql/sql_parse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_parse.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -5762,7 +5762,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7293,7 +7293,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -ur mysql-orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql-orig/sql/sql_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_partition.cc 2012-08-14 01:14:59.462197286 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -ur mysql-orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql-orig/sql/sql_plugin.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_plugin.cc 2012-08-14 01:14:59.472197202 +0000
+@@ -512,7 +512,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2131,7 +2131,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -ur mysql-orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql-orig/sql/sql_prepare.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_prepare.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -ur mysql-orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql-orig/sql/sql_profile.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_profile.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -254,7 +254,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -ur mysql-orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql-orig/sql/sql_repl.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_repl.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -1299,12 +1299,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1478,7 +1478,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1750,14 +1750,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1766,7 +1766,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql-orig/sql/sql_select.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_select.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -3022,7 +3022,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3958,7 +3958,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3981,7 +3981,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4144,7 +4144,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4464,7 +4464,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4631,7 +4631,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5581,7 +5581,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10488,7 +10488,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13708,7 +13708,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13720,7 +13720,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14416,7 +14416,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14538,7 +14538,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -ur mysql-orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql-orig/sql/sql_show.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_show.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1875,7 +1875,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2006,7 +2006,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3276,7 +3276,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7095,7 +7095,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -ur mysql-orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql-orig/sql/sql_string.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_string.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -700,7 +700,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -786,7 +786,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -803,7 +803,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -1004,7 +1004,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1190,7 +1190,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -ur mysql-orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql-orig/sql/sql_table.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_table.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -3276,7 +3276,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -ur mysql-orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql-orig/sql/sql_yacc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.cc 2012-08-14 01:14:59.502196954 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -ur mysql-orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql-orig/sql/sql_yacc.yy 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.yy 2012-08-14 01:14:59.512196872 +0000
+@@ -1807,7 +1807,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1817,7 +1817,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -ur mysql-orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql-orig/sql/thr_malloc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/thr_malloc.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -132,7 +132,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -ur mysql-orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql-orig/sql/tztime.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/tztime.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -169,7 +169,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -398,7 +398,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1825,7 +1825,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -ur mysql-orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql-orig/sql/unireg.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/unireg.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -498,7 +498,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -718,7 +718,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -ur mysql-orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql-orig/sql-common/client.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/client.c 2012-08-14 01:14:59.512196872 +0000
+@@ -730,7 +730,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2113,7 +2113,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -ur mysql-orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql-orig/sql-common/my_time.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/my_time.c 2012-08-14 01:14:59.512196872 +0000
+@@ -251,7 +251,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -ur mysql-orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql-orig/storage/csv/ha_tina.cc 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/csv/ha_tina.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -1195,7 +1195,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1431,7 +1431,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -ur mysql-orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql-orig/storage/example/ha_example.h 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/example/ha_example.h 2012-08-14 01:14:59.512196872 +0000
+@@ -112,14 +112,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -130,7 +130,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -141,7 +141,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -ur mysql-orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql-orig/storage/federated/ha_federated.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/federated/ha_federated.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -ur mysql-orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql-orig/storage/heap/hp_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_create.c 2012-08-14 01:14:59.512196872 +0000
+@@ -230,7 +230,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -ur mysql-orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql-orig/storage/heap/hp_test2.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_test2.c 2012-08-14 01:14:59.512196872 +0000
+@@ -138,7 +138,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -219,7 +219,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -ur mysql-orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql-orig/storage/innobase/include/ut0byte.h 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/innobase/include/ut0byte.h 2012-08-14 01:14:59.522196790 +0000
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -ur mysql-orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql-orig/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:14:59.522196790 +0000
+@@ -4898,7 +4898,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4908,7 +4908,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -ur mysql-orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql-orig/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:14:59.552196542 +0000
+@@ -1115,7 +1115,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -ur mysql-orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql-orig/storage/myisam/ft_boolean_search.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/ft_boolean_search.c 2012-08-14 01:14:59.552196542 +0000
+@@ -48,9 +48,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -ur mysql-orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql-orig/storage/myisam/ha_myisam.cc 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2012-08-14 01:14:59.552196542 +0000
+@@ -1546,7 +1546,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -ur mysql-orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql-orig/storage/myisam/mi_cache.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_cache.c 2012-08-14 01:14:59.572196376 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -ur mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql-orig/storage/myisam/mi_check.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_check.c 2012-08-14 01:14:59.572196376 +0000
+@@ -2175,7 +2175,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2331,7 +2331,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2420,7 +2420,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2784,7 +2784,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3982,7 +3982,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+diff -ur mysql-orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql-orig/storage/myisam/mi_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_create.c 2012-08-14 01:14:59.572196376 +0000
+@@ -439,8 +439,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -529,7 +529,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -567,7 +567,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql-orig/storage/myisam/mi_dynrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2012-08-14 01:14:59.572196376 +0000
+@@ -882,7 +882,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -ur mysql-orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql-orig/storage/myisam/mi_extra.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_extra.c 2012-08-14 01:14:59.572196376 +0000
+@@ -101,7 +101,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -ur mysql-orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql-orig/storage/myisam/mi_open.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_open.c 2012-08-14 01:14:59.582196294 +0000
+@@ -330,7 +330,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -503,7 +503,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -716,10 +716,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -ur mysql-orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql-orig/storage/myisam/mi_packrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_packrec.c 2012-08-14 01:14:59.582196294 +0000
+@@ -686,7 +686,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1401,7 +1401,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -ur mysql-orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql-orig/storage/myisam/mi_test1.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test1.c 2012-08-14 01:14:59.582196294 +0000
+@@ -438,7 +438,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -ur mysql-orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql-orig/storage/myisam/mi_test2.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test2.c 2012-08-14 01:14:59.582196294 +0000
+@@ -603,7 +603,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -ur mysql-orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql-orig/storage/myisam/myisamlog.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/myisamlog.c 2012-08-14 01:14:59.582196294 +0000
+@@ -92,7 +92,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -ur mysql-orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql-orig/storage/myisam/myisampack.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/myisampack.c 2012-08-14 01:14:59.582196294 +0000
+@@ -1240,7 +1240,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3002,7 +3002,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql-orig/storage/myisam/rt_mbr.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/rt_mbr.c 2012-08-14 01:14:59.582196294 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -ur mysql-orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql-orig/storage/myisam/sort.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/sort.c 2012-08-14 01:14:59.582196294 +0000
+@@ -131,7 +131,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -348,7 +348,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -822,7 +822,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -843,7 +843,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -ur mysql-orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql-orig/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:14:59.582196294 +0000
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -ur mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:12:29.673435501 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -ur mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:12:29.683435419 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -ur mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -ur mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -ur mysql-orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql-orig/storage/ndb/test/src/getarg.c 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2012-08-14 01:14:59.582196294 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -ur mysql-orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql-orig/strings/ctype-big5.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-big5.c 2012-08-14 01:14:59.592196210 +0000
+@@ -254,7 +254,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -267,7 +267,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql-orig/strings/ctype-bin.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-bin.c 2012-08-14 01:14:59.592196210 +0000
+@@ -82,7 +82,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -133,7 +133,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -177,7 +177,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -406,7 +406,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -419,7 +419,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql-orig/strings/ctype-gbk.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-gbk.c 2012-08-14 01:14:59.592196210 +0000
+@@ -2617,7 +2617,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2628,7 +2628,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql-orig/strings/ctype-mb.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-mb.c 2012-08-14 01:14:59.592196210 +0000
+@@ -369,7 +369,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -413,7 +413,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -452,7 +452,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql-orig/strings/ctype-simple.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-simple.c 2012-08-14 01:14:59.592196210 +0000
+@@ -161,7 +161,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -875,7 +875,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -929,7 +929,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1160,7 +1160,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -ur mysql-orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql-orig/strings/ctype-tis620.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-tis620.c 2012-08-14 01:14:59.592196210 +0000
+@@ -583,7 +583,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -640,7 +640,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -ur mysql-orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql-orig/strings/ctype-uca.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-uca.c 2012-08-14 01:14:59.592196210 +0000
+@@ -7569,7 +7569,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -ur mysql-orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql-orig/strings/ctype-ucs2.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-ucs2.c 2012-08-14 01:14:59.602196128 +0000
+@@ -280,7 +280,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1332,7 +1332,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1426,7 +1426,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1473,7 +1473,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql-orig/strings/ctype-utf8.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-utf8.c 2012-08-14 01:14:59.602196128 +0000
+@@ -2114,7 +2114,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -ur mysql-orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql-orig/strings/decimal.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/decimal.c 2012-08-14 01:14:59.602196128 +0000
+@@ -405,7 +405,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -428,7 +428,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1531,8 +1531,8 @@
+
+ if (to != from)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg0+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg0+MYSQL_MAX(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
+@@ -1543,7 +1543,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1645,7 +1645,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1664,7 +1664,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1713,11 +1713,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1732,7 +1732,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1757,7 +1757,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1768,7 +1768,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1786,14 +1786,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1814,7 +1814,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1889,7 +1889,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1900,7 +1900,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1924,7 +1924,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2187,11 +2187,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2315,7 +2315,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2353,7 +2353,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -ur mysql-orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql-orig/strings/my_vsnprintf.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/my_vsnprintf.c 2012-08-14 01:14:59.602196128 +0000
+@@ -143,7 +143,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -ur mysql-orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql-orig/strings/str2int.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/str2int.c 2012-08-14 01:14:59.602196128 +0000
+@@ -84,7 +84,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -ur mysql-orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql-orig/vio/viosocket.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/vio/viosocket.c 2012-08-14 01:14:59.602196128 +0000
+@@ -79,7 +79,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:34 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:34 UTC (permalink / raw
To: gentoo-commits
commit: 4c4de3089d89d2d44edbcfedcafffab325dc1172
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:33:31 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:33:31 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=4c4de308
Clean up .orig and .rej blocks, add tracking.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
07110_all_mysql_gcc-4.2_5.1.57.patch | 66446 +--------------------------------
1 file changed, 6 insertions(+), 66440 deletions(-)
diff --git a/07110_all_mysql_gcc-4.2_5.1.57.patch b/07110_all_mysql_gcc-4.2_5.1.57.patch
index 7265c94..24bb194 100644
--- a/07110_all_mysql_gcc-4.2_5.1.57.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.57.patch
@@ -1,3 +1,9 @@
+
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
diff -urN mysql-old/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
--- mysql-old/client/mysqlbinlog.cc 2011-05-10 17:45:45.693349043 +0000
+++ mysql/client/mysqlbinlog.cc 2011-05-10 17:56:01.266682376 +0000
@@ -1231,6170 +1237,6 @@ diff -urN mysql-old/sql/item_func.cc mysql/sql/item_func.cc
}
initialized=1;
if (error)
-diff -urN mysql-old/sql/item_func.cc.orig mysql/sql/item_func.cc.orig
---- mysql-old/sql/item_func.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/item_func.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,6160 @@
-+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+
-+/**
-+ @file
-+
-+ @brief
-+ This file defines all numerical functions
-+*/
-+
-+#ifdef USE_PRAGMA_IMPLEMENTATION
-+#pragma implementation // gcc: Class implementation
-+#endif
-+
-+#include "mysql_priv.h"
-+#include "slave.h" // for wait_for_master_pos
-+#include "rpl_mi.h"
-+#include <m_ctype.h>
-+#include <hash.h>
-+#include <time.h>
-+#include <ft_global.h>
-+#include <my_bit.h>
-+
-+#include "sp_head.h"
-+#include "sp_rcontext.h"
-+#include "sp.h"
-+
-+#ifdef NO_EMBEDDED_ACCESS_CHECKS
-+#define sp_restore_security_context(A,B) while (0) {}
-+#endif
-+
-+bool check_reserved_words(LEX_STRING *name)
-+{
-+ if (!my_strcasecmp(system_charset_info, name->str, "GLOBAL") ||
-+ !my_strcasecmp(system_charset_info, name->str, "LOCAL") ||
-+ !my_strcasecmp(system_charset_info, name->str, "SESSION"))
-+ return TRUE;
-+ return FALSE;
-+}
-+
-+
-+/**
-+ @return
-+ TRUE if item is a constant
-+*/
-+
-+bool
-+eval_const_cond(COND *cond)
-+{
-+ return ((Item_func*) cond)->val_int() ? TRUE : FALSE;
-+}
-+
-+
-+void Item_func::set_arguments(List<Item> &list)
-+{
-+ allowed_arg_cols= 1;
-+ arg_count=list.elements;
-+ args= tmp_arg; // If 2 arguments
-+ if (arg_count <= 2 || (args=(Item**) sql_alloc(sizeof(Item*)*arg_count)))
-+ {
-+ List_iterator_fast<Item> li(list);
-+ Item *item;
-+ Item **save_args= args;
-+
-+ while ((item=li++))
-+ {
-+ *(save_args++)= item;
-+ with_sum_func|=item->with_sum_func;
-+ }
-+ }
-+ list.empty(); // Fields are used
-+}
-+
-+Item_func::Item_func(List<Item> &list)
-+ :allowed_arg_cols(1)
-+{
-+ set_arguments(list);
-+}
-+
-+Item_func::Item_func(THD *thd, Item_func *item)
-+ :Item_result_field(thd, item),
-+ allowed_arg_cols(item->allowed_arg_cols),
-+ arg_count(item->arg_count),
-+ used_tables_cache(item->used_tables_cache),
-+ not_null_tables_cache(item->not_null_tables_cache),
-+ const_item_cache(item->const_item_cache)
-+{
-+ if (arg_count)
-+ {
-+ if (arg_count <=2)
-+ args= tmp_arg;
-+ else
-+ {
-+ if (!(args=(Item**) thd->alloc(sizeof(Item*)*arg_count)))
-+ return;
-+ }
-+ memcpy((char*) args, (char*) item->args, sizeof(Item*)*arg_count);
-+ }
-+}
-+
-+
-+/*
-+ Resolve references to table column for a function and its argument
-+
-+ SYNOPSIS:
-+ fix_fields()
-+ thd Thread object
-+ ref Pointer to where this object is used. This reference
-+ is used if we want to replace this object with another
-+ one (for example in the summary functions).
-+
-+ DESCRIPTION
-+ Call fix_fields() for all arguments to the function. The main intention
-+ is to allow all Item_field() objects to setup pointers to the table fields.
-+
-+ Sets as a side effect the following class variables:
-+ maybe_null Set if any argument may return NULL
-+ with_sum_func Set if any of the arguments contains a sum function
-+ used_tables_cache Set to union of the tables used by arguments
-+
-+ str_value.charset If this is a string function, set this to the
-+ character set for the first argument.
-+ If any argument is binary, this is set to binary
-+
-+ If for any item any of the defaults are wrong, then this can
-+ be fixed in the fix_length_and_dec() function that is called
-+ after this one or by writing a specialized fix_fields() for the
-+ item.
-+
-+ RETURN VALUES
-+ FALSE ok
-+ TRUE Got error. Stored with my_error().
-+*/
-+
-+bool
-+Item_func::fix_fields(THD *thd, Item **ref)
-+{
-+ DBUG_ASSERT(fixed == 0);
-+ Item **arg,**arg_end;
-+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
-+ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
-+#endif
-+
-+ used_tables_cache= not_null_tables_cache= 0;
-+ const_item_cache=1;
-+
-+ /*
-+ Use stack limit of STACK_MIN_SIZE * 2 since
-+ on some platforms a recursive call to fix_fields
-+ requires more than STACK_MIN_SIZE bytes (e.g. for
-+ MIPS, it takes about 22kB to make one recursive
-+ call to Item_func::fix_fields())
-+ */
-+ if (check_stack_overrun(thd, STACK_MIN_SIZE * 2, buff))
-+ return TRUE; // Fatal error if flag is set!
-+ if (arg_count)
-+ { // Print purify happy
-+ for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
-+ {
-+ Item *item;
-+ /*
-+ We can't yet set item to *arg as fix_fields may change *arg
-+ We shouldn't call fix_fields() twice, so check 'fixed' field first
-+ */
-+ if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
-+ return TRUE; /* purecov: inspected */
-+ item= *arg;
-+
-+ if (allowed_arg_cols)
-+ {
-+ if (item->check_cols(allowed_arg_cols))
-+ return 1;
-+ }
-+ else
-+ {
-+ /* we have to fetch allowed_arg_cols from first argument */
-+ DBUG_ASSERT(arg == args); // it is first argument
-+ allowed_arg_cols= item->cols();
-+ DBUG_ASSERT(allowed_arg_cols); // Can't be 0 any more
-+ }
-+
-+ if (item->maybe_null)
-+ maybe_null=1;
-+
-+ with_sum_func= with_sum_func || item->with_sum_func;
-+ used_tables_cache|= item->used_tables();
-+ not_null_tables_cache|= item->not_null_tables();
-+ const_item_cache&= item->const_item();
-+ with_subselect|= item->with_subselect;
-+ }
-+ }
-+ fix_length_and_dec();
-+ if (thd->is_error()) // An error inside fix_length_and_dec occured
-+ return TRUE;
-+ fixed= 1;
-+ return FALSE;
-+}
-+
-+
-+bool Item_func::walk(Item_processor processor, bool walk_subquery,
-+ uchar *argument)
-+{
-+ if (arg_count)
-+ {
-+ Item **arg,**arg_end;
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
-+ {
-+ if ((*arg)->walk(processor, walk_subquery, argument))
-+ return 1;
-+ }
-+ }
-+ return (this->*processor)(argument);
-+}
-+
-+void Item_func::traverse_cond(Cond_traverser traverser,
-+ void *argument, traverse_order order)
-+{
-+ if (arg_count)
-+ {
-+ Item **arg,**arg_end;
-+
-+ switch (order) {
-+ case(PREFIX):
-+ (*traverser)(this, argument);
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
-+ {
-+ (*arg)->traverse_cond(traverser, argument, order);
-+ }
-+ break;
-+ case (POSTFIX):
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
-+ {
-+ (*arg)->traverse_cond(traverser, argument, order);
-+ }
-+ (*traverser)(this, argument);
-+ }
-+ }
-+ else
-+ (*traverser)(this, argument);
-+}
-+
-+
-+/**
-+ Transform an Item_func object with a transformer callback function.
-+
-+ The function recursively applies the transform method to each
-+ argument of the Item_func node.
-+ If the call of the method for an argument item returns a new item
-+ the old item is substituted for a new one.
-+ After this the transformer is applied to the root node
-+ of the Item_func object.
-+ @param transformer the transformer callback function to be applied to
-+ the nodes of the tree of the object
-+ @param argument parameter to be passed to the transformer
-+
-+ @return
-+ Item returned as the result of transformation of the root node
-+*/
-+
-+Item *Item_func::transform(Item_transformer transformer, uchar *argument)
-+{
-+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
-+
-+ if (arg_count)
-+ {
-+ Item **arg,**arg_end;
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
-+ {
-+ Item *new_item= (*arg)->transform(transformer, argument);
-+ if (!new_item)
-+ return 0;
-+
-+ /*
-+ THD::change_item_tree() should be called only if the tree was
-+ really transformed, i.e. when a new item has been created.
-+ Otherwise we'll be allocating a lot of unnecessary memory for
-+ change records at each execution.
-+ */
-+ if (*arg != new_item)
-+ current_thd->change_item_tree(arg, new_item);
-+ }
-+ }
-+ return (this->*transformer)(argument);
-+}
-+
-+
-+/**
-+ Compile Item_func object with a processor and a transformer
-+ callback functions.
-+
-+ First the function applies the analyzer to the root node of
-+ the Item_func object. Then if the analizer succeeeds (returns TRUE)
-+ the function recursively applies the compile method to each argument
-+ of the Item_func node.
-+ If the call of the method for an argument item returns a new item
-+ the old item is substituted for a new one.
-+ After this the transformer is applied to the root node
-+ of the Item_func object.
-+
-+ @param analyzer the analyzer callback function to be applied to the
-+ nodes of the tree of the object
-+ @param[in,out] arg_p parameter to be passed to the processor
-+ @param transformer the transformer callback function to be applied to the
-+ nodes of the tree of the object
-+ @param arg_t parameter to be passed to the transformer
-+
-+ @return
-+ Item returned as the result of transformation of the root node
-+*/
-+
-+Item *Item_func::compile(Item_analyzer analyzer, uchar **arg_p,
-+ Item_transformer transformer, uchar *arg_t)
-+{
-+ if (!(this->*analyzer)(arg_p))
-+ return 0;
-+ if (arg_count)
-+ {
-+ Item **arg,**arg_end;
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end; arg++)
-+ {
-+ /*
-+ The same parameter value of arg_p must be passed
-+ to analyze any argument of the condition formula.
-+ */
-+ uchar *arg_v= *arg_p;
-+ Item *new_item= (*arg)->compile(analyzer, &arg_v, transformer, arg_t);
-+ if (new_item && *arg != new_item)
-+ current_thd->change_item_tree(arg, new_item);
-+ }
-+ }
-+ return (this->*transformer)(arg_t);
-+}
-+
-+/**
-+ See comments in Item_cmp_func::split_sum_func()
-+*/
-+
-+void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
-+ List<Item> &fields)
-+{
-+ Item **arg, **arg_end;
-+ for (arg= args, arg_end= args+arg_count; arg != arg_end ; arg++)
-+ (*arg)->split_sum_func2(thd, ref_pointer_array, fields, arg, TRUE);
-+}
-+
-+
-+void Item_func::update_used_tables()
-+{
-+ used_tables_cache=0;
-+ const_item_cache=1;
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ args[i]->update_used_tables();
-+ used_tables_cache|=args[i]->used_tables();
-+ const_item_cache&=args[i]->const_item();
-+ }
-+}
-+
-+
-+table_map Item_func::used_tables() const
-+{
-+ return used_tables_cache;
-+}
-+
-+
-+table_map Item_func::not_null_tables() const
-+{
-+ return not_null_tables_cache;
-+}
-+
-+
-+void Item_func::print(String *str, enum_query_type query_type)
-+{
-+ str->append(func_name());
-+ str->append('(');
-+ print_args(str, 0, query_type);
-+ str->append(')');
-+}
-+
-+
-+void Item_func::print_args(String *str, uint from, enum_query_type query_type)
-+{
-+ for (uint i=from ; i < arg_count ; i++)
-+ {
-+ if (i != from)
-+ str->append(',');
-+ args[i]->print(str, query_type);
-+ }
-+}
-+
-+
-+void Item_func::print_op(String *str, enum_query_type query_type)
-+{
-+ str->append('(');
-+ for (uint i=0 ; i < arg_count-1 ; i++)
-+ {
-+ args[i]->print(str, query_type);
-+ str->append(' ');
-+ str->append(func_name());
-+ str->append(' ');
-+ }
-+ args[arg_count-1]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+
-+bool Item_func::eq(const Item *item, bool binary_cmp) const
-+{
-+ /* Assume we don't have rtti */
-+ if (this == item)
-+ return 1;
-+ if (item->type() != FUNC_ITEM)
-+ return 0;
-+ Item_func *item_func=(Item_func*) item;
-+ Item_func::Functype func_type;
-+ if ((func_type= functype()) != item_func->functype() ||
-+ arg_count != item_func->arg_count ||
-+ (func_type != Item_func::FUNC_SP &&
-+ func_name() != item_func->func_name()) ||
-+ (func_type == Item_func::FUNC_SP &&
-+ my_strcasecmp(system_charset_info, func_name(), item_func->func_name())))
-+ return 0;
-+ for (uint i=0; i < arg_count ; i++)
-+ if (!args[i]->eq(item_func->args[i], binary_cmp))
-+ return 0;
-+ return 1;
-+}
-+
-+
-+Field *Item_func::tmp_table_field(TABLE *table)
-+{
-+ Field *field= NULL;
-+
-+ switch (result_type()) {
-+ case INT_RESULT:
-+ if (max_length > MY_INT32_NUM_DECIMAL_DIGITS)
-+ field= new Field_longlong(max_length, maybe_null, name, unsigned_flag);
-+ else
-+ field= new Field_long(max_length, maybe_null, name, unsigned_flag);
-+ break;
-+ case REAL_RESULT:
-+ field= new Field_double(max_length, maybe_null, name, decimals);
-+ break;
-+ case STRING_RESULT:
-+ return make_string_field(table);
-+ break;
-+ case DECIMAL_RESULT:
-+ field= Field_new_decimal::create_from_item(this);
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ field= 0;
-+ break;
-+ }
-+ if (field)
-+ field->init(table);
-+ return field;
-+}
-+
-+
-+bool Item_func::is_expensive_processor(uchar *arg)
-+{
-+ return is_expensive();
-+}
-+
-+
-+my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
-+{
-+ DBUG_ASSERT(fixed);
-+ longlong nr= val_int();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ int2my_decimal(E_DEC_FATAL_ERROR, nr, unsigned_flag, decimal_value);
-+ return decimal_value;
-+}
-+
-+
-+String *Item_real_func::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double nr= val_real();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ str->set_real(nr,decimals, &my_charset_bin);
-+ return str;
-+}
-+
-+
-+my_decimal *Item_real_func::val_decimal(my_decimal *decimal_value)
-+{
-+ DBUG_ASSERT(fixed);
-+ double nr= val_real();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ double2my_decimal(E_DEC_FATAL_ERROR, nr, decimal_value);
-+ return decimal_value;
-+}
-+
-+
-+void Item_func::fix_num_length_and_dec()
-+{
-+ uint fl_length= 0;
-+ decimals=0;
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ set_if_bigger(decimals,args[i]->decimals);
-+ set_if_bigger(fl_length, args[i]->max_length);
-+ }
-+ max_length=float_length(decimals);
-+ if (fl_length > max_length)
-+ {
-+ decimals= NOT_FIXED_DEC;
-+ max_length= float_length(NOT_FIXED_DEC);
-+ }
-+}
-+
-+
-+void Item_func_numhybrid::fix_num_length_and_dec()
-+{}
-+
-+
-+/**
-+ Set max_length/decimals of function if function is fixed point and
-+ result length/precision depends on argument ones.
-+*/
-+
-+void Item_func::count_decimal_length()
-+{
-+ int max_int_part= 0;
-+ decimals= 0;
-+ unsigned_flag= 1;
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ set_if_bigger(decimals, args[i]->decimals);
-+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
-+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
-+ }
-+ int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
-+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
-+ unsigned_flag);
-+}
-+
-+
-+/**
-+ Set max_length of if it is maximum length of its arguments.
-+*/
-+
-+void Item_func::count_only_length()
-+{
-+ max_length= 0;
-+ unsigned_flag= 0;
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ set_if_bigger(max_length, args[i]->max_length);
-+ set_if_bigger(unsigned_flag, args[i]->unsigned_flag);
-+ }
-+}
-+
-+
-+/**
-+ Set max_length/decimals of function if function is floating point and
-+ result length/precision depends on argument ones.
-+*/
-+
-+void Item_func::count_real_length()
-+{
-+ uint32 length= 0;
-+ decimals= 0;
-+ max_length= 0;
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ if (decimals != NOT_FIXED_DEC)
-+ {
-+ set_if_bigger(decimals, args[i]->decimals);
-+ set_if_bigger(length, (args[i]->max_length - args[i]->decimals));
-+ }
-+ set_if_bigger(max_length, args[i]->max_length);
-+ }
-+ if (decimals != NOT_FIXED_DEC)
-+ {
-+ max_length= length;
-+ length+= decimals;
-+ if (length < max_length) // If previous operation gave overflow
-+ max_length= UINT_MAX32;
-+ else
-+ max_length= length;
-+ }
-+}
-+
-+
-+
-+void Item_func::signal_divide_by_null()
-+{
-+ THD *thd= current_thd;
-+ if (thd->variables.sql_mode & MODE_ERROR_FOR_DIVISION_BY_ZERO)
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, ER_DIVISION_BY_ZERO,
-+ ER(ER_DIVISION_BY_ZERO));
-+ null_value= 1;
-+}
-+
-+
-+Item *Item_func::get_tmp_table_item(THD *thd)
-+{
-+ if (!with_sum_func && !const_item())
-+ return new Item_field(result_field);
-+ return copy_or_same(thd);
-+}
-+
-+double Item_int_func::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+
-+ return unsigned_flag ? (double) ((ulonglong) val_int()) : (double) val_int();
-+}
-+
-+
-+String *Item_int_func::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong nr=val_int();
-+ if (null_value)
-+ return 0;
-+ str->set_int(nr, unsigned_flag, &my_charset_bin);
-+ return str;
-+}
-+
-+
-+void Item_func_connection_id::fix_length_and_dec()
-+{
-+ Item_int_func::fix_length_and_dec();
-+ max_length= 10;
-+}
-+
-+
-+bool Item_func_connection_id::fix_fields(THD *thd, Item **ref)
-+{
-+ if (Item_int_func::fix_fields(thd, ref))
-+ return TRUE;
-+ thd->thread_specific_used= TRUE;
-+ value= thd->variables.pseudo_thread_id;
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Check arguments here to determine result's type for a numeric
-+ function of two arguments.
-+*/
-+
-+void Item_num_op::find_num_type(void)
-+{
-+ DBUG_ENTER("Item_num_op::find_num_type");
-+ DBUG_PRINT("info", ("name %s", func_name()));
-+ DBUG_ASSERT(arg_count == 2);
-+ Item_result r0= args[0]->result_type();
-+ Item_result r1= args[1]->result_type();
-+
-+ if (r0 == REAL_RESULT || r1 == REAL_RESULT ||
-+ r0 == STRING_RESULT || r1 ==STRING_RESULT)
-+ {
-+ count_real_length();
-+ max_length= float_length(decimals);
-+ hybrid_type= REAL_RESULT;
-+ }
-+ else if (r0 == DECIMAL_RESULT || r1 == DECIMAL_RESULT)
-+ {
-+ hybrid_type= DECIMAL_RESULT;
-+ result_precision();
-+ }
-+ else
-+ {
-+ DBUG_ASSERT(r0 == INT_RESULT && r1 == INT_RESULT);
-+ decimals= 0;
-+ hybrid_type=INT_RESULT;
-+ result_precision();
-+ }
-+ DBUG_PRINT("info", ("Type: %s",
-+ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
-+ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
-+ hybrid_type == INT_RESULT ? "INT_RESULT" :
-+ "--ILLEGAL!!!--")));
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ 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)
-+*/
-+
-+void Item_func_num1::find_num_type()
-+{
-+ DBUG_ENTER("Item_func_num1::find_num_type");
-+ DBUG_PRINT("info", ("name %s", func_name()));
-+ switch (hybrid_type= args[0]->result_type()) {
-+ case INT_RESULT:
-+ unsigned_flag= args[0]->unsigned_flag;
-+ break;
-+ case STRING_RESULT:
-+ case REAL_RESULT:
-+ hybrid_type= REAL_RESULT;
-+ max_length= float_length(decimals);
-+ break;
-+ case DECIMAL_RESULT:
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ DBUG_PRINT("info", ("Type: %s",
-+ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
-+ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
-+ hybrid_type == INT_RESULT ? "INT_RESULT" :
-+ "--ILLEGAL!!!--")));
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+void Item_func_num1::fix_num_length_and_dec()
-+{
-+ decimals= args[0]->decimals;
-+ max_length= args[0]->max_length;
-+}
-+
-+
-+void Item_func_numhybrid::fix_length_and_dec()
-+{
-+ fix_num_length_and_dec();
-+ find_num_type();
-+}
-+
-+
-+String *Item_func_numhybrid::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ switch (hybrid_type) {
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal decimal_value, *val;
-+ if (!(val= decimal_op(&decimal_value)))
-+ return 0; // null is set
-+ my_decimal_round(E_DEC_FATAL_ERROR, val, decimals, FALSE, val);
-+ my_decimal2string(E_DEC_FATAL_ERROR, val, 0, 0, 0, str);
-+ break;
-+ }
-+ case INT_RESULT:
-+ {
-+ longlong nr= int_op();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ str->set_int(nr, unsigned_flag, &my_charset_bin);
-+ break;
-+ }
-+ case REAL_RESULT:
-+ {
-+ double nr= real_op();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ str->set_real(nr,decimals,&my_charset_bin);
-+ break;
-+ }
-+ case STRING_RESULT:
-+ return str_op(&str_value);
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ return str;
-+}
-+
-+
-+double Item_func_numhybrid::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ switch (hybrid_type) {
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal decimal_value, *val;
-+ double result;
-+ if (!(val= decimal_op(&decimal_value)))
-+ return 0.0; // null is set
-+ my_decimal2double(E_DEC_FATAL_ERROR, val, &result);
-+ return result;
-+ }
-+ case INT_RESULT:
-+ {
-+ longlong result= int_op();
-+ return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
-+ }
-+ 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);
-+ }
-+ return 0.0;
-+}
-+
-+
-+longlong Item_func_numhybrid::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ switch (hybrid_type) {
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal decimal_value, *val;
-+ if (!(val= decimal_op(&decimal_value)))
-+ return 0; // null is set
-+ longlong result;
-+ my_decimal2int(E_DEC_FATAL_ERROR, val, unsigned_flag, &result);
-+ return result;
-+ }
-+ case INT_RESULT:
-+ return int_op();
-+ case REAL_RESULT:
-+ return (longlong) rint(real_op());
-+ case STRING_RESULT:
-+ {
-+ int err_not_used;
-+ String *res;
-+ if (!(res= str_op(&str_value)))
-+ return 0;
-+
-+ char *end= (char*) res->ptr() + res->length();
-+ CHARSET_INFO *cs= res->charset();
-+ return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
-+ }
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ return 0;
-+}
-+
-+
-+my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
-+{
-+ my_decimal *val= decimal_value;
-+ DBUG_ASSERT(fixed == 1);
-+ switch (hybrid_type) {
-+ case DECIMAL_RESULT:
-+ val= decimal_op(decimal_value);
-+ break;
-+ case INT_RESULT:
-+ {
-+ longlong result= int_op();
-+ int2my_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
-+ break;
-+ }
-+ case REAL_RESULT:
-+ {
-+ double result= (double)real_op();
-+ double2my_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
-+ break;
-+ }
-+ case STRING_RESULT:
-+ {
-+ String *res;
-+ if (!(res= str_op(&str_value)))
-+ return NULL;
-+
-+ str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
-+ res->length(), res->charset(), decimal_value);
-+ break;
-+ }
-+ case ROW_RESULT:
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ return val;
-+}
-+
-+
-+void Item_func_signed::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("cast("));
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" as signed)"));
-+
-+}
-+
-+
-+longlong Item_func_signed::val_int_from_str(int *error)
-+{
-+ char buff[MAX_FIELD_WIDTH], *end, *start;
-+ uint32 length;
-+ String tmp(buff,sizeof(buff), &my_charset_bin), *res;
-+ longlong value;
-+
-+ /*
-+ For a string result, we must first get the string and then convert it
-+ to a longlong
-+ */
-+
-+ if (!(res= args[0]->val_str(&tmp)))
-+ {
-+ null_value= 1;
-+ *error= 0;
-+ return 0;
-+ }
-+ null_value= 0;
-+ start= (char *)res->ptr();
-+ length= res->length();
-+
-+ end= start + length;
-+ value= my_strtoll10(start, &end, error);
-+ if (*error > 0 || end != start+ length)
-+ {
-+ char err_buff[128];
-+ String err_tmp(err_buff,(uint32) sizeof(err_buff), system_charset_info);
-+ err_tmp.copy(start, length, system_charset_info);
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_TRUNCATED_WRONG_VALUE,
-+ ER(ER_TRUNCATED_WRONG_VALUE), "INTEGER",
-+ err_tmp.c_ptr());
-+ }
-+ return value;
-+}
-+
-+
-+longlong Item_func_signed::val_int()
-+{
-+ longlong value;
-+ int error;
-+
-+ if (args[0]->cast_to_int_type() != STRING_RESULT ||
-+ args[0]->result_as_longlong())
-+ {
-+ value= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ return value;
-+ }
-+
-+ value= val_int_from_str(&error);
-+ if (value < 0 && error == 0)
-+ {
-+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
-+ "Cast to signed converted positive out-of-range integer to "
-+ "it's negative complement");
-+ }
-+ return value;
-+}
-+
-+
-+void Item_func_unsigned::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("cast("));
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" as unsigned)"));
-+
-+}
-+
-+
-+longlong Item_func_unsigned::val_int()
-+{
-+ longlong value;
-+ int error;
-+
-+ if (args[0]->cast_to_int_type() == DECIMAL_RESULT)
-+ {
-+ my_decimal tmp, *dec= args[0]->val_decimal(&tmp);
-+ if (!(null_value= args[0]->null_value))
-+ my_decimal2int(E_DEC_FATAL_ERROR, dec, 1, &value);
-+ else
-+ value= 0;
-+ return value;
-+ }
-+ else if (args[0]->cast_to_int_type() != STRING_RESULT ||
-+ args[0]->result_as_longlong())
-+ {
-+ value= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ return value;
-+ }
-+
-+ value= val_int_from_str(&error);
-+ if (error < 0)
-+ push_warning(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
-+ "Cast to unsigned converted negative integer to it's "
-+ "positive complement");
-+ return value;
-+}
-+
-+
-+String *Item_decimal_typecast::val_str(String *str)
-+{
-+ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
-+ if (null_value)
-+ return NULL;
-+ my_decimal2string(E_DEC_FATAL_ERROR, tmp, 0, 0, 0, str);
-+ return str;
-+}
-+
-+
-+double Item_decimal_typecast::val_real()
-+{
-+ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
-+ double res;
-+ if (null_value)
-+ return 0.0;
-+ my_decimal2double(E_DEC_FATAL_ERROR, tmp, &res);
-+ return res;
-+}
-+
-+
-+longlong Item_decimal_typecast::val_int()
-+{
-+ my_decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
-+ longlong res;
-+ if (null_value)
-+ return 0;
-+ my_decimal2int(E_DEC_FATAL_ERROR, tmp, unsigned_flag, &res);
-+ return res;
-+}
-+
-+
-+my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
-+{
-+ my_decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
-+ bool sign;
-+ uint precision;
-+
-+ if ((null_value= args[0]->null_value))
-+ return NULL;
-+ my_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, FALSE, dec);
-+ sign= dec->sign();
-+ if (unsigned_flag)
-+ {
-+ if (sign)
-+ {
-+ my_decimal_set_zero(dec);
-+ goto err;
-+ }
-+ }
-+ precision= my_decimal_length_to_precision(max_length,
-+ decimals, unsigned_flag);
-+ if (precision - decimals < (uint) my_decimal_intg(dec))
-+ {
-+ max_my_decimal(dec, precision, decimals);
-+ dec->sign(sign);
-+ goto err;
-+ }
-+ return dec;
-+
-+err:
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_WARN_DATA_OUT_OF_RANGE,
-+ ER(ER_WARN_DATA_OUT_OF_RANGE),
-+ name, 1);
-+ return dec;
-+}
-+
-+
-+void Item_decimal_typecast::print(String *str, enum_query_type query_type)
-+{
-+ char len_buf[20*3 + 1];
-+ char *end;
-+
-+ uint precision= my_decimal_length_to_precision(max_length, decimals,
-+ unsigned_flag);
-+ str->append(STRING_WITH_LEN("cast("));
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" as decimal("));
-+
-+ end=int10_to_str(precision, len_buf,10);
-+ str->append(len_buf, (uint32) (end - len_buf));
-+
-+ str->append(',');
-+
-+ end=int10_to_str(decimals, len_buf,10);
-+ str->append(len_buf, (uint32) (end - len_buf));
-+
-+ str->append(')');
-+ str->append(')');
-+}
-+
-+
-+double Item_func_plus::real_op()
-+{
-+ double value= args[0]->val_real() + args[1]->val_real();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0.0;
-+ return fix_result(value);
-+}
-+
-+
-+longlong Item_func_plus::int_op()
-+{
-+ longlong value=args[0]->val_int()+args[1]->val_int();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0;
-+ return value;
-+}
-+
-+
-+/**
-+ Calculate plus of two decimals.
-+
-+ @param decimal_value Buffer that can be used to store result
-+
-+ @retval
-+ 0 Value was NULL; In this case null_value is set
-+ @retval
-+ \# Value of operation as a decimal
-+*/
-+
-+my_decimal *Item_func_plus::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal value1, *val1;
-+ my_decimal value2, *val2;
-+ val1= args[0]->val_decimal(&value1);
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ val2= args[1]->val_decimal(&value2);
-+ if (!(null_value= (args[1]->null_value ||
-+ (my_decimal_add(E_DEC_FATAL_ERROR, decimal_value, val1,
-+ val2) > 3))))
-+ return decimal_value;
-+ return 0;
-+}
-+
-+/**
-+ Set precision of results for additive operations (+ and -)
-+*/
-+void Item_func_additive_op::result_precision()
-+{
-+ decimals= max(args[0]->decimals, args[1]->decimals);
-+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
-+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
-+ int precision= max(arg1_int, arg2_int) + 1 + decimals;
-+
-+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
-+ if (result_type() == INT_RESULT)
-+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
-+ else
-+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
-+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
-+ unsigned_flag);
-+}
-+
-+
-+/**
-+ The following function is here to allow the user to force
-+ subtraction of UNSIGNED BIGINT to return negative values.
-+*/
-+
-+void Item_func_minus::fix_length_and_dec()
-+{
-+ Item_num_op::fix_length_and_dec();
-+ if (unsigned_flag &&
-+ (current_thd->variables.sql_mode & MODE_NO_UNSIGNED_SUBTRACTION))
-+ unsigned_flag=0;
-+}
-+
-+
-+double Item_func_minus::real_op()
-+{
-+ double value= args[0]->val_real() - args[1]->val_real();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0.0;
-+ return fix_result(value);
-+}
-+
-+
-+longlong Item_func_minus::int_op()
-+{
-+ longlong value=args[0]->val_int() - args[1]->val_int();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0;
-+ return value;
-+}
-+
-+
-+/**
-+ See Item_func_plus::decimal_op for comments.
-+*/
-+
-+my_decimal *Item_func_minus::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal value1, *val1;
-+ my_decimal value2, *val2=
-+
-+ val1= args[0]->val_decimal(&value1);
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ val2= args[1]->val_decimal(&value2);
-+ if (!(null_value= (args[1]->null_value ||
-+ (my_decimal_sub(E_DEC_FATAL_ERROR, decimal_value, val1,
-+ val2) > 3))))
-+ return decimal_value;
-+ return 0;
-+}
-+
-+
-+double Item_func_mul::real_op()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real() * args[1]->val_real();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0.0;
-+ return fix_result(value);
-+}
-+
-+
-+longlong Item_func_mul::int_op()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong value=args[0]->val_int()*args[1]->val_int();
-+ if ((null_value=args[0]->null_value || args[1]->null_value))
-+ return 0;
-+ return value;
-+}
-+
-+
-+/** See Item_func_plus::decimal_op for comments. */
-+
-+my_decimal *Item_func_mul::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal value1, *val1;
-+ my_decimal value2, *val2;
-+ val1= args[0]->val_decimal(&value1);
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ val2= args[1]->val_decimal(&value2);
-+ if (!(null_value= (args[1]->null_value ||
-+ (my_decimal_mul(E_DEC_FATAL_ERROR, decimal_value, val1,
-+ val2) > 3))))
-+ return decimal_value;
-+ return 0;
-+}
-+
-+
-+void Item_func_mul::result_precision()
-+{
-+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
-+ if (result_type() == INT_RESULT)
-+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
-+ else
-+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
-+ decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
-+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
-+ uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
-+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
-+ unsigned_flag);
-+}
-+
-+
-+double Item_func_div::real_op()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ double val2= args[1]->val_real();
-+ if ((null_value= args[0]->null_value || args[1]->null_value))
-+ return 0.0;
-+ if (val2 == 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return fix_result(value/val2);
-+}
-+
-+
-+my_decimal *Item_func_div::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal value1, *val1;
-+ my_decimal value2, *val2;
-+ int err;
-+
-+ val1= args[0]->val_decimal(&value1);
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ val2= args[1]->val_decimal(&value2);
-+ if ((null_value= args[1]->null_value))
-+ return 0;
-+ if ((err= my_decimal_div(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
-+ val1, val2, prec_increment)) > 3)
-+ {
-+ if (err == E_DEC_DIV_ZERO)
-+ signal_divide_by_null();
-+ null_value= 1;
-+ return 0;
-+ }
-+ return decimal_value;
-+}
-+
-+
-+void Item_func_div::result_precision()
-+{
-+ uint precision=min(args[0]->decimal_precision() +
-+ args[1]->decimals + prec_increment,
-+ DECIMAL_MAX_PRECISION);
-+
-+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
-+ if (result_type() == INT_RESULT)
-+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
-+ else
-+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
-+ decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
-+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
-+ unsigned_flag);
-+}
-+
-+
-+void Item_func_div::fix_length_and_dec()
-+{
-+ DBUG_ENTER("Item_func_div::fix_length_and_dec");
-+ prec_increment= current_thd->variables.div_precincrement;
-+ Item_num_op::fix_length_and_dec();
-+ switch(hybrid_type) {
-+ case REAL_RESULT:
-+ {
-+ decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
-+ set_if_smaller(decimals, NOT_FIXED_DEC);
-+ uint tmp=float_length(decimals);
-+ if (decimals == NOT_FIXED_DEC)
-+ max_length= tmp;
-+ else
-+ {
-+ max_length=args[0]->max_length - args[0]->decimals + decimals;
-+ set_if_smaller(max_length,tmp);
-+ }
-+ break;
-+ }
-+ case INT_RESULT:
-+ hybrid_type= DECIMAL_RESULT;
-+ DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
-+ result_precision();
-+ break;
-+ case DECIMAL_RESULT:
-+ result_precision();
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ maybe_null= 1; // devision by zero
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/* Integer division */
-+longlong Item_func_int_div::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong value=args[0]->val_int();
-+ longlong val2=args[1]->val_int();
-+ if ((null_value= (args[0]->null_value || args[1]->null_value)))
-+ return 0;
-+ if (val2 == 0)
-+ {
-+ signal_divide_by_null();
-+ return 0;
-+ }
-+
-+ if (unsigned_flag)
-+ return ((ulonglong) value / (ulonglong) val2);
-+ else if (value == LONGLONG_MIN && val2 == -1)
-+ return LONGLONG_MIN;
-+ else
-+ return value / val2;
-+}
-+
-+
-+void Item_func_int_div::fix_length_and_dec()
-+{
-+ Item_result argtype= args[0]->result_type();
-+ /* use precision ony for the data type it is applicable for and valid */
-+ max_length=args[0]->max_length -
-+ (argtype == DECIMAL_RESULT || argtype == INT_RESULT ?
-+ args[0]->decimals : 0);
-+ maybe_null=1;
-+ unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag;
-+}
-+
-+
-+longlong Item_func_mod::int_op()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong value= args[0]->val_int();
-+ longlong val2= args[1]->val_int();
-+ longlong result;
-+
-+ if ((null_value= args[0]->null_value || args[1]->null_value))
-+ return 0; /* purecov: inspected */
-+ if (val2 == 0)
-+ {
-+ signal_divide_by_null();
-+ return 0;
-+ }
-+
-+ if (args[0]->unsigned_flag)
-+ result= args[1]->unsigned_flag ?
-+ ((ulonglong) value) % ((ulonglong) val2) : ((ulonglong) value) % val2;
-+ else result= args[1]->unsigned_flag ?
-+ value % ((ulonglong) val2) :
-+ (val2 == -1) ? 0 : value % val2;
-+
-+ return result;
-+}
-+
-+double Item_func_mod::real_op()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ double val2= args[1]->val_real();
-+ if ((null_value= args[0]->null_value || args[1]->null_value))
-+ return 0.0; /* purecov: inspected */
-+ if (val2 == 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return fmod(value,val2);
-+}
-+
-+
-+my_decimal *Item_func_mod::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal value1, *val1;
-+ my_decimal value2, *val2;
-+
-+ val1= args[0]->val_decimal(&value1);
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ val2= args[1]->val_decimal(&value2);
-+ if ((null_value= args[1]->null_value))
-+ return 0;
-+ switch (my_decimal_mod(E_DEC_FATAL_ERROR & ~E_DEC_DIV_ZERO, decimal_value,
-+ val1, val2)) {
-+ case E_DEC_TRUNCATED:
-+ case E_DEC_OK:
-+ return decimal_value;
-+ case E_DEC_DIV_ZERO:
-+ signal_divide_by_null();
-+ default:
-+ null_value= 1;
-+ return 0;
-+ }
-+}
-+
-+
-+void Item_func_mod::result_precision()
-+{
-+ decimals= max(args[0]->decimals, args[1]->decimals);
-+ max_length= max(args[0]->max_length, args[1]->max_length);
-+}
-+
-+
-+void Item_func_mod::fix_length_and_dec()
-+{
-+ Item_num_op::fix_length_and_dec();
-+ maybe_null= 1;
-+ unsigned_flag= args[0]->unsigned_flag;
-+}
-+
-+
-+double Item_func_neg::real_op()
-+{
-+ double value= args[0]->val_real();
-+ null_value= args[0]->null_value;
-+ return -value;
-+}
-+
-+
-+longlong Item_func_neg::int_op()
-+{
-+ longlong value= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ return -value;
-+}
-+
-+
-+my_decimal *Item_func_neg::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal val, *value= args[0]->val_decimal(&val);
-+ if (!(null_value= args[0]->null_value))
-+ {
-+ my_decimal2decimal(value, decimal_value);
-+ my_decimal_neg(decimal_value);
-+ return decimal_value;
-+ }
-+ return 0;
-+}
-+
-+
-+void Item_func_neg::fix_num_length_and_dec()
-+{
-+ decimals= args[0]->decimals;
-+ /* 1 add because sign can appear */
-+ max_length= args[0]->max_length + 1;
-+}
-+
-+
-+void Item_func_neg::fix_length_and_dec()
-+{
-+ DBUG_ENTER("Item_func_neg::fix_length_and_dec");
-+ Item_func_num1::fix_length_and_dec();
-+
-+ /*
-+ If this is in integer context keep the context as integer if possible
-+ (This is how multiplication and other integer functions works)
-+ Use val() to get value as arg_type doesn't mean that item is
-+ Item_int or Item_real due to existence of Item_param.
-+ */
-+ if (hybrid_type == INT_RESULT && args[0]->const_item())
-+ {
-+ longlong val= args[0]->val_int();
-+ if ((ulonglong) val >= (ulonglong) LONGLONG_MIN &&
-+ ((ulonglong) val != (ulonglong) LONGLONG_MIN ||
-+ args[0]->type() != INT_ITEM))
-+ {
-+ /*
-+ Ensure that result is converted to DECIMAL, as longlong can't hold
-+ the negated number
-+ */
-+ hybrid_type= DECIMAL_RESULT;
-+ DBUG_PRINT("info", ("Type changed: DECIMAL_RESULT"));
-+ }
-+ }
-+ unsigned_flag= 0;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+double Item_func_abs::real_op()
-+{
-+ double value= args[0]->val_real();
-+ null_value= args[0]->null_value;
-+ return fabs(value);
-+}
-+
-+
-+longlong Item_func_abs::int_op()
-+{
-+ longlong value= args[0]->val_int();
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ return (value >= 0) || unsigned_flag ? value : -value;
-+}
-+
-+
-+my_decimal *Item_func_abs::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal val, *value= args[0]->val_decimal(&val);
-+ if (!(null_value= args[0]->null_value))
-+ {
-+ my_decimal2decimal(value, decimal_value);
-+ if (decimal_value->sign())
-+ my_decimal_neg(decimal_value);
-+ return decimal_value;
-+ }
-+ return 0;
-+}
-+
-+
-+void Item_func_abs::fix_length_and_dec()
-+{
-+ Item_func_num1::fix_length_and_dec();
-+ unsigned_flag= args[0]->unsigned_flag;
-+}
-+
-+
-+/** Gateway to natural LOG function. */
-+double Item_func_ln::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value= args[0]->null_value))
-+ return 0.0;
-+ if (value <= 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return log(value);
-+}
-+
-+/**
-+ Extended but so slower LOG function.
-+
-+ We have to check if all values are > zero and first one is not one
-+ as these are the cases then result is not a number.
-+*/
-+double Item_func_log::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value= args[0]->null_value))
-+ return 0.0;
-+ if (value <= 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ if (arg_count == 2)
-+ {
-+ double value2= args[1]->val_real();
-+ if ((null_value= args[1]->null_value))
-+ return 0.0;
-+ if (value2 <= 0.0 || value == 1.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return log(value2) / log(value);
-+ }
-+ return log(value);
-+}
-+
-+double Item_func_log2::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+
-+ if ((null_value=args[0]->null_value))
-+ return 0.0;
-+ if (value <= 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return log(value) / M_LN2;
-+}
-+
-+double Item_func_log10::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value= args[0]->null_value))
-+ return 0.0;
-+ if (value <= 0.0)
-+ {
-+ signal_divide_by_null();
-+ return 0.0;
-+ }
-+ return log10(value);
-+}
-+
-+double Item_func_exp::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0.0; /* purecov: inspected */
-+ return fix_result(exp(value));
-+}
-+
-+double Item_func_sqrt::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=(args[0]->null_value || value < 0)))
-+ return 0.0; /* purecov: inspected */
-+ return sqrt(value);
-+}
-+
-+double Item_func_pow::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ double val2= args[1]->val_real();
-+ if ((null_value=(args[0]->null_value || args[1]->null_value)))
-+ return 0.0; /* purecov: inspected */
-+ return fix_result(pow(value,val2));
-+}
-+
-+// Trigonometric functions
-+
-+double Item_func_acos::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
-+ volatile double value= args[0]->val_real();
-+ if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
-+ return 0.0;
-+ return acos(value);
-+}
-+
-+double Item_func_asin::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ // the volatile's for BUG #2338 to calm optimizer down (because of gcc's bug)
-+ volatile double value= args[0]->val_real();
-+ if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
-+ return 0.0;
-+ return asin(value);
-+}
-+
-+double Item_func_atan::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0.0;
-+ if (arg_count == 2)
-+ {
-+ double val2= args[1]->val_real();
-+ if ((null_value=args[1]->null_value))
-+ return 0.0;
-+ return fix_result(atan2(value,val2));
-+ }
-+ return atan(value);
-+}
-+
-+double Item_func_cos::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0.0;
-+ return cos(value);
-+}
-+
-+double Item_func_sin::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0.0;
-+ return sin(value);
-+}
-+
-+double Item_func_tan::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0.0;
-+ return fix_result(tan(value));
-+}
-+
-+
-+// Shift-functions, same as << and >> in C/C++
-+
-+
-+longlong Item_func_shift_left::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint shift;
-+ ulonglong res= ((ulonglong) args[0]->val_int() <<
-+ (shift=(uint) args[1]->val_int()));
-+ if (args[0]->null_value || args[1]->null_value)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0));
-+}
-+
-+longlong Item_func_shift_right::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint shift;
-+ ulonglong res= (ulonglong) args[0]->val_int() >>
-+ (shift=(uint) args[1]->val_int());
-+ if (args[0]->null_value || args[1]->null_value)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ return (shift < sizeof(longlong)*8 ? (longlong) res : LL(0));
-+}
-+
-+
-+longlong Item_func_bit_neg::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ ulonglong res= (ulonglong) args[0]->val_int();
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ return ~res;
-+}
-+
-+
-+// Conversion functions
-+
-+void Item_func_integer::fix_length_and_dec()
-+{
-+ max_length=args[0]->max_length - args[0]->decimals+1;
-+ uint tmp=float_length(decimals);
-+ set_if_smaller(max_length,tmp);
-+ decimals=0;
-+}
-+
-+void Item_func_int_val::fix_num_length_and_dec()
-+{
-+ ulonglong tmp_max_length= (ulonglong ) args[0]->max_length -
-+ (args[0]->decimals ? args[0]->decimals + 1 : 0) + 2;
-+ max_length= tmp_max_length > (ulonglong) max_field_size ?
-+ max_field_size : (uint32) tmp_max_length;
-+ uint tmp= float_length(decimals);
-+ set_if_smaller(max_length,tmp);
-+ decimals= 0;
-+}
-+
-+
-+void Item_func_int_val::find_num_type()
-+{
-+ DBUG_ENTER("Item_func_int_val::find_num_type");
-+ DBUG_PRINT("info", ("name %s", func_name()));
-+ switch(hybrid_type= args[0]->result_type())
-+ {
-+ case STRING_RESULT:
-+ case REAL_RESULT:
-+ hybrid_type= REAL_RESULT;
-+ max_length= float_length(decimals);
-+ break;
-+ case INT_RESULT:
-+ case DECIMAL_RESULT:
-+ /*
-+ -2 because in most high position can't be used any digit for longlong
-+ and one position for increasing value during operation
-+ */
-+ if ((args[0]->max_length - args[0]->decimals) >=
-+ (DECIMAL_LONGLONG_DIGITS - 2))
-+ {
-+ hybrid_type= DECIMAL_RESULT;
-+ }
-+ else
-+ {
-+ unsigned_flag= args[0]->unsigned_flag;
-+ hybrid_type= INT_RESULT;
-+ }
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ DBUG_PRINT("info", ("Type: %s",
-+ (hybrid_type == REAL_RESULT ? "REAL_RESULT" :
-+ hybrid_type == DECIMAL_RESULT ? "DECIMAL_RESULT" :
-+ hybrid_type == INT_RESULT ? "INT_RESULT" :
-+ "--ILLEGAL!!!--")));
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+longlong Item_func_ceiling::int_op()
-+{
-+ longlong result;
-+ switch (args[0]->result_type()) {
-+ case INT_RESULT:
-+ result= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ break;
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal dec_buf, *dec;
-+ if ((dec= Item_func_ceiling::decimal_op(&dec_buf)))
-+ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
-+ else
-+ result= 0;
-+ break;
-+ }
-+ default:
-+ result= (longlong)Item_func_ceiling::real_op();
-+ };
-+ return result;
-+}
-+
-+
-+double Item_func_ceiling::real_op()
-+{
-+ /*
-+ the volatile's for BUG #3051 to calm optimizer down (because of gcc's
-+ bug)
-+ */
-+ volatile double value= args[0]->val_real();
-+ null_value= args[0]->null_value;
-+ return ceil(value);
-+}
-+
-+
-+my_decimal *Item_func_ceiling::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal val, *value= args[0]->val_decimal(&val);
-+ if (!(null_value= (args[0]->null_value ||
-+ my_decimal_ceiling(E_DEC_FATAL_ERROR, value,
-+ decimal_value) > 1)))
-+ return decimal_value;
-+ return 0;
-+}
-+
-+
-+longlong Item_func_floor::int_op()
-+{
-+ longlong result;
-+ switch (args[0]->result_type()) {
-+ case INT_RESULT:
-+ result= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ break;
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal dec_buf, *dec;
-+ if ((dec= Item_func_floor::decimal_op(&dec_buf)))
-+ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
-+ else
-+ result= 0;
-+ break;
-+ }
-+ default:
-+ result= (longlong)Item_func_floor::real_op();
-+ };
-+ return result;
-+}
-+
-+
-+double Item_func_floor::real_op()
-+{
-+ /*
-+ the volatile's for BUG #3051 to calm optimizer down (because of gcc's
-+ bug)
-+ */
-+ volatile double value= args[0]->val_real();
-+ null_value= args[0]->null_value;
-+ return floor(value);
-+}
-+
-+
-+my_decimal *Item_func_floor::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal val, *value= args[0]->val_decimal(&val);
-+ if (!(null_value= (args[0]->null_value ||
-+ my_decimal_floor(E_DEC_FATAL_ERROR, value,
-+ decimal_value) > 1)))
-+ return decimal_value;
-+ return 0;
-+}
-+
-+
-+void Item_func_round::fix_length_and_dec()
-+{
-+ int decimals_to_set;
-+ longlong val1;
-+ bool val1_unsigned;
-+
-+ unsigned_flag= args[0]->unsigned_flag;
-+ if (!args[1]->const_item())
-+ {
-+ decimals= args[0]->decimals;
-+ max_length= float_length(decimals);
-+ if (args[0]->result_type() == DECIMAL_RESULT)
-+ {
-+ max_length++;
-+ hybrid_type= DECIMAL_RESULT;
-+ }
-+ else
-+ hybrid_type= REAL_RESULT;
-+ return;
-+ }
-+
-+ val1= args[1]->val_int();
-+ val1_unsigned= args[1]->unsigned_flag;
-+ if (val1 < 0)
-+ decimals_to_set= val1_unsigned ? INT_MAX : 0;
-+ else
-+ decimals_to_set= (val1 > INT_MAX) ? INT_MAX : (int) val1;
-+
-+ if (args[0]->decimals == NOT_FIXED_DEC)
-+ {
-+ decimals= min(decimals_to_set, NOT_FIXED_DEC);
-+ max_length= float_length(decimals);
-+ hybrid_type= REAL_RESULT;
-+ return;
-+ }
-+
-+ switch (args[0]->result_type()) {
-+ case REAL_RESULT:
-+ case STRING_RESULT:
-+ hybrid_type= REAL_RESULT;
-+ decimals= min(decimals_to_set, NOT_FIXED_DEC);
-+ max_length= float_length(decimals);
-+ break;
-+ case INT_RESULT:
-+ if ((!decimals_to_set && truncate) || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS))
-+ {
-+ int length_can_increase= test(!truncate && (val1 < 0) && !val1_unsigned);
-+ max_length= args[0]->max_length + length_can_increase;
-+ /* Here we can keep INT_RESULT */
-+ hybrid_type= INT_RESULT;
-+ decimals= 0;
-+ break;
-+ }
-+ /* fall through */
-+ case DECIMAL_RESULT:
-+ {
-+ hybrid_type= DECIMAL_RESULT;
-+ decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
-+ int decimals_delta= args[0]->decimals - decimals_to_set;
-+ int precision= args[0]->decimal_precision();
-+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
-+
-+ precision-= decimals_delta - length_increase;
-+ decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
-+ max_length= my_decimal_precision_to_length_no_truncation(precision,
-+ decimals,
-+ unsigned_flag);
-+ break;
-+ }
-+ default:
-+ DBUG_ASSERT(0); /* This result type isn't handled */
-+ }
-+}
-+
-+double my_double_round(double value, longlong dec, bool dec_unsigned,
-+ bool truncate)
-+{
-+ double tmp;
-+ bool dec_negative= (dec < 0) && !dec_unsigned;
-+ ulonglong abs_dec= dec_negative ? -dec : dec;
-+ /*
-+ tmp2 is here to avoid return the value with 80 bit precision
-+ This will fix that the test round(0.1,1) = round(0.1,1) is true
-+ */
-+ volatile double tmp2;
-+
-+ tmp=(abs_dec < array_elements(log_10) ?
-+ log_10[abs_dec] : pow(10.0,(double) abs_dec));
-+
-+ if (dec_negative && my_isinf(tmp))
-+ tmp2= 0;
-+ else if (!dec_negative && my_isinf(value * tmp))
-+ tmp2= value;
-+ else if (truncate)
-+ {
-+ if (value >= 0)
-+ tmp2= dec < 0 ? floor(value/tmp)*tmp : floor(value*tmp)/tmp;
-+ else
-+ tmp2= dec < 0 ? ceil(value/tmp)*tmp : ceil(value*tmp)/tmp;
-+ }
-+ else
-+ tmp2=dec < 0 ? rint(value/tmp)*tmp : rint(value*tmp)/tmp;
-+ return tmp2;
-+}
-+
-+
-+double Item_func_round::real_op()
-+{
-+ double value= args[0]->val_real();
-+
-+ if (!(null_value= args[0]->null_value || args[1]->null_value))
-+ return my_double_round(value, args[1]->val_int(), args[1]->unsigned_flag,
-+ truncate);
-+
-+ return 0.0;
-+}
-+
-+/*
-+ Rounds a given value to a power of 10 specified as the 'to' argument,
-+ avoiding overflows when the value is close to the ulonglong range boundary.
-+*/
-+
-+static inline ulonglong my_unsigned_round(ulonglong value, ulonglong to)
-+{
-+ ulonglong tmp= value / to * to;
-+ return (value - tmp < (to >> 1)) ? tmp : tmp + to;
-+}
-+
-+
-+longlong Item_func_round::int_op()
-+{
-+ longlong value= args[0]->val_int();
-+ longlong dec= args[1]->val_int();
-+ decimals= 0;
-+ ulonglong abs_dec;
-+ if ((null_value= args[0]->null_value || args[1]->null_value))
-+ return 0;
-+ if ((dec >= 0) || args[1]->unsigned_flag)
-+ return value; // integer have not digits after point
-+
-+ abs_dec= -dec;
-+ longlong tmp;
-+
-+ if(abs_dec >= array_elements(log_10_int))
-+ return 0;
-+
-+ tmp= log_10_int[abs_dec];
-+
-+ if (truncate)
-+ value= (unsigned_flag) ?
-+ ((ulonglong) value / tmp) * tmp : (value / tmp) * tmp;
-+ else
-+ value= (unsigned_flag || value >= 0) ?
-+ my_unsigned_round((ulonglong) value, tmp) :
-+ -(longlong) my_unsigned_round((ulonglong) -value, tmp);
-+ return value;
-+}
-+
-+
-+my_decimal *Item_func_round::decimal_op(my_decimal *decimal_value)
-+{
-+ my_decimal val, *value= args[0]->val_decimal(&val);
-+ longlong dec= args[1]->val_int();
-+ if (dec >= 0 || args[1]->unsigned_flag)
-+ dec= min((ulonglong) dec, decimals);
-+ else if (dec < INT_MIN)
-+ dec= INT_MIN;
-+
-+ if (!(null_value= (args[0]->null_value || args[1]->null_value ||
-+ my_decimal_round(E_DEC_FATAL_ERROR, value, (int) dec,
-+ truncate, decimal_value) > 1)))
-+ {
-+ decimal_value->frac= decimals;
-+ return decimal_value;
-+ }
-+ return 0;
-+}
-+
-+
-+void Item_func_rand::seed_random(Item *arg)
-+{
-+ /*
-+ TODO: do not do reinit 'rand' for every execute of PS/SP if
-+ args[0] is a constant.
-+ */
-+ uint32 tmp= (uint32) arg->val_int();
-+ randominit(rand, (uint32) (tmp*0x10001L+55555555L),
-+ (uint32) (tmp*0x10000001L));
-+}
-+
-+
-+bool Item_func_rand::fix_fields(THD *thd,Item **ref)
-+{
-+ if (Item_real_func::fix_fields(thd, ref))
-+ return TRUE;
-+ used_tables_cache|= RAND_TABLE_BIT;
-+ if (arg_count)
-+ { // Only use argument once in query
-+ /*
-+ Allocate rand structure once: we must use thd->stmt_arena
-+ to create rand in proper mem_root if it's a prepared statement or
-+ stored procedure.
-+
-+ No need to send a Rand log event if seed was given eg: RAND(seed),
-+ as it will be replicated in the query as such.
-+ */
-+ if (!rand && !(rand= (struct rand_struct*)
-+ thd->stmt_arena->alloc(sizeof(*rand))))
-+ return TRUE;
-+ }
-+ else
-+ {
-+ /*
-+ Save the seed only the first time RAND() is used in the query
-+ Once events are forwarded rather than recreated,
-+ the following can be skipped if inside the slave thread
-+ */
-+ if (!thd->rand_used)
-+ {
-+ thd->rand_used= 1;
-+ thd->rand_saved_seed1= thd->rand.seed1;
-+ thd->rand_saved_seed2= thd->rand.seed2;
-+ }
-+ rand= &thd->rand;
-+ }
-+ return FALSE;
-+}
-+
-+void Item_func_rand::update_used_tables()
-+{
-+ Item_real_func::update_used_tables();
-+ used_tables_cache|= RAND_TABLE_BIT;
-+}
-+
-+
-+double Item_func_rand::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (arg_count)
-+ {
-+ if (!args[0]->const_item())
-+ seed_random(args[0]);
-+ else if (first_eval)
-+ {
-+ /*
-+ Constantness of args[0] may be set during JOIN::optimize(), if arg[0]
-+ is a field item of "constant" table. Thus, we have to evaluate
-+ seed_random() for constant arg there but not at the fix_fields method.
-+ */
-+ first_eval= FALSE;
-+ seed_random(args[0]);
-+ }
-+ }
-+ return my_rnd(rand);
-+}
-+
-+longlong Item_func_sign::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ null_value=args[0]->null_value;
-+ return value < 0.0 ? -1 : (value > 0 ? 1 : 0);
-+}
-+
-+
-+double Item_func_units::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ return value*mul+add;
-+}
-+
-+
-+void Item_func_min_max::fix_length_and_dec()
-+{
-+ int max_int_part=0;
-+ bool datetime_found= FALSE;
-+ decimals=0;
-+ max_length=0;
-+ maybe_null=0;
-+ cmp_type=args[0]->result_type();
-+
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ set_if_bigger(max_length, args[i]->max_length);
-+ set_if_bigger(decimals, args[i]->decimals);
-+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
-+ if (args[i]->maybe_null)
-+ maybe_null=1;
-+ cmp_type=item_cmp_type(cmp_type,args[i]->result_type());
-+ if (args[i]->result_type() != ROW_RESULT && args[i]->is_datetime())
-+ {
-+ datetime_found= TRUE;
-+ if (!datetime_item || args[i]->field_type() == MYSQL_TYPE_DATETIME)
-+ datetime_item= args[i];
-+ }
-+ }
-+ if (cmp_type == STRING_RESULT)
-+ {
-+ agg_arg_charsets(collation, args, arg_count, MY_COLL_CMP_CONV, 1);
-+ if (datetime_found)
-+ {
-+ thd= current_thd;
-+ compare_as_dates= TRUE;
-+ }
-+ }
-+ else if ((cmp_type == DECIMAL_RESULT) || (cmp_type == INT_RESULT))
-+ max_length= my_decimal_precision_to_length_no_truncation(max_int_part +
-+ decimals, decimals,
-+ unsigned_flag);
-+ else if (cmp_type == REAL_RESULT)
-+ max_length= float_length(decimals);
-+ cached_field_type= agg_field_type(args, arg_count);
-+}
-+
-+
-+/*
-+ Compare item arguments in the DATETIME context.
-+
-+ SYNOPSIS
-+ cmp_datetimes()
-+ value [out] found least/greatest DATE/DATETIME value
-+
-+ DESCRIPTION
-+ Compare item arguments as DATETIME values and return the index of the
-+ least/greatest argument in the arguments array.
-+ The correct integer DATE/DATETIME value of the found argument is
-+ stored to the value pointer, if latter is provided.
-+
-+ RETURN
-+ 0 If one of arguments is NULL or there was a execution error
-+ # index of the least/greatest argument
-+*/
-+
-+uint Item_func_min_max::cmp_datetimes(ulonglong *value)
-+{
-+ longlong UNINIT_VAR(min_max);
-+ uint min_max_idx= 0;
-+
-+ for (uint i=0; i < arg_count ; i++)
-+ {
-+ Item **arg= args + i;
-+ bool is_null;
-+ longlong res= get_datetime_value(thd, &arg, 0, datetime_item, &is_null);
-+
-+ /* Check if we need to stop (because of error or KILL) and stop the loop */
-+ if (thd->is_error())
-+ {
-+ null_value= 1;
-+ return 0;
-+ }
-+
-+ if ((null_value= args[i]->null_value))
-+ return 0;
-+ if (i == 0 || (res < min_max ? cmp_sign : -cmp_sign) > 0)
-+ {
-+ min_max= res;
-+ min_max_idx= i;
-+ }
-+ }
-+ if (value)
-+ {
-+ *value= min_max;
-+ if (datetime_item->field_type() == MYSQL_TYPE_DATE)
-+ *value/= 1000000L;
-+ }
-+ return min_max_idx;
-+}
-+
-+
-+String *Item_func_min_max::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (compare_as_dates)
-+ {
-+ String *str_res;
-+ uint min_max_idx= cmp_datetimes(NULL);
-+ if (null_value)
-+ return 0;
-+ str_res= args[min_max_idx]->val_str(str);
-+ if (args[min_max_idx]->null_value)
-+ {
-+ // check if the call to val_str() above returns a NULL value
-+ null_value= 1;
-+ return NULL;
-+ }
-+ str_res->set_charset(collation.collation);
-+ return str_res;
-+ }
-+ switch (cmp_type) {
-+ case INT_RESULT:
-+ {
-+ longlong nr=val_int();
-+ if (null_value)
-+ return 0;
-+ str->set_int(nr, unsigned_flag, &my_charset_bin);
-+ return str;
-+ }
-+ case DECIMAL_RESULT:
-+ {
-+ my_decimal dec_buf, *dec_val= val_decimal(&dec_buf);
-+ if (null_value)
-+ return 0;
-+ my_decimal2string(E_DEC_FATAL_ERROR, dec_val, 0, 0, 0, str);
-+ return str;
-+ }
-+ case REAL_RESULT:
-+ {
-+ double nr= val_real();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ str->set_real(nr,decimals,&my_charset_bin);
-+ return str;
-+ }
-+ case STRING_RESULT:
-+ {
-+ String *UNINIT_VAR(res);
-+ for (uint i=0; i < arg_count ; i++)
-+ {
-+ if (i == 0)
-+ res=args[i]->val_str(str);
-+ else
-+ {
-+ String *res2;
-+ res2= args[i]->val_str(res == str ? &tmp_value : str);
-+ if (res2)
-+ {
-+ int cmp= sortcmp(res,res2,collation.collation);
-+ if ((cmp_sign < 0 ? cmp : -cmp) < 0)
-+ res=res2;
-+ }
-+ }
-+ if ((null_value= args[i]->null_value))
-+ return 0;
-+ }
-+ res->set_charset(collation.collation);
-+ return res;
-+ }
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ return 0;
-+ }
-+ return 0; // Keep compiler happy
-+}
-+
-+
-+double Item_func_min_max::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double value=0.0;
-+ if (compare_as_dates)
-+ {
-+ ulonglong result= 0;
-+ (void)cmp_datetimes(&result);
-+ return (double)result;
-+ }
-+ for (uint i=0; i < arg_count ; i++)
-+ {
-+ if (i == 0)
-+ value= args[i]->val_real();
-+ else
-+ {
-+ double tmp= args[i]->val_real();
-+ if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
-+ value=tmp;
-+ }
-+ if ((null_value= args[i]->null_value))
-+ break;
-+ }
-+ return value;
-+}
-+
-+
-+longlong Item_func_min_max::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong value=0;
-+ if (compare_as_dates)
-+ {
-+ ulonglong result= 0;
-+ (void)cmp_datetimes(&result);
-+ return (longlong)result;
-+ }
-+ for (uint i=0; i < arg_count ; i++)
-+ {
-+ if (i == 0)
-+ value=args[i]->val_int();
-+ else
-+ {
-+ longlong tmp=args[i]->val_int();
-+ if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
-+ value=tmp;
-+ }
-+ if ((null_value= args[i]->null_value))
-+ break;
-+ }
-+ return value;
-+}
-+
-+
-+my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ my_decimal tmp_buf, *tmp, *UNINIT_VAR(res);
-+
-+ if (compare_as_dates)
-+ {
-+ ulonglong value= 0;
-+ (void)cmp_datetimes(&value);
-+ ulonglong2decimal(value, dec);
-+ return dec;
-+ }
-+ for (uint i=0; i < arg_count ; i++)
-+ {
-+ if (i == 0)
-+ res= args[i]->val_decimal(dec);
-+ else
-+ {
-+ tmp= args[i]->val_decimal(&tmp_buf); // Zero if NULL
-+ if (tmp && (my_decimal_cmp(tmp, res) * cmp_sign) < 0)
-+ {
-+ if (tmp == &tmp_buf)
-+ {
-+ /* Move value out of tmp_buf as this will be reused on next loop */
-+ my_decimal2decimal(tmp, dec);
-+ res= dec;
-+ }
-+ else
-+ res= tmp;
-+ }
-+ }
-+ if ((null_value= args[i]->null_value))
-+ {
-+ res= 0;
-+ break;
-+ }
-+ }
-+ return res;
-+}
-+
-+
-+longlong Item_func_length::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ return (longlong) res->length();
-+}
-+
-+
-+longlong Item_func_char_length::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ return (longlong) res->numchars();
-+}
-+
-+
-+longlong Item_func_coercibility::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ null_value= 0;
-+ return (longlong) args[0]->collation.derivation;
-+}
-+
-+
-+void Item_func_locate::fix_length_and_dec()
-+{
-+ max_length= MY_INT32_NUM_DECIMAL_DIGITS;
-+ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
-+}
-+
-+
-+longlong Item_func_locate::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *a=args[0]->val_str(&value1);
-+ String *b=args[1]->val_str(&value2);
-+ if (!a || !b)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ /* must be longlong to avoid truncation */
-+ longlong start= 0;
-+ longlong start0= 0;
-+ my_match_t match;
-+
-+ if (arg_count == 3)
-+ {
-+ start0= start= args[2]->val_int() - 1;
-+
-+ if ((start < 0) || (start > a->length()))
-+ return 0;
-+
-+ /* start is now sufficiently valid to pass to charpos function */
-+ start= a->charpos((int) start);
-+
-+ if (start + b->length() > a->length())
-+ return 0;
-+ }
-+
-+ if (!b->length()) // Found empty string at start
-+ return start + 1;
-+
-+ if (!cmp_collation.collation->coll->instr(cmp_collation.collation,
-+ a->ptr()+start,
-+ (uint) (a->length()-start),
-+ b->ptr(), b->length(),
-+ &match, 1))
-+ return 0;
-+ return (longlong) match.mb_len + start0 + 1;
-+}
-+
-+
-+void Item_func_locate::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("locate("));
-+ args[1]->print(str, query_type);
-+ str->append(',');
-+ args[0]->print(str, query_type);
-+ if (arg_count == 3)
-+ {
-+ str->append(',');
-+ args[2]->print(str, query_type);
-+ }
-+ str->append(')');
-+}
-+
-+
-+longlong Item_func_field::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+
-+ if (cmp_type == STRING_RESULT)
-+ {
-+ String *field;
-+ if (!(field= args[0]->val_str(&value)))
-+ return 0;
-+ for (uint i=1 ; i < arg_count ; i++)
-+ {
-+ String *tmp_value=args[i]->val_str(&tmp);
-+ if (tmp_value && !sortcmp(field,tmp_value,cmp_collation.collation))
-+ return (longlong) (i);
-+ }
-+ }
-+ 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 (val == args[i]->val_int() && !args[i]->null_value)
-+ return (longlong) (i);
-+ }
-+ }
-+ else if (cmp_type == DECIMAL_RESULT)
-+ {
-+ 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);
-+ if (!args[i]->null_value && !my_decimal_cmp(dec_arg, dec))
-+ return (longlong) (i);
-+ }
-+ }
-+ else
-+ {
-+ double val= args[0]->val_real();
-+ if (args[0]->null_value)
-+ return 0;
-+ for (uint i=1; i < arg_count ; i++)
-+ {
-+ if (val == args[i]->val_real() && !args[i]->null_value)
-+ return (longlong) (i);
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+void Item_func_field::fix_length_and_dec()
-+{
-+ maybe_null=0; max_length=3;
-+ cmp_type= args[0]->result_type();
-+ for (uint i=1; i < arg_count ; i++)
-+ cmp_type= item_cmp_type(cmp_type, args[i]->result_type());
-+ if (cmp_type == STRING_RESULT)
-+ agg_arg_charsets(cmp_collation, args, arg_count, MY_COLL_CMP_CONV, 1);
-+}
-+
-+
-+longlong Item_func_ascii::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ return (longlong) (res->length() ? (uchar) (*res)[0] : (uchar) 0);
-+}
-+
-+longlong Item_func_ord::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ if (!res->length()) return 0;
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ register const char *str=res->ptr();
-+ register uint32 n=0, l=my_ismbchar(res->charset(),str,str+res->length());
-+ if (!l)
-+ return (longlong)((uchar) *str);
-+ while (l--)
-+ n=(n<<8)|(uint32)((uchar) *str++);
-+ return (longlong) n;
-+ }
-+#endif
-+ return (longlong) ((uchar) (*res)[0]);
-+}
-+
-+ /* Search after a string in a string of strings separated by ',' */
-+ /* Returns number of found type >= 1 or 0 if not found */
-+ /* This optimizes searching in enums to bit testing! */
-+
-+void Item_func_find_in_set::fix_length_and_dec()
-+{
-+ decimals=0;
-+ max_length=3; // 1-999
-+ if (args[0]->const_item() && args[1]->type() == FIELD_ITEM)
-+ {
-+ Field *field= ((Item_field*) args[1])->field;
-+ if (field->real_type() == MYSQL_TYPE_SET)
-+ {
-+ String *find=args[0]->val_str(&value);
-+ if (find)
-+ {
-+ enum_value= find_type(((Field_enum*) field)->typelib,find->ptr(),
-+ find->length(), 0);
-+ enum_bit=0;
-+ if (enum_value)
-+ enum_bit=LL(1) << (enum_value-1);
-+ }
-+ }
-+ }
-+ agg_arg_charsets(cmp_collation, args, 2, MY_COLL_CMP_CONV, 1);
-+}
-+
-+static const char separator=',';
-+
-+longlong Item_func_find_in_set::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (enum_value)
-+ {
-+ ulonglong tmp=(ulonglong) args[1]->val_int();
-+ if (!(null_value=args[1]->null_value || args[0]->null_value))
-+ {
-+ if (tmp & enum_bit)
-+ return enum_value;
-+ }
-+ return 0L;
-+ }
-+
-+ String *find=args[0]->val_str(&value);
-+ String *buffer=args[1]->val_str(&value2);
-+ if (!find || !buffer)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+
-+ int diff;
-+ if ((diff=buffer->length() - find->length()) >= 0)
-+ {
-+ my_wc_t wc= 0;
-+ CHARSET_INFO *cs= cmp_collation.collation;
-+ const char *str_begin= buffer->ptr();
-+ const char *str_end= buffer->ptr();
-+ const char *real_end= str_end+buffer->length();
-+ const uchar *find_str= (const uchar *) find->ptr();
-+ uint find_str_len= find->length();
-+ int position= 0;
-+ while (1)
-+ {
-+ int symbol_len;
-+ if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end,
-+ (uchar*) real_end)) > 0)
-+ {
-+ const char *substr_end= str_end + symbol_len;
-+ bool is_last_item= (substr_end == real_end);
-+ bool is_separator= (wc == (my_wc_t) separator);
-+ if (is_separator || is_last_item)
-+ {
-+ position++;
-+ if (is_last_item && !is_separator)
-+ str_end= substr_end;
-+ if (!my_strnncoll(cs, (const uchar *) str_begin,
-+ (uint) (str_end - str_begin),
-+ find_str, find_str_len))
-+ return (longlong) position;
-+ else
-+ str_begin= substr_end;
-+ }
-+ str_end= substr_end;
-+ }
-+ else if (str_end - str_begin == 0 &&
-+ find_str_len == 0 &&
-+ wc == (my_wc_t) separator)
-+ return (longlong) ++position;
-+ else
-+ return LL(0);
-+ }
-+ }
-+ return 0;
-+}
-+
-+longlong Item_func_bit_count::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ ulonglong value= (ulonglong) args[0]->val_int();
-+ if ((null_value= args[0]->null_value))
-+ return 0; /* purecov: inspected */
-+ return (longlong) my_count_bits(value);
-+}
-+
-+
-+/****************************************************************************
-+** Functions to handle dynamic loadable functions
-+** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
-+** Rewritten by monty.
-+****************************************************************************/
-+
-+#ifdef HAVE_DLOPEN
-+
-+void udf_handler::cleanup()
-+{
-+ if (!not_original)
-+ {
-+ if (initialized)
-+ {
-+ if (u_d->func_deinit != NULL)
-+ {
-+ Udf_func_deinit deinit= u_d->func_deinit;
-+ (*deinit)(&initid);
-+ }
-+ free_udf(u_d);
-+ initialized= FALSE;
-+ }
-+ if (buffers) // Because of bug in ecc
-+ delete [] buffers;
-+ buffers= 0;
-+ }
-+}
-+
-+
-+bool
-+udf_handler::fix_fields(THD *thd, Item_result_field *func,
-+ uint arg_count, Item **arguments)
-+{
-+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
-+ uchar buff[STACK_BUFF_ALLOC]; // Max argument in function
-+#endif
-+ DBUG_ENTER("Item_udf_func::fix_fields");
-+
-+ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
-+ DBUG_RETURN(TRUE); // Fatal error flag is set!
-+
-+ udf_func *tmp_udf=find_udf(u_d->name.str,(uint) u_d->name.length,1);
-+
-+ if (!tmp_udf)
-+ {
-+ my_error(ER_CANT_FIND_UDF, MYF(0), u_d->name.str, errno);
-+ DBUG_RETURN(TRUE);
-+ }
-+ u_d=tmp_udf;
-+ args=arguments;
-+
-+ /* Fix all arguments */
-+ func->maybe_null=0;
-+ used_tables_cache=0;
-+ const_item_cache=1;
-+
-+ if ((f_args.arg_count=arg_count))
-+ {
-+ if (!(f_args.arg_type= (Item_result*)
-+ sql_alloc(f_args.arg_count*sizeof(Item_result))))
-+
-+ {
-+ free_udf(u_d);
-+ DBUG_RETURN(TRUE);
-+ }
-+ uint i;
-+ Item **arg,**arg_end;
-+ for (i=0, arg=arguments, arg_end=arguments+arg_count;
-+ arg != arg_end ;
-+ arg++,i++)
-+ {
-+ if (!(*arg)->fixed &&
-+ (*arg)->fix_fields(thd, arg))
-+ DBUG_RETURN(1);
-+ // we can't assign 'item' before, because fix_fields() can change arg
-+ Item *item= *arg;
-+ if (item->check_cols(1))
-+ DBUG_RETURN(TRUE);
-+ /*
-+ TODO: We should think about this. It is not always
-+ right way just to set an UDF result to return my_charset_bin
-+ if one argument has binary sorting order.
-+ The result collation should be calculated according to arguments
-+ derivations in some cases and should not in other cases.
-+ Moreover, some arguments can represent a numeric input
-+ which doesn't effect the result character set and collation.
-+ There is no a general rule for UDF. Everything depends on
-+ the particular user defined function.
-+ */
-+ if (item->collation.collation->state & MY_CS_BINSORT)
-+ func->collation.set(&my_charset_bin);
-+ if (item->maybe_null)
-+ func->maybe_null=1;
-+ func->with_sum_func= func->with_sum_func || item->with_sum_func;
-+ used_tables_cache|=item->used_tables();
-+ const_item_cache&=item->const_item();
-+ f_args.arg_type[i]=item->result_type();
-+ }
-+ //TODO: why all following memory is not allocated with 1 call of sql_alloc?
-+ if (!(buffers=new String[arg_count]) ||
-+ !(f_args.args= (char**) sql_alloc(arg_count * sizeof(char *))) ||
-+ !(f_args.lengths= (ulong*) sql_alloc(arg_count * sizeof(long))) ||
-+ !(f_args.maybe_null= (char*) sql_alloc(arg_count * sizeof(char))) ||
-+ !(num_buffer= (char*) sql_alloc(arg_count *
-+ ALIGN_SIZE(sizeof(double)))) ||
-+ !(f_args.attributes= (char**) sql_alloc(arg_count * sizeof(char *))) ||
-+ !(f_args.attribute_lengths= (ulong*) sql_alloc(arg_count *
-+ sizeof(long))))
-+ {
-+ free_udf(u_d);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ func->fix_length_and_dec();
-+ initid.max_length=func->max_length;
-+ initid.maybe_null=func->maybe_null;
-+ initid.const_item=const_item_cache;
-+ initid.decimals=func->decimals;
-+ initid.ptr=0;
-+
-+ if (u_d->func_init)
-+ {
-+ char init_msg_buff[MYSQL_ERRMSG_SIZE];
-+ char *to=num_buffer;
-+ for (uint i=0; i < arg_count; i++)
-+ {
-+ /*
-+ For a constant argument i, args->args[i] points to the argument value.
-+ For non-constant, args->args[i] is NULL.
-+ */
-+ f_args.args[i]= NULL; /* Non-const unless updated below. */
-+
-+ f_args.lengths[i]= arguments[i]->max_length;
-+ f_args.maybe_null[i]= (char) arguments[i]->maybe_null;
-+ f_args.attributes[i]= arguments[i]->name;
-+ f_args.attribute_lengths[i]= arguments[i]->name_length;
-+
-+ if (arguments[i]->const_item())
-+ {
-+ switch (arguments[i]->result_type())
-+ {
-+ case STRING_RESULT:
-+ case DECIMAL_RESULT:
-+ {
-+ String *res= arguments[i]->val_str(&buffers[i]);
-+ if (arguments[i]->null_value)
-+ continue;
-+ f_args.args[i]= (char*) res->c_ptr();
-+ f_args.lengths[i]= res->length();
-+ break;
-+ }
-+ case INT_RESULT:
-+ *((longlong*) to)= arguments[i]->val_int();
-+ if (arguments[i]->null_value)
-+ continue;
-+ f_args.args[i]= to;
-+ to+= ALIGN_SIZE(sizeof(longlong));
-+ break;
-+ case REAL_RESULT:
-+ *((double*) to)= arguments[i]->val_real();
-+ if (arguments[i]->null_value)
-+ continue;
-+ f_args.args[i]= to;
-+ to+= ALIGN_SIZE(sizeof(double));
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ }
-+ }
-+ Udf_func_init init= u_d->func_init;
-+ if ((error=(uchar) init(&initid, &f_args, init_msg_buff)))
-+ {
-+ my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
-+ u_d->name.str, init_msg_buff);
-+ free_udf(u_d);
-+ DBUG_RETURN(TRUE);
-+ }
-+ func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
-+ func->maybe_null=initid.maybe_null;
-+ const_item_cache=initid.const_item;
-+ /*
-+ Keep used_tables_cache in sync with const_item_cache.
-+ See the comment in Item_udf_func::update_used tables.
-+ */
-+ if (!const_item_cache && !used_tables_cache)
-+ used_tables_cache= RAND_TABLE_BIT;
-+ func->decimals=min(initid.decimals,NOT_FIXED_DEC);
-+ }
-+ initialized=1;
-+ if (error)
-+ {
-+ my_error(ER_CANT_INITIALIZE_UDF, MYF(0),
-+ u_d->name.str, ER(ER_UNKNOWN_ERROR));
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+bool udf_handler::get_arguments()
-+{
-+ if (error)
-+ return 1; // Got an error earlier
-+ char *to= num_buffer;
-+ uint str_count=0;
-+ for (uint i=0; i < f_args.arg_count; i++)
-+ {
-+ f_args.args[i]=0;
-+ switch (f_args.arg_type[i]) {
-+ case STRING_RESULT:
-+ case DECIMAL_RESULT:
-+ {
-+ String *res=args[i]->val_str(&buffers[str_count++]);
-+ if (!(args[i]->null_value))
-+ {
-+ f_args.args[i]= (char*) res->ptr();
-+ f_args.lengths[i]= res->length();
-+ break;
-+ }
-+ }
-+ case INT_RESULT:
-+ *((longlong*) to) = args[i]->val_int();
-+ if (!args[i]->null_value)
-+ {
-+ f_args.args[i]=to;
-+ to+= ALIGN_SIZE(sizeof(longlong));
-+ }
-+ break;
-+ case REAL_RESULT:
-+ *((double*) to)= args[i]->val_real();
-+ if (!args[i]->null_value)
-+ {
-+ f_args.args[i]=to;
-+ to+= ALIGN_SIZE(sizeof(double));
-+ }
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/**
-+ @return
-+ (String*)NULL in case of NULL values
-+*/
-+String *udf_handler::val_str(String *str,String *save_str)
-+{
-+ uchar is_null_tmp=0;
-+ ulong res_length;
-+ DBUG_ENTER("udf_handler::val_str");
-+
-+ if (get_arguments())
-+ DBUG_RETURN(0);
-+ char * (*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
-+ (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
-+ u_d->func;
-+
-+ if ((res_length=str->alloced_length()) < MAX_FIELD_WIDTH)
-+ { // This happens VERY seldom
-+ if (str->alloc(MAX_FIELD_WIDTH))
-+ {
-+ error=1;
-+ DBUG_RETURN(0);
-+ }
-+ }
-+ char *res=func(&initid, &f_args, (char*) str->ptr(), &res_length,
-+ &is_null_tmp, &error);
-+ DBUG_PRINT("info", ("udf func returned, res_length: %lu", res_length));
-+ if (is_null_tmp || !res || error) // The !res is for safety
-+ {
-+ DBUG_PRINT("info", ("Null or error"));
-+ DBUG_RETURN(0);
-+ }
-+ if (res == str->ptr())
-+ {
-+ str->length(res_length);
-+ DBUG_PRINT("exit", ("str: %s", str->ptr()));
-+ DBUG_RETURN(str);
-+ }
-+ save_str->set(res, res_length, str->charset());
-+ DBUG_PRINT("exit", ("save_str: %s", save_str->ptr()));
-+ DBUG_RETURN(save_str);
-+}
-+
-+
-+/*
-+ For the moment, UDF functions are returning DECIMAL values as strings
-+*/
-+
-+my_decimal *udf_handler::val_decimal(my_bool *null_value, my_decimal *dec_buf)
-+{
-+ char buf[DECIMAL_MAX_STR_LENGTH+1], *end;
-+ ulong res_length= DECIMAL_MAX_STR_LENGTH;
-+
-+ if (get_arguments())
-+ {
-+ *null_value=1;
-+ return 0;
-+ }
-+ char *(*func)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *)=
-+ (char* (*)(UDF_INIT *, UDF_ARGS *, char *, ulong *, uchar *, uchar *))
-+ u_d->func;
-+
-+ char *res= func(&initid, &f_args, buf, &res_length, &is_null, &error);
-+ if (is_null || error)
-+ {
-+ *null_value= 1;
-+ return 0;
-+ }
-+ end= res+ res_length;
-+ str2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf, &end);
-+ return dec_buf;
-+}
-+
-+
-+void Item_udf_func::cleanup()
-+{
-+ udf.cleanup();
-+ Item_func::cleanup();
-+}
-+
-+
-+void Item_udf_func::print(String *str, enum_query_type query_type)
-+{
-+ str->append(func_name());
-+ str->append('(');
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ if (i != 0)
-+ str->append(',');
-+ args[i]->print_item_w_name(str, query_type);
-+ }
-+ str->append(')');
-+}
-+
-+
-+double Item_func_udf_float::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ DBUG_ENTER("Item_func_udf_float::val");
-+ DBUG_PRINT("info",("result_type: %d arg_count: %d",
-+ args[0]->result_type(), arg_count));
-+ DBUG_RETURN(udf.val(&null_value));
-+}
-+
-+
-+String *Item_func_udf_float::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ double nr= val_real();
-+ if (null_value)
-+ return 0; /* purecov: inspected */
-+ str->set_real(nr,decimals,&my_charset_bin);
-+ return str;
-+}
-+
-+
-+longlong Item_func_udf_int::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ DBUG_ENTER("Item_func_udf_int::val_int");
-+ DBUG_RETURN(udf.val_int(&null_value));
-+}
-+
-+
-+String *Item_func_udf_int::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ longlong nr=val_int();
-+ if (null_value)
-+ return 0;
-+ str->set_int(nr, unsigned_flag, &my_charset_bin);
-+ return str;
-+}
-+
-+
-+longlong Item_func_udf_decimal::val_int()
-+{
-+ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
-+ longlong result;
-+ if (null_value)
-+ return 0;
-+ my_decimal2int(E_DEC_FATAL_ERROR, dec, unsigned_flag, &result);
-+ return result;
-+}
-+
-+
-+double Item_func_udf_decimal::val_real()
-+{
-+ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
-+ double result;
-+ if (null_value)
-+ return 0.0;
-+ my_decimal2double(E_DEC_FATAL_ERROR, dec, &result);
-+ return result;
-+}
-+
-+
-+my_decimal *Item_func_udf_decimal::val_decimal(my_decimal *dec_buf)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ DBUG_ENTER("Item_func_udf_decimal::val_decimal");
-+ DBUG_PRINT("info",("result_type: %d arg_count: %d",
-+ args[0]->result_type(), arg_count));
-+
-+ DBUG_RETURN(udf.val_decimal(&null_value, dec_buf));
-+}
-+
-+
-+String *Item_func_udf_decimal::val_str(String *str)
-+{
-+ my_decimal dec_buf, *dec= udf.val_decimal(&null_value, &dec_buf);
-+ if (null_value)
-+ return 0;
-+ if (str->length() < DECIMAL_MAX_STR_LENGTH)
-+ str->length(DECIMAL_MAX_STR_LENGTH);
-+ my_decimal_round(E_DEC_FATAL_ERROR, dec, decimals, FALSE, &dec_buf);
-+ my_decimal2string(E_DEC_FATAL_ERROR, &dec_buf, 0, 0, '0', str);
-+ return str;
-+}
-+
-+
-+void Item_func_udf_decimal::fix_length_and_dec()
-+{
-+ fix_num_length_and_dec();
-+}
-+
-+
-+/* Default max_length is max argument length */
-+
-+void Item_func_udf_str::fix_length_and_dec()
-+{
-+ DBUG_ENTER("Item_func_udf_str::fix_length_and_dec");
-+ max_length=0;
-+ for (uint i = 0; i < arg_count; i++)
-+ set_if_bigger(max_length,args[i]->max_length);
-+ DBUG_VOID_RETURN;
-+}
-+
-+String *Item_func_udf_str::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=udf.val_str(str,&str_value);
-+ null_value = !res;
-+ return res;
-+}
-+
-+
-+/**
-+ @note
-+ This has to come last in the udf_handler methods, or C for AIX
-+ version 6.0.0.0 fails to compile with debugging enabled. (Yes, really.)
-+*/
-+
-+udf_handler::~udf_handler()
-+{
-+ /* Everything should be properly cleaned up by this moment. */
-+ DBUG_ASSERT(not_original || !(initialized || buffers));
-+}
-+
-+#else
-+bool udf_handler::get_arguments() { return 0; }
-+#endif /* HAVE_DLOPEN */
-+
-+/*
-+** User level locks
-+*/
-+
-+pthread_mutex_t LOCK_user_locks;
-+static HASH hash_user_locks;
-+
-+class User_level_lock
-+{
-+ uchar *key;
-+ size_t key_length;
-+
-+public:
-+ int count;
-+ bool locked;
-+ pthread_cond_t cond;
-+ my_thread_id thread_id;
-+ void set_thread(THD *thd) { thread_id= thd->thread_id; }
-+
-+ User_level_lock(const uchar *key_arg,uint length, ulong id)
-+ :key_length(length),count(1),locked(1), thread_id(id)
-+ {
-+ key= (uchar*) my_memdup(key_arg,length,MYF(0));
-+ pthread_cond_init(&cond,NULL);
-+ if (key)
-+ {
-+ if (my_hash_insert(&hash_user_locks,(uchar*) this))
-+ {
-+ my_free(key,MYF(0));
-+ key=0;
-+ }
-+ }
-+ }
-+ ~User_level_lock()
-+ {
-+ if (key)
-+ {
-+ hash_delete(&hash_user_locks,(uchar*) this);
-+ my_free(key, MYF(0));
-+ }
-+ pthread_cond_destroy(&cond);
-+ }
-+ inline bool initialized() { return key != 0; }
-+ friend void item_user_lock_release(User_level_lock *ull);
-+ friend uchar *ull_get_key(const User_level_lock *ull, size_t *length,
-+ my_bool not_used);
-+};
-+
-+uchar *ull_get_key(const User_level_lock *ull, size_t *length,
-+ my_bool not_used __attribute__((unused)))
-+{
-+ *length= ull->key_length;
-+ return ull->key;
-+}
-+
-+
-+static bool item_user_lock_inited= 0;
-+
-+void item_user_lock_init(void)
-+{
-+ pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW);
-+ hash_init(&hash_user_locks,system_charset_info,
-+ 16,0,0,(hash_get_key) ull_get_key,NULL,0);
-+ item_user_lock_inited= 1;
-+}
-+
-+void item_user_lock_free(void)
-+{
-+ if (item_user_lock_inited)
-+ {
-+ item_user_lock_inited= 0;
-+ hash_free(&hash_user_locks);
-+ pthread_mutex_destroy(&LOCK_user_locks);
-+ }
-+}
-+
-+void item_user_lock_release(User_level_lock *ull)
-+{
-+ ull->locked=0;
-+ ull->thread_id= 0;
-+ if (--ull->count)
-+ pthread_cond_signal(&ull->cond);
-+ else
-+ delete ull;
-+}
-+
-+/**
-+ Wait until we are at or past the given position in the master binlog
-+ on the slave.
-+*/
-+
-+longlong Item_master_pos_wait::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ THD* thd = current_thd;
-+ String *log_name = args[0]->val_str(&value);
-+ int event_count= 0;
-+
-+ null_value=0;
-+ if (thd->slave_thread || !log_name || !log_name->length())
-+ {
-+ null_value = 1;
-+ return 0;
-+ }
-+#ifdef HAVE_REPLICATION
-+ longlong pos = (ulong)args[1]->val_int();
-+ longlong timeout = (arg_count==3) ? args[2]->val_int() : 0 ;
-+ if ((event_count = active_mi->rli.wait_for_pos(thd, log_name, pos, timeout)) == -2)
-+ {
-+ null_value = 1;
-+ event_count=0;
-+ }
-+#endif
-+ return event_count;
-+}
-+
-+
-+/**
-+ Get a user level lock. If the thread has an old lock this is first released.
-+
-+ @retval
-+ 1 : Got lock
-+ @retval
-+ 0 : Timeout
-+ @retval
-+ NULL : Error
-+*/
-+
-+longlong Item_func_get_lock::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ longlong timeout=args[1]->val_int();
-+ struct timespec abstime;
-+ THD *thd=current_thd;
-+ User_level_lock *ull;
-+ int error;
-+ DBUG_ENTER("Item_func_get_lock::val_int");
-+
-+ /*
-+ In slave thread no need to get locks, everything is serialized. Anyway
-+ there is no way to make GET_LOCK() work on slave like it did on master
-+ (i.e. make it return exactly the same value) because we don't have the
-+ same other concurrent threads environment. No matter what we return here,
-+ it's not guaranteed to be same as on master.
-+ */
-+ if (thd->slave_thread)
-+ DBUG_RETURN(1);
-+
-+ pthread_mutex_lock(&LOCK_user_locks);
-+
-+ if (!res || !res->length())
-+ {
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ null_value=1;
-+ DBUG_RETURN(0);
-+ }
-+ DBUG_PRINT("info", ("lock %.*s, thd=%ld", res->length(), res->ptr(),
-+ (long) thd->real_id));
-+ null_value=0;
-+
-+ if (thd->ull)
-+ {
-+ item_user_lock_release(thd->ull);
-+ thd->ull=0;
-+ }
-+
-+ if (!(ull= ((User_level_lock *) hash_search(&hash_user_locks,
-+ (uchar*) res->ptr(),
-+ (size_t) res->length()))))
-+ {
-+ ull= new User_level_lock((uchar*) res->ptr(), (size_t) res->length(),
-+ thd->thread_id);
-+ if (!ull || !ull->initialized())
-+ {
-+ delete ull;
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ null_value=1; // Probably out of memory
-+ DBUG_RETURN(0);
-+ }
-+ ull->set_thread(thd);
-+ thd->ull=ull;
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ DBUG_PRINT("info", ("made new lock"));
-+ DBUG_RETURN(1); // Got new lock
-+ }
-+ ull->count++;
-+ DBUG_PRINT("info", ("ull->count=%d", ull->count));
-+
-+ /*
-+ Structure is now initialized. Try to get the lock.
-+ Set up control struct to allow others to abort locks.
-+ */
-+ thd_proc_info(thd, "User lock");
-+ thd->mysys_var->current_mutex= &LOCK_user_locks;
-+ thd->mysys_var->current_cond= &ull->cond;
-+
-+ set_timespec(abstime,timeout);
-+ error= 0;
-+ while (ull->locked && !thd->killed)
-+ {
-+ DBUG_PRINT("info", ("waiting on lock"));
-+ error= pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime);
-+ if (error == ETIMEDOUT || error == ETIME)
-+ {
-+ DBUG_PRINT("info", ("lock wait timeout"));
-+ break;
-+ }
-+ error= 0;
-+ }
-+
-+ if (ull->locked)
-+ {
-+ if (!--ull->count)
-+ {
-+ DBUG_ASSERT(0);
-+ delete ull; // Should never happen
-+ }
-+ if (!error) // Killed (thd->killed != 0)
-+ {
-+ error=1;
-+ null_value=1; // Return NULL
-+ }
-+ }
-+ else // We got the lock
-+ {
-+ ull->locked=1;
-+ ull->set_thread(thd);
-+ ull->thread_id= thd->thread_id;
-+ thd->ull=ull;
-+ error=0;
-+ DBUG_PRINT("info", ("got the lock"));
-+ }
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+
-+ pthread_mutex_lock(&thd->mysys_var->mutex);
-+ thd_proc_info(thd, 0);
-+ thd->mysys_var->current_mutex= 0;
-+ thd->mysys_var->current_cond= 0;
-+ pthread_mutex_unlock(&thd->mysys_var->mutex);
-+
-+ DBUG_RETURN(!error ? 1 : 0);
-+}
-+
-+
-+/**
-+ Release a user level lock.
-+ @return
-+ - 1 if lock released
-+ - 0 if lock wasn't held
-+ - (SQL) NULL if no such lock
-+*/
-+
-+longlong Item_func_release_lock::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ User_level_lock *ull;
-+ longlong result;
-+ THD *thd=current_thd;
-+ DBUG_ENTER("Item_func_release_lock::val_int");
-+ if (!res || !res->length())
-+ {
-+ null_value=1;
-+ DBUG_RETURN(0);
-+ }
-+ DBUG_PRINT("info", ("lock %.*s", res->length(), res->ptr()));
-+ null_value=0;
-+
-+ result=0;
-+ pthread_mutex_lock(&LOCK_user_locks);
-+ if (!(ull= ((User_level_lock*) hash_search(&hash_user_locks,
-+ (const uchar*) res->ptr(),
-+ (size_t) res->length()))))
-+ {
-+ null_value=1;
-+ }
-+ else
-+ {
-+ DBUG_PRINT("info", ("ull->locked=%d ull->thread=%lu thd=%lu",
-+ (int) ull->locked,
-+ (long)ull->thread_id,
-+ (long)thd->thread_id));
-+ if (ull->locked && current_thd->thread_id == ull->thread_id)
-+ {
-+ DBUG_PRINT("info", ("release lock"));
-+ result=1; // Release is ok
-+ item_user_lock_release(ull);
-+ thd->ull=0;
-+ }
-+ }
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ DBUG_RETURN(result);
-+}
-+
-+
-+longlong Item_func_last_insert_id::val_int()
-+{
-+ THD *thd= current_thd;
-+ DBUG_ASSERT(fixed == 1);
-+ if (arg_count)
-+ {
-+ longlong value= args[0]->val_int();
-+ null_value= args[0]->null_value;
-+ /*
-+ LAST_INSERT_ID(X) must affect the client's mysql_insert_id() as
-+ documented in the manual. We don't want to touch
-+ first_successful_insert_id_in_cur_stmt because it would make
-+ LAST_INSERT_ID(X) take precedence over an generated auto_increment
-+ value for this row.
-+ */
-+ thd->arg_of_last_insert_id_function= TRUE;
-+ thd->first_successful_insert_id_in_prev_stmt= value;
-+ return value;
-+ }
-+ return thd->read_first_successful_insert_id_in_prev_stmt();
-+}
-+
-+
-+bool Item_func_last_insert_id::fix_fields(THD *thd, Item **ref)
-+{
-+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-+ return Item_int_func::fix_fields(thd, ref);
-+}
-+
-+
-+/* This function is just used to test speed of different functions */
-+
-+longlong Item_func_benchmark::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char buff[MAX_FIELD_WIDTH];
-+ String tmp(buff,sizeof(buff), &my_charset_bin);
-+ my_decimal tmp_decimal;
-+ THD *thd=current_thd;
-+ ulonglong loop_count;
-+
-+ loop_count= (ulonglong) args[0]->val_int();
-+
-+ if (args[0]->null_value ||
-+ (!args[0]->unsigned_flag && (((longlong) loop_count) < 0)))
-+ {
-+ if (!args[0]->null_value)
-+ {
-+ char buff[22];
-+ llstr(((longlong) loop_count), buff);
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
-+ "count", buff, "benchmark");
-+ }
-+
-+ null_value= 1;
-+ return 0;
-+ }
-+
-+ null_value=0;
-+ for (ulonglong loop=0 ; loop < loop_count && !thd->killed; loop++)
-+ {
-+ switch (args[1]->result_type()) {
-+ case REAL_RESULT:
-+ (void) args[1]->val_real();
-+ break;
-+ case INT_RESULT:
-+ (void) args[1]->val_int();
-+ break;
-+ case STRING_RESULT:
-+ (void) args[1]->val_str(&tmp);
-+ break;
-+ case DECIMAL_RESULT:
-+ (void) args[1]->val_decimal(&tmp_decimal);
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ return 0;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+void Item_func_benchmark::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("benchmark("));
-+ args[0]->print(str, query_type);
-+ str->append(',');
-+ args[1]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+
-+/** This function is just used to create tests with time gaps. */
-+
-+longlong Item_func_sleep::val_int()
-+{
-+ THD *thd= current_thd;
-+ struct timespec abstime;
-+ pthread_cond_t cond;
-+ int error;
-+
-+ DBUG_ASSERT(fixed == 1);
-+
-+ double time= args[0]->val_real();
-+ /*
-+ On 64-bit OSX pthread_cond_timedwait() waits forever
-+ if passed abstime time has already been exceeded by
-+ the system time.
-+ When given a very short timeout (< 10 mcs) just return
-+ immediately.
-+ We assume that the lines between this test and the call
-+ to pthread_cond_timedwait() will be executed in less than 0.00001 sec.
-+ */
-+ if (time < 0.00001)
-+ return 0;
-+
-+ set_timespec_nsec(abstime, (ulonglong)(time * ULL(1000000000)));
-+
-+ pthread_cond_init(&cond, NULL);
-+ pthread_mutex_lock(&LOCK_user_locks);
-+
-+ thd_proc_info(thd, "User sleep");
-+ thd->mysys_var->current_mutex= &LOCK_user_locks;
-+ thd->mysys_var->current_cond= &cond;
-+
-+ error= 0;
-+ while (!thd->killed)
-+ {
-+ error= pthread_cond_timedwait(&cond, &LOCK_user_locks, &abstime);
-+ if (error == ETIMEDOUT || error == ETIME)
-+ break;
-+ error= 0;
-+ }
-+ thd_proc_info(thd, 0);
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ pthread_mutex_lock(&thd->mysys_var->mutex);
-+ thd->mysys_var->current_mutex= 0;
-+ thd->mysys_var->current_cond= 0;
-+ pthread_mutex_unlock(&thd->mysys_var->mutex);
-+
-+ pthread_cond_destroy(&cond);
-+
-+ return test(!error); // Return 1 killed
-+}
-+
-+
-+#define extra_size sizeof(double)
-+
-+static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
-+ bool create_if_not_exists)
-+{
-+ user_var_entry *entry;
-+
-+ if (!(entry = (user_var_entry*) hash_search(hash, (uchar*) name.str,
-+ name.length)) &&
-+ create_if_not_exists)
-+ {
-+ uint size=ALIGN_SIZE(sizeof(user_var_entry))+name.length+1+extra_size;
-+ if (!hash_inited(hash))
-+ return 0;
-+ if (!(entry = (user_var_entry*) my_malloc(size,MYF(MY_WME))))
-+ return 0;
-+ entry->name.str=(char*) entry+ ALIGN_SIZE(sizeof(user_var_entry))+
-+ extra_size;
-+ entry->name.length=name.length;
-+ entry->value=0;
-+ entry->length=0;
-+ entry->update_query_id=0;
-+ entry->collation.set(NULL, DERIVATION_IMPLICIT, 0);
-+ entry->unsigned_flag= 0;
-+ /*
-+ If we are here, we were called from a SET or a query which sets a
-+ variable. Imagine it is this:
-+ INSERT INTO t SELECT @a:=10, @a:=@a+1.
-+ Then when we have a Item_func_get_user_var (because of the @a+1) so we
-+ think we have to write the value of @a to the binlog. But before that,
-+ we have a Item_func_set_user_var to create @a (@a:=10), in this we mark
-+ the variable as "already logged" (line below) so that it won't be logged
-+ by Item_func_get_user_var (because that's not necessary).
-+ */
-+ entry->used_query_id=current_thd->query_id;
-+ entry->type=STRING_RESULT;
-+ memcpy(entry->name.str, name.str, name.length+1);
-+ if (my_hash_insert(hash,(uchar*) entry))
-+ {
-+ my_free((char*) entry,MYF(0));
-+ return 0;
-+ }
-+ }
-+ return entry;
-+}
-+
-+
-+void Item_func_set_user_var::cleanup()
-+{
-+ Item_func::cleanup();
-+ entry= NULL;
-+}
-+
-+
-+bool Item_func_set_user_var::set_entry(THD *thd, bool create_if_not_exists)
-+{
-+ if (entry && thd->thread_id == entry_thread_id)
-+ goto end; // update entry->update_query_id for PS
-+ if (!(entry= get_variable(&thd->user_vars, name, create_if_not_exists)))
-+ {
-+ entry_thread_id= 0;
-+ return TRUE;
-+ }
-+ entry_thread_id= thd->thread_id;
-+ /*
-+ Remember the last query which updated it, this way a query can later know
-+ if this variable is a constant item in the query (it is if update_query_id
-+ is different from query_id).
-+ */
-+end:
-+ entry->update_query_id= thd->query_id;
-+ return FALSE;
-+}
-+
-+
-+/*
-+ When a user variable is updated (in a SET command or a query like
-+ SELECT @a:= ).
-+*/
-+
-+bool Item_func_set_user_var::fix_fields(THD *thd, Item **ref)
-+{
-+ DBUG_ASSERT(fixed == 0);
-+ /* fix_fields will call Item_func_set_user_var::fix_length_and_dec */
-+ if (Item_func::fix_fields(thd, ref) || set_entry(thd, TRUE))
-+ return TRUE;
-+ /*
-+ As it is wrong and confusing to associate any
-+ character set with NULL, @a should be latin2
-+ after this query sequence:
-+
-+ SET @a=_latin2'string';
-+ SET @a=NULL;
-+
-+ I.e. the second query should not change the charset
-+ to the current default value, but should keep the
-+ original value assigned during the first query.
-+ In order to do it, we don't copy charset
-+ from the argument if the argument is NULL
-+ and the variable has previously been initialized.
-+ */
-+ null_item= (args[0]->type() == NULL_ITEM);
-+ if (!entry->collation.collation || !null_item)
-+ entry->collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
-+ collation.set(entry->collation.collation, DERIVATION_IMPLICIT);
-+ cached_result_type= args[0]->result_type();
-+ return FALSE;
-+}
-+
-+
-+void
-+Item_func_set_user_var::fix_length_and_dec()
-+{
-+ maybe_null=args[0]->maybe_null;
-+ max_length=args[0]->max_length;
-+ decimals=args[0]->decimals;
-+ unsigned_flag= args[0]->unsigned_flag;
-+ collation.set(args[0]->collation.collation, DERIVATION_IMPLICIT);
-+}
-+
-+
-+/*
-+ Mark field in read_map
-+
-+ NOTES
-+ This is used by filesort to register used fields in a a temporary
-+ column read set or to register used fields in a view
-+*/
-+
-+bool Item_func_set_user_var::register_field_in_read_map(uchar *arg)
-+{
-+ if (result_field)
-+ {
-+ TABLE *table= (TABLE *) arg;
-+ if (result_field->table == table || !table)
-+ bitmap_set_bit(result_field->table->read_set, result_field->field_index);
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Set value to user variable.
-+
-+ @param entry pointer to structure representing variable
-+ @param set_null should we set NULL value ?
-+ @param ptr pointer to buffer with new value
-+ @param length length of new value
-+ @param type type of new value
-+ @param cs charset info for new value
-+ @param dv derivation for new value
-+ @param unsigned_arg indiates if a value of type INT_RESULT is unsigned
-+
-+ @retval
-+ false success
-+ @retval
-+ true failure
-+*/
-+
-+static bool
-+update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
-+ Item_result type, CHARSET_INFO *cs, Derivation dv,
-+ bool unsigned_arg)
-+{
-+ if (set_null)
-+ {
-+ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
-+ if (entry->value && entry->value != pos)
-+ my_free(entry->value,MYF(0));
-+ entry->value= 0;
-+ entry->length= 0;
-+ }
-+ else
-+ {
-+ if (type == STRING_RESULT)
-+ length++; // Store strings with end \0
-+ if (length <= extra_size)
-+ {
-+ /* Save value in value struct */
-+ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
-+ if (entry->value != pos)
-+ {
-+ if (entry->value)
-+ my_free(entry->value,MYF(0));
-+ entry->value=pos;
-+ }
-+ }
-+ else
-+ {
-+ /* Allocate variable */
-+ if (entry->length != length)
-+ {
-+ char *pos= (char*) entry+ ALIGN_SIZE(sizeof(user_var_entry));
-+ if (entry->value == pos)
-+ entry->value=0;
-+ entry->value= (char*) my_realloc(entry->value, length,
-+ MYF(MY_ALLOW_ZERO_PTR | MY_WME));
-+ if (!entry->value)
-+ return 1;
-+ }
-+ }
-+ if (type == STRING_RESULT)
-+ {
-+ length--; // Fix length change above
-+ entry->value[length]= 0; // Store end \0
-+ }
-+ memmove(entry->value, ptr, length);
-+ if (type == DECIMAL_RESULT)
-+ ((my_decimal*)entry->value)->fix_buffer_pointer();
-+ entry->length= length;
-+ entry->collation.set(cs, dv);
-+ entry->unsigned_flag= unsigned_arg;
-+ }
-+ entry->type=type;
-+ return 0;
-+}
-+
-+
-+bool
-+Item_func_set_user_var::update_hash(void *ptr, uint length,
-+ Item_result res_type,
-+ CHARSET_INFO *cs, Derivation dv,
-+ bool unsigned_arg)
-+{
-+ /*
-+ If we set a variable explicitely to NULL then keep the old
-+ result type of the variable
-+ */
-+ if ((null_value= args[0]->null_value) && null_item)
-+ res_type= entry->type; // Don't change type of item
-+ if (::update_hash(entry, (null_value= args[0]->null_value),
-+ ptr, length, res_type, cs, dv, unsigned_arg))
-+ {
-+ current_thd->fatal_error(); // Probably end of memory
-+ null_value= 1;
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/** Get the value of a variable as a double. */
-+
-+double user_var_entry::val_real(my_bool *null_value)
-+{
-+ if ((*null_value= (value == 0)))
-+ return 0.0;
-+
-+ switch (type) {
-+ case REAL_RESULT:
-+ return *(double*) value;
-+ case INT_RESULT:
-+ return (double) *(longlong*) value;
-+ case DECIMAL_RESULT:
-+ {
-+ double result;
-+ my_decimal2double(E_DEC_FATAL_ERROR, (my_decimal *)value, &result);
-+ return result;
-+ }
-+ case STRING_RESULT:
-+ return my_atof(value); // This is null terminated
-+ case ROW_RESULT:
-+ DBUG_ASSERT(1); // Impossible
-+ break;
-+ }
-+ return 0.0; // Impossible
-+}
-+
-+
-+/** Get the value of a variable as an integer. */
-+
-+longlong user_var_entry::val_int(my_bool *null_value) const
-+{
-+ if ((*null_value= (value == 0)))
-+ return LL(0);
-+
-+ switch (type) {
-+ case REAL_RESULT:
-+ return (longlong) *(double*) value;
-+ case INT_RESULT:
-+ return *(longlong*) value;
-+ case DECIMAL_RESULT:
-+ {
-+ longlong result;
-+ my_decimal2int(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, &result);
-+ return result;
-+ }
-+ case STRING_RESULT:
-+ {
-+ int error;
-+ return my_strtoll10(value, (char**) 0, &error);// String is null terminated
-+ }
-+ case ROW_RESULT:
-+ DBUG_ASSERT(1); // Impossible
-+ break;
-+ }
-+ return LL(0); // Impossible
-+}
-+
-+
-+/** Get the value of a variable as a string. */
-+
-+String *user_var_entry::val_str(my_bool *null_value, String *str,
-+ uint decimals)
-+{
-+ if ((*null_value= (value == 0)))
-+ return (String*) 0;
-+
-+ switch (type) {
-+ case REAL_RESULT:
-+ str->set_real(*(double*) value, decimals, &my_charset_bin);
-+ break;
-+ case INT_RESULT:
-+ if (!unsigned_flag)
-+ str->set(*(longlong*) value, &my_charset_bin);
-+ else
-+ str->set(*(ulonglong*) value, &my_charset_bin);
-+ break;
-+ case DECIMAL_RESULT:
-+ my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str);
-+ break;
-+ case STRING_RESULT:
-+ if (str->copy(value, length, collation.collation))
-+ str= 0; // EOM error
-+ case ROW_RESULT:
-+ DBUG_ASSERT(1); // Impossible
-+ break;
-+ }
-+ return(str);
-+}
-+
-+/** Get the value of a variable as a decimal. */
-+
-+my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
-+{
-+ if ((*null_value= (value == 0)))
-+ return 0;
-+
-+ switch (type) {
-+ case REAL_RESULT:
-+ double2my_decimal(E_DEC_FATAL_ERROR, *(double*) value, val);
-+ break;
-+ case INT_RESULT:
-+ int2my_decimal(E_DEC_FATAL_ERROR, *(longlong*) value, 0, val);
-+ break;
-+ case DECIMAL_RESULT:
-+ my_decimal2decimal((my_decimal *) value, val);
-+ break;
-+ case STRING_RESULT:
-+ str2my_decimal(E_DEC_FATAL_ERROR, value, length, collation.collation, val);
-+ break;
-+ case ROW_RESULT:
-+ DBUG_ASSERT(1); // Impossible
-+ break;
-+ }
-+ return(val);
-+}
-+
-+/**
-+ This functions is invoked on SET \@variable or
-+ \@variable:= expression.
-+
-+ Evaluate (and check expression), store results.
-+
-+ @note
-+ For now it always return OK. All problem with value evaluating
-+ will be caught by thd->is_error() check in sql_set_variables().
-+
-+ @retval
-+ FALSE OK.
-+*/
-+
-+bool
-+Item_func_set_user_var::check(bool use_result_field)
-+{
-+ DBUG_ENTER("Item_func_set_user_var::check");
-+ if (use_result_field && !result_field)
-+ use_result_field= FALSE;
-+
-+ switch (cached_result_type) {
-+ case REAL_RESULT:
-+ {
-+ save_result.vreal= use_result_field ? result_field->val_real() :
-+ args[0]->val_real();
-+ break;
-+ }
-+ case INT_RESULT:
-+ {
-+ save_result.vint= use_result_field ? result_field->val_int() :
-+ args[0]->val_int();
-+ unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
-+ args[0]->unsigned_flag;
-+ break;
-+ }
-+ case STRING_RESULT:
-+ {
-+ save_result.vstr= use_result_field ? result_field->val_str(&value) :
-+ args[0]->val_str(&value);
-+ break;
-+ }
-+ case DECIMAL_RESULT:
-+ {
-+ save_result.vdec= use_result_field ?
-+ result_field->val_decimal(&decimal_buff) :
-+ args[0]->val_decimal(&decimal_buff);
-+ break;
-+ }
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ @brief Evaluate and store item's result.
-+ This function is invoked on "SELECT ... INTO @var ...".
-+
-+ @param item An item to get value from.
-+*/
-+
-+void Item_func_set_user_var::save_item_result(Item *item)
-+{
-+ DBUG_ENTER("Item_func_set_user_var::save_item_result");
-+
-+ switch (cached_result_type) {
-+ case REAL_RESULT:
-+ save_result.vreal= item->val_result();
-+ break;
-+ case INT_RESULT:
-+ save_result.vint= item->val_int_result();
-+ unsigned_flag= item->unsigned_flag;
-+ break;
-+ case STRING_RESULT:
-+ save_result.vstr= item->str_result(&value);
-+ break;
-+ case DECIMAL_RESULT:
-+ save_result.vdec= item->val_decimal_result(&decimal_buff);
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // Should never happen
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ This functions is invoked on
-+ SET \@variable or \@variable:= expression.
-+
-+ @note
-+ We have to store the expression as such in the variable, independent of
-+ the value method used by the user
-+
-+ @retval
-+ 0 OK
-+ @retval
-+ 1 EOM Error
-+
-+*/
-+
-+bool
-+Item_func_set_user_var::update()
-+{
-+ bool res= 0;
-+ DBUG_ENTER("Item_func_set_user_var::update");
-+
-+ switch (cached_result_type) {
-+ case REAL_RESULT:
-+ {
-+ res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
-+ REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
-+ break;
-+ }
-+ case INT_RESULT:
-+ {
-+ res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
-+ INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
-+ unsigned_flag);
-+ break;
-+ }
-+ case STRING_RESULT:
-+ {
-+ if (!save_result.vstr) // Null value
-+ res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
-+ DERIVATION_IMPLICIT, 0);
-+ else
-+ res= update_hash((void*) save_result.vstr->ptr(),
-+ save_result.vstr->length(), STRING_RESULT,
-+ save_result.vstr->charset(),
-+ DERIVATION_IMPLICIT, 0);
-+ break;
-+ }
-+ case DECIMAL_RESULT:
-+ {
-+ if (!save_result.vdec) // Null value
-+ res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
-+ DERIVATION_IMPLICIT, 0);
-+ else
-+ res= update_hash((void*) save_result.vdec,
-+ sizeof(my_decimal), DECIMAL_RESULT,
-+ &my_charset_bin, DERIVATION_IMPLICIT, 0);
-+ break;
-+ }
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be chosen
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ DBUG_RETURN(res);
-+}
-+
-+
-+double Item_func_set_user_var::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(0);
-+ update(); // Store expression
-+ return entry->val_real(&null_value);
-+}
-+
-+longlong Item_func_set_user_var::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(0);
-+ update(); // Store expression
-+ return entry->val_int(&null_value);
-+}
-+
-+String *Item_func_set_user_var::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(0);
-+ update(); // Store expression
-+ return entry->val_str(&null_value, str, decimals);
-+}
-+
-+
-+my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(0);
-+ update(); // Store expression
-+ return entry->val_decimal(&null_value, val);
-+}
-+
-+
-+double Item_func_set_user_var::val_result()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return entry->val_real(&null_value);
-+}
-+
-+longlong Item_func_set_user_var::val_int_result()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return entry->val_int(&null_value);
-+}
-+
-+bool Item_func_set_user_var::val_bool_result()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return entry->val_int(&null_value) != 0;
-+}
-+
-+String *Item_func_set_user_var::str_result(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return entry->val_str(&null_value, str, decimals);
-+}
-+
-+
-+my_decimal *Item_func_set_user_var::val_decimal_result(my_decimal *val)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return entry->val_decimal(&null_value, val);
-+}
-+
-+
-+bool Item_func_set_user_var::is_null_result()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ check(TRUE);
-+ update(); // Store expression
-+ return is_null();
-+}
-+
-+
-+void Item_func_set_user_var::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("(@"));
-+ str->append(name.str, name.length);
-+ str->append(STRING_WITH_LEN(":="));
-+ args[0]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+
-+void Item_func_set_user_var::print_as_stmt(String *str,
-+ enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("set @"));
-+ str->append(name.str, name.length);
-+ str->append(STRING_WITH_LEN(":="));
-+ args[0]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
-+{
-+ if (result_field)
-+ {
-+ check(1);
-+ update();
-+ return protocol->store(result_field);
-+ }
-+ return Item::send(protocol, str_arg);
-+}
-+
-+void Item_func_set_user_var::make_field(Send_field *tmp_field)
-+{
-+ if (result_field)
-+ {
-+ result_field->make_field(tmp_field);
-+ DBUG_ASSERT(tmp_field->table_name != 0);
-+ if (Item::name)
-+ tmp_field->col_name=Item::name; // Use user supplied name
-+ }
-+ else
-+ Item::make_field(tmp_field);
-+}
-+
-+
-+/*
-+ Save the value of a user variable into a field
-+
-+ SYNOPSIS
-+ save_in_field()
-+ field target field to save the value to
-+ no_conversion flag indicating whether conversions are allowed
-+
-+ DESCRIPTION
-+ Save the function value into a field and update the user variable
-+ accordingly. If a result field is defined and the target field doesn't
-+ coincide with it then the value from the result field will be used as
-+ the new value of the user variable.
-+
-+ The reason to have this method rather than simply using the result
-+ field in the val_xxx() methods is that the value from the result field
-+ not always can be used when the result field is defined.
-+ Let's consider the following cases:
-+ 1) when filling a tmp table the result field is defined but the value of it
-+ is undefined because it has to be produced yet. Thus we can't use it.
-+ 2) on execution of an INSERT ... SELECT statement the save_in_field()
-+ function will be called to fill the data in the new record. If the SELECT
-+ part uses a tmp table then the result field is defined and should be
-+ used in order to get the correct result.
-+
-+ The difference between the SET_USER_VAR function and regular functions
-+ like CONCAT is that the Item_func objects for the regular functions are
-+ replaced by Item_field objects after the values of these functions have
-+ been stored in a tmp table. Yet an object of the Item_field class cannot
-+ be used to update a user variable.
-+ Due to this we have to handle the result field in a special way here and
-+ in the Item_func_set_user_var::send() function.
-+
-+ RETURN VALUES
-+ FALSE Ok
-+ TRUE Error
-+*/
-+
-+int Item_func_set_user_var::save_in_field(Field *field, bool no_conversions,
-+ bool can_use_result_field)
-+{
-+ bool use_result_field= (!can_use_result_field ? 0 :
-+ (result_field && result_field != field));
-+ int error;
-+
-+ /* Update the value of the user variable */
-+ check(use_result_field);
-+ update();
-+
-+ if (result_type() == STRING_RESULT ||
-+ (result_type() == REAL_RESULT &&
-+ field->result_type() == STRING_RESULT))
-+ {
-+ String *result;
-+ CHARSET_INFO *cs= collation.collation;
-+ char buff[MAX_FIELD_WIDTH]; // Alloc buffer for small columns
-+ str_value.set_quick(buff, sizeof(buff), cs);
-+ result= entry->val_str(&null_value, &str_value, decimals);
-+
-+ if (null_value)
-+ {
-+ str_value.set_quick(0, 0, cs);
-+ return set_field_to_null_with_conversions(field, no_conversions);
-+ }
-+
-+ /* NOTE: If null_value == FALSE, "result" must be not NULL. */
-+
-+ field->set_notnull();
-+ error=field->store(result->ptr(),result->length(),cs);
-+ str_value.set_quick(0, 0, cs);
-+ }
-+ else if (result_type() == REAL_RESULT)
-+ {
-+ double nr= entry->val_real(&null_value);
-+ if (null_value)
-+ return set_field_to_null(field);
-+ field->set_notnull();
-+ error=field->store(nr);
-+ }
-+ else if (result_type() == DECIMAL_RESULT)
-+ {
-+ my_decimal decimal_value;
-+ my_decimal *val= entry->val_decimal(&null_value, &decimal_value);
-+ if (null_value)
-+ return set_field_to_null(field);
-+ field->set_notnull();
-+ error=field->store_decimal(val);
-+ }
-+ else
-+ {
-+ longlong nr= entry->val_int(&null_value);
-+ if (null_value)
-+ return set_field_to_null_with_conversions(field, no_conversions);
-+ field->set_notnull();
-+ error=field->store(nr, unsigned_flag);
-+ }
-+ return error;
-+}
-+
-+
-+String *
-+Item_func_get_user_var::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ DBUG_ENTER("Item_func_get_user_var::val_str");
-+ if (!var_entry)
-+ DBUG_RETURN((String*) 0); // No such variable
-+ DBUG_RETURN(var_entry->val_str(&null_value, str, decimals));
-+}
-+
-+
-+double Item_func_get_user_var::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (!var_entry)
-+ return 0.0; // No such variable
-+ return (var_entry->val_real(&null_value));
-+}
-+
-+
-+my_decimal *Item_func_get_user_var::val_decimal(my_decimal *dec)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (!var_entry)
-+ return 0;
-+ return var_entry->val_decimal(&null_value, dec);
-+}
-+
-+
-+longlong Item_func_get_user_var::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (!var_entry)
-+ return LL(0); // No such variable
-+ return (var_entry->val_int(&null_value));
-+}
-+
-+
-+/**
-+ Get variable by name and, if necessary, put the record of variable
-+ use into the binary log.
-+
-+ When a user variable is invoked from an update query (INSERT, UPDATE etc),
-+ stores this variable and its value in thd->user_var_events, so that it can be
-+ written to the binlog (will be written just before the query is written, see
-+ log.cc).
-+
-+ @param thd Current thread
-+ @param name Variable name
-+ @param[out] out_entry variable structure or NULL. The pointer is set
-+ regardless of whether function succeeded or not.
-+
-+ @retval
-+ 0 OK
-+ @retval
-+ 1 Failed to put appropriate record into binary log
-+
-+*/
-+
-+int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
-+ LEX_STRING &name, user_var_entry **out_entry)
-+{
-+ BINLOG_USER_VAR_EVENT *user_var_event;
-+ user_var_entry *var_entry;
-+ var_entry= get_variable(&thd->user_vars, name, 0);
-+
-+ /*
-+ Any reference to user-defined variable which is done from stored
-+ function or trigger affects their execution and the execution of the
-+ calling statement. We must log all such variables even if they are
-+ not involved in table-updating statements.
-+ */
-+ if (!(opt_bin_log &&
-+ (is_update_query(sql_command) || thd->in_sub_stmt)))
-+ {
-+ *out_entry= var_entry;
-+ return 0;
-+ }
-+
-+ if (!var_entry)
-+ {
-+ /*
-+ If the variable does not exist, it's NULL, but we want to create it so
-+ that it gets into the binlog (if it didn't, the slave could be
-+ influenced by a variable of the same name previously set by another
-+ thread).
-+ We create it like if it had been explicitly set with SET before.
-+ The 'new' mimics what sql_yacc.yy does when 'SET @a=10;'.
-+ sql_set_variables() is what is called from 'case SQLCOM_SET_OPTION'
-+ in dispatch_command()). Instead of building a one-element list to pass to
-+ sql_set_variables(), we could instead manually call check() and update();
-+ this would save memory and time; but calling sql_set_variables() makes
-+ one unique place to maintain (sql_set_variables()).
-+
-+ Manipulation with lex is necessary since free_underlaid_joins
-+ is going to release memory belonging to the main query.
-+ */
-+
-+ List<set_var_base> tmp_var_list;
-+ LEX *sav_lex= thd->lex, lex_tmp;
-+ thd->lex= &lex_tmp;
-+ lex_start(thd);
-+ tmp_var_list.push_back(new set_var_user(new Item_func_set_user_var(name,
-+ new Item_null())));
-+ /* Create the variable */
-+ if (sql_set_variables(thd, &tmp_var_list))
-+ {
-+ thd->lex= sav_lex;
-+ goto err;
-+ }
-+ thd->lex= sav_lex;
-+ if (!(var_entry= get_variable(&thd->user_vars, name, 0)))
-+ goto err;
-+ }
-+ else if (var_entry->used_query_id == thd->query_id ||
-+ mysql_bin_log.is_query_in_union(thd, var_entry->used_query_id))
-+ {
-+ /*
-+ If this variable was already stored in user_var_events by this query
-+ (because it's used in more than one place in the query), don't store
-+ it.
-+ */
-+ *out_entry= var_entry;
-+ return 0;
-+ }
-+
-+ uint size;
-+ /*
-+ First we need to store value of var_entry, when the next situation
-+ appears:
-+ > set @a:=1;
-+ > insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
-+ We have to write to binlog value @a= 1.
-+
-+ We allocate the user_var_event on user_var_events_alloc pool, not on
-+ the this-statement-execution pool because in SPs user_var_event objects
-+ may need to be valid after current [SP] statement execution pool is
-+ destroyed.
-+ */
-+ size= ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT)) + var_entry->length;
-+ if (!(user_var_event= (BINLOG_USER_VAR_EVENT *)
-+ alloc_root(thd->user_var_events_alloc, size)))
-+ goto err;
-+
-+ user_var_event->value= (char*) user_var_event +
-+ ALIGN_SIZE(sizeof(BINLOG_USER_VAR_EVENT));
-+ user_var_event->user_var_event= var_entry;
-+ user_var_event->type= var_entry->type;
-+ user_var_event->charset_number= var_entry->collation.collation->number;
-+ if (!var_entry->value)
-+ {
-+ /* NULL value*/
-+ user_var_event->length= 0;
-+ user_var_event->value= 0;
-+ }
-+ else
-+ {
-+ user_var_event->length= var_entry->length;
-+ memcpy(user_var_event->value, var_entry->value,
-+ var_entry->length);
-+ }
-+ /* Mark that this variable has been used by this query */
-+ var_entry->used_query_id= thd->query_id;
-+ if (insert_dynamic(&thd->user_var_events, (uchar*) &user_var_event))
-+ goto err;
-+
-+ *out_entry= var_entry;
-+ return 0;
-+
-+err:
-+ *out_entry= var_entry;
-+ return 1;
-+}
-+
-+void Item_func_get_user_var::fix_length_and_dec()
-+{
-+ THD *thd=current_thd;
-+ int error;
-+ maybe_null=1;
-+ decimals=NOT_FIXED_DEC;
-+ max_length=MAX_BLOB_WIDTH;
-+
-+ error= get_var_with_binlog(thd, thd->lex->sql_command, name, &var_entry);
-+
-+ /*
-+ If the variable didn't exist it has been created as a STRING-type.
-+ 'var_entry' is NULL only if there occured an error during the call to
-+ get_var_with_binlog.
-+ */
-+ if (var_entry)
-+ {
-+ m_cached_result_type= var_entry->type;
-+ unsigned_flag= var_entry->unsigned_flag;
-+ max_length= var_entry->length;
-+
-+ collation.set(var_entry->collation);
-+ switch(m_cached_result_type) {
-+ case REAL_RESULT:
-+ max_length= DBL_DIG + 8;
-+ break;
-+ case INT_RESULT:
-+ max_length= MAX_BIGINT_WIDTH;
-+ decimals=0;
-+ break;
-+ case STRING_RESULT:
-+ max_length= MAX_BLOB_WIDTH - 1;
-+ break;
-+ case DECIMAL_RESULT:
-+ max_length= DECIMAL_MAX_STR_LENGTH;
-+ decimals= DECIMAL_MAX_SCALE;
-+ break;
-+ case ROW_RESULT: // Keep compiler happy
-+ default:
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ }
-+ else
-+ {
-+ collation.set(&my_charset_bin, DERIVATION_IMPLICIT);
-+ null_value= 1;
-+ m_cached_result_type= STRING_RESULT;
-+ max_length= MAX_BLOB_WIDTH;
-+ }
-+
-+ if (error)
-+ thd->fatal_error();
-+
-+ return;
-+}
-+
-+
-+bool Item_func_get_user_var::const_item() const
-+{
-+ return (!var_entry || current_thd->query_id != var_entry->update_query_id);
-+}
-+
-+
-+enum Item_result Item_func_get_user_var::result_type() const
-+{
-+ return m_cached_result_type;
-+}
-+
-+
-+void Item_func_get_user_var::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("(@"));
-+ str->append(name.str,name.length);
-+ str->append(')');
-+}
-+
-+
-+bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
-+{
-+ /* Assume we don't have rtti */
-+ if (this == item)
-+ return 1; // Same item is same.
-+ /* Check if other type is also a get_user_var() object */
-+ if (item->type() != FUNC_ITEM ||
-+ ((Item_func*) item)->functype() != functype())
-+ return 0;
-+ Item_func_get_user_var *other=(Item_func_get_user_var*) item;
-+ return (name.length == other->name.length &&
-+ !memcmp(name.str, other->name.str, name.length));
-+}
-+
-+
-+bool Item_func_get_user_var::set_value(THD *thd,
-+ sp_rcontext * /*ctx*/, Item **it)
-+{
-+ Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it);
-+ /*
-+ Item_func_set_user_var is not fixed after construction, call
-+ fix_fields().
-+ */
-+ return (!suv || suv->fix_fields(thd, it) || suv->check(0) || suv->update());
-+}
-+
-+
-+bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
-+{
-+ DBUG_ASSERT(fixed == 0);
-+ DBUG_ASSERT(thd->lex->exchange);
-+ if (Item::fix_fields(thd, ref) ||
-+ !(entry= get_variable(&thd->user_vars, name, 1)))
-+ return TRUE;
-+ entry->type= STRING_RESULT;
-+ /*
-+ Let us set the same collation which is used for loading
-+ of fields in LOAD DATA INFILE.
-+ (Since Item_user_var_as_out_param is used only there).
-+ */
-+ entry->collation.set(thd->lex->exchange->cs ?
-+ thd->lex->exchange->cs :
-+ thd->variables.collation_database);
-+ entry->update_query_id= thd->query_id;
-+ return FALSE;
-+}
-+
-+
-+void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs)
-+{
-+ if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs,
-+ DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
-+ current_thd->fatal_error(); // Probably end of memory
-+}
-+
-+
-+void Item_user_var_as_out_param::set_value(const char *str, uint length,
-+ CHARSET_INFO* cs)
-+{
-+ if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs,
-+ DERIVATION_IMPLICIT, 0 /* unsigned_arg */))
-+ current_thd->fatal_error(); // Probably end of memory
-+}
-+
-+
-+double Item_user_var_as_out_param::val_real()
-+{
-+ DBUG_ASSERT(0);
-+ return 0.0;
-+}
-+
-+
-+longlong Item_user_var_as_out_param::val_int()
-+{
-+ DBUG_ASSERT(0);
-+ return 0;
-+}
-+
-+
-+String* Item_user_var_as_out_param::val_str(String *str)
-+{
-+ DBUG_ASSERT(0);
-+ return 0;
-+}
-+
-+
-+my_decimal* Item_user_var_as_out_param::val_decimal(my_decimal *decimal_buffer)
-+{
-+ DBUG_ASSERT(0);
-+ return 0;
-+}
-+
-+
-+void Item_user_var_as_out_param::print(String *str, enum_query_type query_type)
-+{
-+ str->append('@');
-+ str->append(name.str,name.length);
-+}
-+
-+
-+Item_func_get_system_var::
-+Item_func_get_system_var(sys_var *var_arg, enum_var_type var_type_arg,
-+ LEX_STRING *component_arg, const char *name_arg,
-+ size_t name_len_arg)
-+ :var(var_arg), var_type(var_type_arg), orig_var_type(var_type_arg),
-+ component(*component_arg), cache_present(0)
-+{
-+ /* set_name() will allocate the name */
-+ set_name(name_arg, (uint) name_len_arg, system_charset_info);
-+}
-+
-+
-+bool Item_func_get_system_var::is_written_to_binlog()
-+{
-+ return var->is_written_to_binlog(var_type);
-+}
-+
-+
-+void Item_func_get_system_var::update_null_value()
-+{
-+ THD *thd= current_thd;
-+ int save_no_errors= thd->no_errors;
-+ thd->no_errors= TRUE;
-+ Item::update_null_value();
-+ thd->no_errors= save_no_errors;
-+}
-+
-+
-+void Item_func_get_system_var::fix_length_and_dec()
-+{
-+ char *cptr;
-+ maybe_null= TRUE;
-+ max_length= 0;
-+
-+ if (var->check_type(var_type))
-+ {
-+ if (var_type != OPT_DEFAULT)
-+ {
-+ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0),
-+ var->name, var_type == OPT_GLOBAL ? "SESSION" : "GLOBAL");
-+ return;
-+ }
-+ /* As there was no local variable, return the global value */
-+ var_type= OPT_GLOBAL;
-+ }
-+
-+ switch (var->show_type())
-+ {
-+ case SHOW_LONG:
-+ case SHOW_INT:
-+ case SHOW_HA_ROWS:
-+ unsigned_flag= TRUE;
-+ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
-+ decimals=0;
-+ break;
-+ case SHOW_LONGLONG:
-+ unsigned_flag= TRUE;
-+ max_length= MY_INT64_NUM_DECIMAL_DIGITS;
-+ decimals=0;
-+ break;
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ cptr= var->show_type() == SHOW_CHAR_PTR ?
-+ *(char**) var->value_ptr(current_thd, var_type, &component) :
-+ (char*) var->value_ptr(current_thd, var_type, &component);
-+ if (cptr)
-+ max_length= strlen(cptr) * system_charset_info->mbmaxlen;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ collation.set(system_charset_info, DERIVATION_SYSCONST);
-+ decimals=NOT_FIXED_DEC;
-+ break;
-+ case SHOW_BOOL:
-+ case SHOW_MY_BOOL:
-+ unsigned_flag= FALSE;
-+ max_length= 1;
-+ decimals=0;
-+ break;
-+ case SHOW_DOUBLE:
-+ unsigned_flag= FALSE;
-+ decimals= 6;
-+ max_length= DBL_DIG + 6;
-+ break;
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ break;
-+ }
-+}
-+
-+
-+void Item_func_get_system_var::print(String *str, enum_query_type query_type)
-+{
-+ str->append(name, name_length);
-+}
-+
-+
-+enum Item_result Item_func_get_system_var::result_type() const
-+{
-+ switch (var->show_type())
-+ {
-+ case SHOW_BOOL:
-+ case SHOW_MY_BOOL:
-+ case SHOW_INT:
-+ case SHOW_LONG:
-+ case SHOW_LONGLONG:
-+ case SHOW_HA_ROWS:
-+ return INT_RESULT;
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ return STRING_RESULT;
-+ case SHOW_DOUBLE:
-+ return REAL_RESULT;
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ return STRING_RESULT; // keep the compiler happy
-+ }
-+}
-+
-+
-+enum_field_types Item_func_get_system_var::field_type() const
-+{
-+ switch (var->show_type())
-+ {
-+ case SHOW_BOOL:
-+ case SHOW_MY_BOOL:
-+ case SHOW_INT:
-+ case SHOW_LONG:
-+ case SHOW_LONGLONG:
-+ case SHOW_HA_ROWS:
-+ return MYSQL_TYPE_LONGLONG;
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ return MYSQL_TYPE_VARCHAR;
-+ case SHOW_DOUBLE:
-+ return MYSQL_TYPE_DOUBLE;
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ return MYSQL_TYPE_VARCHAR; // keep the compiler happy
-+ }
-+}
-+
-+
-+/*
-+ Uses var, var_type, component, cache_present, used_query_id, thd,
-+ cached_llval, null_value, cached_null_value
-+*/
-+#define get_sys_var_safe(type) \
-+do { \
-+ type value; \
-+ pthread_mutex_lock(&LOCK_global_system_variables); \
-+ value= *(type*) var->value_ptr(thd, var_type, &component); \
-+ pthread_mutex_unlock(&LOCK_global_system_variables); \
-+ cache_present |= GET_SYS_VAR_CACHE_LONG; \
-+ used_query_id= thd->query_id; \
-+ cached_llval= null_value ? 0 : (longlong) value; \
-+ cached_null_value= null_value; \
-+ return cached_llval; \
-+} while (0)
-+
-+
-+longlong Item_func_get_system_var::val_int()
-+{
-+ THD *thd= current_thd;
-+
-+ if (cache_present && thd->query_id == used_query_id)
-+ {
-+ if (cache_present & GET_SYS_VAR_CACHE_LONG)
-+ {
-+ null_value= cached_null_value;
-+ return cached_llval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
-+ {
-+ null_value= cached_null_value;
-+ cached_llval= (longlong) cached_dval;
-+ cache_present|= GET_SYS_VAR_CACHE_LONG;
-+ return cached_llval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_STRING)
-+ {
-+ null_value= cached_null_value;
-+ if (!null_value)
-+ cached_llval= longlong_from_string_with_check (cached_strval.charset(),
-+ cached_strval.c_ptr(),
-+ cached_strval.c_ptr() +
-+ cached_strval.length());
-+ else
-+ cached_llval= 0;
-+ cache_present|= GET_SYS_VAR_CACHE_LONG;
-+ return cached_llval;
-+ }
-+ }
-+
-+ switch (var->show_type())
-+ {
-+ case SHOW_INT: get_sys_var_safe (uint);
-+ case SHOW_LONG: get_sys_var_safe (ulong);
-+ case SHOW_LONGLONG: get_sys_var_safe (ulonglong);
-+ case SHOW_HA_ROWS: get_sys_var_safe (ha_rows);
-+ case SHOW_BOOL: get_sys_var_safe (bool);
-+ case SHOW_MY_BOOL: get_sys_var_safe (my_bool);
-+ case SHOW_DOUBLE:
-+ {
-+ double dval= val_real();
-+
-+ used_query_id= thd->query_id;
-+ cached_llval= (longlong) dval;
-+ cache_present|= GET_SYS_VAR_CACHE_LONG;
-+ return cached_llval;
-+ }
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ {
-+ String *str_val= val_str(NULL);
-+
-+ if (str_val && str_val->length())
-+ cached_llval= longlong_from_string_with_check (system_charset_info,
-+ str_val->c_ptr(),
-+ str_val->c_ptr() +
-+ str_val->length());
-+ else
-+ {
-+ null_value= TRUE;
-+ cached_llval= 0;
-+ }
-+
-+ cache_present|= GET_SYS_VAR_CACHE_LONG;
-+ return cached_llval;
-+ }
-+
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ return 0; // keep the compiler happy
-+ }
-+}
-+
-+
-+String* Item_func_get_system_var::val_str(String* str)
-+{
-+ THD *thd= current_thd;
-+
-+ if (cache_present && thd->query_id == used_query_id)
-+ {
-+ if (cache_present & GET_SYS_VAR_CACHE_STRING)
-+ {
-+ null_value= cached_null_value;
-+ return null_value ? NULL : &cached_strval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_LONG)
-+ {
-+ null_value= cached_null_value;
-+ if (!null_value)
-+ cached_strval.set (cached_llval, collation.collation);
-+ cache_present|= GET_SYS_VAR_CACHE_STRING;
-+ return null_value ? NULL : &cached_strval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
-+ {
-+ null_value= cached_null_value;
-+ if (!null_value)
-+ cached_strval.set_real (cached_dval, decimals, collation.collation);
-+ cache_present|= GET_SYS_VAR_CACHE_STRING;
-+ return null_value ? NULL : &cached_strval;
-+ }
-+ }
-+
-+ str= &cached_strval;
-+ switch (var->show_type())
-+ {
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ {
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ char *cptr= var->show_type() == SHOW_CHAR_PTR ?
-+ *(char**) var->value_ptr(thd, var_type, &component) :
-+ (char*) var->value_ptr(thd, var_type, &component);
-+ if (cptr)
-+ {
-+ if (str->copy(cptr, strlen(cptr), collation.collation))
-+ {
-+ null_value= TRUE;
-+ str= NULL;
-+ }
-+ }
-+ else
-+ {
-+ null_value= TRUE;
-+ str= NULL;
-+ }
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ break;
-+ }
-+
-+ case SHOW_INT:
-+ case SHOW_LONG:
-+ case SHOW_LONGLONG:
-+ case SHOW_HA_ROWS:
-+ case SHOW_BOOL:
-+ case SHOW_MY_BOOL:
-+ str->set (val_int(), collation.collation);
-+ break;
-+ case SHOW_DOUBLE:
-+ str->set_real (val_real(), decimals, collation.collation);
-+ break;
-+
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ str= NULL;
-+ break;
-+ }
-+
-+ cache_present|= GET_SYS_VAR_CACHE_STRING;
-+ used_query_id= thd->query_id;
-+ cached_null_value= null_value;
-+ return str;
-+}
-+
-+
-+double Item_func_get_system_var::val_real()
-+{
-+ THD *thd= current_thd;
-+
-+ if (cache_present && thd->query_id == used_query_id)
-+ {
-+ if (cache_present & GET_SYS_VAR_CACHE_DOUBLE)
-+ {
-+ null_value= cached_null_value;
-+ return cached_dval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_LONG)
-+ {
-+ null_value= cached_null_value;
-+ cached_dval= (double)cached_llval;
-+ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
-+ return cached_dval;
-+ }
-+ else if (cache_present & GET_SYS_VAR_CACHE_STRING)
-+ {
-+ null_value= cached_null_value;
-+ if (!null_value)
-+ cached_dval= double_from_string_with_check (cached_strval.charset(),
-+ cached_strval.c_ptr(),
-+ cached_strval.c_ptr() +
-+ cached_strval.length());
-+ else
-+ cached_dval= 0;
-+ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
-+ return cached_dval;
-+ }
-+ }
-+
-+ switch (var->show_type())
-+ {
-+ case SHOW_DOUBLE:
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ cached_dval= *(double*) var->value_ptr(thd, var_type, &component);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ used_query_id= thd->query_id;
-+ cached_null_value= null_value;
-+ if (null_value)
-+ cached_dval= 0;
-+ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
-+ return cached_dval;
-+ case SHOW_CHAR:
-+ case SHOW_CHAR_PTR:
-+ {
-+ char *cptr;
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ cptr= var->show_type() == SHOW_CHAR ?
-+ (char*) var->value_ptr(thd, var_type, &component) :
-+ *(char**) var->value_ptr(thd, var_type, &component);
-+ if (cptr)
-+ cached_dval= double_from_string_with_check (system_charset_info,
-+ cptr, cptr + strlen (cptr));
-+ else
-+ {
-+ null_value= TRUE;
-+ cached_dval= 0;
-+ }
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ used_query_id= thd->query_id;
-+ cached_null_value= null_value;
-+ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
-+ return cached_dval;
-+ }
-+ case SHOW_INT:
-+ case SHOW_LONG:
-+ case SHOW_LONGLONG:
-+ case SHOW_HA_ROWS:
-+ case SHOW_BOOL:
-+ case SHOW_MY_BOOL:
-+ cached_dval= (double) val_int();
-+ cache_present|= GET_SYS_VAR_CACHE_DOUBLE;
-+ used_query_id= thd->query_id;
-+ cached_null_value= null_value;
-+ return cached_dval;
-+ default:
-+ my_error(ER_VAR_CANT_BE_READ, MYF(0), var->name);
-+ return 0;
-+ }
-+}
-+
-+
-+bool Item_func_get_system_var::eq(const Item *item, bool binary_cmp) const
-+{
-+ /* Assume we don't have rtti */
-+ if (this == item)
-+ return 1; // Same item is same.
-+ /* Check if other type is also a get_user_var() object */
-+ if (item->type() != FUNC_ITEM ||
-+ ((Item_func*) item)->functype() != functype())
-+ return 0;
-+ Item_func_get_system_var *other=(Item_func_get_system_var*) item;
-+ return (var == other->var && var_type == other->var_type);
-+}
-+
-+
-+void Item_func_get_system_var::cleanup()
-+{
-+ Item_func::cleanup();
-+ cache_present= 0;
-+ var_type= orig_var_type;
-+ cached_strval.free();
-+}
-+
-+
-+longlong Item_func_inet_aton::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint byte_result = 0;
-+ ulonglong result = 0; // We are ready for 64 bit addresses
-+ const char *p,* end;
-+ char c = '.'; // we mark c to indicate invalid IP in case length is 0
-+ char buff[36];
-+ int dot_count= 0;
-+
-+ String *s,tmp(buff,sizeof(buff),&my_charset_bin);
-+ if (!(s = args[0]->val_str(&tmp))) // If null value
-+ goto err;
-+ null_value=0;
-+
-+ end= (p = s->ptr()) + s->length();
-+ while (p < end)
-+ {
-+ c = *p++;
-+ int digit = (int) (c - '0'); // Assume ascii
-+ if (digit >= 0 && digit <= 9)
-+ {
-+ if ((byte_result = byte_result * 10 + digit) > 255)
-+ goto err; // Wrong address
-+ }
-+ else if (c == '.')
-+ {
-+ dot_count++;
-+ result= (result << 8) + (ulonglong) byte_result;
-+ byte_result = 0;
-+ }
-+ else
-+ goto err; // Invalid character
-+ }
-+ if (c != '.') // IP number can't end on '.'
-+ {
-+ /*
-+ Handle short-forms addresses according to standard. Examples:
-+ 127 -> 0.0.0.127
-+ 127.1 -> 127.0.0.1
-+ 127.2.1 -> 127.2.0.1
-+ */
-+ switch (dot_count) {
-+ case 1: result<<= 8; /* Fall through */
-+ case 2: result<<= 8; /* Fall through */
-+ }
-+ return (result << 8) + (ulonglong) byte_result;
-+ }
-+
-+err:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_match::init_search(bool no_order)
-+{
-+ DBUG_ENTER("Item_func_match::init_search");
-+
-+ /* Check if init_search() has been called before */
-+ if (ft_handler)
-+ {
-+ /*
-+ We should reset ft_handler as it is cleaned up
-+ on destruction of FT_SELECT object
-+ (necessary in case of re-execution of subquery).
-+ TODO: FT_SELECT should not clean up ft_handler.
-+ */
-+ if (join_key)
-+ table->file->ft_handler= ft_handler;
-+ DBUG_VOID_RETURN;
-+ }
-+
-+ if (key == NO_SUCH_KEY)
-+ {
-+ List<Item> fields;
-+ fields.push_back(new Item_string(" ",1, cmp_collation.collation));
-+ for (uint i=1; i < arg_count; i++)
-+ fields.push_back(args[i]);
-+ concat_ws=new Item_func_concat_ws(fields);
-+ /*
-+ Above function used only to get value and do not need fix_fields for it:
-+ Item_string - basic constant
-+ fields - fix_fields() was already called for this arguments
-+ Item_func_concat_ws - do not need fix_fields() to produce value
-+ */
-+ concat_ws->quick_fix_field();
-+ }
-+
-+ if (master)
-+ {
-+ join_key=master->join_key=join_key|master->join_key;
-+ master->init_search(no_order);
-+ ft_handler=master->ft_handler;
-+ join_key=master->join_key;
-+ DBUG_VOID_RETURN;
-+ }
-+
-+ String *ft_tmp= 0;
-+
-+ // MATCH ... AGAINST (NULL) is meaningless, but possible
-+ if (!(ft_tmp=key_item()->val_str(&value)))
-+ {
-+ ft_tmp= &value;
-+ value.set("",0,cmp_collation.collation);
-+ }
-+
-+ if (ft_tmp->charset() != cmp_collation.collation)
-+ {
-+ uint dummy_errors;
-+ search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
-+ cmp_collation.collation, &dummy_errors);
-+ ft_tmp= &search_value;
-+ }
-+
-+ if (join_key && !no_order)
-+ flags|=FT_SORTED;
-+ ft_handler=table->file->ft_init_ext(flags, key, ft_tmp);
-+
-+ if (join_key)
-+ table->file->ft_handler=ft_handler;
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+bool Item_func_match::fix_fields(THD *thd, Item **ref)
-+{
-+ DBUG_ASSERT(fixed == 0);
-+ Item *UNINIT_VAR(item); // Safe as arg_count is > 1
-+
-+ maybe_null=1;
-+ join_key=0;
-+
-+ /*
-+ const_item is assumed in quite a bit of places, so it would be difficult
-+ to remove; If it would ever to be removed, this should include
-+ modifications to find_best and auto_close as complement to auto_init code
-+ above.
-+ */
-+ if (Item_func::fix_fields(thd, ref) ||
-+ !args[0]->const_during_execution())
-+ {
-+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
-+ return TRUE;
-+ }
-+
-+ const_item_cache=0;
-+ for (uint i=1 ; i < arg_count ; i++)
-+ {
-+ item=args[i];
-+ if (item->type() == Item::REF_ITEM)
-+ args[i]= item= *((Item_ref *)item)->ref;
-+ if (item->type() != Item::FIELD_ITEM)
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "AGAINST");
-+ return TRUE;
-+ }
-+ }
-+ /*
-+ Check that all columns come from the same table.
-+ We've already checked that columns in MATCH are fields so
-+ PARAM_TABLE_BIT can only appear from AGAINST argument.
-+ */
-+ if ((used_tables_cache & ~PARAM_TABLE_BIT) != item->used_tables())
-+ key=NO_SUCH_KEY;
-+
-+ if (key == NO_SUCH_KEY && !(flags & FT_BOOL))
-+ {
-+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"MATCH");
-+ return TRUE;
-+ }
-+ table=((Item_field *)item)->field->table;
-+ if (!(table->file->ha_table_flags() & HA_CAN_FULLTEXT))
-+ {
-+ my_error(ER_TABLE_CANT_HANDLE_FT, MYF(0));
-+ return 1;
-+ }
-+ table->fulltext_searched=1;
-+ return agg_arg_collations_for_comparison(cmp_collation,
-+ args+1, arg_count-1, 0);
-+}
-+
-+bool Item_func_match::fix_index()
-+{
-+ Item_field *item;
-+ uint ft_to_key[MAX_KEY], ft_cnt[MAX_KEY], fts=0, keynr;
-+ uint max_cnt=0, mkeys=0, i;
-+
-+ if (key == NO_SUCH_KEY)
-+ return 0;
-+
-+ if (!table)
-+ goto err;
-+
-+ for (keynr=0 ; keynr < table->s->keys ; keynr++)
-+ {
-+ if ((table->key_info[keynr].flags & HA_FULLTEXT) &&
-+ (flags & FT_BOOL ? table->keys_in_use_for_query.is_set(keynr) :
-+ table->s->keys_in_use.is_set(keynr)))
-+
-+ {
-+ ft_to_key[fts]=keynr;
-+ ft_cnt[fts]=0;
-+ fts++;
-+ }
-+ }
-+
-+ if (!fts)
-+ goto err;
-+
-+ for (i=1; i < arg_count; i++)
-+ {
-+ item=(Item_field*)args[i];
-+ for (keynr=0 ; keynr < fts ; keynr++)
-+ {
-+ KEY *ft_key=&table->key_info[ft_to_key[keynr]];
-+ uint key_parts=ft_key->key_parts;
-+
-+ for (uint part=0 ; part < key_parts ; part++)
-+ {
-+ if (item->field->eq(ft_key->key_part[part].field))
-+ ft_cnt[keynr]++;
-+ }
-+ }
-+ }
-+
-+ for (keynr=0 ; keynr < fts ; keynr++)
-+ {
-+ if (ft_cnt[keynr] > max_cnt)
-+ {
-+ mkeys=0;
-+ max_cnt=ft_cnt[mkeys]=ft_cnt[keynr];
-+ ft_to_key[mkeys]=ft_to_key[keynr];
-+ continue;
-+ }
-+ if (max_cnt && ft_cnt[keynr] == max_cnt)
-+ {
-+ mkeys++;
-+ ft_cnt[mkeys]=ft_cnt[keynr];
-+ ft_to_key[mkeys]=ft_to_key[keynr];
-+ continue;
-+ }
-+ }
-+
-+ for (keynr=0 ; keynr <= mkeys ; keynr++)
-+ {
-+ // partial keys doesn't work
-+ if (max_cnt < arg_count-1 ||
-+ max_cnt < table->key_info[ft_to_key[keynr]].key_parts)
-+ continue;
-+
-+ key=ft_to_key[keynr];
-+
-+ return 0;
-+ }
-+
-+err:
-+ if (flags & FT_BOOL)
-+ {
-+ key=NO_SUCH_KEY;
-+ return 0;
-+ }
-+ my_message(ER_FT_MATCHING_KEY_NOT_FOUND,
-+ ER(ER_FT_MATCHING_KEY_NOT_FOUND), MYF(0));
-+ return 1;
-+}
-+
-+
-+bool Item_func_match::eq(const Item *item, bool binary_cmp) const
-+{
-+ if (item->type() != FUNC_ITEM ||
-+ ((Item_func*)item)->functype() != FT_FUNC ||
-+ flags != ((Item_func_match*)item)->flags)
-+ return 0;
-+
-+ Item_func_match *ifm=(Item_func_match*) item;
-+
-+ if (key == ifm->key && table == ifm->table &&
-+ key_item()->eq(ifm->key_item(), binary_cmp))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+
-+double Item_func_match::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ DBUG_ENTER("Item_func_match::val");
-+ if (ft_handler == NULL)
-+ DBUG_RETURN(-1.0);
-+
-+ if (key != NO_SUCH_KEY && table->null_row) /* NULL row from an outer join */
-+ DBUG_RETURN(0.0);
-+
-+ if (join_key)
-+ {
-+ if (table->file->ft_handler)
-+ DBUG_RETURN(ft_handler->please->get_relevance(ft_handler));
-+ join_key=0;
-+ }
-+
-+ if (key == NO_SUCH_KEY)
-+ {
-+ String *a= concat_ws->val_str(&value);
-+ if ((null_value= (a == 0)) || !a->length())
-+ DBUG_RETURN(0);
-+ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
-+ (uchar *)a->ptr(), a->length()));
-+ }
-+ DBUG_RETURN(ft_handler->please->find_relevance(ft_handler,
-+ table->record[0], 0));
-+}
-+
-+void Item_func_match::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("(match "));
-+ print_args(str, 1, query_type);
-+ str->append(STRING_WITH_LEN(" against ("));
-+ args[0]->print(str, query_type);
-+ if (flags & FT_BOOL)
-+ str->append(STRING_WITH_LEN(" in boolean mode"));
-+ else if (flags & FT_EXPAND)
-+ str->append(STRING_WITH_LEN(" with query expansion"));
-+ str->append(STRING_WITH_LEN("))"));
-+}
-+
-+longlong Item_func_bit_xor::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ ulonglong arg1= (ulonglong) args[0]->val_int();
-+ ulonglong arg2= (ulonglong) args[1]->val_int();
-+ if ((null_value= (args[0]->null_value || args[1]->null_value)))
-+ return 0;
-+ return (longlong) (arg1 ^ arg2);
-+}
-+
-+
-+/***************************************************************************
-+ System variables
-+****************************************************************************/
-+
-+/**
-+ Return value of an system variable base[.name] as a constant item.
-+
-+ @param thd Thread handler
-+ @param var_type global / session
-+ @param name Name of base or system variable
-+ @param component Component.
-+
-+ @note
-+ If component.str = 0 then the variable name is in 'name'
-+
-+ @return
-+ - 0 : error
-+ - # : constant item
-+*/
-+
-+
-+Item *get_system_var(THD *thd, enum_var_type var_type, LEX_STRING name,
-+ LEX_STRING component)
-+{
-+ sys_var *var;
-+ LEX_STRING *base_name, *component_name;
-+
-+ if (component.str)
-+ {
-+ base_name= &component;
-+ component_name= &name;
-+ }
-+ else
-+ {
-+ base_name= &name;
-+ component_name= &component; // Empty string
-+ }
-+
-+ if (!(var= find_sys_var(thd, base_name->str, base_name->length)))
-+ return 0;
-+ if (component.str)
-+ {
-+ if (!var->is_struct())
-+ {
-+ my_error(ER_VARIABLE_IS_NOT_STRUCT, MYF(0), base_name->str);
-+ return 0;
-+ }
-+ }
-+ thd->lex->uncacheable(UNCACHEABLE_SIDEEFFECT);
-+
-+ set_if_smaller(component_name->length, MAX_SYS_VAR_LENGTH);
-+
-+ return new Item_func_get_system_var(var, var_type, component_name,
-+ NULL, 0);
-+}
-+
-+
-+/**
-+ Check a user level lock.
-+
-+ Sets null_value=TRUE on error.
-+
-+ @retval
-+ 1 Available
-+ @retval
-+ 0 Already taken, or error
-+*/
-+
-+longlong Item_func_is_free_lock::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ User_level_lock *ull;
-+
-+ null_value=0;
-+ if (!res || !res->length())
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+
-+ pthread_mutex_lock(&LOCK_user_locks);
-+ ull= (User_level_lock *) hash_search(&hash_user_locks, (uchar*) res->ptr(),
-+ (size_t) res->length());
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ if (!ull || !ull->locked)
-+ return 1;
-+ return 0;
-+}
-+
-+longlong Item_func_is_used_lock::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ User_level_lock *ull;
-+
-+ null_value=1;
-+ if (!res || !res->length())
-+ return 0;
-+
-+ pthread_mutex_lock(&LOCK_user_locks);
-+ ull= (User_level_lock *) hash_search(&hash_user_locks, (uchar*) res->ptr(),
-+ (size_t) res->length());
-+ pthread_mutex_unlock(&LOCK_user_locks);
-+ if (!ull || !ull->locked)
-+ return 0;
-+
-+ null_value=0;
-+ return ull->thread_id;
-+}
-+
-+
-+longlong Item_func_row_count::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ THD *thd= current_thd;
-+
-+ return thd->row_count_func;
-+}
-+
-+
-+
-+
-+Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name)
-+ :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL)
-+{
-+ maybe_null= 1;
-+ m_name->init_qname(current_thd);
-+ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
-+ dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
-+}
-+
-+
-+Item_func_sp::Item_func_sp(Name_resolution_context *context_arg,
-+ sp_name *name, List<Item> &list)
-+ :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL)
-+{
-+ maybe_null= 1;
-+ m_name->init_qname(current_thd);
-+ dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)+ sizeof(TABLE_SHARE));
-+ dummy_table->s= (TABLE_SHARE*) (dummy_table+1);
-+}
-+
-+
-+void
-+Item_func_sp::cleanup()
-+{
-+ if (sp_result_field)
-+ {
-+ delete sp_result_field;
-+ sp_result_field= NULL;
-+ }
-+ m_sp= NULL;
-+ dummy_table->alias= NULL;
-+ Item_func::cleanup();
-+}
-+
-+const char *
-+Item_func_sp::func_name() const
-+{
-+ THD *thd= current_thd;
-+ /* Calculate length to avoid reallocation of string for sure */
-+ uint len= (((m_name->m_explicit_name ? m_name->m_db.length : 0) +
-+ m_name->m_name.length)*2 + //characters*quoting
-+ 2 + // ` and `
-+ (m_name->m_explicit_name ?
-+ 3 : 0) + // '`', '`' and '.' for the db
-+ 1 + // end of string
-+ ALIGN_SIZE(1)); // to avoid String reallocation
-+ String qname((char *)alloc_root(thd->mem_root, len), len,
-+ system_charset_info);
-+
-+ qname.length(0);
-+ if (m_name->m_explicit_name)
-+ {
-+ append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length);
-+ qname.append('.');
-+ }
-+ append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length);
-+ return qname.ptr();
-+}
-+
-+
-+int my_missing_function_error(const LEX_STRING &token, const char *func_name)
-+{
-+ if (token.length && is_lex_native_function (&token))
-+ return my_error(ER_FUNC_INEXISTENT_NAME_COLLISION, MYF(0), func_name);
-+ else
-+ return my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", func_name);
-+}
-+
-+
-+/**
-+ @brief Initialize the result field by creating a temporary dummy table
-+ and assign it to a newly created field object. Meta data used to
-+ create the field is fetched from the sp_head belonging to the stored
-+ proceedure found in the stored procedure functon cache.
-+
-+ @note This function should be called from fix_fields to init the result
-+ field. It is some what related to Item_field.
-+
-+ @see Item_field
-+
-+ @param thd A pointer to the session and thread context.
-+
-+ @return Function return error status.
-+ @retval TRUE is returned on an error
-+ @retval FALSE is returned on success.
-+*/
-+
-+bool
-+Item_func_sp::init_result_field(THD *thd)
-+{
-+ LEX_STRING empty_name= { C_STRING_WITH_LEN("") };
-+ TABLE_SHARE *share;
-+ DBUG_ENTER("Item_func_sp::init_result_field");
-+
-+ DBUG_ASSERT(m_sp == NULL);
-+ DBUG_ASSERT(sp_result_field == NULL);
-+
-+ if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
-+ &thd->sp_func_cache, TRUE)))
-+ {
-+ my_missing_function_error (m_name->m_name, m_name->m_qname.str);
-+ context->process_error(thd);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /*
-+ A Field need to be attached to a Table.
-+ Below we "create" a dummy table by initializing
-+ the needed pointers.
-+ */
-+
-+ share= dummy_table->s;
-+ dummy_table->alias = "";
-+ dummy_table->maybe_null = maybe_null;
-+ dummy_table->in_use= thd;
-+ dummy_table->copy_blobs= TRUE;
-+ share->table_cache_key = empty_name;
-+ share->table_name = empty_name;
-+
-+ if (!(sp_result_field= m_sp->create_result_field(max_length, name,
-+ dummy_table)))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ if (sp_result_field->pack_length() > sizeof(result_buf))
-+ {
-+ void *tmp;
-+ if (!(tmp= sql_alloc(sp_result_field->pack_length())))
-+ DBUG_RETURN(TRUE);
-+ sp_result_field->move_field((uchar*) tmp);
-+ }
-+ else
-+ sp_result_field->move_field(result_buf);
-+
-+ sp_result_field->null_ptr= (uchar *) &null_value;
-+ sp_result_field->null_bit= 1;
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ @brief Initialize local members with values from the Field interface.
-+
-+ @note called from Item::fix_fields.
-+*/
-+
-+void Item_func_sp::fix_length_and_dec()
-+{
-+ DBUG_ENTER("Item_func_sp::fix_length_and_dec");
-+
-+ DBUG_ASSERT(sp_result_field);
-+ decimals= sp_result_field->decimals();
-+ max_length= sp_result_field->field_length;
-+ collation.set(sp_result_field->charset());
-+ maybe_null= 1;
-+ unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG);
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ @brief Execute function & store value in field.
-+
-+ @return Function returns error status.
-+ @retval FALSE on success.
-+ @retval TRUE if an error occurred.
-+*/
-+
-+bool
-+Item_func_sp::execute()
-+{
-+ THD *thd= current_thd;
-+
-+ /* Execute function and store the return value in the field. */
-+
-+ if (execute_impl(thd))
-+ {
-+ null_value= 1;
-+ context->process_error(thd);
-+ if (thd->killed)
-+ thd->send_kill_message();
-+ return TRUE;
-+ }
-+
-+ /* Check that the field (the value) is not NULL. */
-+
-+ null_value= sp_result_field->is_null();
-+
-+ return null_value;
-+}
-+
-+
-+/**
-+ @brief Execute function and store the return value in the field.
-+
-+ @note This function was intended to be the concrete implementation of
-+ the interface function execute. This was never realized.
-+
-+ @return The error state.
-+ @retval FALSE on success
-+ @retval TRUE if an error occurred.
-+*/
-+bool
-+Item_func_sp::execute_impl(THD *thd)
-+{
-+ bool err_status= TRUE;
-+ Sub_statement_state statement_state;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ Security_context *save_security_ctx= thd->security_ctx;
-+#endif
-+ enum enum_sp_data_access access=
-+ (m_sp->m_chistics->daccess == SP_DEFAULT_ACCESS) ?
-+ SP_DEFAULT_ACCESS_MAPPING : m_sp->m_chistics->daccess;
-+
-+ DBUG_ENTER("Item_func_sp::execute_impl");
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (context->security_ctx)
-+ {
-+ /* Set view definer security context */
-+ thd->security_ctx= context->security_ctx;
-+ }
-+#endif
-+ if (sp_check_access(thd))
-+ goto error;
-+
-+ /*
-+ Throw an error if a non-deterministic function is called while
-+ statement-based replication (SBR) is active.
-+ */
-+
-+ if (!m_sp->m_chistics->detistic && !trust_function_creators &&
-+ (access == SP_CONTAINS_SQL || access == SP_MODIFIES_SQL_DATA) &&
-+ (mysql_bin_log.is_open() &&
-+ thd->variables.binlog_format == BINLOG_FORMAT_STMT))
-+ {
-+ my_error(ER_BINLOG_UNSAFE_ROUTINE, MYF(0));
-+ goto error;
-+ }
-+
-+ /*
-+ Disable the binlogging if this is not a SELECT statement. If this is a
-+ SELECT, leave binlogging on, so execute_function() code writes the
-+ function call into binlog.
-+ */
-+ thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION);
-+ err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field);
-+ thd->restore_sub_statement_state(&statement_state);
-+
-+error:
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ thd->security_ctx= save_security_ctx;
-+#endif
-+
-+ DBUG_RETURN(err_status);
-+}
-+
-+
-+void
-+Item_func_sp::make_field(Send_field *tmp_field)
-+{
-+ DBUG_ENTER("Item_func_sp::make_field");
-+ DBUG_ASSERT(sp_result_field);
-+ sp_result_field->make_field(tmp_field);
-+ if (name)
-+ tmp_field->col_name= name;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+enum enum_field_types
-+Item_func_sp::field_type() const
-+{
-+ DBUG_ENTER("Item_func_sp::field_type");
-+ DBUG_ASSERT(sp_result_field);
-+ DBUG_RETURN(sp_result_field->type());
-+}
-+
-+Item_result
-+Item_func_sp::result_type() const
-+{
-+ DBUG_ENTER("Item_func_sp::result_type");
-+ DBUG_PRINT("info", ("m_sp = %p", (void *) m_sp));
-+ DBUG_ASSERT(sp_result_field);
-+ DBUG_RETURN(sp_result_field->result_type());
-+}
-+
-+longlong Item_func_found_rows::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ return current_thd->found_rows();
-+}
-+
-+
-+Field *
-+Item_func_sp::tmp_table_field(TABLE *t_arg)
-+{
-+ DBUG_ENTER("Item_func_sp::tmp_table_field");
-+
-+ DBUG_ASSERT(sp_result_field);
-+ DBUG_RETURN(sp_result_field);
-+}
-+
-+
-+/**
-+ @brief Checks if requested access to function can be granted to user.
-+ If function isn't found yet, it searches function first.
-+ If function can't be found or user don't have requested access
-+ error is raised.
-+
-+ @param thd thread handler
-+
-+ @return Indication if the access was granted or not.
-+ @retval FALSE Access is granted.
-+ @retval TRUE Requested access can't be granted or function doesn't exists.
-+
-+*/
-+
-+bool
-+Item_func_sp::sp_check_access(THD *thd)
-+{
-+ DBUG_ENTER("Item_func_sp::sp_check_access");
-+ DBUG_ASSERT(m_sp);
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (check_routine_access(thd, EXECUTE_ACL,
-+ m_sp->m_db.str, m_sp->m_name.str, 0, FALSE))
-+ DBUG_RETURN(TRUE);
-+#endif
-+
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+bool
-+Item_func_sp::fix_fields(THD *thd, Item **ref)
-+{
-+ bool res;
-+ DBUG_ENTER("Item_func_sp::fix_fields");
-+ DBUG_ASSERT(fixed == 0);
-+
-+ /*
-+ We must call init_result_field before Item_func::fix_fields()
-+ to make m_sp and result_field members available to fix_length_and_dec(),
-+ which is called from Item_func::fix_fields().
-+ */
-+ res= init_result_field(thd);
-+
-+ if (res)
-+ DBUG_RETURN(res);
-+
-+ res= Item_func::fix_fields(thd, ref);
-+
-+ if (res)
-+ DBUG_RETURN(res);
-+
-+ if (thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW)
-+ {
-+ /*
-+ Here we check privileges of the stored routine only during view
-+ creation, in order to validate the view. A runtime check is
-+ perfomed in Item_func_sp::execute(), and this method is not
-+ called during context analysis. Notice, that during view
-+ creation we do not infer into stored routine bodies and do not
-+ check privileges of its statements, which would probably be a
-+ good idea especially if the view has SQL SECURITY DEFINER and
-+ the used stored procedure has SQL SECURITY DEFINER.
-+ */
-+ res= sp_check_access(thd);
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ /*
-+ Try to set and restore the security context to see whether it's valid
-+ */
-+ Security_context *save_secutiry_ctx;
-+ res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx);
-+ if (!res)
-+ m_sp->m_security_ctx.restore_security_context(thd, save_secutiry_ctx);
-+
-+#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */
-+ }
-+
-+ if (!m_sp->m_chistics->detistic)
-+ {
-+ used_tables_cache |= RAND_TABLE_BIT;
-+ const_item_cache= FALSE;
-+ }
-+
-+ DBUG_RETURN(res);
-+}
-+
-+
-+void Item_func_sp::update_used_tables()
-+{
-+ Item_func::update_used_tables();
-+
-+ if (!m_sp->m_chistics->detistic)
-+ {
-+ used_tables_cache |= RAND_TABLE_BIT;
-+ const_item_cache= FALSE;
-+ }
-+}
-+
-+
-+/*
-+ uuid_short handling.
-+
-+ The short uuid is defined as a longlong that contains the following bytes:
-+
-+ Bytes Comment
-+ 1 Server_id & 255
-+ 4 Startup time of server in seconds
-+ 3 Incrementor
-+
-+ This means that an uuid is guaranteed to be unique
-+ even in a replication environment if the following holds:
-+
-+ - The last byte of the server id is unique
-+ - If you between two shutdown of the server don't get more than
-+ an average of 2^24 = 16M calls to uuid_short() per second.
-+*/
-+
-+ulonglong uuid_value;
-+
-+void uuid_short_init()
-+{
-+ uuid_value= ((((ulonglong) server_id) << 56) +
-+ (((ulonglong) server_start_time) << 24));
-+}
-+
-+
-+longlong Item_func_uuid_short::val_int()
-+{
-+ ulonglong val;
-+ pthread_mutex_lock(&LOCK_uuid_generator);
-+ val= uuid_value++;
-+ pthread_mutex_unlock(&LOCK_uuid_generator);
-+ return (longlong) val;
-+}
diff -urN mysql-old/sql/item_func.h mysql/sql/item_func.h
--- mysql-old/sql/item_func.h 2011-05-10 17:45:45.640015709 +0000
+++ mysql/sql/item_func.h 2011-05-10 17:56:01.346682377 +0000
@@ -7478,4540 +1320,6 @@ diff -urN mysql-old/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
tv-= delta;
nanoseq-= delta;
}
-diff -urN mysql-old/sql/item_strfunc.cc.orig mysql/sql/item_strfunc.cc.orig
---- mysql-old/sql/item_strfunc.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/item_strfunc.cc.orig 2011-04-12 12:11:38.000000000 +0000
-@@ -0,0 +1,3643 @@
-+/* Copyright (C) 2000-2006 MySQL AB
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+
-+/**
-+ @file
-+
-+ @brief
-+ This file defines all string functions
-+
-+ @warning
-+ Some string functions don't always put and end-null on a String.
-+ (This shouldn't be needed)
-+*/
-+
-+#ifdef USE_PRAGMA_IMPLEMENTATION
-+#pragma implementation // gcc: Class implementation
-+#endif
-+
-+#include "mysql_priv.h"
-+#include <m_ctype.h>
-+#include "my_md5.h"
-+#include "sha1.h"
-+#include "my_aes.h"
-+#include <zlib.h>
-+C_MODE_START
-+#include "../mysys/my_static.h" // For soundex_map
-+C_MODE_END
-+
-+/**
-+ @todo Remove this. It is not safe to use a shared String object.
-+ */
-+String my_empty_string("",default_charset_info);
-+
-+
-+/*
-+ Convert an array of bytes to a hexadecimal representation.
-+
-+ Used to generate a hexadecimal representation of a message digest.
-+*/
-+static void array_to_hex(char *to, const char *str, uint len)
-+{
-+ const char *str_end= str + len;
-+ for (; str != str_end; ++str)
-+ {
-+ *to++= _dig_vec_lower[((uchar) *str) >> 4];
-+ *to++= _dig_vec_lower[((uchar) *str) & 0x0F];
-+ }
-+}
-+
-+
-+bool Item_str_func::fix_fields(THD *thd, Item **ref)
-+{
-+ bool res= Item_func::fix_fields(thd, ref);
-+ /*
-+ In Item_str_func::check_well_formed_result() we may set null_value
-+ flag on the same condition as in test() below.
-+ */
-+ maybe_null= (maybe_null ||
-+ test(thd->variables.sql_mode &
-+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)));
-+ return res;
-+}
-+
-+
-+my_decimal *Item_str_func::val_decimal(my_decimal *decimal_value)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char buff[64];
-+ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
-+ res= val_str(&tmp);
-+ if (!res)
-+ return 0;
-+ (void)str2my_decimal(E_DEC_FATAL_ERROR, (char*) res->ptr(),
-+ res->length(), res->charset(), decimal_value);
-+ return decimal_value;
-+}
-+
-+
-+double Item_str_func::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ int err_not_used;
-+ char *end_not_used, buff[64];
-+ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
-+ res= val_str(&tmp);
-+ return res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
-+ &end_not_used, &err_not_used) : 0.0;
-+}
-+
-+
-+longlong Item_str_func::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ int err;
-+ char buff[22];
-+ String *res, tmp(buff,sizeof(buff), &my_charset_bin);
-+ res= val_str(&tmp);
-+ return (res ?
-+ my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
-+ &err) :
-+ (longlong) 0);
-+}
-+
-+
-+String *Item_func_md5::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String * sptr= args[0]->val_str(str);
-+ str->set_charset(&my_charset_bin);
-+ if (sptr)
-+ {
-+ uchar digest[16];
-+
-+ null_value=0;
-+ MY_MD5_HASH(digest,(uchar *) sptr->ptr(), sptr->length());
-+ if (str->alloc(32)) // Ensure that memory is free
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ array_to_hex((char *) str->ptr(), (const char*) digest, 16);
-+ str->length((uint) 32);
-+ return str;
-+ }
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_md5::fix_length_and_dec()
-+{
-+ max_length=32;
-+ /*
-+ The MD5() function treats its parameter as being a case sensitive. Thus
-+ we set binary collation on it so different instances of MD5() will be
-+ compared properly.
-+ */
-+ args[0]->collation.set(
-+ get_charset_by_csname(args[0]->collation.collation->csname,
-+ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
-+}
-+
-+
-+String *Item_func_sha::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String * sptr= args[0]->val_str(str);
-+ str->set_charset(&my_charset_bin);
-+ if (sptr) /* If we got value different from NULL */
-+ {
-+ SHA1_CONTEXT context; /* Context used to generate SHA1 hash */
-+ /* Temporary buffer to store 160bit digest */
-+ uint8 digest[SHA1_HASH_SIZE];
-+ mysql_sha1_reset(&context); /* We do not have to check for error here */
-+ /* No need to check error as the only case would be too long message */
-+ mysql_sha1_input(&context,
-+ (const uchar *) sptr->ptr(), sptr->length());
-+ /* Ensure that memory is free and we got result */
-+ if (!( str->alloc(SHA1_HASH_SIZE*2) ||
-+ (mysql_sha1_result(&context,digest))))
-+ {
-+ array_to_hex((char *) str->ptr(), (const char*) digest, SHA1_HASH_SIZE);
-+ str->length((uint) SHA1_HASH_SIZE*2);
-+ null_value=0;
-+ return str;
-+ }
-+ }
-+ null_value=1;
-+ return 0;
-+}
-+
-+void Item_func_sha::fix_length_and_dec()
-+{
-+ max_length=SHA1_HASH_SIZE*2; // size of hex representation of hash
-+ /*
-+ The SHA() function treats its parameter as being a case sensitive. Thus
-+ we set binary collation on it so different instances of MD5() will be
-+ compared properly.
-+ */
-+ args[0]->collation.set(
-+ get_charset_by_csname(args[0]->collation.collation->csname,
-+ MY_CS_BINSORT,MYF(0)), DERIVATION_COERCIBLE);
-+}
-+
-+
-+/* Implementation of AES encryption routines */
-+
-+String *Item_func_aes_encrypt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char key_buff[80];
-+ String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
-+ String *sptr= args[0]->val_str(str); // String to encrypt
-+ String *key= args[1]->val_str(&tmp_key_value); // key
-+ int aes_length;
-+ if (sptr && key) // we need both arguments to be not NULL
-+ {
-+ null_value=0;
-+ aes_length=my_aes_get_size(sptr->length()); // Calculate result length
-+
-+ if (!str_value.alloc(aes_length)) // Ensure that memory is free
-+ {
-+ // finally encrypt directly to allocated buffer.
-+ if (my_aes_encrypt(sptr->ptr(),sptr->length(), (char*) str_value.ptr(),
-+ key->ptr(), key->length()) == aes_length)
-+ {
-+ // We got the expected result length
-+ str_value.length((uint) aes_length);
-+ return &str_value;
-+ }
-+ }
-+ }
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_aes_encrypt::fix_length_and_dec()
-+{
-+ max_length=my_aes_get_size(args[0]->max_length);
-+}
-+
-+
-+String *Item_func_aes_decrypt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char key_buff[80];
-+ String tmp_key_value(key_buff, sizeof(key_buff), system_charset_info);
-+ String *sptr, *key;
-+ DBUG_ENTER("Item_func_aes_decrypt::val_str");
-+
-+ sptr= args[0]->val_str(str); // String to decrypt
-+ key= args[1]->val_str(&tmp_key_value); // Key
-+ if (sptr && key) // Need to have both arguments not NULL
-+ {
-+ null_value=0;
-+ if (!str_value.alloc(sptr->length())) // Ensure that memory is free
-+ {
-+ // finally decrypt directly to allocated buffer.
-+ int length;
-+ length=my_aes_decrypt(sptr->ptr(), sptr->length(),
-+ (char*) str_value.ptr(),
-+ key->ptr(), key->length());
-+ if (length >= 0) // if we got correct data data
-+ {
-+ str_value.length((uint) length);
-+ DBUG_RETURN(&str_value);
-+ }
-+ }
-+ }
-+ // Bad parameters. No memory or bad data will all go here
-+ null_value=1;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+void Item_func_aes_decrypt::fix_length_and_dec()
-+{
-+ max_length=args[0]->max_length;
-+ maybe_null= 1;
-+}
-+
-+
-+/**
-+ Concatenate args with the following premises:
-+ If only one arg (which is ok), return value of arg;
-+ Don't reallocate val_str() if not absolute necessary.
-+*/
-+
-+String *Item_func_concat::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res,*res2,*use_as_buff;
-+ uint i;
-+ bool is_const= 0;
-+
-+ null_value=0;
-+ if (!(res=args[0]->val_str(str)))
-+ goto null;
-+ use_as_buff= &tmp_value;
-+ /* Item_subselect in --ps-protocol mode will state it as a non-const */
-+ is_const= args[0]->const_item() || !args[0]->used_tables();
-+ for (i=1 ; i < arg_count ; i++)
-+ {
-+ if (res->length() == 0)
-+ {
-+ if (!(res=args[i]->val_str(str)))
-+ goto null;
-+ /*
-+ CONCAT accumulates its result in the result of its the first
-+ non-empty argument. Because of this we need is_const to be
-+ evaluated only for it.
-+ */
-+ is_const= args[i]->const_item() || !args[i]->used_tables();
-+ }
-+ else
-+ {
-+ if (!(res2=args[i]->val_str(use_as_buff)))
-+ goto null;
-+ if (res2->length() == 0)
-+ continue;
-+ if (res->length()+res2->length() >
-+ current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
-+ current_thd->variables.max_allowed_packet);
-+ goto null;
-+ }
-+ if (!is_const && res->alloced_length() >= res->length()+res2->length())
-+ { // Use old buffer
-+ res->append(*res2);
-+ }
-+ else if (str->alloced_length() >= res->length()+res2->length())
-+ {
-+ if (str->ptr() == res2->ptr())
-+ str->replace(0,0,*res);
-+ else
-+ {
-+ str->copy(*res);
-+ str->append(*res2);
-+ }
-+ res= str;
-+ use_as_buff= &tmp_value;
-+ }
-+ else if (res == &tmp_value)
-+ {
-+ if (res->append(*res2)) // Must be a blob
-+ goto null;
-+ }
-+ else if (res2 == &tmp_value)
-+ { // This can happend only 1 time
-+ if (tmp_value.replace(0,0,*res))
-+ goto null;
-+ res= &tmp_value;
-+ use_as_buff=str; // Put next arg here
-+ }
-+ else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
-+ res2->ptr() <= tmp_value.ptr() + tmp_value.alloced_length())
-+ {
-+ /*
-+ This happens really seldom:
-+ In this case res2 is sub string of tmp_value. We will
-+ now work in place in tmp_value to set it to res | res2
-+ */
-+ /* Chop the last characters in tmp_value that isn't in res2 */
-+ tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
-+ res2->length());
-+ /* Place res2 at start of tmp_value, remove chars before res2 */
-+ if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
-+ *res))
-+ goto null;
-+ res= &tmp_value;
-+ use_as_buff=str; // Put next arg here
-+ }
-+ else
-+ { // Two big const strings
-+ /*
-+ NOTE: We should be prudent in the initial allocation unit -- the
-+ size of the arguments is a function of data distribution, which
-+ can be any. Instead of overcommitting at the first row, we grow
-+ the allocated amount by the factor of 2. This ensures that no
-+ more than 25% of memory will be overcommitted on average.
-+ */
-+
-+ uint concat_len= res->length() + res2->length();
-+
-+ if (tmp_value.alloced_length() < concat_len)
-+ {
-+ if (tmp_value.alloced_length() == 0)
-+ {
-+ if (tmp_value.alloc(concat_len))
-+ goto null;
-+ }
-+ else
-+ {
-+ uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
-+
-+ if (tmp_value.realloc(new_len))
-+ goto null;
-+ }
-+ }
-+
-+ if (tmp_value.copy(*res) || tmp_value.append(*res2))
-+ goto null;
-+
-+ res= &tmp_value;
-+ use_as_buff=str;
-+ }
-+ is_const= 0;
-+ }
-+ }
-+ res->set_charset(collation.collation);
-+ return res;
-+
-+null:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_concat::fix_length_and_dec()
-+{
-+ ulonglong max_result_length= 0;
-+
-+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
-+ return;
-+
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
-+ max_result_length+= (args[i]->max_length /
-+ args[i]->collation.collation->mbmaxlen) *
-+ collation.collation->mbmaxlen;
-+ else
-+ max_result_length+= args[i]->max_length;
-+ }
-+
-+ if (max_result_length >= MAX_BLOB_WIDTH)
-+ {
-+ max_result_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) max_result_length;
-+}
-+
-+/**
-+ @details
-+ Function des_encrypt() by tonu@spam.ee & monty
-+ Works only if compiled with OpenSSL library support.
-+ @return
-+ A binary string where first character is CHAR(128 | key-number).
-+ If one uses a string key key_number is 127.
-+ Encryption result is longer than original by formula:
-+ @code new_length= org_length + (8-(org_length % 8))+1 @endcode
-+*/
-+
-+String *Item_func_des_encrypt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+#ifdef HAVE_OPENSSL
-+ uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
-+ DES_cblock ivec;
-+ struct st_des_keyblock keyblock;
-+ struct st_des_keyschedule keyschedule;
-+ const char *append_str="********";
-+ uint key_number, res_length, tail;
-+ String *res= args[0]->val_str(str);
-+
-+ if ((null_value= args[0]->null_value))
-+ return 0; // ENCRYPT(NULL) == NULL
-+ if ((res_length=res->length()) == 0)
-+ return make_empty_result();
-+
-+ if (arg_count == 1)
-+ {
-+ /* Protect against someone doing FLUSH DES_KEY_FILE */
-+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
-+ keyschedule= des_keyschedule[key_number=des_default_key];
-+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
-+ }
-+ else if (args[1]->result_type() == INT_RESULT)
-+ {
-+ key_number= (uint) args[1]->val_int();
-+ if (key_number > 9)
-+ goto error;
-+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
-+ keyschedule= des_keyschedule[key_number];
-+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
-+ }
-+ else
-+ {
-+ String *keystr=args[1]->val_str(&tmp_value);
-+ if (!keystr)
-+ goto error;
-+ key_number=127; // User key string
-+
-+ /* We make good 24-byte (168 bit) key from given plaintext key with MD5 */
-+ bzero((char*) &ivec,sizeof(ivec));
-+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
-+ (uchar*) keystr->ptr(), (int) keystr->length(),
-+ 1, (uchar*) &keyblock,ivec);
-+ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
-+ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
-+ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
-+ }
-+
-+ /*
-+ The problem: DES algorithm requires original data to be in 8-bytes
-+ chunks. Missing bytes get filled with '*'s and result of encryption
-+ can be up to 8 bytes longer than original string. When decrypted,
-+ we do not know the size of original string :(
-+ We add one byte with value 0x1..0x8 as the last byte of the padded
-+ string marking change of string length.
-+ */
-+
-+ tail= 8 - (res_length % 8); // 1..8 marking extra length
-+ res_length+=tail;
-+ tmp_arg.realloc(res_length);
-+ tmp_arg.length(0);
-+ tmp_arg.append(res->ptr(), res->length());
-+ code= ER_OUT_OF_RESOURCES;
-+ if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1))
-+ goto error;
-+ tmp_arg[res_length-1]=tail; // save extra length
-+ tmp_value.realloc(res_length+1);
-+ tmp_value.length(res_length+1);
-+ tmp_value.set_charset(&my_charset_bin);
-+ tmp_value[0]=(char) (128 | key_number);
-+ // Real encryption
-+ bzero((char*) &ivec,sizeof(ivec));
-+ DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()),
-+ (uchar*) (tmp_value.ptr()+1),
-+ res_length,
-+ &keyschedule.ks1,
-+ &keyschedule.ks2,
-+ &keyschedule.ks3,
-+ &ivec, TRUE);
-+ return &tmp_value;
-+
-+error:
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ code, ER(code),
-+ "des_encrypt");
-+#else
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
-+ "des_encrypt","--with-openssl");
-+#endif /* HAVE_OPENSSL */
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+String *Item_func_des_decrypt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+#ifdef HAVE_OPENSSL
-+ uint code= ER_WRONG_PARAMETERS_TO_PROCEDURE;
-+ DES_cblock ivec;
-+ struct st_des_keyblock keyblock;
-+ struct st_des_keyschedule keyschedule;
-+ String *res= args[0]->val_str(str);
-+ uint length,tail;
-+
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ length= res->length();
-+ if (length < 9 || (length % 8) != 1 || !((*res)[0] & 128))
-+ return res; // Skip decryption if not encrypted
-+
-+ if (arg_count == 1) // If automatic uncompression
-+ {
-+ uint key_number=(uint) (*res)[0] & 127;
-+ // Check if automatic key and that we have privilege to uncompress using it
-+ if (!(current_thd->security_ctx->master_access & SUPER_ACL) ||
-+ key_number > 9)
-+ goto error;
-+
-+ VOID(pthread_mutex_lock(&LOCK_des_key_file));
-+ keyschedule= des_keyschedule[key_number];
-+ VOID(pthread_mutex_unlock(&LOCK_des_key_file));
-+ }
-+ else
-+ {
-+ // We make good 24-byte (168 bit) key from given plaintext key with MD5
-+ String *keystr=args[1]->val_str(&tmp_value);
-+ if (!keystr)
-+ goto error;
-+
-+ bzero((char*) &ivec,sizeof(ivec));
-+ EVP_BytesToKey(EVP_des_ede3_cbc(),EVP_md5(),NULL,
-+ (uchar*) keystr->ptr(),(int) keystr->length(),
-+ 1,(uchar*) &keyblock,ivec);
-+ // Here we set all 64-bit keys (56 effective) one by one
-+ DES_set_key_unchecked(&keyblock.key1,&keyschedule.ks1);
-+ DES_set_key_unchecked(&keyblock.key2,&keyschedule.ks2);
-+ DES_set_key_unchecked(&keyblock.key3,&keyschedule.ks3);
-+ }
-+ code= ER_OUT_OF_RESOURCES;
-+ if (tmp_value.alloc(length-1))
-+ goto error;
-+
-+ bzero((char*) &ivec,sizeof(ivec));
-+ DES_ede3_cbc_encrypt((const uchar*) res->ptr()+1,
-+ (uchar*) (tmp_value.ptr()),
-+ length-1,
-+ &keyschedule.ks1,
-+ &keyschedule.ks2,
-+ &keyschedule.ks3,
-+ &ivec, FALSE);
-+ /* Restore old length of key */
-+ if ((tail=(uint) (uchar) tmp_value[length-2]) > 8)
-+ goto wrong_key; // Wrong key
-+ tmp_value.length(length-1-tail);
-+ tmp_value.set_charset(&my_charset_bin);
-+ return &tmp_value;
-+
-+error:
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ code, ER(code),
-+ "des_decrypt");
-+wrong_key:
-+#else
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_FEATURE_DISABLED, ER(ER_FEATURE_DISABLED),
-+ "des_decrypt","--with-openssl");
-+#endif /* HAVE_OPENSSL */
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+/**
-+ concat with separator. First arg is the separator
-+ concat_ws takes at least two arguments.
-+*/
-+
-+String *Item_func_concat_ws::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char tmp_str_buff[10];
-+ String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
-+ *sep_str, *res, *res2,*use_as_buff;
-+ uint i;
-+ bool is_const= 0;
-+
-+ null_value=0;
-+ if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
-+ goto null;
-+
-+ use_as_buff= &tmp_value;
-+ str->length(0); // QQ; Should be removed
-+ res=str;
-+
-+ // Skip until non-null argument is found.
-+ // If not, return the empty string
-+ for (i=1; i < arg_count; i++)
-+ if ((res= args[i]->val_str(str)))
-+ {
-+ is_const= args[i]->const_item() || !args[i]->used_tables();
-+ break;
-+ }
-+
-+ if (i == arg_count)
-+ return make_empty_result();
-+
-+ for (i++; i < arg_count ; i++)
-+ {
-+ if (!(res2= args[i]->val_str(use_as_buff)))
-+ continue; // Skip NULL
-+
-+ if (res->length() + sep_str->length() + res2->length() >
-+ current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
-+ current_thd->variables.max_allowed_packet);
-+ goto null;
-+ }
-+ if (!is_const && res->alloced_length() >=
-+ res->length() + sep_str->length() + res2->length())
-+ { // Use old buffer
-+ res->append(*sep_str); // res->length() > 0 always
-+ res->append(*res2);
-+ }
-+ else if (str->alloced_length() >=
-+ res->length() + sep_str->length() + res2->length())
-+ {
-+ /* We have room in str; We can't get any errors here */
-+ if (str->ptr() == res2->ptr())
-+ { // This is quite uncommon!
-+ str->replace(0,0,*sep_str);
-+ str->replace(0,0,*res);
-+ }
-+ else
-+ {
-+ str->copy(*res);
-+ str->append(*sep_str);
-+ str->append(*res2);
-+ }
-+ res=str;
-+ use_as_buff= &tmp_value;
-+ }
-+ else if (res == &tmp_value)
-+ {
-+ if (res->append(*sep_str) || res->append(*res2))
-+ goto null; // Must be a blob
-+ }
-+ else if (res2 == &tmp_value)
-+ { // This can happend only 1 time
-+ if (tmp_value.replace(0,0,*sep_str) || tmp_value.replace(0,0,*res))
-+ goto null;
-+ res= &tmp_value;
-+ use_as_buff=str; // Put next arg here
-+ }
-+ else if (tmp_value.is_alloced() && res2->ptr() >= tmp_value.ptr() &&
-+ res2->ptr() < tmp_value.ptr() + tmp_value.alloced_length())
-+ {
-+ /*
-+ This happens really seldom:
-+ In this case res2 is sub string of tmp_value. We will
-+ now work in place in tmp_value to set it to res | sep_str | res2
-+ */
-+ /* Chop the last characters in tmp_value that isn't in res2 */
-+ tmp_value.length((uint32) (res2->ptr() - tmp_value.ptr()) +
-+ res2->length());
-+ /* Place res2 at start of tmp_value, remove chars before res2 */
-+ if (tmp_value.replace(0,(uint32) (res2->ptr() - tmp_value.ptr()),
-+ *res) ||
-+ tmp_value.replace(res->length(),0, *sep_str))
-+ goto null;
-+ res= &tmp_value;
-+ use_as_buff=str; // Put next arg here
-+ }
-+ else
-+ { // Two big const strings
-+ /*
-+ NOTE: We should be prudent in the initial allocation unit -- the
-+ size of the arguments is a function of data distribution, which can
-+ be any. Instead of overcommitting at the first row, we grow the
-+ allocated amount by the factor of 2. This ensures that no more than
-+ 25% of memory will be overcommitted on average.
-+ */
-+
-+ uint concat_len= res->length() + sep_str->length() + res2->length();
-+
-+ if (tmp_value.alloced_length() < concat_len)
-+ {
-+ if (tmp_value.alloced_length() == 0)
-+ {
-+ if (tmp_value.alloc(concat_len))
-+ goto null;
-+ }
-+ else
-+ {
-+ uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
-+
-+ if (tmp_value.realloc(new_len))
-+ goto null;
-+ }
-+ }
-+
-+ if (tmp_value.copy(*res) ||
-+ tmp_value.append(*sep_str) ||
-+ tmp_value.append(*res2))
-+ goto null;
-+ res= &tmp_value;
-+ use_as_buff=str;
-+ }
-+ }
-+ res->set_charset(collation.collation);
-+ return res;
-+
-+null:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_concat_ws::fix_length_and_dec()
-+{
-+ ulonglong max_result_length;
-+
-+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
-+ return;
-+
-+ /*
-+ arg_count cannot be less than 2,
-+ it is done on parser level in sql_yacc.yy
-+ so, (arg_count - 2) is safe here.
-+ */
-+ max_result_length= (ulonglong) args[0]->max_length * (arg_count - 2);
-+ for (uint i=1 ; i < arg_count ; i++)
-+ max_result_length+=args[i]->max_length;
-+
-+ if (max_result_length >= MAX_BLOB_WIDTH)
-+ {
-+ max_result_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) max_result_length;
-+}
-+
-+
-+String *Item_func_reverse::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res = args[0]->val_str(str);
-+ char *ptr, *end, *tmp;
-+
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ /* An empty string is a special case as the string pointer may be null */
-+ if (!res->length())
-+ return make_empty_result();
-+ if (tmp_value.alloced_length() < res->length() &&
-+ tmp_value.realloc(res->length()))
-+ {
-+ null_value= 1;
-+ return 0;
-+ }
-+ tmp_value.length(res->length());
-+ tmp_value.set_charset(res->charset());
-+ ptr= (char *) res->ptr();
-+ end= ptr + res->length();
-+ tmp= (char *) tmp_value.ptr() + tmp_value.length();
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ register uint32 l;
-+ while (ptr < end)
-+ {
-+ if ((l= my_ismbchar(res->charset(),ptr,end)))
-+ {
-+ tmp-= l;
-+ memcpy(tmp,ptr,l);
-+ ptr+= l;
-+ }
-+ else
-+ *--tmp= *ptr++;
-+ }
-+ }
-+ else
-+#endif /* USE_MB */
-+ {
-+ while (ptr < end)
-+ *--tmp= *ptr++;
-+ }
-+ return &tmp_value;
-+}
-+
-+
-+void Item_func_reverse::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ max_length = args[0]->max_length;
-+}
-+
-+/**
-+ Replace all occurences of string2 in string1 with string3.
-+
-+ Don't reallocate val_str() if not needed.
-+
-+ @todo
-+ Fix that this works with binary strings when using USE_MB
-+*/
-+
-+String *Item_func_replace::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res,*res2,*res3;
-+ int offset;
-+ uint from_length,to_length;
-+ bool alloced=0;
-+#ifdef USE_MB
-+ const char *ptr,*end,*strend,*search,*search_end;
-+ register uint32 l;
-+ bool binary_cmp;
-+#endif
-+
-+ null_value=0;
-+ res=args[0]->val_str(str);
-+ if (args[0]->null_value)
-+ goto null;
-+ res2=args[1]->val_str(&tmp_value);
-+ if (args[1]->null_value)
-+ goto null;
-+
-+ res->set_charset(collation.collation);
-+
-+#ifdef USE_MB
-+ binary_cmp = ((res->charset()->state & MY_CS_BINSORT) || !use_mb(res->charset()));
-+#endif
-+
-+ if (res2->length() == 0)
-+ return res;
-+#ifndef USE_MB
-+ if ((offset=res->strstr(*res2)) < 0)
-+ return res;
-+#else
-+ offset=0;
-+ if (binary_cmp && (offset=res->strstr(*res2)) < 0)
-+ return res;
-+#endif
-+ if (!(res3=args[2]->val_str(&tmp_value2)))
-+ goto null;
-+ from_length= res2->length();
-+ to_length= res3->length();
-+
-+#ifdef USE_MB
-+ if (!binary_cmp)
-+ {
-+ search=res2->ptr();
-+ search_end=search+from_length;
-+redo:
-+ DBUG_ASSERT(res->ptr() || !offset);
-+ ptr=res->ptr()+offset;
-+ strend=res->ptr()+res->length();
-+ /*
-+ In some cases val_str() can return empty string
-+ with ptr() == NULL and length() == 0.
-+ Let's check strend to avoid overflow.
-+ */
-+ end= strend ? strend - from_length + 1 : NULL;
-+ while (ptr < end)
-+ {
-+ if (*ptr == *search)
-+ {
-+ register char *i,*j;
-+ i=(char*) ptr+1; j=(char*) search+1;
-+ while (j != search_end)
-+ if (*i++ != *j++) goto skip;
-+ offset= (int) (ptr-res->ptr());
-+ if (res->length()-from_length + to_length >
-+ current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(),
-+ current_thd->variables.max_allowed_packet);
-+
-+ goto null;
-+ }
-+ if (!alloced)
-+ {
-+ alloced=1;
-+ res=copy_if_not_alloced(str,res,res->length()+to_length);
-+ }
-+ res->replace((uint) offset,from_length,*res3);
-+ offset+=(int) to_length;
-+ goto redo;
-+ }
-+skip:
-+ if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
-+ else ++ptr;
-+ }
-+ }
-+ else
-+#endif /* USE_MB */
-+ do
-+ {
-+ if (res->length()-from_length + to_length >
-+ current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED), func_name(),
-+ current_thd->variables.max_allowed_packet);
-+ goto null;
-+ }
-+ if (!alloced)
-+ {
-+ alloced=1;
-+ res=copy_if_not_alloced(str,res,res->length()+to_length);
-+ }
-+ res->replace((uint) offset,from_length,*res3);
-+ offset+=(int) to_length;
-+ }
-+ while ((offset=res->strstr(*res2,(uint) offset)) >= 0);
-+ return res;
-+
-+null:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_replace::fix_length_and_dec()
-+{
-+ ulonglong max_result_length= args[0]->max_length;
-+ int diff=(int) (args[2]->max_length - args[1]->max_length);
-+ if (diff > 0 && args[1]->max_length)
-+ { // Calculate of maxreplaces
-+ ulonglong max_substrs= max_result_length/args[1]->max_length;
-+ max_result_length+= max_substrs * (uint) diff;
-+ }
-+ if (max_result_length >= MAX_BLOB_WIDTH)
-+ {
-+ max_result_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) max_result_length;
-+
-+ if (agg_arg_charsets(collation, args, 3, MY_COLL_CMP_CONV, 1))
-+ return;
-+}
-+
-+
-+String *Item_func_insert::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res,*res2;
-+ longlong start, length; /* must be longlong to avoid truncation */
-+
-+ null_value=0;
-+ res=args[0]->val_str(str);
-+ res2=args[3]->val_str(&tmp_value);
-+ start= args[1]->val_int() - 1;
-+ length= args[2]->val_int();
-+
-+ if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
-+ args[3]->null_value)
-+ goto null; /* purecov: inspected */
-+
-+ if ((start < 0) || (start > res->length()))
-+ return res; // Wrong param; skip insert
-+ if ((length < 0) || (length > res->length()))
-+ length= res->length();
-+
-+ /*
-+ There is one exception not handled (intentionaly) by the character set
-+ aggregation code. If one string is strong side and is binary, and
-+ another one is weak side and is a multi-byte character string,
-+ then we need to operate on the second string in terms on bytes when
-+ calling ::numchars() and ::charpos(), rather than in terms of characters.
-+ Lets substitute its character set to binary.
-+ */
-+ if (collation.collation == &my_charset_bin)
-+ {
-+ res->set_charset(&my_charset_bin);
-+ res2->set_charset(&my_charset_bin);
-+ }
-+
-+ /* start and length are now sufficiently valid to pass to charpos function */
-+ start= res->charpos((int) start);
-+ length= res->charpos((int) length, (uint32) start);
-+
-+ /* Re-testing with corrected params */
-+ if (start > res->length())
-+ return res; /* purecov: inspected */ // Wrong param; skip insert
-+ if (length > res->length() - start)
-+ length= res->length() - start;
-+
-+ if ((ulonglong) (res->length() - length + res2->length()) >
-+ (ulonglong) current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(), current_thd->variables.max_allowed_packet);
-+ goto null;
-+ }
-+ res=copy_if_not_alloced(str,res,res->length());
-+ res->replace((uint32) start,(uint32) length,*res2);
-+ return res;
-+null:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_insert::fix_length_and_dec()
-+{
-+ ulonglong max_result_length;
-+
-+ // Handle character set for args[0] and args[3].
-+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 3))
-+ return;
-+ max_result_length= ((ulonglong) args[0]->max_length+
-+ (ulonglong) args[3]->max_length);
-+ if (max_result_length >= MAX_BLOB_WIDTH)
-+ {
-+ max_result_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) max_result_length;
-+}
-+
-+
-+String *Item_str_conv::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res;
-+ if (!(res=args[0]->val_str(str)))
-+ {
-+ null_value=1; /* purecov: inspected */
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ if (multiply == 1)
-+ {
-+ uint len;
-+ res= copy_if_not_alloced(str,res,res->length());
-+ len= converter(collation.collation, (char*) res->ptr(), res->length(),
-+ (char*) res->ptr(), res->length());
-+ DBUG_ASSERT(len <= res->length());
-+ res->length(len);
-+ }
-+ else
-+ {
-+ uint len= res->length() * multiply;
-+ tmp_value.alloc(len);
-+ tmp_value.set_charset(collation.collation);
-+ len= converter(collation.collation, (char*) res->ptr(), res->length(),
-+ (char*) tmp_value.ptr(), len);
-+ tmp_value.length(len);
-+ res= &tmp_value;
-+ }
-+ return res;
-+}
-+
-+
-+void Item_func_lcase::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ multiply= collation.collation->casedn_multiply;
-+ converter= collation.collation->cset->casedn;
-+ max_length= args[0]->max_length * multiply;
-+}
-+
-+void Item_func_ucase::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ multiply= collation.collation->caseup_multiply;
-+ converter= collation.collation->cset->caseup;
-+ max_length= args[0]->max_length * multiply;
-+}
-+
-+
-+String *Item_func_left::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+
-+ /* must be longlong to avoid truncation */
-+ longlong length= args[1]->val_int();
-+ uint char_pos;
-+
-+ if ((null_value=(args[0]->null_value || args[1]->null_value)))
-+ return 0;
-+
-+ /* if "unsigned_flag" is set, we have a *huge* positive number. */
-+ if ((length <= 0) && (!args[1]->unsigned_flag))
-+ return make_empty_result();
-+ if ((res->length() <= (ulonglong) length) ||
-+ (res->length() <= (char_pos= res->charpos((int) length))))
-+ return res;
-+
-+ tmp_value.set(*res, 0, char_pos);
-+ return &tmp_value;
-+}
-+
-+
-+void Item_str_func::left_right_max_length()
-+{
-+ max_length=args[0]->max_length;
-+ if (args[1]->const_item())
-+ {
-+ int length=(int) args[1]->val_int()*collation.collation->mbmaxlen;
-+ if (length <= 0)
-+ max_length=0;
-+ else
-+ set_if_smaller(max_length,(uint) length);
-+ }
-+}
-+
-+
-+void Item_func_left::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ left_right_max_length();
-+}
-+
-+
-+String *Item_func_right::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ /* must be longlong to avoid truncation */
-+ longlong length= args[1]->val_int();
-+
-+ if ((null_value=(args[0]->null_value || args[1]->null_value)))
-+ return 0; /* purecov: inspected */
-+
-+ /* if "unsigned_flag" is set, we have a *huge* positive number. */
-+ if ((length <= 0) && (!args[1]->unsigned_flag))
-+ return make_empty_result(); /* purecov: inspected */
-+
-+ if (res->length() <= (ulonglong) length)
-+ return res; /* purecov: inspected */
-+
-+ uint start=res->numchars();
-+ if (start <= (uint) length)
-+ return res;
-+ start=res->charpos(start - (uint) length);
-+ tmp_value.set(*res,start,res->length()-start);
-+ return &tmp_value;
-+}
-+
-+
-+void Item_func_right::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ left_right_max_length();
-+}
-+
-+
-+String *Item_func_substr::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res = args[0]->val_str(str);
-+ /* must be longlong to avoid truncation */
-+ longlong start= args[1]->val_int();
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Limit so that code sees out-of-bound value properly. */
-+ longlong length= arg_count == 3 ? args[2]->val_int() : INT_MAX32;
-+ longlong tmp_length;
-+
-+ if ((null_value=(args[0]->null_value || args[1]->null_value ||
-+ (arg_count == 3 && args[2]->null_value))))
-+ return 0; /* purecov: inspected */
-+
-+ /* Negative or zero length, will return empty string. */
-+ if ((arg_count == 3) && (length <= 0) &&
-+ (length == 0 || !args[2]->unsigned_flag))
-+ return make_empty_result();
-+
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if ((length <= 0) || (length > INT_MAX32))
-+ length= INT_MAX32;
-+
-+ /* if "unsigned_flag" is set, we have a *huge* positive number. */
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ if ((!args[1]->unsigned_flag && (start < INT_MIN32 || start > INT_MAX32)) ||
-+ (args[1]->unsigned_flag && ((ulonglong) start > INT_MAX32)))
-+ return make_empty_result();
-+
-+ start= ((start < 0) ? res->numchars() + start : start - 1);
-+ start= res->charpos((int) start);
-+ if ((start < 0) || ((uint) start + 1 > res->length()))
-+ return make_empty_result();
-+
-+ length= res->charpos((int) length, (uint32) start);
-+ tmp_length= res->length() - start;
-+ length= min(length, tmp_length);
-+
-+ if (!start && (longlong) res->length() == length)
-+ return res;
-+ tmp_value.set(*res, (uint32) start, (uint32) length);
-+ return &tmp_value;
-+}
-+
-+
-+void Item_func_substr::fix_length_and_dec()
-+{
-+ max_length=args[0]->max_length;
-+
-+ collation.set(args[0]->collation);
-+ if (args[1]->const_item())
-+ {
-+ int32 start= (int32) args[1]->val_int();
-+ if (start < 0)
-+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
-+ else
-+ max_length-= min((uint)(start - 1), max_length);
-+ }
-+ if (arg_count == 3 && args[2]->const_item())
-+ {
-+ int32 length= (int32) args[2]->val_int();
-+ if (length <= 0)
-+ max_length=0; /* purecov: inspected */
-+ else
-+ set_if_smaller(max_length,(uint) length);
-+ }
-+ max_length*= collation.collation->mbmaxlen;
-+}
-+
-+
-+void Item_func_substr_index::fix_length_and_dec()
-+{
-+ max_length= args[0]->max_length;
-+
-+ if (agg_arg_charsets(collation, args, 2, MY_COLL_CMP_CONV, 1))
-+ return;
-+}
-+
-+
-+String *Item_func_substr_index::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ String *delimiter= args[1]->val_str(&tmp_value);
-+ int32 count= (int32) args[2]->val_int();
-+ uint offset;
-+
-+ if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
-+ { // string and/or delim are null
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ uint delimiter_length= delimiter->length();
-+ if (!res->length() || !delimiter_length || !count)
-+ return make_empty_result(); // Wrong parameters
-+
-+ res->set_charset(collation.collation);
-+
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ const char *ptr= res->ptr();
-+ const char *strend= ptr+res->length();
-+ const char *end= strend-delimiter_length+1;
-+ const char *search= delimiter->ptr();
-+ const char *search_end= search+delimiter_length;
-+ int32 n=0,c=count,pass;
-+ register uint32 l;
-+ for (pass=(count>0);pass<2;++pass)
-+ {
-+ while (ptr < end)
-+ {
-+ if (*ptr == *search)
-+ {
-+ register char *i,*j;
-+ i=(char*) ptr+1; j=(char*) search+1;
-+ while (j != search_end)
-+ if (*i++ != *j++) goto skip;
-+ if (pass==0) ++n;
-+ else if (!--c) break;
-+ ptr+= delimiter_length;
-+ continue;
-+ }
-+ skip:
-+ if ((l=my_ismbchar(res->charset(), ptr,strend))) ptr+=l;
-+ else ++ptr;
-+ } /* either not found or got total number when count<0 */
-+ if (pass == 0) /* count<0 */
-+ {
-+ c+=n+1;
-+ if (c<=0) return res; /* not found, return original string */
-+ ptr=res->ptr();
-+ }
-+ else
-+ {
-+ if (c) return res; /* Not found, return original string */
-+ if (count>0) /* return left part */
-+ {
-+ tmp_value.set(*res,0,(ulong) (ptr-res->ptr()));
-+ }
-+ else /* return right part */
-+ {
-+ ptr+= delimiter_length;
-+ tmp_value.set(*res,(ulong) (ptr-res->ptr()), (ulong) (strend-ptr));
-+ }
-+ }
-+ }
-+ }
-+ else
-+#endif /* USE_MB */
-+ {
-+ if (count > 0)
-+ { // start counting from the beginning
-+ for (offset=0; ; offset+= delimiter_length)
-+ {
-+ if ((int) (offset= res->strstr(*delimiter, offset)) < 0)
-+ return res; // Didn't find, return org string
-+ if (!--count)
-+ {
-+ tmp_value.set(*res,0,offset);
-+ break;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ Negative index, start counting at the end
-+ */
-+ for (offset=res->length(); offset ;)
-+ {
-+ /*
-+ this call will result in finding the position pointing to one
-+ address space less than where the found substring is located
-+ in res
-+ */
-+ if ((int) (offset= res->strrstr(*delimiter, offset)) < 0)
-+ return res; // Didn't find, return org string
-+ /*
-+ At this point, we've searched for the substring
-+ the number of times as supplied by the index value
-+ */
-+ if (!++count)
-+ {
-+ offset+= delimiter_length;
-+ tmp_value.set(*res,offset,res->length()- offset);
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ /*
-+ We always mark tmp_value as const so that if val_str() is called again
-+ on this object, we don't disrupt the contents of tmp_value when it was
-+ derived from another String.
-+ */
-+ tmp_value.mark_as_const();
-+ return (&tmp_value);
-+}
-+
-+/*
-+** The trim functions are extension to ANSI SQL because they trim substrings
-+** They ltrim() and rtrim() functions are optimized for 1 byte strings
-+** They also return the original string if possible, else they return
-+** a substring that points at the original string.
-+*/
-+
-+
-+String *Item_func_ltrim::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char buff[MAX_FIELD_WIDTH], *ptr, *end;
-+ String tmp(buff,sizeof(buff),system_charset_info);
-+ String *res, *remove_str;
-+ uint remove_length;
-+ LINT_INIT(remove_length);
-+
-+ res= args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ remove_str= &remove; /* Default value. */
-+ if (arg_count == 2)
-+ {
-+ remove_str= args[1]->val_str(&tmp);
-+ if ((null_value= args[1]->null_value))
-+ return 0;
-+ }
-+
-+ if ((remove_length= remove_str->length()) == 0 ||
-+ remove_length > res->length())
-+ return res;
-+
-+ ptr= (char*) res->ptr();
-+ end= ptr+res->length();
-+ if (remove_length == 1)
-+ {
-+ char chr=(*remove_str)[0];
-+ while (ptr != end && *ptr == chr)
-+ ptr++;
-+ }
-+ else
-+ {
-+ const char *r_ptr=remove_str->ptr();
-+ end-=remove_length;
-+ while (ptr <= end && !memcmp(ptr, r_ptr, remove_length))
-+ ptr+=remove_length;
-+ end+=remove_length;
-+ }
-+ if (ptr == res->ptr())
-+ return res;
-+ tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
-+ return &tmp_value;
-+}
-+
-+
-+String *Item_func_rtrim::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char buff[MAX_FIELD_WIDTH], *ptr, *end;
-+ String tmp(buff, sizeof(buff), system_charset_info);
-+ String *res, *remove_str;
-+ uint remove_length;
-+ LINT_INIT(remove_length);
-+
-+ res= args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ remove_str= &remove; /* Default value. */
-+ if (arg_count == 2)
-+ {
-+ remove_str= args[1]->val_str(&tmp);
-+ if ((null_value= args[1]->null_value))
-+ return 0;
-+ }
-+
-+ if ((remove_length= remove_str->length()) == 0 ||
-+ remove_length > res->length())
-+ return res;
-+
-+ ptr= (char*) res->ptr();
-+ end= ptr+res->length();
-+#ifdef USE_MB
-+ char *p=ptr;
-+ register uint32 l;
-+#endif
-+ if (remove_length == 1)
-+ {
-+ char chr=(*remove_str)[0];
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ while (ptr < end)
-+ {
-+ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l,p=ptr;
-+ else ++ptr;
-+ }
-+ ptr=p;
-+ }
-+#endif
-+ while (ptr != end && end[-1] == chr)
-+ end--;
-+ }
-+ else
-+ {
-+ const char *r_ptr=remove_str->ptr();
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ loop:
-+ while (ptr + remove_length < end)
-+ {
-+ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
-+ else ++ptr;
-+ }
-+ if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
-+ {
-+ end-=remove_length;
-+ ptr=p;
-+ goto loop;
-+ }
-+ }
-+ else
-+#endif /* USE_MB */
-+ {
-+ while (ptr + remove_length <= end &&
-+ !memcmp(end-remove_length, r_ptr, remove_length))
-+ end-=remove_length;
-+ }
-+ }
-+ if (end == res->ptr()+res->length())
-+ return res;
-+ tmp_value.set(*res,0,(uint) (end-res->ptr()));
-+ return &tmp_value;
-+}
-+
-+
-+String *Item_func_trim::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char buff[MAX_FIELD_WIDTH], *ptr, *end;
-+ const char *r_ptr;
-+ String tmp(buff, sizeof(buff), system_charset_info);
-+ String *res, *remove_str;
-+ uint remove_length;
-+ LINT_INIT(remove_length);
-+
-+ res= args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ remove_str= &remove; /* Default value. */
-+ if (arg_count == 2)
-+ {
-+ remove_str= args[1]->val_str(&tmp);
-+ if ((null_value= args[1]->null_value))
-+ return 0;
-+ }
-+
-+ if ((remove_length= remove_str->length()) == 0 ||
-+ remove_length > res->length())
-+ return res;
-+
-+ ptr= (char*) res->ptr();
-+ end= ptr+res->length();
-+ r_ptr= remove_str->ptr();
-+ while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
-+ ptr+=remove_length;
-+#ifdef USE_MB
-+ if (use_mb(res->charset()))
-+ {
-+ char *p=ptr;
-+ register uint32 l;
-+ loop:
-+ while (ptr + remove_length < end)
-+ {
-+ if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l;
-+ else ++ptr;
-+ }
-+ if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
-+ {
-+ end-=remove_length;
-+ ptr=p;
-+ goto loop;
-+ }
-+ ptr=p;
-+ }
-+ else
-+#endif /* USE_MB */
-+ {
-+ while (ptr + remove_length <= end &&
-+ !memcmp(end-remove_length,r_ptr,remove_length))
-+ end-=remove_length;
-+ }
-+ if (ptr == res->ptr() && end == ptr+res->length())
-+ return res;
-+ tmp_value.set(*res,(uint) (ptr - res->ptr()),(uint) (end-ptr));
-+ return &tmp_value;
-+}
-+
-+void Item_func_trim::fix_length_and_dec()
-+{
-+ max_length= args[0]->max_length;
-+ if (arg_count == 1)
-+ {
-+ collation.set(args[0]->collation);
-+ remove.set_charset(collation.collation);
-+ remove.set_ascii(" ",1);
-+ }
-+ else
-+ {
-+ // Handle character set for args[1] and args[0].
-+ // Note that we pass args[1] as the first item, and args[0] as the second.
-+ if (agg_arg_charsets(collation, &args[1], 2, MY_COLL_CMP_CONV, -1))
-+ return;
-+ }
-+}
-+
-+void Item_func_trim::print(String *str, enum_query_type query_type)
-+{
-+ if (arg_count == 1)
-+ {
-+ Item_func::print(str, query_type);
-+ return;
-+ }
-+ str->append(Item_func_trim::func_name());
-+ str->append('(');
-+ str->append(mode_name());
-+ str->append(' ');
-+ args[1]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" from "));
-+ args[0]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+
-+/* Item_func_password */
-+
-+String *Item_func_password::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ if (res->length() == 0)
-+ return make_empty_result();
-+ my_make_scrambled_password(tmp_value, res->ptr(), res->length());
-+ str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH, res->charset());
-+ return str;
-+}
-+
-+char *Item_func_password::alloc(THD *thd, const char *password,
-+ size_t pass_len)
-+{
-+ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH+1);
-+ if (buff)
-+ my_make_scrambled_password(buff, password, pass_len);
-+ return buff;
-+}
-+
-+/* Item_func_old_password */
-+
-+String *Item_func_old_password::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ if (res->length() == 0)
-+ return make_empty_result();
-+ my_make_scrambled_password_323(tmp_value, res->ptr(), res->length());
-+ str->set(tmp_value, SCRAMBLED_PASSWORD_CHAR_LENGTH_323, res->charset());
-+ return str;
-+}
-+
-+char *Item_func_old_password::alloc(THD *thd, const char *password,
-+ size_t pass_len)
-+{
-+ char *buff= (char *) thd->alloc(SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1);
-+ if (buff)
-+ my_make_scrambled_password_323(buff, password, pass_len);
-+ return buff;
-+}
-+
-+
-+#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-+
-+String *Item_func_encrypt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res =args[0]->val_str(str);
-+
-+#ifdef HAVE_CRYPT
-+ char salt[3],*salt_ptr;
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ if (res->length() == 0)
-+ return make_empty_result();
-+ if (arg_count == 1)
-+ { // generate random salt
-+ time_t timestamp=current_thd->query_start();
-+ salt[0] = bin_to_ascii( (ulong) timestamp & 0x3f);
-+ salt[1] = bin_to_ascii(( (ulong) timestamp >> 5) & 0x3f);
-+ salt[2] = 0;
-+ salt_ptr=salt;
-+ }
-+ else
-+ { // obtain salt from the first two bytes
-+ String *salt_str=args[1]->val_str(&tmp_value);
-+ if ((null_value= (args[1]->null_value || salt_str->length() < 2)))
-+ return 0;
-+ salt_ptr= salt_str->c_ptr_safe();
-+ }
-+ pthread_mutex_lock(&LOCK_crypt);
-+ char *tmp= crypt(res->c_ptr_safe(),salt_ptr);
-+ if (!tmp)
-+ {
-+ pthread_mutex_unlock(&LOCK_crypt);
-+ null_value= 1;
-+ return 0;
-+ }
-+ str->set(tmp, (uint) strlen(tmp), &my_charset_bin);
-+ str->copy();
-+ pthread_mutex_unlock(&LOCK_crypt);
-+ return str;
-+#else
-+ null_value=1;
-+ return 0;
-+#endif /* HAVE_CRYPT */
-+}
-+
-+bool Item_func_encode::seed()
-+{
-+ char buf[80];
-+ ulong rand_nr[2];
-+ String *key, tmp(buf, sizeof(buf), system_charset_info);
-+
-+ if (!(key= args[1]->val_str(&tmp)))
-+ return TRUE;
-+
-+ hash_password(rand_nr, key->ptr(), key->length());
-+ sql_crypt.init(rand_nr);
-+
-+ return FALSE;
-+}
-+
-+void Item_func_encode::fix_length_and_dec()
-+{
-+ max_length=args[0]->max_length;
-+ maybe_null=args[0]->maybe_null || args[1]->maybe_null;
-+ collation.set(&my_charset_bin);
-+ /* Precompute the seed state if the item is constant. */
-+ seeded= args[1]->const_item() &&
-+ (args[1]->result_type() == STRING_RESULT) && !seed();
-+}
-+
-+String *Item_func_encode::val_str(String *str)
-+{
-+ String *res;
-+ DBUG_ASSERT(fixed == 1);
-+
-+ if (!(res=args[0]->val_str(str)))
-+ {
-+ null_value= 1;
-+ return NULL;
-+ }
-+
-+ if (!seeded && seed())
-+ {
-+ null_value= 1;
-+ return NULL;
-+ }
-+
-+ null_value= 0;
-+ res= copy_if_not_alloced(str, res, res->length());
-+ crypto_transform(res);
-+ sql_crypt.reinit();
-+
-+ return res;
-+}
-+
-+void Item_func_encode::crypto_transform(String *res)
-+{
-+ sql_crypt.encode((char*) res->ptr(),res->length());
-+ res->set_charset(&my_charset_bin);
-+}
-+
-+void Item_func_decode::crypto_transform(String *res)
-+{
-+ sql_crypt.decode((char*) res->ptr(),res->length());
-+}
-+
-+
-+Item *Item_func_sysconst::safe_charset_converter(CHARSET_INFO *tocs)
-+{
-+ Item_string *conv;
-+ uint conv_errors;
-+ String tmp, cstr, *ostr= val_str(&tmp);
-+ if (null_value)
-+ {
-+ Item *null_item= new Item_null((char *) fully_qualified_func_name());
-+ null_item->collation.set (tocs);
-+ return null_item;
-+ }
-+ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
-+ if (conv_errors ||
-+ !(conv= new Item_static_string_func(fully_qualified_func_name(),
-+ cstr.ptr(), cstr.length(),
-+ cstr.charset(),
-+ collation.derivation)))
-+ {
-+ return NULL;
-+ }
-+ conv->str_value.copy();
-+ conv->str_value.mark_as_const();
-+ return conv;
-+}
-+
-+
-+String *Item_func_database::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ THD *thd= current_thd;
-+ if (thd->db == NULL)
-+ {
-+ null_value= 1;
-+ return 0;
-+ }
-+ else
-+ str->copy(thd->db, thd->db_length, system_charset_info);
-+ return str;
-+}
-+
-+
-+/**
-+ @note USER() is replicated correctly if binlog_format=ROW or (as of
-+ BUG#28086) binlog_format=MIXED, but is incorrectly replicated to ''
-+ if binlog_format=STATEMENT.
-+*/
-+bool Item_func_user::init(const char *user, const char *host)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+
-+ // For system threads (e.g. replication SQL thread) user may be empty
-+ if (user)
-+ {
-+ CHARSET_INFO *cs= str_value.charset();
-+ size_t res_length= (strlen(user)+strlen(host)+2) * cs->mbmaxlen;
-+
-+ if (str_value.alloc((uint) res_length))
-+ {
-+ null_value=1;
-+ return TRUE;
-+ }
-+
-+ res_length=cs->cset->snprintf(cs, (char*)str_value.ptr(), (uint) res_length,
-+ "%s@%s", user, host);
-+ str_value.length((uint) res_length);
-+ str_value.mark_as_const();
-+ }
-+ return FALSE;
-+}
-+
-+
-+bool Item_func_user::fix_fields(THD *thd, Item **ref)
-+{
-+ return (Item_func_sysconst::fix_fields(thd, ref) ||
-+ init(thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip));
-+}
-+
-+
-+bool Item_func_current_user::fix_fields(THD *thd, Item **ref)
-+{
-+ if (Item_func_sysconst::fix_fields(thd, ref))
-+ return TRUE;
-+
-+ Security_context *ctx=
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ (context->security_ctx
-+ ? context->security_ctx : thd->security_ctx);
-+#else
-+ thd->security_ctx;
-+#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
-+ return init(ctx->priv_user, ctx->priv_host);
-+}
-+
-+
-+void Item_func_soundex::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ max_length=args[0]->max_length;
-+ set_if_bigger(max_length, 4 * collation.collation->mbminlen);
-+ tmp_value.set_charset(collation.collation);
-+}
-+
-+
-+/**
-+ If alpha, map input letter to soundex code.
-+ If not alpha and remove_garbage is set then skip to next char
-+ else return 0
-+*/
-+
-+static int soundex_toupper(int ch)
-+{
-+ return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
-+}
-+
-+
-+static char get_scode(int wc)
-+{
-+ int ch= soundex_toupper(wc);
-+ if (ch < 'A' || ch > 'Z')
-+ {
-+ // Thread extended alfa (country spec)
-+ return '0'; // as vokal
-+ }
-+ return(soundex_map[ch-'A']);
-+}
-+
-+
-+static bool my_uni_isalpha(int wc)
-+{
-+ /*
-+ Return true for all Basic Latin letters: a..z A..Z.
-+ Return true for all Unicode characters with code higher than U+00C0:
-+ - characters between 'z' and U+00C0 are controls and punctuations.
-+ - "U+00C0 LATIN CAPITAL LETTER A WITH GRAVE" is the first letter after 'z'.
-+ */
-+ return (wc >= 'a' && wc <= 'z') ||
-+ (wc >= 'A' && wc <= 'Z') ||
-+ (wc >= 0xC0);
-+}
-+
-+
-+String *Item_func_soundex::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res =args[0]->val_str(str);
-+ char last_ch,ch;
-+ CHARSET_INFO *cs= collation.collation;
-+ my_wc_t wc;
-+ uint nchars;
-+ int rc;
-+
-+ if ((null_value= args[0]->null_value))
-+ return 0; /* purecov: inspected */
-+
-+ if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
-+ return str; /* purecov: inspected */
-+ char *to= (char *) tmp_value.ptr();
-+ char *to_end= to + tmp_value.alloced_length();
-+ char *from= (char *) res->ptr(), *end= from + res->length();
-+
-+ for ( ; ; ) /* Skip pre-space */
-+ {
-+ if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
-+ return make_empty_result(); /* EOL or invalid byte sequence */
-+
-+ if (rc == 1 && cs->ctype)
-+ {
-+ /* Single byte letter found */
-+ if (my_isalpha(cs, *from))
-+ {
-+ last_ch= get_scode(*from); // Code of the first letter
-+ *to++= soundex_toupper(*from++); // Copy first letter
-+ break;
-+ }
-+ from++;
-+ }
-+ else
-+ {
-+ from+= rc;
-+ if (my_uni_isalpha(wc))
-+ {
-+ /* Multibyte letter found */
-+ wc= soundex_toupper(wc);
-+ last_ch= get_scode(wc); // Code of the first letter
-+ if ((rc= cs->cset->wc_mb(cs, wc, (uchar*) to, (uchar*) to_end)) <= 0)
-+ {
-+ /* Extra safety - should not really happen */
-+ DBUG_ASSERT(false);
-+ return make_empty_result();
-+ }
-+ to+= rc;
-+ break;
-+ }
-+ }
-+ }
-+
-+ /*
-+ last_ch is now set to the first 'double-letter' check.
-+ loop on input letters until end of input
-+ */
-+ for (nchars= 1 ; ; )
-+ {
-+ if ((rc= cs->cset->mb_wc(cs, &wc, (uchar*) from, (uchar*) end)) <= 0)
-+ break; /* EOL or invalid byte sequence */
-+
-+ if (rc == 1 && cs->ctype)
-+ {
-+ if (!my_isalpha(cs, *from++))
-+ continue;
-+ }
-+ else
-+ {
-+ from+= rc;
-+ if (!my_uni_isalpha(wc))
-+ continue;
-+ }
-+
-+ ch= get_scode(wc);
-+ if ((ch != '0') && (ch != last_ch)) // if not skipped or double
-+ {
-+ // letter, copy to output
-+ if ((rc= cs->cset->wc_mb(cs, (my_wc_t) ch,
-+ (uchar*) to, (uchar*) to_end)) <= 0)
-+ {
-+ // Extra safety - should not really happen
-+ DBUG_ASSERT(false);
-+ break;
-+ }
-+ to+= rc;
-+ nchars++;
-+ last_ch= ch; // save code of last input letter
-+ } // for next double-letter check
-+ }
-+
-+ /* Pad up to 4 characters with DIGIT ZERO, if the string is shorter */
-+ if (nchars < 4)
-+ {
-+ uint nbytes= (4 - nchars) * cs->mbminlen;
-+ cs->cset->fill(cs, to, nbytes, '0');
-+ to+= nbytes;
-+ }
-+
-+ tmp_value.length((uint) (to-tmp_value.ptr()));
-+ return &tmp_value;
-+}
-+
-+
-+/**
-+ Change a number to format '3,333,333,333.000'.
-+
-+ This should be 'internationalized' sometimes.
-+*/
-+
-+const int FORMAT_MAX_DECIMALS= 30;
-+
-+Item_func_format::Item_func_format(Item *org, Item *dec)
-+: Item_str_func(org, dec)
-+{
-+}
-+
-+void Item_func_format::fix_length_and_dec()
-+{
-+ uint char_length= args[0]->max_length/args[0]->collation.collation->mbmaxlen;
-+ uint max_sep_count= char_length/3 + (decimals ? 1 : 0) + /*sign*/1;
-+ collation.set(default_charset());
-+ max_length= (char_length + max_sep_count + decimals) *
-+ collation.collation->mbmaxlen;
-+}
-+
-+
-+/**
-+ @todo
-+ This needs to be fixed for multi-byte character set where numbers
-+ are stored in more than one byte
-+*/
-+
-+String *Item_func_format::val_str(String *str)
-+{
-+ uint32 length;
-+ uint32 str_length;
-+ /* Number of decimal digits */
-+ int dec;
-+ /* Number of characters used to represent the decimals, including '.' */
-+ uint32 dec_length;
-+ int diff;
-+ DBUG_ASSERT(fixed == 1);
-+
-+ dec= (int) args[1]->val_int();
-+ if (args[1]->null_value)
-+ {
-+ null_value=1;
-+ return NULL;
-+ }
-+
-+ dec= set_zone(dec, 0, FORMAT_MAX_DECIMALS);
-+ dec_length= dec ? dec+1 : 0;
-+ null_value=0;
-+
-+ if (args[0]->result_type() == DECIMAL_RESULT ||
-+ args[0]->result_type() == INT_RESULT)
-+ {
-+ my_decimal dec_val, rnd_dec, *res;
-+ res= args[0]->val_decimal(&dec_val);
-+ if ((null_value=args[0]->null_value))
-+ return 0; /* purecov: inspected */
-+ my_decimal_round(E_DEC_FATAL_ERROR, res, dec, false, &rnd_dec);
-+ my_decimal2string(E_DEC_FATAL_ERROR, &rnd_dec, 0, 0, 0, str);
-+ str_length= str->length();
-+ if (rnd_dec.sign())
-+ str_length--;
-+ }
-+ else
-+ {
-+ double nr= args[0]->val_real();
-+ if ((null_value=args[0]->null_value))
-+ return 0; /* purecov: inspected */
-+ nr= my_double_round(nr, (longlong) dec, FALSE, FALSE);
-+ /* Here default_charset() is right as this is not an automatic conversion */
-+ str->set_real(nr, dec, default_charset());
-+ if (isnan(nr))
-+ return str;
-+ str_length=str->length();
-+ if (nr < 0)
-+ str_length--; // Don't count sign
-+ }
-+ /* We need this test to handle 'nan' values */
-+ if (str_length >= dec_length+4)
-+ {
-+ char *tmp,*pos;
-+ length= str->length()+(diff=((int)(str_length- dec_length-1))/3);
-+ str= copy_if_not_alloced(&tmp_str,str,length);
-+ str->length(length);
-+ tmp= (char*) str->ptr()+length - dec_length-1;
-+ for (pos= (char*) str->ptr()+length-1; pos != tmp; pos--)
-+ pos[0]= pos[-diff];
-+ while (diff)
-+ {
-+ *pos= *(pos - diff);
-+ pos--;
-+ *pos= *(pos - diff);
-+ pos--;
-+ *pos= *(pos - diff);
-+ pos--;
-+ pos[0]=',';
-+ pos--;
-+ diff--;
-+ }
-+ }
-+ return str;
-+}
-+
-+
-+void Item_func_format::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("format("));
-+ args[0]->print(str, query_type);
-+ str->append(',');
-+ args[1]->print(str, query_type);
-+ str->append(')');
-+}
-+
-+void Item_func_elt::fix_length_and_dec()
-+{
-+ max_length=0;
-+ decimals=0;
-+
-+ if (agg_arg_charsets(collation, args+1, arg_count-1, MY_COLL_ALLOW_CONV, 1))
-+ return;
-+
-+ for (uint i= 1 ; i < arg_count ; i++)
-+ {
-+ set_if_bigger(max_length,args[i]->max_length);
-+ set_if_bigger(decimals,args[i]->decimals);
-+ }
-+ maybe_null=1; // NULL if wrong first arg
-+}
-+
-+
-+double Item_func_elt::val_real()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint tmp;
-+ null_value=1;
-+ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
-+ return 0.0;
-+ double result= args[tmp]->val_real();
-+ null_value= args[tmp]->null_value;
-+ return result;
-+}
-+
-+
-+longlong Item_func_elt::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint tmp;
-+ null_value=1;
-+ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
-+ return 0;
-+
-+ longlong result= args[tmp]->val_int();
-+ null_value= args[tmp]->null_value;
-+ return result;
-+}
-+
-+
-+String *Item_func_elt::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint tmp;
-+ null_value=1;
-+ if ((tmp=(uint) args[0]->val_int()) == 0 || tmp >= arg_count)
-+ return NULL;
-+
-+ String *result= args[tmp]->val_str(str);
-+ if (result)
-+ result->set_charset(collation.collation);
-+ null_value= args[tmp]->null_value;
-+ return result;
-+}
-+
-+
-+void Item_func_make_set::split_sum_func(THD *thd, Item **ref_pointer_array,
-+ List<Item> &fields)
-+{
-+ item->split_sum_func2(thd, ref_pointer_array, fields, &item, TRUE);
-+ Item_str_func::split_sum_func(thd, ref_pointer_array, fields);
-+}
-+
-+
-+void Item_func_make_set::fix_length_and_dec()
-+{
-+ max_length=arg_count-1;
-+
-+ if (agg_arg_charsets(collation, args, arg_count, MY_COLL_ALLOW_CONV, 1))
-+ return;
-+
-+ for (uint i=0 ; i < arg_count ; i++)
-+ max_length+=args[i]->max_length;
-+
-+ used_tables_cache|= item->used_tables();
-+ not_null_tables_cache&= item->not_null_tables();
-+ const_item_cache&= item->const_item();
-+ with_sum_func= with_sum_func || item->with_sum_func;
-+}
-+
-+
-+void Item_func_make_set::update_used_tables()
-+{
-+ Item_func::update_used_tables();
-+ item->update_used_tables();
-+ used_tables_cache|=item->used_tables();
-+ const_item_cache&=item->const_item();
-+}
-+
-+
-+String *Item_func_make_set::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ ulonglong bits;
-+ bool first_found=0;
-+ Item **ptr=args;
-+ String *result=&my_empty_string;
-+
-+ bits=item->val_int();
-+ if ((null_value=item->null_value))
-+ return NULL;
-+
-+ if (arg_count < 64)
-+ bits &= ((ulonglong) 1 << arg_count)-1;
-+
-+ for (; bits; bits >>= 1, ptr++)
-+ {
-+ if (bits & 1)
-+ {
-+ String *res= (*ptr)->val_str(str);
-+ if (res) // Skip nulls
-+ {
-+ if (!first_found)
-+ { // First argument
-+ first_found=1;
-+ if (res != str)
-+ result=res; // Use original string
-+ else
-+ {
-+ if (tmp_str.copy(*res)) // Don't use 'str'
-+ return make_empty_result();
-+ result= &tmp_str;
-+ }
-+ }
-+ else
-+ {
-+ if (result != &tmp_str)
-+ { // Copy data to tmp_str
-+ if (tmp_str.alloc(result->length()+res->length()+1) ||
-+ tmp_str.copy(*result))
-+ return make_empty_result();
-+ result= &tmp_str;
-+ }
-+ if (tmp_str.append(STRING_WITH_LEN(","), &my_charset_bin) || tmp_str.append(*res))
-+ return make_empty_result();
-+ }
-+ }
-+ }
-+ }
-+ return result;
-+}
-+
-+
-+Item *Item_func_make_set::transform(Item_transformer transformer, uchar *arg)
-+{
-+ DBUG_ASSERT(!current_thd->is_stmt_prepare());
-+
-+ Item *new_item= item->transform(transformer, arg);
-+ if (!new_item)
-+ return 0;
-+
-+ /*
-+ THD::change_item_tree() should be called only if the tree was
-+ really transformed, i.e. when a new item has been created.
-+ Otherwise we'll be allocating a lot of unnecessary memory for
-+ change records at each execution.
-+ */
-+ if (item != new_item)
-+ current_thd->change_item_tree(&item, new_item);
-+ return Item_str_func::transform(transformer, arg);
-+}
-+
-+
-+void Item_func_make_set::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("make_set("));
-+ item->print(str, query_type);
-+ if (arg_count)
-+ {
-+ str->append(',');
-+ print_args(str, 0, query_type);
-+ }
-+ str->append(')');
-+}
-+
-+
-+String *Item_func_char::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ str->length(0);
-+ str->set_charset(collation.collation);
-+ for (uint i=0 ; i < arg_count ; i++)
-+ {
-+ int32 num=(int32) args[i]->val_int();
-+ if (!args[i]->null_value)
-+ {
-+ char char_num= (char) num;
-+ if (num&0xFF000000L) {
-+ str->append((char)(num>>24));
-+ goto b2;
-+ } else if (num&0xFF0000L) {
-+ b2: str->append((char)(num>>16));
-+ goto b1;
-+ } else if (num&0xFF00L) {
-+ b1: str->append((char)(num>>8));
-+ }
-+ str->append(&char_num, 1);
-+ }
-+ }
-+ str->realloc(str->length()); // Add end 0 (for Purify)
-+ return check_well_formed_result(str);
-+}
-+
-+
-+inline String* alloc_buffer(String *res,String *str,String *tmp_value,
-+ ulong length)
-+{
-+ if (res->alloced_length() < length)
-+ {
-+ if (str->alloced_length() >= length)
-+ {
-+ (void) str->copy(*res);
-+ str->length(length);
-+ return str;
-+ }
-+ if (tmp_value->alloc(length))
-+ return 0;
-+ (void) tmp_value->copy(*res);
-+ tmp_value->length(length);
-+ return tmp_value;
-+ }
-+ res->length(length);
-+ return res;
-+}
-+
-+
-+void Item_func_repeat::fix_length_and_dec()
-+{
-+ collation.set(args[0]->collation);
-+ if (args[1]->const_item())
-+ {
-+ /* must be longlong to avoid truncation */
-+ longlong count= args[1]->val_int();
-+
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if (count > INT_MAX32)
-+ count= INT_MAX32;
-+
-+ ulonglong max_result_length= (ulonglong) args[0]->max_length * count;
-+ if (max_result_length >= MAX_BLOB_WIDTH)
-+ {
-+ max_result_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) max_result_length;
-+ }
-+ else
-+ {
-+ max_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+}
-+
-+/**
-+ Item_func_repeat::str is carefully written to avoid reallocs
-+ as much as possible at the cost of a local buffer
-+*/
-+
-+String *Item_func_repeat::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint length,tot_length;
-+ char *to;
-+ /* must be longlong to avoid truncation */
-+ longlong count= args[1]->val_int();
-+ String *res= args[0]->val_str(str);
-+
-+ if (args[0]->null_value || args[1]->null_value)
-+ goto err; // string and/or delim are null
-+ null_value= 0;
-+
-+ if (count <= 0 && (count == 0 || !args[1]->unsigned_flag))
-+ return make_empty_result();
-+
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Bounds check on count: If this is triggered, we will error. */
-+ if ((ulonglong) count > INT_MAX32)
-+ count= INT_MAX32;
-+ if (count == 1) // To avoid reallocs
-+ return res;
-+ length=res->length();
-+ // Safe length check
-+ if (length > current_thd->variables.max_allowed_packet / (uint) count)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(), current_thd->variables.max_allowed_packet);
-+ goto err;
-+ }
-+ tot_length= length*(uint) count;
-+ if (!(res= alloc_buffer(res,str,&tmp_value,tot_length)))
-+ goto err;
-+
-+ to=(char*) res->ptr()+length;
-+ while (--count)
-+ {
-+ memcpy(to,res->ptr(),length);
-+ to+=length;
-+ }
-+ return (res);
-+
-+err:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_rpad::fix_length_and_dec()
-+{
-+ // Handle character set for args[0] and args[2].
-+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
-+ return;
-+ if (args[1]->const_item())
-+ {
-+ ulonglong length= 0;
-+
-+ if (collation.collation->mbmaxlen > 0)
-+ {
-+ ulonglong temp= (ulonglong) args[1]->val_int();
-+
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if (temp > INT_MAX32)
-+ temp = INT_MAX32;
-+
-+ length= temp * collation.collation->mbmaxlen;
-+ }
-+
-+ if (length >= MAX_BLOB_WIDTH)
-+ {
-+ length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) length;
-+ }
-+ else
-+ {
-+ max_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+}
-+
-+
-+String *Item_func_rpad::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint32 res_byte_length,res_char_length,pad_char_length,pad_byte_length;
-+ char *to;
-+ const char *ptr_pad;
-+ /* must be longlong to avoid truncation */
-+ longlong count= args[1]->val_int();
-+ longlong byte_count;
-+ String *res= args[0]->val_str(str);
-+ String *rpad= args[2]->val_str(&rpad_str);
-+
-+ if (!res || args[1]->null_value || !rpad ||
-+ ((count < 0) && !args[1]->unsigned_flag))
-+ goto err;
-+ null_value=0;
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if ((ulonglong) count > INT_MAX32)
-+ count= INT_MAX32;
-+ /*
-+ There is one exception not handled (intentionaly) by the character set
-+ aggregation code. If one string is strong side and is binary, and
-+ another one is weak side and is a multi-byte character string,
-+ then we need to operate on the second string in terms on bytes when
-+ calling ::numchars() and ::charpos(), rather than in terms of characters.
-+ Lets substitute its character set to binary.
-+ */
-+ if (collation.collation == &my_charset_bin)
-+ {
-+ res->set_charset(&my_charset_bin);
-+ rpad->set_charset(&my_charset_bin);
-+ }
-+
-+ if (count <= (res_char_length= res->numchars()))
-+ { // String to pad is big enough
-+ res->length(res->charpos((int) count)); // Shorten result if longer
-+ return (res);
-+ }
-+ pad_char_length= rpad->numchars();
-+
-+ byte_count= count * collation.collation->mbmaxlen;
-+ if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(), current_thd->variables.max_allowed_packet);
-+ goto err;
-+ }
-+ if (args[2]->null_value || !pad_char_length)
-+ goto err;
-+ res_byte_length= res->length(); /* Must be done before alloc_buffer */
-+ if (!(res= alloc_buffer(res,str,&tmp_value, (ulong) byte_count)))
-+ goto err;
-+
-+ to= (char*) res->ptr()+res_byte_length;
-+ ptr_pad=rpad->ptr();
-+ pad_byte_length= rpad->length();
-+ count-= res_char_length;
-+ for ( ; (uint32) count > pad_char_length; count-= pad_char_length)
-+ {
-+ memcpy(to,ptr_pad,pad_byte_length);
-+ to+= pad_byte_length;
-+ }
-+ if (count)
-+ {
-+ pad_byte_length= rpad->charpos((int) count);
-+ memcpy(to,ptr_pad,(size_t) pad_byte_length);
-+ to+= pad_byte_length;
-+ }
-+ res->length((uint) (to- (char*) res->ptr()));
-+ return (res);
-+
-+ err:
-+ null_value=1;
-+ return 0;
-+}
-+
-+
-+void Item_func_lpad::fix_length_and_dec()
-+{
-+ // Handle character set for args[0] and args[2].
-+ if (agg_arg_charsets(collation, &args[0], 2, MY_COLL_ALLOW_CONV, 2))
-+ return;
-+
-+ if (args[1]->const_item())
-+ {
-+ ulonglong length= 0;
-+
-+ if (collation.collation->mbmaxlen > 0)
-+ {
-+ ulonglong temp= (ulonglong) args[1]->val_int();
-+
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if (temp > INT_MAX32)
-+ temp= INT_MAX32;
-+
-+ length= temp * collation.collation->mbmaxlen;
-+ }
-+
-+ if (length >= MAX_BLOB_WIDTH)
-+ {
-+ length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+ max_length= (ulong) length;
-+ }
-+ else
-+ {
-+ max_length= MAX_BLOB_WIDTH;
-+ maybe_null= 1;
-+ }
-+}
-+
-+
-+String *Item_func_lpad::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint32 res_char_length,pad_char_length;
-+ /* must be longlong to avoid truncation */
-+ longlong count= args[1]->val_int();
-+ longlong byte_count;
-+ String *res= args[0]->val_str(&tmp_value);
-+ String *pad= args[2]->val_str(&lpad_str);
-+
-+ if (!res || args[1]->null_value || !pad ||
-+ ((count < 0) && !args[1]->unsigned_flag))
-+ goto err;
-+ null_value=0;
-+ /* Assumes that the maximum length of a String is < INT_MAX32. */
-+ /* Set here so that rest of code sees out-of-bound value as such. */
-+ if ((ulonglong) count > INT_MAX32)
-+ count= INT_MAX32;
-+
-+ /*
-+ There is one exception not handled (intentionaly) by the character set
-+ aggregation code. If one string is strong side and is binary, and
-+ another one is weak side and is a multi-byte character string,
-+ then we need to operate on the second string in terms on bytes when
-+ calling ::numchars() and ::charpos(), rather than in terms of characters.
-+ Lets substitute its character set to binary.
-+ */
-+ if (collation.collation == &my_charset_bin)
-+ {
-+ res->set_charset(&my_charset_bin);
-+ pad->set_charset(&my_charset_bin);
-+ }
-+
-+ res_char_length= res->numchars();
-+
-+ if (count <= res_char_length)
-+ {
-+ res->length(res->charpos((int) count));
-+ return res;
-+ }
-+
-+ pad_char_length= pad->numchars();
-+ byte_count= count * collation.collation->mbmaxlen;
-+
-+ if ((ulonglong) byte_count > current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(), current_thd->variables.max_allowed_packet);
-+ goto err;
-+ }
-+
-+ if (args[2]->null_value || !pad_char_length ||
-+ str->alloc((uint32) byte_count))
-+ goto err;
-+
-+ str->length(0);
-+ str->set_charset(collation.collation);
-+ count-= res_char_length;
-+ while (count >= pad_char_length)
-+ {
-+ str->append(*pad);
-+ count-= pad_char_length;
-+ }
-+ if (count > 0)
-+ str->append(pad->ptr(), pad->charpos((int) count), collation.collation);
-+
-+ str->append(*res);
-+ null_value= 0;
-+ return str;
-+
-+err:
-+ null_value= 1;
-+ return 0;
-+}
-+
-+
-+String *Item_func_conv::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ char *endptr,ans[65],*ptr;
-+ longlong dec;
-+ int from_base= (int) args[1]->val_int();
-+ int to_base= (int) args[2]->val_int();
-+ int err;
-+
-+ if (args[0]->null_value || args[1]->null_value || args[2]->null_value ||
-+ abs(to_base) > 36 || abs(to_base) < 2 ||
-+ abs(from_base) > 36 || abs(from_base) < 2 || !(res->length()))
-+ {
-+ null_value= 1;
-+ return NULL;
-+ }
-+ null_value= 0;
-+ unsigned_flag= !(from_base < 0);
-+
-+ if (args[0]->field_type() == MYSQL_TYPE_BIT)
-+ {
-+ /*
-+ Special case: The string representation of BIT doesn't resemble the
-+ decimal representation, so we shouldn't change it to string and then to
-+ decimal.
-+ */
-+ dec= args[0]->val_int();
-+ }
-+ else
-+ {
-+ if (from_base < 0)
-+ dec= my_strntoll(res->charset(), res->ptr(), res->length(),
-+ -from_base, &endptr, &err);
-+ else
-+ dec= (longlong) my_strntoull(res->charset(), res->ptr(), res->length(),
-+ from_base, &endptr, &err);
-+ }
-+
-+ ptr= longlong2str(dec, ans, to_base);
-+ if (str->copy(ans, (uint32) (ptr-ans), default_charset()))
-+ return make_empty_result();
-+ return str;
-+}
-+
-+
-+String *Item_func_conv_charset::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ if (use_cached_value)
-+ return null_value ? 0 : &str_value;
-+ String *arg= args[0]->val_str(str);
-+ uint dummy_errors;
-+ if (!arg)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value= tmp_value.copy(arg->ptr(), arg->length(), arg->charset(),
-+ conv_charset, &dummy_errors);
-+ return null_value ? 0 : check_well_formed_result(&tmp_value);
-+}
-+
-+void Item_func_conv_charset::fix_length_and_dec()
-+{
-+ collation.set(conv_charset, DERIVATION_IMPLICIT);
-+ max_length = args[0]->max_length*conv_charset->mbmaxlen;
-+}
-+
-+void Item_func_conv_charset::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("convert("));
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" using "));
-+ str->append(conv_charset->csname);
-+ str->append(')');
-+}
-+
-+String *Item_func_set_collation::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ str=args[0]->val_str(str);
-+ if ((null_value=args[0]->null_value))
-+ return 0;
-+ str->set_charset(collation.collation);
-+ return str;
-+}
-+
-+void Item_func_set_collation::fix_length_and_dec()
-+{
-+ CHARSET_INFO *set_collation;
-+ const char *colname;
-+ String tmp, *str= args[1]->val_str(&tmp);
-+ colname= str->c_ptr();
-+ if (colname == binary_keyword)
-+ set_collation= get_charset_by_csname(args[0]->collation.collation->csname,
-+ MY_CS_BINSORT,MYF(0));
-+ else
-+ {
-+ if (!(set_collation= get_charset_by_name(colname,MYF(0))))
-+ {
-+ my_error(ER_UNKNOWN_COLLATION, MYF(0), colname);
-+ return;
-+ }
-+ }
-+
-+ if (!set_collation ||
-+ !my_charset_same(args[0]->collation.collation,set_collation))
-+ {
-+ my_error(ER_COLLATION_CHARSET_MISMATCH, MYF(0),
-+ colname, args[0]->collation.collation->csname);
-+ return;
-+ }
-+ collation.set(set_collation, DERIVATION_EXPLICIT,
-+ args[0]->collation.repertoire);
-+ max_length= args[0]->max_length;
-+}
-+
-+
-+bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
-+{
-+ /* Assume we don't have rtti */
-+ if (this == item)
-+ return 1;
-+ if (item->type() != FUNC_ITEM)
-+ return 0;
-+ Item_func *item_func=(Item_func*) item;
-+ if (arg_count != item_func->arg_count ||
-+ functype() != item_func->functype())
-+ return 0;
-+ Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item;
-+ if (collation.collation != item_func_sc->collation.collation)
-+ return 0;
-+ for (uint i=0; i < arg_count ; i++)
-+ if (!args[i]->eq(item_func_sc->args[i], binary_cmp))
-+ return 0;
-+ return 1;
-+}
-+
-+
-+void Item_func_set_collation::print(String *str, enum_query_type query_type)
-+{
-+ str->append('(');
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" collate "));
-+ DBUG_ASSERT(args[1]->basic_const_item() &&
-+ args[1]->type() == Item::STRING_ITEM);
-+ args[1]->str_value.print(str);
-+ str->append(')');
-+}
-+
-+String *Item_func_charset::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint dummy_errors;
-+
-+ CHARSET_INFO *cs= args[0]->collation.collation;
-+ null_value= 0;
-+ str->copy(cs->csname, (uint) strlen(cs->csname),
-+ &my_charset_latin1, collation.collation, &dummy_errors);
-+ return str;
-+}
-+
-+String *Item_func_collation::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uint dummy_errors;
-+ CHARSET_INFO *cs= args[0]->collation.collation;
-+
-+ null_value= 0;
-+ str->copy(cs->name, (uint) strlen(cs->name),
-+ &my_charset_latin1, collation.collation, &dummy_errors);
-+ return str;
-+}
-+
-+
-+String *Item_func_hex::val_str(String *str)
-+{
-+ String *res;
-+ DBUG_ASSERT(fixed == 1);
-+ if (args[0]->result_type() != STRING_RESULT)
-+ {
-+ ulonglong dec;
-+ char ans[65],*ptr;
-+ /* Return hex of unsigned longlong value */
-+ if (args[0]->result_type() == REAL_RESULT ||
-+ args[0]->result_type() == DECIMAL_RESULT)
-+ {
-+ double val= args[0]->val_real();
-+ if ((val <= (double) LONGLONG_MIN) ||
-+ (val >= (double) (ulonglong) ULONGLONG_MAX))
-+ dec= ~(longlong) 0;
-+ else
-+ dec= (ulonglong) (val + (val > 0 ? 0.5 : -0.5));
-+ }
-+ else
-+ dec= (ulonglong) args[0]->val_int();
-+
-+ if ((null_value= args[0]->null_value))
-+ return 0;
-+ ptr= longlong2str(dec,ans,16);
-+ if (str->copy(ans,(uint32) (ptr-ans),default_charset()))
-+ return make_empty_result(); // End of memory
-+ return str;
-+ }
-+
-+ /* Convert given string to a hex string, character by character */
-+ res= args[0]->val_str(str);
-+ if (!res || tmp_value.alloc(res->length()*2+1))
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ null_value=0;
-+ tmp_value.length(res->length()*2);
-+
-+ octet2hex((char*) tmp_value.ptr(), res->ptr(), res->length());
-+ return &tmp_value;
-+}
-+
-+ /** Convert given hex string to a binary string. */
-+
-+String *Item_func_unhex::val_str(String *str)
-+{
-+ const char *from, *end;
-+ char *to;
-+ String *res;
-+ uint length;
-+ DBUG_ASSERT(fixed == 1);
-+
-+ res= args[0]->val_str(str);
-+ if (!res || tmp_value.alloc(length= (1+res->length())/2))
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+
-+ from= res->ptr();
-+ null_value= 0;
-+ tmp_value.length(length);
-+ to= (char*) tmp_value.ptr();
-+ if (res->length() % 2)
-+ {
-+ int hex_char;
-+ *to++= hex_char= hexchar_to_int(*from++);
-+ if ((null_value= (hex_char == -1)))
-+ return 0;
-+ }
-+ for (end=res->ptr()+res->length(); from < end ; from+=2, to++)
-+ {
-+ int hex_char;
-+ *to= (hex_char= hexchar_to_int(from[0])) << 4;
-+ if ((null_value= (hex_char == -1)))
-+ return 0;
-+ *to|= hex_char= hexchar_to_int(from[1]);
-+ if ((null_value= (hex_char == -1)))
-+ return 0;
-+ }
-+ return &tmp_value;
-+}
-+
-+
-+void Item_func_binary::print(String *str, enum_query_type query_type)
-+{
-+ str->append(STRING_WITH_LEN("cast("));
-+ args[0]->print(str, query_type);
-+ str->append(STRING_WITH_LEN(" as binary)"));
-+}
-+
-+
-+#include <my_dir.h> // For my_stat
-+
-+String *Item_load_file::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *file_name;
-+ File file;
-+ MY_STAT stat_info;
-+ char path[FN_REFLEN];
-+ DBUG_ENTER("load_file");
-+
-+ if (!(file_name= args[0]->val_str(str))
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ || !(current_thd->security_ctx->master_access & FILE_ACL)
-+#endif
-+ )
-+ goto err;
-+
-+ (void) fn_format(path, file_name->c_ptr_safe(), mysql_real_data_home, "",
-+ MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
-+
-+ /* Read only allowed from within dir specified by secure_file_priv */
-+ if (!is_secure_file_path(path))
-+ goto err;
-+
-+ if (!my_stat(path, &stat_info, MYF(0)))
-+ goto err;
-+
-+ if (!(stat_info.st_mode & S_IROTH))
-+ {
-+ /* my_error(ER_TEXTFILE_NOT_READABLE, MYF(0), file_name->c_ptr()); */
-+ goto err;
-+ }
-+ if (stat_info.st_size > (long) current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_ALLOWED_PACKET_OVERFLOWED,
-+ ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
-+ func_name(), current_thd->variables.max_allowed_packet);
-+ goto err;
-+ }
-+ if (tmp_value.alloc(stat_info.st_size))
-+ goto err;
-+ if ((file = my_open(file_name->ptr(), O_RDONLY, MYF(0))) < 0)
-+ goto err;
-+ if (my_read(file, (uchar*) tmp_value.ptr(), stat_info.st_size, MYF(MY_NABP)))
-+ {
-+ my_close(file, MYF(0));
-+ goto err;
-+ }
-+ tmp_value.length(stat_info.st_size);
-+ my_close(file, MYF(0));
-+ null_value = 0;
-+ DBUG_RETURN(&tmp_value);
-+
-+err:
-+ null_value = 1;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+String* Item_func_export_set::val_str(String* str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ ulonglong the_set = (ulonglong) args[0]->val_int();
-+ String yes_buf, *yes;
-+ yes = args[1]->val_str(&yes_buf);
-+ String no_buf, *no;
-+ no = args[2]->val_str(&no_buf);
-+ String *sep = NULL, sep_buf ;
-+
-+ uint num_set_values = 64;
-+ ulonglong mask = 0x1;
-+ str->length(0);
-+ str->set_charset(collation.collation);
-+
-+ /* Check if some argument is a NULL value */
-+ if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ /*
-+ Arg count can only be 3, 4 or 5 here. This is guaranteed from the
-+ grammar for EXPORT_SET()
-+ */
-+ switch(arg_count) {
-+ case 5:
-+ num_set_values = (uint) args[4]->val_int();
-+ if (num_set_values > 64)
-+ num_set_values=64;
-+ if (args[4]->null_value)
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ /* Fall through */
-+ case 4:
-+ if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
-+ {
-+ null_value=1;
-+ return 0;
-+ }
-+ break;
-+ case 3:
-+ {
-+ /* errors is not checked - assume "," can always be converted */
-+ uint errors;
-+ sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
-+ sep = &sep_buf;
-+ }
-+ break;
-+ default:
-+ DBUG_ASSERT(0); // cannot happen
-+ }
-+ null_value=0;
-+
-+ for (uint i = 0; i < num_set_values; i++, mask = (mask << 1))
-+ {
-+ if (the_set & mask)
-+ str->append(*yes);
-+ else
-+ str->append(*no);
-+ if (i != num_set_values - 1)
-+ str->append(*sep);
-+ }
-+ return str;
-+}
-+
-+void Item_func_export_set::fix_length_and_dec()
-+{
-+ uint length=max(args[1]->max_length,args[2]->max_length);
-+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
-+ max_length=length*64+sep_length*63;
-+
-+ if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
-+ MY_COLL_ALLOW_CONV, 1))
-+ return;
-+}
-+
-+String* Item_func_inet_ntoa::val_str(String* str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ uchar buf[8], *p;
-+ ulonglong n = (ulonglong) args[0]->val_int();
-+ char num[4];
-+
-+ /*
-+ We do not know if args[0] is NULL until we have called
-+ some val function on it if args[0] is not a constant!
-+
-+ Also return null if n > 255.255.255.255
-+ */
-+ if ((null_value= (args[0]->null_value || n > (ulonglong) LL(4294967295))))
-+ return 0; // Null value
-+
-+ str->set_charset(collation.collation);
-+ str->length(0);
-+ int4store(buf,n);
-+
-+ /* Now we can assume little endian. */
-+
-+ num[3]='.';
-+ for (p=buf+4 ; p-- > buf ; )
-+ {
-+ uint c = *p;
-+ uint n1,n2; // Try to avoid divisions
-+ n1= c / 100; // 100 digits
-+ c-= n1*100;
-+ n2= c / 10; // 10 digits
-+ c-=n2*10; // last digit
-+ num[0]=(char) n1+'0';
-+ num[1]=(char) n2+'0';
-+ num[2]=(char) c+'0';
-+ uint length=(n1 ? 4 : n2 ? 3 : 2); // Remove pre-zero
-+
-+ (void) str->append(num+4-length,length);
-+ }
-+ str->length(str->length()-1); // Remove last '.';
-+ return str;
-+}
-+
-+
-+#define get_esc_bit(mask, num) (1 & (*((mask) + ((num) >> 3))) >> ((num) & 7))
-+
-+/**
-+ QUOTE() function returns argument string in single quotes suitable for
-+ using in a SQL statement.
-+
-+ Adds a \\ before all characters that needs to be escaped in a SQL string.
-+ We also escape '^Z' (END-OF-FILE in windows) to avoid probelms when
-+ running commands from a file in windows.
-+
-+ This function is very useful when you want to generate SQL statements.
-+
-+ @note
-+ QUOTE(NULL) returns the string 'NULL' (4 letters, without quotes).
-+
-+ @retval
-+ str Quoted string
-+ @retval
-+ NULL Out of memory.
-+*/
-+
-+String *Item_func_quote::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ /*
-+ Bit mask that has 1 for set for the position of the following characters:
-+ 0, \, ' and ^Z
-+ */
-+
-+ static uchar escmask[32]=
-+ {
-+ 0x01, 0x00, 0x00, 0x04, 0x80, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-+ };
-+
-+ char *from, *to, *end, *start;
-+ String *arg= args[0]->val_str(str);
-+ uint arg_length, new_length;
-+ if (!arg) // Null argument
-+ {
-+ /* Return the string 'NULL' */
-+ str->copy(STRING_WITH_LEN("NULL"), collation.collation);
-+ null_value= 0;
-+ return str;
-+ }
-+
-+ arg_length= arg->length();
-+
-+ if (collation.collation->mbmaxlen == 1)
-+ {
-+ new_length= arg_length + 2; /* for beginning and ending ' signs */
-+ for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++)
-+ new_length+= get_esc_bit(escmask, (uchar) *from);
-+ }
-+ else
-+ {
-+ new_length= (arg_length * 2) + /* For string characters */
-+ (2 * collation.collation->mbmaxlen); /* For quotes */
-+ }
-+
-+ if (tmp_value.alloc(new_length))
-+ goto null;
-+
-+ if (collation.collation->mbmaxlen > 1)
-+ {
-+ CHARSET_INFO *cs= collation.collation;
-+ int mblen;
-+ uchar *to_end;
-+ to= (char*) tmp_value.ptr();
-+ to_end= (uchar*) to + new_length;
-+
-+ /* Put leading quote */
-+ if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
-+ goto null;
-+ to+= mblen;
-+
-+ for (start= (char*) arg->ptr(), end= start + arg_length; start < end; )
-+ {
-+ my_wc_t wc;
-+ bool escape;
-+ if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0)
-+ goto null;
-+ start+= mblen;
-+ switch (wc) {
-+ case 0: escape= 1; wc= '0'; break;
-+ case '\032': escape= 1; wc= 'Z'; break;
-+ case '\'': escape= 1; break;
-+ case '\\': escape= 1; break;
-+ default: escape= 0; break;
-+ }
-+ if (escape)
-+ {
-+ if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0)
-+ goto null;
-+ to+= mblen;
-+ }
-+ if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0)
-+ goto null;
-+ to+= mblen;
-+ }
-+
-+ /* Put trailing quote */
-+ if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0)
-+ goto null;
-+ to+= mblen;
-+ new_length= to - tmp_value.ptr();
-+ goto ret;
-+ }
-+
-+ /*
-+ We replace characters from the end to the beginning
-+ */
-+ to= (char*) tmp_value.ptr() + new_length - 1;
-+ *to--= '\'';
-+ for (start= (char*) arg->ptr(),end= start + arg_length; end-- != start; to--)
-+ {
-+ /*
-+ We can't use the bitmask here as we want to replace \O and ^Z with 0
-+ and Z
-+ */
-+ switch (*end) {
-+ case 0:
-+ *to--= '0';
-+ *to= '\\';
-+ break;
-+ case '\032':
-+ *to--= 'Z';
-+ *to= '\\';
-+ break;
-+ case '\'':
-+ case '\\':
-+ *to--= *end;
-+ *to= '\\';
-+ break;
-+ default:
-+ *to= *end;
-+ break;
-+ }
-+ }
-+ *to= '\'';
-+
-+ret:
-+ tmp_value.length(new_length);
-+ tmp_value.set_charset(collation.collation);
-+ null_value= 0;
-+ return &tmp_value;
-+
-+null:
-+ null_value= 1;
-+ return 0;
-+}
-+
-+longlong Item_func_uncompressed_length::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ if (res->is_empty()) return 0;
-+
-+ /*
-+ If length is <= 4 bytes, data is corrupt. This is the best we can do
-+ to detect garbage input without decompressing it.
-+ */
-+ if (res->length() <= 4)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_ZLIB_Z_DATA_ERROR,
-+ ER(ER_ZLIB_Z_DATA_ERROR));
-+ null_value= 1;
-+ return 0;
-+ }
-+
-+ /*
-+ res->ptr() using is safe because we have tested that string is at least
-+ 5 bytes long.
-+ res->c_ptr() is not used because:
-+ - we do not need \0 terminated string to get first 4 bytes
-+ - c_ptr() tests simbol after string end (uninitialiozed memory) which
-+ confuse valgrind
-+ */
-+ return uint4korr(res->ptr()) & 0x3FFFFFFF;
-+}
-+
-+longlong Item_func_crc32::val_int()
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res=args[0]->val_str(&value);
-+ if (!res)
-+ {
-+ null_value=1;
-+ return 0; /* purecov: inspected */
-+ }
-+ null_value=0;
-+ return (longlong) crc32(0L, (uchar*)res->ptr(), res->length());
-+}
-+
-+#ifdef HAVE_COMPRESS
-+#include "zlib.h"
-+
-+String *Item_func_compress::val_str(String *str)
-+{
-+ int err= Z_OK, code;
-+ ulong new_size;
-+ String *res;
-+ Byte *body;
-+ char *tmp, *last_char;
-+ DBUG_ASSERT(fixed == 1);
-+
-+ if (!(res= args[0]->val_str(str)))
-+ {
-+ null_value= 1;
-+ return 0;
-+ }
-+ null_value= 0;
-+ if (res->is_empty()) return res;
-+
-+ /*
-+ Citation from zlib.h (comment for compress function):
-+
-+ Compresses the source buffer into the destination buffer. sourceLen is
-+ the byte length of the source buffer. Upon entry, destLen is the total
-+ size of the destination buffer, which must be at least 0.1% larger than
-+ sourceLen plus 12 bytes.
-+ We assume here that the buffer can't grow more than .25 %.
-+ */
-+ new_size= res->length() + res->length() / 5 + 12;
-+
-+ // Check new_size overflow: new_size <= res->length()
-+ if (((uint32) (new_size+5) <= res->length()) ||
-+ buffer.realloc((uint32) new_size + 4 + 1))
-+ {
-+ null_value= 1;
-+ return 0;
-+ }
-+
-+ body= ((Byte*)buffer.ptr()) + 4;
-+
-+ // As far as we have checked res->is_empty() we can use ptr()
-+ if ((err= compress(body, &new_size,
-+ (const Bytef*)res->ptr(), res->length())) != Z_OK)
-+ {
-+ code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR;
-+ push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
-+ null_value= 1;
-+ return 0;
-+ }
-+
-+ tmp= (char*)buffer.ptr(); // int4store is a macro; avoid side effects
-+ int4store(tmp, res->length() & 0x3FFFFFFF);
-+
-+ /* This is to ensure that things works for CHAR fields, which trim ' ': */
-+ last_char= ((char*)body)+new_size-1;
-+ if (*last_char == ' ')
-+ {
-+ *++last_char= '.';
-+ new_size++;
-+ }
-+
-+ buffer.length((uint32)new_size + 4);
-+ return &buffer;
-+}
-+
-+
-+String *Item_func_uncompress::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ String *res= args[0]->val_str(str);
-+ ulong new_size;
-+ int err;
-+ uint code;
-+
-+ if (!res)
-+ goto err;
-+ null_value= 0;
-+ if (res->is_empty())
-+ return res;
-+
-+ /* If length is less than 4 bytes, data is corrupt */
-+ if (res->length() <= 4)
-+ {
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_ZLIB_Z_DATA_ERROR,
-+ ER(ER_ZLIB_Z_DATA_ERROR));
-+ goto err;
-+ }
-+
-+ /* Size of uncompressed data is stored as first 4 bytes of field */
-+ new_size= uint4korr(res->ptr()) & 0x3FFFFFFF;
-+ if (new_size > current_thd->variables.max_allowed_packet)
-+ {
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_TOO_BIG_FOR_UNCOMPRESS,
-+ ER(ER_TOO_BIG_FOR_UNCOMPRESS),
-+ current_thd->variables.max_allowed_packet);
-+ goto err;
-+ }
-+ if (buffer.realloc((uint32)new_size))
-+ goto err;
-+
-+ if ((err= uncompress((Byte*)buffer.ptr(), &new_size,
-+ ((const Bytef*)res->ptr())+4,res->length())) == Z_OK)
-+ {
-+ buffer.length((uint32) new_size);
-+ return &buffer;
-+ }
-+
-+ code= ((err == Z_BUF_ERROR) ? ER_ZLIB_Z_BUF_ERROR :
-+ ((err == Z_MEM_ERROR) ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_DATA_ERROR));
-+ push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code));
-+
-+err:
-+ null_value= 1;
-+ return 0;
-+}
-+#endif
-+
-+/*
-+ UUID, as in
-+ DCE 1.1: Remote Procedure Call,
-+ Open Group Technical Standard Document Number C706, October 1997,
-+ (supersedes C309 DCE: Remote Procedure Call 8/1994,
-+ which was basis for ISO/IEC 11578:1996 specification)
-+*/
-+
-+static struct rand_struct uuid_rand;
-+static uint nanoseq;
-+static ulonglong uuid_time=0;
-+static char clock_seq_and_node_str[]="-0000-000000000000";
-+
-+/**
-+ number of 100-nanosecond intervals between
-+ 1582-10-15 00:00:00.00 and 1970-01-01 00:00:00.00.
-+*/
-+#define UUID_TIME_OFFSET ((ulonglong) 141427 * 24 * 60 * 60 * \
-+ 1000 * 1000 * 10)
-+
-+#define UUID_VERSION 0x1000
-+#define UUID_VARIANT 0x8000
-+
-+static void tohex(char *to, uint from, uint len)
-+{
-+ to+= len;
-+ while (len--)
-+ {
-+ *--to= _dig_vec_lower[from & 15];
-+ from >>= 4;
-+ }
-+}
-+
-+static void set_clock_seq_str()
-+{
-+ uint16 clock_seq= ((uint)(my_rnd(&uuid_rand)*16383)) | UUID_VARIANT;
-+ tohex(clock_seq_and_node_str+1, clock_seq, 4);
-+ nanoseq= 0;
-+}
-+
-+String *Item_func_uuid::val_str(String *str)
-+{
-+ DBUG_ASSERT(fixed == 1);
-+ char *s;
-+ THD *thd= current_thd;
-+
-+ pthread_mutex_lock(&LOCK_uuid_generator);
-+ if (! uuid_time) /* first UUID() call. initializing data */
-+ {
-+ ulong tmp=sql_rnd_with_mutex();
-+ uchar mac[6];
-+ int i;
-+ if (my_gethwaddr(mac))
-+ {
-+ /* purecov: begin inspected */
-+ /*
-+ generating random "hardware addr"
-+ and because specs explicitly specify that it should NOT correlate
-+ with a clock_seq value (initialized random below), we use a separate
-+ randominit() here
-+ */
-+ randominit(&uuid_rand, tmp + (ulong) thd, tmp + (ulong)global_query_id);
-+ for (i=0; i < (int)sizeof(mac); i++)
-+ mac[i]=(uchar)(my_rnd(&uuid_rand)*255);
-+ /* purecov: end */
-+ }
-+ s=clock_seq_and_node_str+sizeof(clock_seq_and_node_str)-1;
-+ for (i=sizeof(mac)-1 ; i>=0 ; i--)
-+ {
-+ *--s=_dig_vec_lower[mac[i] & 15];
-+ *--s=_dig_vec_lower[mac[i] >> 4];
-+ }
-+ randominit(&uuid_rand, tmp + (ulong) server_start_time,
-+ tmp + (ulong) thd->status_var.bytes_sent);
-+ set_clock_seq_str();
-+ }
-+
-+ ulonglong tv= my_getsystime() + UUID_TIME_OFFSET + nanoseq;
-+
-+ if (likely(tv > uuid_time))
-+ {
-+ /*
-+ Current time is ahead of last timestamp, as it should be.
-+ If we "borrowed time", give it back, just as long as we
-+ stay ahead of the previous timestamp.
-+ */
-+ if (nanoseq)
-+ {
-+ DBUG_ASSERT((tv > uuid_time) && (nanoseq > 0));
-+ /*
-+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
-+ */
-+ ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
-+ tv-= delta;
-+ nanoseq-= delta;
-+ }
-+ }
-+ else
-+ {
-+ if (unlikely(tv == uuid_time))
-+ {
-+ /*
-+ For low-res system clocks. If several requests for UUIDs
-+ end up on the same tick, we add a nano-second to make them
-+ different.
-+ ( current_timestamp + nanoseq * calls_in_this_period )
-+ may end up > next_timestamp; this is OK. Nonetheless, we'll
-+ try to unwind nanoseq when we get a chance to.
-+ If nanoseq overflows, we'll start over with a new numberspace
-+ (so the if() below is needed so we can avoid the ++tv and thus
-+ match the follow-up if() if nanoseq overflows!).
-+ */
-+ if (likely(++nanoseq))
-+ ++tv;
-+ }
-+
-+ if (unlikely(tv <= uuid_time))
-+ {
-+ /*
-+ If the admin changes the system clock (or due to Daylight
-+ Saving Time), the system clock may be turned *back* so we
-+ go through a period once more for which we already gave out
-+ UUIDs. To avoid duplicate UUIDs despite potentially identical
-+ times, we make a new random component.
-+ We also come here if the nanoseq "borrowing" overflows.
-+ In either case, we throw away any nanoseq borrowing since it's
-+ irrelevant in the new numberspace.
-+ */
-+ set_clock_seq_str();
-+ tv= my_getsystime() + UUID_TIME_OFFSET;
-+ nanoseq= 0;
-+ DBUG_PRINT("uuid",("making new numberspace"));
-+ }
-+ }
-+
-+ uuid_time=tv;
-+ pthread_mutex_unlock(&LOCK_uuid_generator);
-+
-+ uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
-+ uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
-+ uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
-+
-+ str->realloc(UUID_LENGTH+1);
-+ str->length(UUID_LENGTH);
-+ str->set_charset(system_charset_info);
-+ s=(char *) str->ptr();
-+ s[8]=s[13]='-';
-+ tohex(s, time_low, 8);
-+ tohex(s+9, time_mid, 4);
-+ tohex(s+14, time_hi_and_version, 4);
-+ strmov(s+18, clock_seq_and_node_str);
-+ return str;
-+}
-diff -urN mysql-old/sql/item_strfunc.h.orig mysql/sql/item_strfunc.h.orig
---- mysql-old/sql/item_strfunc.h.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/item_strfunc.h.orig 2011-04-12 12:11:38.000000000 +0000
-@@ -0,0 +1,868 @@
-+/* Copyright (C) 2000-2003 MySQL AB
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+
-+/* This file defines all string functions */
-+
-+#ifdef USE_PRAGMA_INTERFACE
-+#pragma interface /* gcc class implementation */
-+#endif
-+
-+class Item_str_func :public Item_func
-+{
-+protected:
-+ /**
-+ Sets the result value of the function an empty string, using the current
-+ character set. No memory is allocated.
-+ @retval A pointer to the str_value member.
-+ */
-+ String *make_empty_result() {
-+ str_value.set("", 0, collation.collation);
-+ return &str_value;
-+ }
-+public:
-+ Item_str_func() :Item_func() { decimals=NOT_FIXED_DEC; }
-+ Item_str_func(Item *a) :Item_func(a) {decimals=NOT_FIXED_DEC; }
-+ Item_str_func(Item *a,Item *b) :Item_func(a,b) { decimals=NOT_FIXED_DEC; }
-+ Item_str_func(Item *a,Item *b,Item *c) :Item_func(a,b,c) { decimals=NOT_FIXED_DEC; }
-+ Item_str_func(Item *a,Item *b,Item *c,Item *d) :Item_func(a,b,c,d) {decimals=NOT_FIXED_DEC; }
-+ Item_str_func(Item *a,Item *b,Item *c,Item *d, Item* e) :Item_func(a,b,c,d,e) {decimals=NOT_FIXED_DEC; }
-+ Item_str_func(List<Item> &list) :Item_func(list) {decimals=NOT_FIXED_DEC; }
-+ longlong val_int();
-+ double val_real();
-+ my_decimal *val_decimal(my_decimal *);
-+ enum Item_result result_type () const { return STRING_RESULT; }
-+ void left_right_max_length();
-+ bool fix_fields(THD *thd, Item **ref);
-+};
-+
-+class Item_func_md5 :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_md5(Item *a) :Item_str_func(a)
-+ {
-+ collation.set(&my_charset_bin);
-+ }
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "md5"; }
-+};
-+
-+
-+class Item_func_sha :public Item_str_func
-+{
-+public:
-+ Item_func_sha(Item *a) :Item_str_func(a)
-+ {
-+ collation.set(&my_charset_bin);
-+ }
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "sha"; }
-+};
-+
-+class Item_func_aes_encrypt :public Item_str_func
-+{
-+public:
-+ Item_func_aes_encrypt(Item *a, Item *b) :Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "aes_encrypt"; }
-+};
-+
-+class Item_func_aes_decrypt :public Item_str_func
-+{
-+public:
-+ Item_func_aes_decrypt(Item *a, Item *b) :Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "aes_decrypt"; }
-+};
-+
-+
-+class Item_func_concat :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_concat(List<Item> &list) :Item_str_func(list) {}
-+ Item_func_concat(Item *a,Item *b) :Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "concat"; }
-+};
-+
-+class Item_func_concat_ws :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_concat_ws(List<Item> &list) :Item_str_func(list) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "concat_ws"; }
-+ table_map not_null_tables() const { return 0; }
-+};
-+
-+class Item_func_reverse :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_reverse(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "reverse"; }
-+};
-+
-+
-+class Item_func_replace :public Item_str_func
-+{
-+ String tmp_value,tmp_value2;
-+public:
-+ Item_func_replace(Item *org,Item *find,Item *replace)
-+ :Item_str_func(org,find,replace) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "replace"; }
-+};
-+
-+
-+class Item_func_insert :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_insert(Item *org,Item *start,Item *length,Item *new_str)
-+ :Item_str_func(org,start,length,new_str) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "insert"; }
-+};
-+
-+
-+class Item_str_conv :public Item_str_func
-+{
-+protected:
-+ uint multiply;
-+ my_charset_conv_case converter;
-+ String tmp_value;
-+public:
-+ Item_str_conv(Item *item) :Item_str_func(item) {}
-+ String *val_str(String *);
-+};
-+
-+
-+class Item_func_lcase :public Item_str_conv
-+{
-+public:
-+ Item_func_lcase(Item *item) :Item_str_conv(item) {}
-+ const char *func_name() const { return "lcase"; }
-+ void fix_length_and_dec();
-+};
-+
-+class Item_func_ucase :public Item_str_conv
-+{
-+public:
-+ Item_func_ucase(Item *item) :Item_str_conv(item) {}
-+ const char *func_name() const { return "ucase"; }
-+ void fix_length_and_dec();
-+};
-+
-+
-+class Item_func_left :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_left(Item *a,Item *b) :Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "left"; }
-+};
-+
-+
-+class Item_func_right :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_right(Item *a,Item *b) :Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "right"; }
-+};
-+
-+
-+class Item_func_substr :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_substr(Item *a,Item *b) :Item_str_func(a,b) {}
-+ Item_func_substr(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "substr"; }
-+};
-+
-+
-+class Item_func_substr_index :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_substr_index(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "substring_index"; }
-+};
-+
-+
-+class Item_func_trim :public Item_str_func
-+{
-+protected:
-+ String tmp_value;
-+ String remove;
-+public:
-+ Item_func_trim(Item *a,Item *b) :Item_str_func(a,b) {}
-+ Item_func_trim(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "trim"; }
-+ virtual void print(String *str, enum_query_type query_type);
-+ virtual const char *mode_name() const { return "both"; }
-+};
-+
-+
-+class Item_func_ltrim :public Item_func_trim
-+{
-+public:
-+ Item_func_ltrim(Item *a,Item *b) :Item_func_trim(a,b) {}
-+ Item_func_ltrim(Item *a) :Item_func_trim(a) {}
-+ String *val_str(String *);
-+ const char *func_name() const { return "ltrim"; }
-+ const char *mode_name() const { return "leading"; }
-+};
-+
-+
-+class Item_func_rtrim :public Item_func_trim
-+{
-+public:
-+ Item_func_rtrim(Item *a,Item *b) :Item_func_trim(a,b) {}
-+ Item_func_rtrim(Item *a) :Item_func_trim(a) {}
-+ String *val_str(String *);
-+ const char *func_name() const { return "rtrim"; }
-+ const char *mode_name() const { return "trailing"; }
-+};
-+
-+
-+/*
-+ Item_func_password -- new (4.1.1) PASSWORD() function implementation.
-+ Returns strcat('*', octet2hex(sha1(sha1(password)))). '*' stands for new
-+ password format, sha1(sha1(password) is so-called hash_stage2 value.
-+ Length of returned string is always 41 byte. To find out how entire
-+ authentication procedure works, see comments in password.c.
-+*/
-+
-+class Item_func_password :public Item_str_func
-+{
-+ char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH+1];
-+public:
-+ Item_func_password(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *str);
-+ void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH; }
-+ const char *func_name() const { return "password"; }
-+ static char *alloc(THD *thd, const char *password, size_t pass_len);
-+};
-+
-+
-+/*
-+ Item_func_old_password -- PASSWORD() implementation used in MySQL 3.21 - 4.0
-+ compatibility mode. This item is created in sql_yacc.yy when
-+ 'old_passwords' session variable is set, and to handle OLD_PASSWORD()
-+ function.
-+*/
-+
-+class Item_func_old_password :public Item_str_func
-+{
-+ char tmp_value[SCRAMBLED_PASSWORD_CHAR_LENGTH_323+1];
-+public:
-+ Item_func_old_password(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *str);
-+ void fix_length_and_dec() { max_length= SCRAMBLED_PASSWORD_CHAR_LENGTH_323; }
-+ const char *func_name() const { return "old_password"; }
-+ static char *alloc(THD *thd, const char *password, size_t pass_len);
-+};
-+
-+
-+class Item_func_des_encrypt :public Item_str_func
-+{
-+ String tmp_value,tmp_arg;
-+public:
-+ Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
-+ Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ maybe_null=1;
-+ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
-+ max_length = args[0]->max_length + 9;
-+ }
-+ const char *func_name() const { return "des_encrypt"; }
-+};
-+
-+class Item_func_des_decrypt :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
-+ Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ maybe_null=1;
-+ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
-+ max_length = args[0]->max_length - 9;
-+ }
-+ const char *func_name() const { return "des_decrypt"; }
-+};
-+
-+class Item_func_encrypt :public Item_str_func
-+{
-+ String tmp_value;
-+
-+ /* Encapsulate common constructor actions */
-+ void constructor_helper()
-+ {
-+ collation.set(&my_charset_bin);
-+ }
-+public:
-+ Item_func_encrypt(Item *a) :Item_str_func(a)
-+ {
-+ constructor_helper();
-+ }
-+ Item_func_encrypt(Item *a, Item *b): Item_str_func(a,b)
-+ {
-+ constructor_helper();
-+ }
-+ String *val_str(String *);
-+ void fix_length_and_dec() { maybe_null=1; max_length = 13; }
-+ const char *func_name() const { return "encrypt"; }
-+};
-+
-+#include "sql_crypt.h"
-+
-+
-+class Item_func_encode :public Item_str_func
-+{
-+private:
-+ /** Whether the PRNG has already been seeded. */
-+ bool seeded;
-+protected:
-+ SQL_CRYPT sql_crypt;
-+public:
-+ Item_func_encode(Item *a, Item *seed):
-+ Item_str_func(a, seed) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "encode"; }
-+protected:
-+ virtual void crypto_transform(String *);
-+private:
-+ /** Provide a seed for the PRNG sequence. */
-+ bool seed();
-+};
-+
-+
-+class Item_func_decode :public Item_func_encode
-+{
-+public:
-+ Item_func_decode(Item *a, Item *seed): Item_func_encode(a, seed) {}
-+ const char *func_name() const { return "decode"; }
-+protected:
-+ void crypto_transform(String *);
-+};
-+
-+
-+class Item_func_sysconst :public Item_str_func
-+{
-+public:
-+ Item_func_sysconst()
-+ { collation.set(system_charset_info,DERIVATION_SYSCONST); }
-+ Item *safe_charset_converter(CHARSET_INFO *tocs);
-+ /*
-+ Used to create correct Item name in new converted item in
-+ safe_charset_converter, return string representation of this function
-+ call
-+ */
-+ virtual const char *fully_qualified_func_name() const = 0;
-+};
-+
-+
-+class Item_func_database :public Item_func_sysconst
-+{
-+public:
-+ Item_func_database() :Item_func_sysconst() {}
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ max_length= MAX_FIELD_NAME * system_charset_info->mbmaxlen;
-+ maybe_null=1;
-+ }
-+ const char *func_name() const { return "database"; }
-+ const char *fully_qualified_func_name() const { return "database()"; }
-+};
-+
-+
-+class Item_func_user :public Item_func_sysconst
-+{
-+protected:
-+ bool init (const char *user, const char *host);
-+
-+public:
-+ Item_func_user()
-+ {
-+ str_value.set("", 0, system_charset_info);
-+ }
-+ String *val_str(String *)
-+ {
-+ DBUG_ASSERT(fixed == 1);
-+ return (null_value ? 0 : &str_value);
-+ }
-+ bool fix_fields(THD *thd, Item **ref);
-+ void fix_length_and_dec()
-+ {
-+ max_length= (USERNAME_LENGTH +
-+ (HOSTNAME_LENGTH + 1) * SYSTEM_CHARSET_MBMAXLEN);
-+ }
-+ const char *func_name() const { return "user"; }
-+ const char *fully_qualified_func_name() const { return "user()"; }
-+ int save_in_field(Field *field, bool no_conversions)
-+ {
-+ return save_str_value_in_field(field, &str_value);
-+ }
-+};
-+
-+
-+class Item_func_current_user :public Item_func_user
-+{
-+ Name_resolution_context *context;
-+
-+public:
-+ Item_func_current_user(Name_resolution_context *context_arg)
-+ : context(context_arg) {}
-+ bool fix_fields(THD *thd, Item **ref);
-+ const char *func_name() const { return "current_user"; }
-+ const char *fully_qualified_func_name() const { return "current_user()"; }
-+};
-+
-+
-+class Item_func_soundex :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_soundex(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "soundex"; }
-+};
-+
-+
-+class Item_func_elt :public Item_str_func
-+{
-+public:
-+ Item_func_elt(List<Item> &list) :Item_str_func(list) {}
-+ double val_real();
-+ longlong val_int();
-+ String *val_str(String *str);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "elt"; }
-+};
-+
-+
-+class Item_func_make_set :public Item_str_func
-+{
-+ Item *item;
-+ String tmp_str;
-+
-+public:
-+ Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
-+ String *val_str(String *str);
-+ bool fix_fields(THD *thd, Item **ref)
-+ {
-+ DBUG_ASSERT(fixed == 0);
-+ return ((!item->fixed && item->fix_fields(thd, &item)) ||
-+ item->check_cols(1) ||
-+ Item_func::fix_fields(thd, ref));
-+ }
-+ void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
-+ void fix_length_and_dec();
-+ void update_used_tables();
-+ const char *func_name() const { return "make_set"; }
-+
-+ bool walk(Item_processor processor, bool walk_subquery, uchar *arg)
-+ {
-+ return item->walk(processor, walk_subquery, arg) ||
-+ Item_str_func::walk(processor, walk_subquery, arg);
-+ }
-+ Item *transform(Item_transformer transformer, uchar *arg);
-+ virtual void print(String *str, enum_query_type query_type);
-+};
-+
-+
-+class Item_func_format :public Item_str_func
-+{
-+ String tmp_str;
-+public:
-+ Item_func_format(Item *org, Item *dec);
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "format"; }
-+ virtual void print(String *str, enum_query_type query_type);
-+};
-+
-+
-+class Item_func_char :public Item_str_func
-+{
-+public:
-+ Item_func_char(List<Item> &list) :Item_str_func(list)
-+ { collation.set(&my_charset_bin); }
-+ Item_func_char(List<Item> &list, CHARSET_INFO *cs) :Item_str_func(list)
-+ { collation.set(cs); }
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ max_length= arg_count * 4;
-+ }
-+ const char *func_name() const { return "char"; }
-+};
-+
-+
-+class Item_func_repeat :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_repeat(Item *arg1,Item *arg2) :Item_str_func(arg1,arg2) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "repeat"; }
-+};
-+
-+
-+class Item_func_rpad :public Item_str_func
-+{
-+ String tmp_value, rpad_str;
-+public:
-+ Item_func_rpad(Item *arg1,Item *arg2,Item *arg3)
-+ :Item_str_func(arg1,arg2,arg3) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "rpad"; }
-+};
-+
-+
-+class Item_func_lpad :public Item_str_func
-+{
-+ String tmp_value, lpad_str;
-+public:
-+ Item_func_lpad(Item *arg1,Item *arg2,Item *arg3)
-+ :Item_str_func(arg1,arg2,arg3) {}
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "lpad"; }
-+};
-+
-+
-+class Item_func_conv :public Item_str_func
-+{
-+public:
-+ Item_func_conv(Item *a,Item *b,Item *c) :Item_str_func(a,b,c) {}
-+ const char *func_name() const { return "conv"; }
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ collation.set(default_charset());
-+ max_length=64;
-+ maybe_null= 1;
-+ }
-+};
-+
-+
-+class Item_func_hex :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_hex(Item *a) :Item_str_func(a) {}
-+ const char *func_name() const { return "hex"; }
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ collation.set(default_charset());
-+ decimals=0;
-+ max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
-+ }
-+};
-+
-+class Item_func_unhex :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_unhex(Item *a) :Item_str_func(a)
-+ {
-+ /* there can be bad hex strings */
-+ maybe_null= 1;
-+ }
-+ const char *func_name() const { return "unhex"; }
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ collation.set(&my_charset_bin);
-+ decimals=0;
-+ max_length=(1+args[0]->max_length)/2;
-+ }
-+};
-+
-+
-+class Item_func_binary :public Item_str_func
-+{
-+public:
-+ Item_func_binary(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *a)
-+ {
-+ DBUG_ASSERT(fixed == 1);
-+ String *tmp=args[0]->val_str(a);
-+ null_value=args[0]->null_value;
-+ if (tmp)
-+ tmp->set_charset(&my_charset_bin);
-+ return tmp;
-+ }
-+ void fix_length_and_dec()
-+ {
-+ collation.set(&my_charset_bin);
-+ max_length=args[0]->max_length;
-+ }
-+ virtual void print(String *str, enum_query_type query_type);
-+ const char *func_name() const { return "cast_as_binary"; }
-+};
-+
-+
-+class Item_load_file :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_load_file(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ const char *func_name() const { return "load_file"; }
-+ void fix_length_and_dec()
-+ {
-+ collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
-+ maybe_null=1;
-+ max_length=MAX_BLOB_WIDTH;
-+ }
-+};
-+
-+
-+class Item_func_export_set: public Item_str_func
-+{
-+ public:
-+ Item_func_export_set(Item *a,Item *b,Item* c) :Item_str_func(a,b,c) {}
-+ Item_func_export_set(Item *a,Item *b,Item* c,Item* d) :Item_str_func(a,b,c,d) {}
-+ Item_func_export_set(Item *a,Item *b,Item* c,Item* d,Item* e) :Item_str_func(a,b,c,d,e) {}
-+ String *val_str(String *str);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "export_set"; }
-+};
-+
-+class Item_func_inet_ntoa : public Item_str_func
-+{
-+public:
-+ Item_func_inet_ntoa(Item *a) :Item_str_func(a)
-+ {
-+ }
-+ String* val_str(String* str);
-+ const char *func_name() const { return "inet_ntoa"; }
-+ void fix_length_and_dec()
-+ {
-+ decimals= 0;
-+ max_length= 3 * 8 + 7;
-+ maybe_null= 1;
-+ }
-+};
-+
-+class Item_func_quote :public Item_str_func
-+{
-+ String tmp_value;
-+public:
-+ Item_func_quote(Item *a) :Item_str_func(a) {}
-+ const char *func_name() const { return "quote"; }
-+ String *val_str(String *);
-+ void fix_length_and_dec()
-+ {
-+ collation.set(args[0]->collation);
-+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
-+ 2 * collation.collation->mbmaxlen;
-+ max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
-+ }
-+};
-+
-+class Item_func_conv_charset :public Item_str_func
-+{
-+ bool use_cached_value;
-+ String tmp_value;
-+public:
-+ bool safe;
-+ CHARSET_INFO *conv_charset; // keep it public
-+ Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a)
-+ { conv_charset= cs; use_cached_value= 0; safe= 0; }
-+ Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const)
-+ :Item_str_func(a)
-+ {
-+ DBUG_ASSERT(args[0]->fixed);
-+ conv_charset= cs;
-+ if (cache_if_const && args[0]->const_item())
-+ {
-+ uint errors= 0;
-+ String tmp, *str= args[0]->val_str(&tmp);
-+ if (!str || str_value.copy(str->ptr(), str->length(),
-+ str->charset(), conv_charset, &errors))
-+ null_value= 1;
-+ use_cached_value= 1;
-+ str_value.mark_as_const();
-+ safe= (errors == 0);
-+ }
-+ else
-+ {
-+ use_cached_value= 0;
-+ /*
-+ Conversion from and to "binary" is safe.
-+ Conversion to Unicode is safe.
-+ Other kind of conversions are potentially lossy.
-+ */
-+ safe= (args[0]->collation.collation == &my_charset_bin ||
-+ cs == &my_charset_bin ||
-+ (cs->state & MY_CS_UNICODE));
-+ }
-+ }
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ const char *func_name() const { return "convert"; }
-+ virtual void print(String *str, enum_query_type query_type);
-+};
-+
-+class Item_func_set_collation :public Item_str_func
-+{
-+public:
-+ Item_func_set_collation(Item *a, Item *b) :Item_str_func(a,b) {};
-+ String *val_str(String *);
-+ void fix_length_and_dec();
-+ bool eq(const Item *item, bool binary_cmp) const;
-+ const char *func_name() const { return "collate"; }
-+ enum Functype functype() const { return COLLATE_FUNC; }
-+ virtual void print(String *str, enum_query_type query_type);
-+ Item_field *filed_for_view_update()
-+ {
-+ /* this function is transparent for view updating */
-+ return args[0]->filed_for_view_update();
-+ }
-+};
-+
-+class Item_func_charset :public Item_str_func
-+{
-+public:
-+ Item_func_charset(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ const char *func_name() const { return "charset"; }
-+ void fix_length_and_dec()
-+ {
-+ collation.set(system_charset_info);
-+ max_length= 64 * collation.collation->mbmaxlen; // should be enough
-+ maybe_null= 0;
-+ };
-+ table_map not_null_tables() const { return 0; }
-+};
-+
-+class Item_func_collation :public Item_str_func
-+{
-+public:
-+ Item_func_collation(Item *a) :Item_str_func(a) {}
-+ String *val_str(String *);
-+ const char *func_name() const { return "collation"; }
-+ void fix_length_and_dec()
-+ {
-+ collation.set(system_charset_info);
-+ max_length= 64 * collation.collation->mbmaxlen; // should be enough
-+ maybe_null= 0;
-+ };
-+ table_map not_null_tables() const { return 0; }
-+};
-+
-+class Item_func_crc32 :public Item_int_func
-+{
-+ String value;
-+public:
-+ Item_func_crc32(Item *a) :Item_int_func(a) { unsigned_flag= 1; }
-+ const char *func_name() const { return "crc32"; }
-+ void fix_length_and_dec() { max_length=10; }
-+ longlong val_int();
-+};
-+
-+class Item_func_uncompressed_length : public Item_int_func
-+{
-+ String value;
-+public:
-+ Item_func_uncompressed_length(Item *a):Item_int_func(a){}
-+ const char *func_name() const{return "uncompressed_length";}
-+ void fix_length_and_dec() { max_length=10; }
-+ longlong val_int();
-+};
-+
-+#ifdef HAVE_COMPRESS
-+#define ZLIB_DEPENDED_FUNCTION ;
-+#else
-+#define ZLIB_DEPENDED_FUNCTION { null_value=1; return 0; }
-+#endif
-+
-+class Item_func_compress: public Item_str_func
-+{
-+ String buffer;
-+public:
-+ Item_func_compress(Item *a):Item_str_func(a){}
-+ void fix_length_and_dec(){max_length= (args[0]->max_length*120)/100+12;}
-+ const char *func_name() const{return "compress";}
-+ String *val_str(String *) ZLIB_DEPENDED_FUNCTION
-+};
-+
-+class Item_func_uncompress: public Item_str_func
-+{
-+ String buffer;
-+public:
-+ Item_func_uncompress(Item *a): Item_str_func(a){}
-+ void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; }
-+ const char *func_name() const{return "uncompress";}
-+ String *val_str(String *) ZLIB_DEPENDED_FUNCTION
-+};
-+
-+#define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
-+class Item_func_uuid: public Item_str_func
-+{
-+public:
-+ Item_func_uuid(): Item_str_func() {}
-+ void fix_length_and_dec() {
-+ collation.set(system_charset_info);
-+ /*
-+ NOTE! uuid() should be changed to use 'ascii'
-+ charset when hex(), format(), md5(), etc, and implicit
-+ number-to-string conversion will use 'ascii'
-+ */
-+ max_length= UUID_LENGTH * system_charset_info->mbmaxlen;
-+ }
-+ const char *func_name() const{ return "uuid"; }
-+ String *val_str(String *);
-+};
-+
-diff -urN mysql-old/sql/item_strfunc.h.rej mysql/sql/item_strfunc.h.rej
---- mysql-old/sql/item_strfunc.h.rej 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/item_strfunc.h.rej 2011-05-10 17:56:01.353349043 +0000
-@@ -0,0 +1,11 @@
-+--- sql/item_strfunc.h 2010-08-03 17:24:28.000000000 +0000
-++++ sql/item_strfunc.h 2010-08-20 22:27:12.919596025 +0000
-+@@ -705,7 +705,7 @@
-+ void fix_length_and_dec()
-+ {
-+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 + 2;
-+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
-++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
-+ collation.set(args[0]->collation);
-+ }
-+ };
diff -urN mysql-old/sql/item_sum.cc mysql/sql/item_sum.cc
--- mysql-old/sql/item_sum.cc 2011-05-10 17:45:45.636682376 +0000
+++ mysql/sql/item_sum.cc 2011-05-10 17:56:01.353349043 +0000
@@ -12369,9302 +1677,6 @@ diff -urN mysql-old/sql/mysqld.cc mysql/sql/mysqld.cc
fd_set readFDs,clientFDs;
THD *thd;
struct sockaddr_in cAddr;
-diff -urN mysql-old/sql/mysqld.cc.orig mysql/sql/mysqld.cc.orig
---- mysql-old/sql/mysqld.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/mysqld.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,9292 @@
-+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+#include "mysql_priv.h"
-+#include <m_ctype.h>
-+#include <my_dir.h>
-+#include <my_bit.h>
-+#include "slave.h"
-+#include "rpl_mi.h"
-+#include "sql_repl.h"
-+#include "rpl_filter.h"
-+#include "repl_failsafe.h"
-+#include <my_stacktrace.h>
-+#include "mysqld_suffix.h"
-+#include "mysys_err.h"
-+#include "events.h"
-+#include "debug_sync.h"
-+
-+#include "../storage/myisam/ha_myisam.h"
-+
-+#include "rpl_injector.h"
-+
-+#ifdef HAVE_SYS_PRCTL_H
-+#include <sys/prctl.h>
-+#endif
-+
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+#if defined(NOT_ENOUGH_TESTED) \
-+ && defined(NDB_SHM_TRANSPORTER) && MYSQL_VERSION_ID >= 50000
-+#define OPT_NDB_SHM_DEFAULT 1
-+#else
-+#define OPT_NDB_SHM_DEFAULT 0
-+#endif
-+#endif
-+
-+#ifndef DEFAULT_SKIP_THREAD_PRIORITY
-+#define DEFAULT_SKIP_THREAD_PRIORITY 0
-+#endif
-+
-+#include <thr_alarm.h>
-+#include <ft_global.h>
-+#include <errmsg.h>
-+#include "sp_rcontext.h"
-+#include "sp_cache.h"
-+
-+#define mysqld_charset &my_charset_latin1
-+
-+#ifdef HAVE_purify
-+#define IF_PURIFY(A,B) (A)
-+#else
-+#define IF_PURIFY(A,B) (B)
-+#endif
-+
-+#if SIZEOF_CHARP == 4
-+#define MAX_MEM_TABLE_SIZE ~(ulong) 0
-+#else
-+#define MAX_MEM_TABLE_SIZE ~(ulonglong) 0
-+#endif
-+
-+/* stack traces are only supported on linux intel */
-+#if defined(__linux__) && defined(__i386__)
-+#define HAVE_STACK_TRACE_ON_SEGV
-+#endif /* __linux__ */
-+
-+/* We have HAVE_purify below as this speeds up the shutdown of MySQL */
-+
-+#if defined(HAVE_DEC_3_2_THREADS) || defined(SIGNALS_DONT_BREAK_READ) || defined(HAVE_purify) && defined(__linux__)
-+#define HAVE_CLOSE_SERVER_SOCK 1
-+#endif
-+
-+extern "C" { // Because of SCO 3.2V4.2
-+#include <errno.h>
-+#include <sys/stat.h>
-+#ifndef __GNU_LIBRARY__
-+#define __GNU_LIBRARY__ // Skip warnings in getopt.h
-+#endif
-+#include <my_getopt.h>
-+#ifdef HAVE_SYSENT_H
-+#include <sysent.h>
-+#endif
-+#ifdef HAVE_PWD_H
-+#include <pwd.h> // For getpwent
-+#endif
-+#ifdef HAVE_GRP_H
-+#include <grp.h>
-+#endif
-+#include <my_net.h>
-+
-+#if !defined(__WIN__)
-+# ifndef __NETWARE__
-+#include <sys/resource.h>
-+# endif /* __NETWARE__ */
-+#ifdef HAVE_SYS_UN_H
-+# include <sys/un.h>
-+#endif
-+#include <netdb.h>
-+#ifdef HAVE_SELECT_H
-+# include <select.h>
-+#endif
-+#ifdef HAVE_SYS_SELECT_H
-+#include <sys/select.h>
-+#endif
-+#include <sys/utsname.h>
-+#endif /* __WIN__ */
-+
-+#include <my_libwrap.h>
-+
-+#ifdef HAVE_SYS_MMAN_H
-+#include <sys/mman.h>
-+#endif
-+
-+#ifdef __WIN__
-+#include <crtdbg.h>
-+#define SIGNAL_FMT "exception 0x%x"
-+#else
-+#define SIGNAL_FMT "signal %d"
-+#endif
-+
-+#ifdef __NETWARE__
-+#define zVOLSTATE_ACTIVE 6
-+#define zVOLSTATE_DEACTIVE 2
-+#define zVOLSTATE_MAINTENANCE 3
-+
-+#undef __event_h__
-+#include <../include/event.h>
-+/*
-+ This #undef exists here because both libc of NetWare and MySQL have
-+ files named event.h which causes compilation errors.
-+*/
-+
-+#include <nks/netware.h>
-+#include <nks/vm.h>
-+#include <library.h>
-+#include <monitor.h>
-+#include <zOmni.h> //For NEB
-+#include <neb.h> //For NEB
-+#include <nebpub.h> //For NEB
-+#include <zEvent.h> //For NSS event structures
-+#include <zPublics.h>
-+
-+static void *neb_consumer_id= NULL; //For storing NEB consumer id
-+static char datavolname[256]= {0};
-+static VolumeID_t datavolid;
-+static event_handle_t eh;
-+static Report_t ref;
-+static void *refneb= NULL;
-+my_bool event_flag= FALSE;
-+static int volumeid= -1;
-+
-+ /* NEB event callback */
-+unsigned long neb_event_callback(struct EventBlock *eblock);
-+static void registerwithneb();
-+static void getvolumename();
-+static void getvolumeID(BYTE *volumeName);
-+#endif /* __NETWARE__ */
-+
-+
-+#ifdef _AIX41
-+int initgroups(const char *,unsigned int);
-+#endif
-+
-+#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
-+#include <ieeefp.h>
-+#ifdef HAVE_FP_EXCEPT // Fix type conflict
-+typedef fp_except fp_except_t;
-+#endif
-+#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
-+#ifdef HAVE_SYS_FPU_H
-+/* for IRIX to use set_fpc_csr() */
-+#include <sys/fpu.h>
-+#endif
-+#ifdef HAVE_FPU_CONTROL_H
-+#include <fpu_control.h>
-+#endif
-+#if defined(__i386__) && !defined(HAVE_FPU_CONTROL_H)
-+# define fpu_control_t unsigned int
-+# define _FPU_EXTENDED 0x300
-+# define _FPU_DOUBLE 0x200
-+# if defined(__GNUC__) || (defined(__SUNPRO_CC) && __SUNPRO_CC >= 0x590)
-+# define _FPU_GETCW(cw) asm volatile ("fnstcw %0" : "=m" (*&cw))
-+# define _FPU_SETCW(cw) asm volatile ("fldcw %0" : : "m" (*&cw))
-+# else
-+# define _FPU_GETCW(cw) (cw= 0)
-+# define _FPU_SETCW(cw)
-+# endif
-+#endif
-+
-+extern "C" my_bool reopen_fstreams(const char *filename,
-+ FILE *outstream, FILE *errstream);
-+
-+inline void setup_fpu()
-+{
-+#if defined(__FreeBSD__) && defined(HAVE_IEEEFP_H)
-+ /* We can't handle floating point exceptions with threads, so disable
-+ this on freebsd
-+ Don't fall for overflow, underflow,divide-by-zero or loss of precision
-+ */
-+#if defined(__i386__)
-+ fpsetmask(~(FP_X_INV | FP_X_DNML | FP_X_OFL | FP_X_UFL | FP_X_DZ |
-+ FP_X_IMP));
-+#else
-+ fpsetmask(~(FP_X_INV | FP_X_OFL | FP_X_UFL | FP_X_DZ |
-+ FP_X_IMP));
-+#endif /* __i386__ */
-+#endif /* __FreeBSD__ && HAVE_IEEEFP_H */
-+
-+#ifdef HAVE_FESETROUND
-+ /* Set FPU rounding mode to "round-to-nearest" */
-+ fesetround(FE_TONEAREST);
-+#endif /* HAVE_FESETROUND */
-+
-+ /*
-+ x86 (32-bit) requires FPU precision to be explicitly set to 64 bit
-+ (double precision) for portable results of floating point operations.
-+ However, there is no need to do so if compiler is using SSE2 for floating
-+ point, double values will be stored and processed in 64 bits anyway.
-+ */
-+#if defined(__i386__) && !defined(__SSE2_MATH__)
-+#if defined(_WIN32)
-+#if !defined(_WIN64)
-+ _control87(_PC_53, MCW_PC);
-+#endif /* !_WIN64 */
-+#else /* !_WIN32 */
-+ fpu_control_t cw;
-+ _FPU_GETCW(cw);
-+ cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE;
-+ _FPU_SETCW(cw);
-+#endif /* _WIN32 && */
-+#endif /* __i386__ */
-+
-+#if defined(__sgi) && defined(HAVE_SYS_FPU_H)
-+ /* Enable denormalized DOUBLE values support for IRIX */
-+ union fpc_csr n;
-+ n.fc_word = get_fpc_csr();
-+ n.fc_struct.flush = 0;
-+ set_fpc_csr(n.fc_word);
-+#endif
-+}
-+
-+} /* cplusplus */
-+
-+#define MYSQL_KILL_SIGNAL SIGTERM
-+
-+#ifdef HAVE_GLIBC2_STYLE_GETHOSTBYNAME_R
-+#include <sys/types.h>
-+#else
-+#include <my_pthread.h> // For thr_setconcurency()
-+#endif
-+
-+#ifdef SOLARIS
-+extern "C" int gethostname(char *name, int namelen);
-+#endif
-+
-+extern "C" sig_handler handle_segfault(int sig);
-+
-+#if defined(__linux__)
-+#define ENABLE_TEMP_POOL 1
-+#else
-+#define ENABLE_TEMP_POOL 0
-+#endif
-+
-+/* Constants */
-+
-+const char *show_comp_option_name[]= {"YES", "NO", "DISABLED"};
-+/*
-+ WARNING: When adding new SQL modes don't forget to update the
-+ tables definitions that stores it's value.
-+ (ie: mysql.event, mysql.proc)
-+*/
-+static const char *sql_mode_names[]=
-+{
-+ "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE",
-+ "?", "ONLY_FULL_GROUP_BY", "NO_UNSIGNED_SUBTRACTION",
-+ "NO_DIR_IN_CREATE",
-+ "POSTGRESQL", "ORACLE", "MSSQL", "DB2", "MAXDB", "NO_KEY_OPTIONS",
-+ "NO_TABLE_OPTIONS", "NO_FIELD_OPTIONS", "MYSQL323", "MYSQL40", "ANSI",
-+ "NO_AUTO_VALUE_ON_ZERO", "NO_BACKSLASH_ESCAPES", "STRICT_TRANS_TABLES",
-+ "STRICT_ALL_TABLES",
-+ "NO_ZERO_IN_DATE", "NO_ZERO_DATE", "ALLOW_INVALID_DATES",
-+ "ERROR_FOR_DIVISION_BY_ZERO",
-+ "TRADITIONAL", "NO_AUTO_CREATE_USER", "HIGH_NOT_PRECEDENCE",
-+ "NO_ENGINE_SUBSTITUTION",
-+ "PAD_CHAR_TO_FULL_LENGTH",
-+ NullS
-+};
-+
-+static const unsigned int sql_mode_names_len[]=
-+{
-+ /*REAL_AS_FLOAT*/ 13,
-+ /*PIPES_AS_CONCAT*/ 15,
-+ /*ANSI_QUOTES*/ 11,
-+ /*IGNORE_SPACE*/ 12,
-+ /*?*/ 1,
-+ /*ONLY_FULL_GROUP_BY*/ 18,
-+ /*NO_UNSIGNED_SUBTRACTION*/ 23,
-+ /*NO_DIR_IN_CREATE*/ 16,
-+ /*POSTGRESQL*/ 10,
-+ /*ORACLE*/ 6,
-+ /*MSSQL*/ 5,
-+ /*DB2*/ 3,
-+ /*MAXDB*/ 5,
-+ /*NO_KEY_OPTIONS*/ 14,
-+ /*NO_TABLE_OPTIONS*/ 16,
-+ /*NO_FIELD_OPTIONS*/ 16,
-+ /*MYSQL323*/ 8,
-+ /*MYSQL40*/ 7,
-+ /*ANSI*/ 4,
-+ /*NO_AUTO_VALUE_ON_ZERO*/ 21,
-+ /*NO_BACKSLASH_ESCAPES*/ 20,
-+ /*STRICT_TRANS_TABLES*/ 19,
-+ /*STRICT_ALL_TABLES*/ 17,
-+ /*NO_ZERO_IN_DATE*/ 15,
-+ /*NO_ZERO_DATE*/ 12,
-+ /*ALLOW_INVALID_DATES*/ 19,
-+ /*ERROR_FOR_DIVISION_BY_ZERO*/ 26,
-+ /*TRADITIONAL*/ 11,
-+ /*NO_AUTO_CREATE_USER*/ 19,
-+ /*HIGH_NOT_PRECEDENCE*/ 19,
-+ /*NO_ENGINE_SUBSTITUTION*/ 22,
-+ /*PAD_CHAR_TO_FULL_LENGTH*/ 23
-+};
-+
-+TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
-+ sql_mode_names,
-+ (unsigned int *)sql_mode_names_len };
-+
-+static const char *optimizer_switch_names[]=
-+{
-+ "index_merge","index_merge_union","index_merge_sort_union",
-+ "index_merge_intersection", "default", NullS
-+};
-+/* Corresponding defines are named OPTIMIZER_SWITCH_XXX */
-+static const unsigned int optimizer_switch_names_len[]=
-+{
-+ sizeof("index_merge") - 1,
-+ sizeof("index_merge_union") - 1,
-+ sizeof("index_merge_sort_union") - 1,
-+ sizeof("index_merge_intersection") - 1,
-+ sizeof("default") - 1
-+};
-+TYPELIB optimizer_switch_typelib= { array_elements(optimizer_switch_names)-1,"",
-+ optimizer_switch_names,
-+ (unsigned int *)optimizer_switch_names_len };
-+
-+static const char *tc_heuristic_recover_names[]=
-+{
-+ "COMMIT", "ROLLBACK", NullS
-+};
-+static TYPELIB tc_heuristic_recover_typelib=
-+{
-+ array_elements(tc_heuristic_recover_names)-1,"",
-+ tc_heuristic_recover_names, NULL
-+};
-+
-+static const char *thread_handling_names[]=
-+{ "one-thread-per-connection", "no-threads",
-+#if HAVE_POOL_OF_THREADS == 1
-+ "pool-of-threads",
-+#endif
-+ NullS};
-+
-+TYPELIB thread_handling_typelib=
-+{
-+ array_elements(thread_handling_names) - 1, "",
-+ thread_handling_names, NULL
-+};
-+
-+const char *first_keyword= "first", *binary_keyword= "BINARY";
-+const char *my_localhost= "localhost", *delayed_user= "DELAYED";
-+#if SIZEOF_OFF_T > 4 && defined(BIG_TABLES)
-+#define GET_HA_ROWS GET_ULL
-+#else
-+#define GET_HA_ROWS GET_ULONG
-+#endif
-+
-+bool opt_large_files= sizeof(my_off_t) > 4;
-+
-+/*
-+ Used with --help for detailed option
-+*/
-+static my_bool opt_help= 0, opt_verbose= 0;
-+
-+arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
-+{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
-+ {&Arg_comparator::compare_real, &Arg_comparator::compare_e_real},
-+ {&Arg_comparator::compare_int_signed, &Arg_comparator::compare_e_int},
-+ {&Arg_comparator::compare_row, &Arg_comparator::compare_e_row},
-+ {&Arg_comparator::compare_decimal, &Arg_comparator::compare_e_decimal}};
-+
-+const char *log_output_names[] = { "NONE", "FILE", "TABLE", NullS};
-+static const unsigned int log_output_names_len[]= { 4, 4, 5, 0 };
-+TYPELIB log_output_typelib= {array_elements(log_output_names)-1,"",
-+ log_output_names,
-+ (unsigned int *) log_output_names_len};
-+
-+/* static variables */
-+
-+/* the default log output is log tables */
-+static bool lower_case_table_names_used= 0;
-+static bool max_long_data_size_used= false;
-+static bool volatile select_thread_in_use, signal_thread_in_use;
-+static bool volatile ready_to_exit;
-+static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
-+static my_bool opt_short_log_format= 0;
-+static uint kill_cached_threads, wake_thread;
-+static ulong killed_threads, thread_created;
-+static ulong max_used_connections;
-+static ulong my_bind_addr; /**< the address we bind to */
-+static volatile ulong cached_thread_count= 0;
-+static const char *sql_mode_str= "OFF";
-+/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
-+static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
-+ "index_merge_sort_union=on,"
-+ "index_merge_intersection=on";
-+static char *mysqld_user, *mysqld_chroot, *log_error_file_ptr;
-+static char *opt_init_slave, *language_ptr, *opt_init_connect;
-+static char *default_character_set_name;
-+static char *character_set_filesystem_name;
-+static char *lc_time_names_name;
-+static char *my_bind_addr_str;
-+static char *default_collation_name;
-+static char *default_storage_engine_str;
-+static char compiled_default_collation_name[]= MYSQL_DEFAULT_COLLATION_NAME;
-+static I_List<THD> thread_cache;
-+static double long_query_time;
-+
-+static pthread_cond_t COND_thread_cache, COND_flush_thread_cache;
-+
-+/* Global variables */
-+
-+bool opt_update_log, opt_bin_log, opt_ignore_builtin_innodb= 0;
-+my_bool opt_log, opt_slow_log;
-+ulong log_output_options;
-+my_bool opt_log_queries_not_using_indexes= 0;
-+bool opt_error_log= IF_WIN(1,0);
-+bool opt_disable_networking=0, opt_skip_show_db=0;
-+bool opt_skip_name_resolve=0;
-+my_bool opt_character_set_client_handshake= 1;
-+bool server_id_supplied = 0;
-+bool opt_endinfo, using_udf_functions;
-+my_bool locked_in_memory;
-+bool opt_using_transactions;
-+bool volatile abort_loop;
-+bool volatile shutdown_in_progress;
-+/*
-+ True if the bootstrap thread is running. Protected by LOCK_thread_count,
-+ just like thread_count.
-+ Used in bootstrap() function to determine if the bootstrap thread
-+ has completed. Note, that we can't use 'thread_count' instead,
-+ since in 5.1, in presence of the Event Scheduler, there may be
-+ event threads running in parallel, so it's impossible to know
-+ what value of 'thread_count' is a sign of completion of the
-+ bootstrap thread.
-+
-+ At the same time, we can't start the event scheduler after
-+ bootstrap either, since we want to be able to process event-related
-+ SQL commands in the init file and in --bootstrap mode.
-+*/
-+bool in_bootstrap= FALSE;
-+/**
-+ @brief 'grant_option' is used to indicate if privileges needs
-+ to be checked, in which case the lock, LOCK_grant, is used
-+ to protect access to the grant table.
-+ @note This flag is dropped in 5.1
-+ @see grant_init()
-+ */
-+bool volatile grant_option;
-+
-+my_bool opt_skip_slave_start = 0; ///< If set, slave is not autostarted
-+my_bool opt_reckless_slave = 0;
-+my_bool opt_enable_named_pipe= 0;
-+my_bool opt_local_infile, opt_slave_compressed_protocol;
-+my_bool opt_safe_user_create = 0, opt_no_mix_types = 0;
-+my_bool opt_show_slave_auth_info, opt_sql_bin_update = 0;
-+my_bool opt_log_slave_updates= 0;
-+bool slave_warning_issued = false;
-+
-+/*
-+ Legacy global handlerton. These will be removed (please do not add more).
-+*/
-+handlerton *heap_hton;
-+handlerton *myisam_hton;
-+handlerton *partition_hton;
-+
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+const char *opt_ndbcluster_connectstring= 0;
-+const char *opt_ndb_connectstring= 0;
-+char opt_ndb_constrbuf[1024]= {0};
-+unsigned opt_ndb_constrbuf_len= 0;
-+my_bool opt_ndb_shm, opt_ndb_optimized_node_selection;
-+ulong opt_ndb_cache_check_time;
-+const char *opt_ndb_mgmd;
-+ulong opt_ndb_nodeid;
-+ulong ndb_extra_logging;
-+#ifdef HAVE_NDB_BINLOG
-+ulong ndb_report_thresh_binlog_epoch_slip;
-+ulong ndb_report_thresh_binlog_mem_usage;
-+#endif
-+
-+extern const char *ndb_distribution_names[];
-+extern TYPELIB ndb_distribution_typelib;
-+extern const char *opt_ndb_distribution;
-+extern enum ndb_distribution opt_ndb_distribution_id;
-+#endif
-+my_bool opt_readonly, use_temp_pool, relay_log_purge;
-+my_bool opt_sync_frm, opt_allow_suspicious_udfs;
-+my_bool opt_secure_auth= 0;
-+char* opt_secure_file_priv= 0;
-+my_bool opt_log_slow_admin_statements= 0;
-+my_bool opt_log_slow_slave_statements= 0;
-+my_bool lower_case_file_system= 0;
-+my_bool opt_large_pages= 0;
-+my_bool opt_myisam_use_mmap= 0;
-+uint opt_large_page_size= 0;
-+#if defined(ENABLED_DEBUG_SYNC)
-+uint opt_debug_sync_timeout= 0;
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+my_bool opt_old_style_user_limits= 0, trust_function_creators= 0;
-+/*
-+ True if there is at least one per-hour limit for some user, so we should
-+ check them before each query (and possibly reset counters when hour is
-+ changed). False otherwise.
-+*/
-+volatile bool mqh_used = 0;
-+my_bool opt_noacl;
-+my_bool sp_automatic_privileges= 1;
-+
-+ulong opt_binlog_rows_event_max_size;
-+const char *binlog_format_names[]= {"MIXED", "STATEMENT", "ROW", NullS};
-+TYPELIB binlog_format_typelib=
-+ { array_elements(binlog_format_names) - 1, "",
-+ binlog_format_names, NULL };
-+ulong opt_binlog_format_id= (ulong) BINLOG_FORMAT_UNSPEC;
-+const char *opt_binlog_format= binlog_format_names[opt_binlog_format_id];
-+#ifdef HAVE_INITGROUPS
-+static bool calling_initgroups= FALSE; /**< Used in SIGSEGV handler. */
-+#endif
-+uint mysqld_port, test_flags, select_errors, dropping_tables, ha_open_options;
-+uint mysqld_port_timeout;
-+uint delay_key_write_options, protocol_version;
-+uint lower_case_table_names;
-+uint tc_heuristic_recover= 0;
-+uint volatile thread_count, thread_running;
-+ulonglong thd_startup_options;
-+ulong back_log, connect_timeout, concurrency, server_id;
-+ulong table_cache_size, table_def_size;
-+ulong what_to_log;
-+ulong query_buff_size, slow_launch_time, slave_open_temp_tables;
-+ulong open_files_limit, max_binlog_size, max_relay_log_size;
-+ulong slave_net_timeout, slave_trans_retries;
-+ulong slave_exec_mode_options;
-+static const char *slave_exec_mode_str= "STRICT";
-+ulong thread_cache_size=0, thread_pool_size= 0;
-+ulong binlog_cache_size=0;
-+ulonglong max_binlog_cache_size=0;
-+ulong query_cache_size=0;
-+ulong refresh_version; /* Increments on each reload */
-+query_id_t global_query_id;
-+ulong aborted_threads, aborted_connects;
-+ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size;
-+ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use;
-+ulong delayed_insert_errors,flush_time;
-+ulong specialflag=0;
-+ulong binlog_cache_use= 0, binlog_cache_disk_use= 0;
-+ulong max_connections, max_connect_errors;
-+/*
-+ Maximum length of parameter value which can be set through
-+ mysql_send_long_data() call.
-+*/
-+ulong max_long_data_size;
-+uint max_user_connections= 0;
-+/**
-+ Limit of the total number of prepared statements in the server.
-+ Is necessary to protect the server against out-of-memory attacks.
-+*/
-+ulong max_prepared_stmt_count;
-+/**
-+ Current total number of prepared statements in the server. This number
-+ is exact, and therefore may not be equal to the difference between
-+ `com_stmt_prepare' and `com_stmt_close' (global status variables), as
-+ the latter ones account for all registered attempts to prepare
-+ a statement (including unsuccessful ones). Prepared statements are
-+ currently connection-local: if the same SQL query text is prepared in
-+ two different connections, this counts as two distinct prepared
-+ statements.
-+*/
-+ulong prepared_stmt_count=0;
-+ulong thread_id=1L,current_pid;
-+ulong slow_launch_threads = 0, sync_binlog_period;
-+ulong expire_logs_days = 0;
-+ulong rpl_recovery_rank=0;
-+const char *log_output_str= "FILE";
-+
-+time_t server_start_time, flush_status_time;
-+
-+char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
-+char *default_tz_name;
-+char log_error_file[FN_REFLEN], glob_hostname[FN_REFLEN];
-+char mysql_real_data_home[FN_REFLEN],
-+ language[FN_REFLEN], reg_ext[FN_EXTLEN], mysql_charsets_dir[FN_REFLEN],
-+ *opt_init_file, *opt_tc_log_file,
-+ def_ft_boolean_syntax[sizeof(ft_boolean_syntax)];
-+char mysql_unpacked_real_data_home[FN_REFLEN];
-+int mysql_unpacked_real_data_home_len;
-+uint reg_ext_length;
-+const key_map key_map_empty(0);
-+key_map key_map_full(0); // Will be initialized later
-+
-+const char *opt_date_time_formats[3];
-+
-+uint mysql_data_home_len;
-+char mysql_data_home_buff[2], *mysql_data_home=mysql_real_data_home;
-+char server_version[SERVER_VERSION_LENGTH];
-+char *mysqld_unix_port, *opt_mysql_tmpdir;
-+const char **errmesg; /**< Error messages */
-+const char *myisam_recover_options_str="OFF";
-+const char *myisam_stats_method_str="nulls_unequal";
-+
-+/** name of reference on left espression in rewritten IN subquery */
-+const char *in_left_expr_name= "<left expr>";
-+/** name of additional condition */
-+const char *in_additional_cond= "<IN COND>";
-+const char *in_having_cond= "<IN HAVING>";
-+
-+my_decimal decimal_zero;
-+/* classes for comparation parsing/processing */
-+Eq_creator eq_creator;
-+Ne_creator ne_creator;
-+Gt_creator gt_creator;
-+Lt_creator lt_creator;
-+Ge_creator ge_creator;
-+Le_creator le_creator;
-+
-+FILE *bootstrap_file;
-+int bootstrap_error;
-+FILE *stderror_file=0;
-+
-+I_List<THD> threads;
-+I_List<NAMED_LIST> key_caches;
-+Rpl_filter* rpl_filter;
-+Rpl_filter* binlog_filter;
-+
-+struct system_variables global_system_variables;
-+struct system_variables max_system_variables;
-+struct system_status_var global_status_var;
-+
-+MY_TMPDIR mysql_tmpdir_list;
-+MY_BITMAP temp_pool;
-+
-+CHARSET_INFO *system_charset_info, *files_charset_info ;
-+CHARSET_INFO *national_charset_info, *table_alias_charset;
-+CHARSET_INFO *character_set_filesystem;
-+
-+MY_LOCALE *my_default_lc_time_names;
-+
-+SHOW_COMP_OPTION have_ssl, have_symlink, have_dlopen, have_query_cache;
-+SHOW_COMP_OPTION have_geometry, have_rtree_keys;
-+SHOW_COMP_OPTION have_crypt, have_compress;
-+SHOW_COMP_OPTION have_community_features;
-+
-+/* Thread specific variables */
-+
-+pthread_key(MEM_ROOT**,THR_MALLOC);
-+pthread_key(THD*, THR_THD);
-+pthread_mutex_t LOCK_mysql_create_db, LOCK_Acl, LOCK_open, LOCK_thread_count,
-+ LOCK_mapped_file, LOCK_status, LOCK_global_read_lock,
-+ LOCK_error_log, LOCK_uuid_generator,
-+ LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create,
-+ LOCK_crypt, LOCK_bytes_sent, LOCK_bytes_received,
-+ LOCK_global_system_variables,
-+ LOCK_user_conn, LOCK_slave_list, LOCK_active_mi,
-+ LOCK_connection_count;
-+/**
-+ The below lock protects access to two global server variables:
-+ max_prepared_stmt_count and prepared_stmt_count. These variables
-+ set the limit and hold the current total number of prepared statements
-+ in the server, respectively. As PREPARE/DEALLOCATE rate in a loaded
-+ server may be fairly high, we need a dedicated lock.
-+*/
-+pthread_mutex_t LOCK_prepared_stmt_count;
-+#ifdef HAVE_OPENSSL
-+pthread_mutex_t LOCK_des_key_file;
-+#endif
-+rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave;
-+rw_lock_t LOCK_system_variables_hash;
-+pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock;
-+pthread_t signal_thread;
-+pthread_attr_t connection_attrib;
-+pthread_mutex_t LOCK_server_started;
-+pthread_cond_t COND_server_started;
-+
-+int mysqld_server_started= 0;
-+
-+File_parser_dummy_hook file_parser_dummy_hook;
-+
-+/* replication parameters, if master_host is not NULL, we are a slave */
-+uint master_port= MYSQL_PORT, master_connect_retry = 60;
-+uint report_port= MYSQL_PORT;
-+ulong master_retry_count=0;
-+char *master_user, *master_password, *master_host, *master_info_file;
-+char *relay_log_info_file, *report_user, *report_password, *report_host;
-+char *opt_relay_logname = 0, *opt_relaylog_index_name=0;
-+my_bool master_ssl;
-+char *master_ssl_key, *master_ssl_cert;
-+char *master_ssl_ca, *master_ssl_capath, *master_ssl_cipher;
-+char *opt_logname, *opt_slow_logname;
-+
-+/* Static variables */
-+
-+static bool kill_in_progress, segfaulted;
-+#ifdef HAVE_STACK_TRACE_ON_SEGV
-+static my_bool opt_do_pstack;
-+#endif /* HAVE_STACK_TRACE_ON_SEGV */
-+static my_bool opt_bootstrap, opt_myisam_log;
-+static int cleanup_done;
-+static ulong opt_specialflag, opt_myisam_block_size;
-+static char *opt_update_logname, *opt_binlog_index_name;
-+static char *opt_tc_heuristic_recover;
-+static char *mysql_home_ptr, *pidfile_name_ptr;
-+static int defaults_argc;
-+static char **defaults_argv;
-+static char *opt_bin_logname;
-+
-+int orig_argc;
-+char **orig_argv;
-+
-+static my_socket unix_sock,ip_sock;
-+struct rand_struct sql_rand; ///< used by sql_class.cc:THD::THD()
-+
-+#ifndef EMBEDDED_LIBRARY
-+struct passwd *user_info;
-+static pthread_t select_thread;
-+static uint thr_kill_signal;
-+#endif
-+
-+/* OS specific variables */
-+
-+#ifdef __WIN__
-+#undef getpid
-+#include <process.h>
-+
-+static pthread_cond_t COND_handler_count;
-+static uint handler_count;
-+static bool start_mode=0, use_opt_args;
-+static int opt_argc;
-+static char **opt_argv;
-+
-+#if !defined(EMBEDDED_LIBRARY)
-+static HANDLE hEventShutdown;
-+static char shutdown_event_name[40];
-+#include "nt_servc.h"
-+static NTService Service; ///< Service object for WinNT
-+#endif /* EMBEDDED_LIBRARY */
-+#endif /* __WIN__ */
-+
-+#ifdef __NT__
-+static char pipe_name[512];
-+static SECURITY_ATTRIBUTES saPipeSecurity;
-+static SECURITY_DESCRIPTOR sdPipeDescriptor;
-+static HANDLE hPipe = INVALID_HANDLE_VALUE;
-+#endif
-+
-+#ifndef EMBEDDED_LIBRARY
-+bool mysqld_embedded=0;
-+#else
-+bool mysqld_embedded=1;
-+#endif
-+
-+static my_bool plugins_are_initialized= FALSE;
-+
-+#ifndef DBUG_OFF
-+static const char* default_dbug_option;
-+#endif
-+#ifdef HAVE_LIBWRAP
-+const char *libwrapName= NULL;
-+int allow_severity = LOG_INFO;
-+int deny_severity = LOG_WARNING;
-+#endif
-+#ifdef HAVE_QUERY_CACHE
-+static ulong query_cache_limit= 0;
-+ulong query_cache_min_res_unit= QUERY_CACHE_MIN_RESULT_DATA_SIZE;
-+Query_cache query_cache;
-+#endif
-+#ifdef HAVE_SMEM
-+char *shared_memory_base_name= default_shared_memory_base_name;
-+my_bool opt_enable_shared_memory;
-+HANDLE smem_event_connect_request= 0;
-+#endif
-+
-+scheduler_functions thread_scheduler;
-+
-+#define SSL_VARS_NOT_STATIC
-+#include "sslopt-vars.h"
-+#ifdef HAVE_OPENSSL
-+#include <openssl/crypto.h>
-+#ifndef HAVE_YASSL
-+typedef struct CRYPTO_dynlock_value
-+{
-+ rw_lock_t lock;
-+} openssl_lock_t;
-+
-+static openssl_lock_t *openssl_stdlocks;
-+static openssl_lock_t *openssl_dynlock_create(const char *, int);
-+static void openssl_dynlock_destroy(openssl_lock_t *, const char *, int);
-+static void openssl_lock_function(int, int, const char *, int);
-+static void openssl_lock(int, openssl_lock_t *, const char *, int);
-+static unsigned long openssl_id_function();
-+#endif
-+char *des_key_file;
-+struct st_VioSSLFd *ssl_acceptor_fd;
-+#endif /* HAVE_OPENSSL */
-+
-+/**
-+ Number of currently active user connections. The variable is protected by
-+ LOCK_connection_count.
-+*/
-+uint connection_count= 0;
-+
-+/* Function declarations */
-+
-+pthread_handler_t signal_hand(void *arg);
-+static int mysql_init_variables(void);
-+static int get_options(int *argc,char **argv);
-+extern "C" my_bool mysqld_get_one_option(int, const struct my_option *, char *);
-+static void set_server_version(void);
-+static int init_thread_environment();
-+static char *get_relative_path(const char *path);
-+static int fix_paths(void);
-+pthread_handler_t handle_connections_sockets(void *arg);
-+pthread_handler_t kill_server_thread(void *arg);
-+static void bootstrap(FILE *file);
-+static bool read_init_file(char *file_name);
-+#ifdef __NT__
-+pthread_handler_t handle_connections_namedpipes(void *arg);
-+#endif
-+#ifdef HAVE_SMEM
-+pthread_handler_t handle_connections_shared_memory(void *arg);
-+#endif
-+pthread_handler_t handle_slave(void *arg);
-+static ulong find_bit_type(const char *x, TYPELIB *bit_lib);
-+static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
-+ const char *option, int *error);
-+static void clean_up(bool print_message);
-+static int test_if_case_insensitive(const char *dir_name);
-+
-+#ifndef EMBEDDED_LIBRARY
-+static void usage(void);
-+static void start_signal_handler(void);
-+static void close_server_sock();
-+static void clean_up_mutexes(void);
-+static void wait_for_signal_thread_to_end(void);
-+static void create_pid_file();
-+static void end_ssl();
-+#endif
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+/****************************************************************************
-+** Code to end mysqld
-+****************************************************************************/
-+
-+static void close_connections(void)
-+{
-+#ifdef EXTRA_DEBUG
-+ int count=0;
-+#endif
-+ DBUG_ENTER("close_connections");
-+
-+ /* Clear thread cache */
-+ kill_cached_threads++;
-+ flush_thread_cache();
-+
-+ /* kill connection thread */
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ DBUG_PRINT("quit", ("waiting for select thread: 0x%lx",
-+ (ulong) select_thread));
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+
-+ while (select_thread_in_use)
-+ {
-+ struct timespec abstime;
-+ int error;
-+ LINT_INIT(error);
-+ DBUG_PRINT("info",("Waiting for select thread"));
-+
-+#ifndef DONT_USE_THR_ALARM
-+ if (pthread_kill(select_thread, thr_client_alarm))
-+ break; // allready dead
-+#endif
-+ set_timespec(abstime, 2);
-+ for (uint tmp=0 ; tmp < 10 && select_thread_in_use; tmp++)
-+ {
-+ error=pthread_cond_timedwait(&COND_thread_count,&LOCK_thread_count,
-+ &abstime);
-+ if (error != EINTR)
-+ break;
-+ }
-+#ifdef EXTRA_DEBUG
-+ if (error != 0 && !count++)
-+ sql_print_error("Got error %d from pthread_cond_timedwait",error);
-+#endif
-+ close_server_sock();
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+#endif /* __WIN__ */
-+
-+
-+ /* Abort listening to new connections */
-+ DBUG_PRINT("quit",("Closing sockets"));
-+ if (!opt_disable_networking )
-+ {
-+ if (ip_sock != INVALID_SOCKET)
-+ {
-+ (void) shutdown(ip_sock, SHUT_RDWR);
-+ (void) closesocket(ip_sock);
-+ ip_sock= INVALID_SOCKET;
-+ }
-+ }
-+#ifdef __NT__
-+ if (hPipe != INVALID_HANDLE_VALUE && opt_enable_named_pipe)
-+ {
-+ HANDLE temp;
-+ DBUG_PRINT("quit", ("Closing named pipes") );
-+
-+ /* Create connection to the handle named pipe handler to break the loop */
-+ if ((temp = CreateFile(pipe_name,
-+ GENERIC_READ | GENERIC_WRITE,
-+ 0,
-+ NULL,
-+ OPEN_EXISTING,
-+ 0,
-+ NULL )) != INVALID_HANDLE_VALUE)
-+ {
-+ WaitNamedPipe(pipe_name, 1000);
-+ DWORD dwMode = PIPE_READMODE_BYTE | PIPE_WAIT;
-+ SetNamedPipeHandleState(temp, &dwMode, NULL, NULL);
-+ CancelIo(temp);
-+ DisconnectNamedPipe(temp);
-+ CloseHandle(temp);
-+ }
-+ }
-+#endif
-+#ifdef HAVE_SYS_UN_H
-+ if (unix_sock != INVALID_SOCKET)
-+ {
-+ (void) shutdown(unix_sock, SHUT_RDWR);
-+ (void) closesocket(unix_sock);
-+ (void) unlink(mysqld_unix_port);
-+ unix_sock= INVALID_SOCKET;
-+ }
-+#endif
-+ end_thr_alarm(0); // Abort old alarms.
-+
-+ /*
-+ First signal all threads that it's time to die
-+ This will give the threads some time to gracefully abort their
-+ statements and inform their clients that the server is about to die.
-+ */
-+
-+ THD *tmp;
-+ (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
-+
-+ I_List_iterator<THD> it(threads);
-+ while ((tmp=it++))
-+ {
-+ DBUG_PRINT("quit",("Informing thread %ld that it's time to die",
-+ tmp->thread_id));
-+ /* We skip slave threads & scheduler on this first loop through. */
-+ if (tmp->slave_thread)
-+ continue;
-+
-+ tmp->killed= THD::KILL_CONNECTION;
-+ thread_scheduler.post_kill_notification(tmp);
-+ if (tmp->mysys_var)
-+ {
-+ tmp->mysys_var->abort=1;
-+ pthread_mutex_lock(&tmp->mysys_var->mutex);
-+ if (tmp->mysys_var->current_cond)
-+ {
-+ pthread_mutex_lock(tmp->mysys_var->current_mutex);
-+ pthread_cond_broadcast(tmp->mysys_var->current_cond);
-+ pthread_mutex_unlock(tmp->mysys_var->current_mutex);
-+ }
-+ pthread_mutex_unlock(&tmp->mysys_var->mutex);
-+ }
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list
-+
-+ Events::deinit();
-+ end_slave();
-+
-+ if (thread_count)
-+ sleep(2); // Give threads time to die
-+
-+ /*
-+ Force remaining threads to die by closing the connection to the client
-+ This will ensure that threads that are waiting for a command from the
-+ client on a blocking read call are aborted.
-+ */
-+
-+ for (;;)
-+ {
-+ DBUG_PRINT("quit",("Locking LOCK_thread_count"));
-+ (void) pthread_mutex_lock(&LOCK_thread_count); // For unlink from list
-+ if (!(tmp=threads.get()))
-+ {
-+ DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ break;
-+ }
-+#ifndef __bsdi__ // Bug in BSDI kernel
-+ if (tmp->vio_ok())
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning(ER(ER_FORCING_CLOSE),my_progname,
-+ tmp->thread_id,
-+ (tmp->main_security_ctx.user ?
-+ tmp->main_security_ctx.user : ""));
-+ close_connection(tmp,0,0);
-+ }
-+#endif
-+ DBUG_PRINT("quit",("Unlocking LOCK_thread_count"));
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ }
-+ /* All threads has now been aborted */
-+ DBUG_PRINT("quit",("Waiting for threads to die (count=%u)",thread_count));
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ while (thread_count)
-+ {
-+ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
-+ DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+
-+ close_active_mi();
-+ DBUG_PRINT("quit",("close_connections thread"));
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+static void close_server_sock()
-+{
-+#ifdef HAVE_CLOSE_SERVER_SOCK
-+ DBUG_ENTER("close_server_sock");
-+ my_socket tmp_sock;
-+ tmp_sock=ip_sock;
-+ if (tmp_sock != INVALID_SOCKET)
-+ {
-+ ip_sock=INVALID_SOCKET;
-+ DBUG_PRINT("info",("calling shutdown on TCP/IP socket"));
-+ VOID(shutdown(tmp_sock, SHUT_RDWR));
-+#if defined(__NETWARE__)
-+ /*
-+ The following code is disabled for normal systems as it causes MySQL
-+ to hang on AIX 4.3 during shutdown
-+ */
-+ DBUG_PRINT("info",("calling closesocket on TCP/IP socket"));
-+ VOID(closesocket(tmp_sock));
-+#endif
-+ }
-+ tmp_sock=unix_sock;
-+ if (tmp_sock != INVALID_SOCKET)
-+ {
-+ unix_sock=INVALID_SOCKET;
-+ DBUG_PRINT("info",("calling shutdown on unix socket"));
-+ VOID(shutdown(tmp_sock, SHUT_RDWR));
-+#if defined(__NETWARE__)
-+ /*
-+ The following code is disabled for normal systems as it may cause MySQL
-+ to hang on AIX 4.3 during shutdown
-+ */
-+ DBUG_PRINT("info",("calling closesocket on unix/IP socket"));
-+ VOID(closesocket(tmp_sock));
-+#endif
-+ VOID(unlink(mysqld_unix_port));
-+ }
-+ DBUG_VOID_RETURN;
-+#endif
-+}
-+
-+#endif /*EMBEDDED_LIBRARY*/
-+
-+
-+void kill_mysql(void)
-+{
-+ DBUG_ENTER("kill_mysql");
-+
-+#if defined(SIGNALS_DONT_BREAK_READ) && !defined(EMBEDDED_LIBRARY)
-+ abort_loop=1; // Break connection loops
-+ close_server_sock(); // Force accept to wake up
-+#endif
-+
-+#if defined(__WIN__)
-+#if !defined(EMBEDDED_LIBRARY)
-+ {
-+ if (!SetEvent(hEventShutdown))
-+ {
-+ DBUG_PRINT("error",("Got error: %ld from SetEvent",GetLastError()));
-+ }
-+ /*
-+ or:
-+ HANDLE hEvent=OpenEvent(0, FALSE, "MySqlShutdown");
-+ SetEvent(hEventShutdown);
-+ CloseHandle(hEvent);
-+ */
-+ }
-+#endif
-+#elif defined(HAVE_PTHREAD_KILL)
-+ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL))
-+ {
-+ DBUG_PRINT("error",("Got error %d from pthread_kill",errno)); /* purecov: inspected */
-+ }
-+#elif !defined(SIGNALS_DONT_BREAK_READ)
-+ kill(current_pid, MYSQL_KILL_SIGNAL);
-+#endif
-+ DBUG_PRINT("quit",("After pthread_kill"));
-+ shutdown_in_progress=1; // Safety if kill didn't work
-+#ifdef SIGNALS_DONT_BREAK_READ
-+ if (!kill_in_progress)
-+ {
-+ pthread_t tmp;
-+ abort_loop=1;
-+ if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
-+ (void*) 0))
-+ sql_print_error("Can't create thread to kill server");
-+ }
-+#endif
-+ DBUG_VOID_RETURN;
-+}
-+
-+/**
-+ Force server down. Kill all connections and threads and exit.
-+
-+ @param sig_ptr Signal number that caused kill_server to be called.
-+
-+ @note
-+ A signal number of 0 mean that the function was not called
-+ from a signal handler and there is thus no signal to block
-+ or stop, we just want to kill the server.
-+*/
-+
-+#if defined(__NETWARE__)
-+extern "C" void kill_server(int sig_ptr)
-+#define RETURN_FROM_KILL_SERVER return
-+#elif !defined(__WIN__)
-+static void *kill_server(void *sig_ptr)
-+#define RETURN_FROM_KILL_SERVER return 0
-+#else
-+static void __cdecl kill_server(int sig_ptr)
-+#define RETURN_FROM_KILL_SERVER return
-+#endif
-+{
-+ DBUG_ENTER("kill_server");
-+#ifndef EMBEDDED_LIBRARY
-+ int sig=(int) (long) sig_ptr; // This is passed a int
-+ // if there is a signal during the kill in progress, ignore the other
-+ if (kill_in_progress) // Safety
-+ {
-+ DBUG_LEAVE;
-+ RETURN_FROM_KILL_SERVER;
-+ }
-+ kill_in_progress=TRUE;
-+ abort_loop=1; // This should be set
-+ if (sig != 0) // 0 is not a valid signal number
-+ my_sigset(sig, SIG_IGN); /* purify inspected */
-+ if (sig == MYSQL_KILL_SIGNAL || sig == 0)
-+ sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
-+ else
-+ sql_print_error(ER(ER_GOT_SIGNAL),my_progname,sig); /* purecov: inspected */
-+
-+#if defined(HAVE_SMEM) && defined(__WIN__)
-+ /*
-+ Send event to smem_event_connect_request for aborting
-+ */
-+ if (!SetEvent(smem_event_connect_request))
-+ {
-+ DBUG_PRINT("error",
-+ ("Got error: %ld from SetEvent of smem_event_connect_request",
-+ GetLastError()));
-+ }
-+#endif
-+
-+ close_connections();
-+ if (sig != MYSQL_KILL_SIGNAL &&
-+ sig != 0)
-+ unireg_abort(1); /* purecov: inspected */
-+ else
-+ unireg_end();
-+
-+ /* purecov: begin deadcode */
-+#ifdef __NETWARE__
-+ if (!event_flag)
-+ pthread_join(select_thread, NULL); // wait for main thread
-+#endif /* __NETWARE__ */
-+
-+ DBUG_LEAVE; // Must match DBUG_ENTER()
-+ my_thread_end();
-+ pthread_exit(0);
-+ /* purecov: end */
-+
-+ RETURN_FROM_KILL_SERVER; // Avoid compiler warnings
-+
-+#else /* EMBEDDED_LIBRARY*/
-+
-+ DBUG_LEAVE;
-+ RETURN_FROM_KILL_SERVER;
-+
-+#endif /* EMBEDDED_LIBRARY */
-+}
-+
-+
-+#if defined(USE_ONE_SIGNAL_HAND) || (defined(__NETWARE__) && defined(SIGNALS_DONT_BREAK_READ))
-+pthread_handler_t kill_server_thread(void *arg __attribute__((unused)))
-+{
-+ my_thread_init(); // Initialize new thread
-+ kill_server(0);
-+ /* purecov: begin deadcode */
-+ my_thread_end();
-+ pthread_exit(0);
-+ return 0;
-+ /* purecov: end */
-+}
-+#endif
-+
-+
-+extern "C" sig_handler print_signal_warning(int sig)
-+{
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Got signal %d from thread %ld", sig,my_thread_id());
-+#ifdef SIGNAL_HANDLER_RESET_ON_DELIVERY
-+ my_sigset(sig,print_signal_warning); /* int. thread system calls */
-+#endif
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ if (sig == SIGALRM)
-+ alarm(2); /* reschedule alarm */
-+#endif
-+}
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/**
-+ cleanup all memory and end program nicely.
-+
-+ If SIGNALS_DONT_BREAK_READ is defined, this function is called
-+ by the main thread. To get MySQL to shut down nicely in this case
-+ (Mac OS X) we have to call exit() instead if pthread_exit().
-+
-+ @note
-+ This function never returns.
-+*/
-+void unireg_end(void)
-+{
-+ clean_up(1);
-+ my_thread_end();
-+#if defined(SIGNALS_DONT_BREAK_READ) && !defined(__NETWARE__)
-+ exit(0);
-+#else
-+ pthread_exit(0); // Exit is in main thread
-+#endif
-+}
-+
-+extern "C" void unireg_abort(int exit_code)
-+{
-+ DBUG_ENTER("unireg_abort");
-+
-+ if (opt_help)
-+ usage();
-+ if (exit_code)
-+ sql_print_error("Aborting\n");
-+ clean_up(!opt_help && (exit_code || !opt_bootstrap)); /* purecov: inspected */
-+ DBUG_PRINT("quit",("done with cleanup in unireg_abort"));
-+ wait_for_signal_thread_to_end();
-+ clean_up_mutexes();
-+ my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
-+ exit(exit_code); /* purecov: inspected */
-+}
-+
-+#endif /*EMBEDDED_LIBRARY*/
-+
-+
-+void clean_up(bool print_message)
-+{
-+ DBUG_PRINT("exit",("clean_up"));
-+ if (cleanup_done++)
-+ return; /* purecov: inspected */
-+
-+ stop_handle_manager();
-+ release_ddl_log();
-+
-+ /*
-+ make sure that handlers finish up
-+ what they have that is dependent on the binlog
-+ */
-+ ha_binlog_end(current_thd);
-+
-+ logger.cleanup_base();
-+
-+ injector::free_instance();
-+ mysql_bin_log.cleanup();
-+
-+#ifdef HAVE_REPLICATION
-+ if (use_slave_mask)
-+ bitmap_free(&slave_error_mask);
-+#endif
-+ my_tz_free();
-+ my_database_names_free();
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ servers_free(1);
-+ acl_free(1);
-+ grant_free();
-+#endif
-+ query_cache_destroy();
-+ table_cache_free();
-+ table_def_free();
-+ hostname_cache_free();
-+ item_user_lock_free();
-+ lex_free(); /* Free some memory */
-+ item_create_cleanup();
-+ set_var_free();
-+ free_charsets();
-+ if (!opt_noacl)
-+ {
-+#ifdef HAVE_DLOPEN
-+ udf_free();
-+#endif
-+ }
-+ plugin_shutdown();
-+ ha_end();
-+ if (tc_log)
-+ tc_log->close();
-+ xid_cache_free();
-+ delete_elements(&key_caches, (void (*)(const char*, uchar*)) free_key_cache);
-+ multi_keycache_free();
-+ free_status_vars();
-+ end_thr_alarm(1); /* Free allocated memory */
-+ my_free_open_file_info();
-+ my_free((char*) global_system_variables.date_format,
-+ MYF(MY_ALLOW_ZERO_PTR));
-+ my_free((char*) global_system_variables.time_format,
-+ MYF(MY_ALLOW_ZERO_PTR));
-+ my_free((char*) global_system_variables.datetime_format,
-+ MYF(MY_ALLOW_ZERO_PTR));
-+ if (defaults_argv)
-+ free_defaults(defaults_argv);
-+ my_free(sys_init_connect.value, MYF(MY_ALLOW_ZERO_PTR));
-+ my_free(sys_init_slave.value, MYF(MY_ALLOW_ZERO_PTR));
-+ my_free(sys_var_general_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
-+ my_free(sys_var_slow_log_path.value, MYF(MY_ALLOW_ZERO_PTR));
-+ free_tmpdir(&mysql_tmpdir_list);
-+#ifdef HAVE_REPLICATION
-+ my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR));
-+#endif
-+ x_free(opt_bin_logname);
-+ x_free(opt_relay_logname);
-+ x_free(opt_secure_file_priv);
-+ bitmap_free(&temp_pool);
-+ free_max_user_conn();
-+#ifdef HAVE_REPLICATION
-+ end_slave_list();
-+#endif
-+ delete binlog_filter;
-+ delete rpl_filter;
-+#ifndef EMBEDDED_LIBRARY
-+ end_ssl();
-+#endif
-+ vio_end();
-+#ifdef USE_REGEX
-+ my_regex_end();
-+#endif
-+#if defined(ENABLED_DEBUG_SYNC)
-+ /* End the debug sync facility. See debug_sync.cc. */
-+ debug_sync_end();
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+
-+#if !defined(EMBEDDED_LIBRARY)
-+ if (!opt_bootstrap)
-+ (void) my_delete(pidfile_name,MYF(0)); // This may not always exist
-+#endif
-+ if (print_message && errmesg && server_start_time)
-+ sql_print_information(ER(ER_SHUTDOWN_COMPLETE),my_progname);
-+ thread_scheduler.end();
-+ finish_client_errs();
-+ my_free((uchar*) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST),
-+ MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR));
-+ DBUG_PRINT("quit", ("Error messages freed"));
-+ /* Tell main we are ready */
-+ logger.cleanup_end();
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ DBUG_PRINT("quit", ("got thread count lock"));
-+ ready_to_exit=1;
-+ /* do the broadcast inside the lock to ensure that my_end() is not called */
-+ (void) pthread_cond_broadcast(&COND_thread_count);
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+
-+ /*
-+ The following lines may never be executed as the main thread may have
-+ killed us
-+ */
-+ DBUG_PRINT("quit", ("done with cleanup"));
-+} /* clean_up */
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/**
-+ This is mainly needed when running with purify, but it's still nice to
-+ know that all child threads have died when mysqld exits.
-+*/
-+static void wait_for_signal_thread_to_end()
-+{
-+#ifndef __NETWARE__
-+ uint i;
-+ /*
-+ Wait up to 10 seconds for signal thread to die. We use this mainly to
-+ avoid getting warnings that my_thread_end has not been called
-+ */
-+ for (i= 0 ; i < 100 && signal_thread_in_use; i++)
-+ {
-+ if (pthread_kill(signal_thread, MYSQL_KILL_SIGNAL) != ESRCH)
-+ break;
-+ my_sleep(100); // Give it time to die
-+ }
-+#endif
-+}
-+
-+
-+static void clean_up_mutexes()
-+{
-+ (void) pthread_mutex_destroy(&LOCK_mysql_create_db);
-+ (void) pthread_mutex_destroy(&LOCK_lock_db);
-+ (void) pthread_mutex_destroy(&LOCK_Acl);
-+ (void) rwlock_destroy(&LOCK_grant);
-+ (void) pthread_mutex_destroy(&LOCK_open);
-+ (void) pthread_mutex_destroy(&LOCK_thread_count);
-+ (void) pthread_mutex_destroy(&LOCK_mapped_file);
-+ (void) pthread_mutex_destroy(&LOCK_status);
-+ (void) pthread_mutex_destroy(&LOCK_error_log);
-+ (void) pthread_mutex_destroy(&LOCK_delayed_insert);
-+ (void) pthread_mutex_destroy(&LOCK_delayed_status);
-+ (void) pthread_mutex_destroy(&LOCK_delayed_create);
-+ (void) pthread_mutex_destroy(&LOCK_manager);
-+ (void) pthread_mutex_destroy(&LOCK_crypt);
-+ (void) pthread_mutex_destroy(&LOCK_bytes_sent);
-+ (void) pthread_mutex_destroy(&LOCK_bytes_received);
-+ (void) pthread_mutex_destroy(&LOCK_user_conn);
-+ (void) pthread_mutex_destroy(&LOCK_connection_count);
-+ Events::destroy_mutexes();
-+#ifdef HAVE_OPENSSL
-+ (void) pthread_mutex_destroy(&LOCK_des_key_file);
-+#ifndef HAVE_YASSL
-+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
-+ (void) rwlock_destroy(&openssl_stdlocks[i].lock);
-+ OPENSSL_free(openssl_stdlocks);
-+#endif
-+#endif
-+#ifdef HAVE_REPLICATION
-+ (void) pthread_mutex_destroy(&LOCK_rpl_status);
-+ (void) pthread_cond_destroy(&COND_rpl_status);
-+#endif
-+ (void) pthread_mutex_destroy(&LOCK_active_mi);
-+ (void) rwlock_destroy(&LOCK_sys_init_connect);
-+ (void) rwlock_destroy(&LOCK_sys_init_slave);
-+ (void) pthread_mutex_destroy(&LOCK_global_system_variables);
-+ (void) rwlock_destroy(&LOCK_system_variables_hash);
-+ (void) pthread_mutex_destroy(&LOCK_global_read_lock);
-+ (void) pthread_mutex_destroy(&LOCK_uuid_generator);
-+ (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count);
-+ (void) pthread_cond_destroy(&COND_thread_count);
-+ (void) pthread_cond_destroy(&COND_refresh);
-+ (void) pthread_cond_destroy(&COND_global_read_lock);
-+ (void) pthread_cond_destroy(&COND_thread_cache);
-+ (void) pthread_cond_destroy(&COND_flush_thread_cache);
-+ (void) pthread_cond_destroy(&COND_manager);
-+}
-+
-+#endif /*EMBEDDED_LIBRARY*/
-+
-+
-+/****************************************************************************
-+** Init IP and UNIX socket
-+****************************************************************************/
-+
-+#ifndef EMBEDDED_LIBRARY
-+static void set_ports()
-+{
-+ char *env;
-+ if (!mysqld_port && !opt_disable_networking)
-+ { // Get port if not from commandline
-+ mysqld_port= MYSQL_PORT;
-+
-+ /*
-+ if builder specifically requested a default port, use that
-+ (even if it coincides with our factory default).
-+ only if they didn't do we check /etc/services (and, failing
-+ on that, fall back to the factory default of 3306).
-+ either default can be overridden by the environment variable
-+ MYSQL_TCP_PORT, which in turn can be overridden with command
-+ line options.
-+ */
-+
-+#if MYSQL_PORT_DEFAULT == 0
-+ struct servent *serv_ptr;
-+ if ((serv_ptr= getservbyname("mysql", "tcp")))
-+ mysqld_port= ntohs((u_short) serv_ptr->s_port); /* purecov: inspected */
-+#endif
-+ if ((env = getenv("MYSQL_TCP_PORT")))
-+ mysqld_port= (uint) atoi(env); /* purecov: inspected */
-+ }
-+ if (!mysqld_unix_port)
-+ {
-+#ifdef __WIN__
-+ mysqld_unix_port= (char*) MYSQL_NAMEDPIPE;
-+#else
-+ mysqld_unix_port= (char*) MYSQL_UNIX_ADDR;
-+#endif
-+ if ((env = getenv("MYSQL_UNIX_PORT")))
-+ mysqld_unix_port= env; /* purecov: inspected */
-+ }
-+}
-+
-+/* Change to run as another user if started with --user */
-+
-+static struct passwd *check_user(const char *user)
-+{
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ struct passwd *tmp_user_info;
-+ uid_t user_id= geteuid();
-+
-+ // Don't bother if we aren't superuser
-+ if (user_id)
-+ {
-+ if (user)
-+ {
-+ /* Don't give a warning, if real user is same as given with --user */
-+ /* purecov: begin tested */
-+ tmp_user_info= getpwnam(user);
-+ if ((!tmp_user_info || user_id != tmp_user_info->pw_uid) &&
-+ global_system_variables.log_warnings)
-+ sql_print_warning(
-+ "One can only use the --user switch if running as root\n");
-+ /* purecov: end */
-+ }
-+ return NULL;
-+ }
-+ if (!user)
-+ {
-+ if (!opt_bootstrap)
-+ {
-+ sql_print_error("Fatal error: Please read \"Security\" section of the manual to find out how to run mysqld as root!\n");
-+ unireg_abort(1);
-+ }
-+ return NULL;
-+ }
-+ /* purecov: begin tested */
-+ if (!strcmp(user,"root"))
-+ return NULL; // Avoid problem with dynamic libraries
-+
-+ if (!(tmp_user_info= getpwnam(user)))
-+ {
-+ // Allow a numeric uid to be used
-+ const char *pos;
-+ for (pos= user; my_isdigit(mysqld_charset,*pos); pos++) ;
-+ if (*pos) // Not numeric id
-+ goto err;
-+ if (!(tmp_user_info= getpwuid(atoi(user))))
-+ goto err;
-+ }
-+ return tmp_user_info;
-+ /* purecov: end */
-+
-+err:
-+ sql_print_error("Fatal error: Can't change to run as user '%s' ; Please check that the user exists!\n",user);
-+ unireg_abort(1);
-+
-+#ifdef PR_SET_DUMPABLE
-+ if (test_flags & TEST_CORE_ON_SIGNAL)
-+ {
-+ /* inform kernel that process is dumpable */
-+ (void) prctl(PR_SET_DUMPABLE, 1);
-+ }
-+#endif
-+
-+#endif
-+ return NULL;
-+}
-+
-+static void set_user(const char *user, struct passwd *user_info_arg)
-+{
-+ /* purecov: begin tested */
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ DBUG_ASSERT(user_info_arg != 0);
-+#ifdef HAVE_INITGROUPS
-+ /*
-+ We can get a SIGSEGV when calling initgroups() on some systems when NSS
-+ is configured to use LDAP and the server is statically linked. We set
-+ calling_initgroups as a flag to the SIGSEGV handler that is then used to
-+ output a specific message to help the user resolve this problem.
-+ */
-+ calling_initgroups= TRUE;
-+ initgroups((char*) user, user_info_arg->pw_gid);
-+ calling_initgroups= FALSE;
-+#endif
-+ if (setgid(user_info_arg->pw_gid) == -1)
-+ {
-+ sql_perror("setgid");
-+ unireg_abort(1);
-+ }
-+ if (setuid(user_info_arg->pw_uid) == -1)
-+ {
-+ sql_perror("setuid");
-+ unireg_abort(1);
-+ }
-+#endif
-+ /* purecov: end */
-+}
-+
-+
-+static void set_effective_user(struct passwd *user_info_arg)
-+{
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ DBUG_ASSERT(user_info_arg != 0);
-+ if (setregid((gid_t)-1, user_info_arg->pw_gid) == -1)
-+ {
-+ sql_perror("setregid");
-+ unireg_abort(1);
-+ }
-+ if (setreuid((uid_t)-1, user_info_arg->pw_uid) == -1)
-+ {
-+ sql_perror("setreuid");
-+ unireg_abort(1);
-+ }
-+#endif
-+}
-+
-+
-+/** Change root user if started with @c --chroot . */
-+static void set_root(const char *path)
-+{
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+ if (chroot(path) == -1)
-+ {
-+ sql_perror("chroot");
-+ unireg_abort(1);
-+ }
-+ my_setwd("/", MYF(0));
-+#endif
-+}
-+
-+static void network_init(void)
-+{
-+ struct sockaddr_in IPaddr;
-+#ifdef HAVE_SYS_UN_H
-+ struct sockaddr_un UNIXaddr;
-+#endif
-+ int arg=1;
-+ int ret;
-+ uint waited;
-+ uint this_wait;
-+ uint retry;
-+ DBUG_ENTER("network_init");
-+ LINT_INIT(ret);
-+
-+ if (thread_scheduler.init())
-+ unireg_abort(1); /* purecov: inspected */
-+
-+ set_ports();
-+
-+ if (mysqld_port != 0 && !opt_disable_networking && !opt_bootstrap)
-+ {
-+ DBUG_PRINT("general",("IP Socket is %d",mysqld_port));
-+ ip_sock = socket(AF_INET, SOCK_STREAM, 0);
-+ if (ip_sock == INVALID_SOCKET)
-+ {
-+ DBUG_PRINT("error",("Got error: %d from socket()",socket_errno));
-+ sql_perror(ER(ER_IPSOCK_ERROR)); /* purecov: tested */
-+ unireg_abort(1); /* purecov: tested */
-+ }
-+ bzero((char*) &IPaddr, sizeof(IPaddr));
-+ IPaddr.sin_family = AF_INET;
-+ IPaddr.sin_addr.s_addr = my_bind_addr;
-+ IPaddr.sin_port = (unsigned short) htons((unsigned short) mysqld_port);
-+
-+#ifndef __WIN__
-+ /*
-+ We should not use SO_REUSEADDR on windows as this would enable a
-+ user to open two mysqld servers with the same TCP/IP port.
-+ */
-+ (void) setsockopt(ip_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,sizeof(arg));
-+#endif /* __WIN__ */
-+ /*
-+ Sometimes the port is not released fast enough when stopping and
-+ restarting the server. This happens quite often with the test suite
-+ on busy Linux systems. Retry to bind the address at these intervals:
-+ Sleep intervals: 1, 2, 4, 6, 9, 13, 17, 22, ...
-+ Retry at second: 1, 3, 7, 13, 22, 35, 52, 74, ...
-+ Limit the sequence by mysqld_port_timeout (set --port-open-timeout=#).
-+ */
-+ for (waited= 0, retry= 1; ; retry++, waited+= this_wait)
-+ {
-+ if (((ret= bind(ip_sock, my_reinterpret_cast(struct sockaddr *) (&IPaddr),
-+ sizeof(IPaddr))) >= 0) ||
-+ (socket_errno != SOCKET_EADDRINUSE) ||
-+ (waited >= mysqld_port_timeout))
-+ break;
-+ sql_print_information("Retrying bind on TCP/IP port %u", mysqld_port);
-+ this_wait= retry * retry / 3 + 1;
-+ sleep(this_wait);
-+ }
-+ if (ret < 0)
-+ {
-+ DBUG_PRINT("error",("Got error: %d from bind",socket_errno));
-+ sql_perror("Can't start server: Bind on TCP/IP port");
-+ sql_print_error("Do you already have another mysqld server running on port: %d ?",mysqld_port);
-+ unireg_abort(1);
-+ }
-+ if (listen(ip_sock,(int) back_log) < 0)
-+ {
-+ sql_perror("Can't start server: listen() on TCP/IP port");
-+ sql_print_error("listen() on TCP/IP failed with error %d",
-+ socket_errno);
-+ unireg_abort(1);
-+ }
-+ }
-+
-+#ifdef __NT__
-+ /* create named pipe */
-+ if (Service.IsNT() && mysqld_unix_port[0] && !opt_bootstrap &&
-+ opt_enable_named_pipe)
-+ {
-+
-+ strxnmov(pipe_name, sizeof(pipe_name)-1, "\\\\.\\pipe\\",
-+ mysqld_unix_port, NullS);
-+ bzero((char*) &saPipeSecurity, sizeof(saPipeSecurity));
-+ bzero((char*) &sdPipeDescriptor, sizeof(sdPipeDescriptor));
-+ if (!InitializeSecurityDescriptor(&sdPipeDescriptor,
-+ SECURITY_DESCRIPTOR_REVISION))
-+ {
-+ sql_perror("Can't start server : Initialize security descriptor");
-+ unireg_abort(1);
-+ }
-+ if (!SetSecurityDescriptorDacl(&sdPipeDescriptor, TRUE, NULL, FALSE))
-+ {
-+ sql_perror("Can't start server : Set security descriptor");
-+ unireg_abort(1);
-+ }
-+ saPipeSecurity.nLength = sizeof(SECURITY_ATTRIBUTES);
-+ saPipeSecurity.lpSecurityDescriptor = &sdPipeDescriptor;
-+ saPipeSecurity.bInheritHandle = FALSE;
-+ if ((hPipe= CreateNamedPipe(pipe_name,
-+ PIPE_ACCESS_DUPLEX|FILE_FLAG_OVERLAPPED,
-+ PIPE_TYPE_BYTE |
-+ PIPE_READMODE_BYTE |
-+ PIPE_WAIT,
-+ PIPE_UNLIMITED_INSTANCES,
-+ (int) global_system_variables.net_buffer_length,
-+ (int) global_system_variables.net_buffer_length,
-+ NMPWAIT_USE_DEFAULT_WAIT,
-+ &saPipeSecurity)) == INVALID_HANDLE_VALUE)
-+ {
-+ LPVOID lpMsgBuf;
-+ int error=GetLastError();
-+ FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
-+ FORMAT_MESSAGE_FROM_SYSTEM,
-+ NULL, error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
-+ (LPTSTR) &lpMsgBuf, 0, NULL );
-+ sql_perror((char *)lpMsgBuf);
-+ LocalFree(lpMsgBuf);
-+ unireg_abort(1);
-+ }
-+ }
-+#endif
-+
-+#if defined(HAVE_SYS_UN_H)
-+ /*
-+ ** Create the UNIX socket
-+ */
-+ if (mysqld_unix_port[0] && !opt_bootstrap)
-+ {
-+ DBUG_PRINT("general",("UNIX Socket is %s",mysqld_unix_port));
-+
-+ if (strlen(mysqld_unix_port) > (sizeof(UNIXaddr.sun_path) - 1))
-+ {
-+ sql_print_error("The socket file path is too long (> %u): %s",
-+ (uint) sizeof(UNIXaddr.sun_path) - 1, mysqld_unix_port);
-+ unireg_abort(1);
-+ }
-+ if ((unix_sock= socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
-+ {
-+ sql_perror("Can't start server : UNIX Socket "); /* purecov: inspected */
-+ unireg_abort(1); /* purecov: inspected */
-+ }
-+ bzero((char*) &UNIXaddr, sizeof(UNIXaddr));
-+ UNIXaddr.sun_family = AF_UNIX;
-+ strmov(UNIXaddr.sun_path, mysqld_unix_port);
-+ (void) unlink(mysqld_unix_port);
-+ (void) setsockopt(unix_sock,SOL_SOCKET,SO_REUSEADDR,(char*)&arg,
-+ sizeof(arg));
-+ umask(0);
-+ if (bind(unix_sock, my_reinterpret_cast(struct sockaddr *) (&UNIXaddr),
-+ sizeof(UNIXaddr)) < 0)
-+ {
-+ sql_perror("Can't start server : Bind on unix socket"); /* purecov: tested */
-+ sql_print_error("Do you already have another mysqld server running on socket: %s ?",mysqld_unix_port);
-+ unireg_abort(1); /* purecov: tested */
-+ }
-+ umask(((~my_umask) & 0666));
-+#if defined(S_IFSOCK) && defined(SECURE_SOCKETS)
-+ (void) chmod(mysqld_unix_port,S_IFSOCK); /* Fix solaris 2.6 bug */
-+#endif
-+ if (listen(unix_sock,(int) back_log) < 0)
-+ sql_print_warning("listen() on Unix socket failed with error %d",
-+ socket_errno);
-+ }
-+#endif
-+ DBUG_PRINT("info",("server started"));
-+ DBUG_VOID_RETURN;
-+}
-+
-+#endif /*!EMBEDDED_LIBRARY*/
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+/**
-+ Close a connection.
-+
-+ @param thd Thread handle
-+ @param errcode Error code to print to console
-+ @param lock 1 if we have have to lock LOCK_thread_count
-+
-+ @note
-+ For the connection that is doing shutdown, this is called twice
-+*/
-+void close_connection(THD *thd, uint errcode, bool lock)
-+{
-+ st_vio *vio;
-+ DBUG_ENTER("close_connection");
-+ DBUG_PRINT("enter",("fd: %s error: '%s'",
-+ thd->net.vio ? vio_description(thd->net.vio) :
-+ "(not connected)",
-+ errcode ? ER(errcode) : ""));
-+ if (lock)
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ thd->killed= THD::KILL_CONNECTION;
-+ if ((vio= thd->net.vio) != 0)
-+ {
-+ if (errcode)
-+ net_send_error(thd, errcode, ER(errcode)); /* purecov: inspected */
-+ vio_close(vio); /* vio is freed in delete thd */
-+ }
-+ if (lock)
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ DBUG_VOID_RETURN;
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+/** Called when a thread is aborted. */
-+/* ARGSUSED */
-+extern "C" sig_handler end_thread_signal(int sig __attribute__((unused)))
-+{
-+ THD *thd=current_thd;
-+ DBUG_ENTER("end_thread_signal");
-+ if (thd && ! thd->bootstrap)
-+ {
-+ statistic_increment(killed_threads, &LOCK_status);
-+ thread_scheduler.end_thread(thd,0); /* purecov: inspected */
-+ }
-+ DBUG_VOID_RETURN; /* purecov: deadcode */
-+}
-+
-+
-+/*
-+ Unlink thd from global list of available connections and free thd
-+
-+ SYNOPSIS
-+ unlink_thd()
-+ thd Thread handler
-+
-+ NOTES
-+ LOCK_thread_count is locked and left locked
-+*/
-+
-+void unlink_thd(THD *thd)
-+{
-+ DBUG_ENTER("unlink_thd");
-+ DBUG_PRINT("enter", ("thd: 0x%lx", (long) thd));
-+ thd->cleanup();
-+
-+ pthread_mutex_lock(&LOCK_connection_count);
-+ --connection_count;
-+ pthread_mutex_unlock(&LOCK_connection_count);
-+
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ thread_count--;
-+ delete thd;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Store thread in cache for reuse by new connections
-+
-+ SYNOPSIS
-+ cache_thread()
-+
-+ NOTES
-+ LOCK_thread_count has to be locked
-+
-+ RETURN
-+ 0 Thread was not put in cache
-+ 1 Thread is to be reused by new connection.
-+ (ie, caller should return, not abort with pthread_exit())
-+*/
-+
-+
-+static bool cache_thread()
-+{
-+ safe_mutex_assert_owner(&LOCK_thread_count);
-+ if (cached_thread_count < thread_cache_size &&
-+ ! abort_loop && !kill_cached_threads)
-+ {
-+ /* Don't kill the thread, just put it in cache for reuse */
-+ DBUG_PRINT("info", ("Adding thread to cache"));
-+ cached_thread_count++;
-+ while (!abort_loop && ! wake_thread && ! kill_cached_threads)
-+ (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count);
-+ cached_thread_count--;
-+ if (kill_cached_threads)
-+ pthread_cond_signal(&COND_flush_thread_cache);
-+ if (wake_thread)
-+ {
-+ THD *thd;
-+ wake_thread--;
-+ thd= thread_cache.get();
-+ thd->thread_stack= (char*) &thd; // For store_globals
-+ (void) thd->store_globals();
-+ /*
-+ THD::mysys_var::abort is associated with physical thread rather
-+ than with THD object. So we need to reset this flag before using
-+ this thread for handling of new THD object/connection.
-+ */
-+ thd->mysys_var->abort= 0;
-+ thd->thr_create_utime= my_micro_time();
-+ threads.append(thd);
-+ return(1);
-+ }
-+ }
-+ return(0);
-+}
-+
-+
-+/*
-+ End thread for the current connection
-+
-+ SYNOPSIS
-+ one_thread_per_connection_end()
-+ thd Thread handler
-+ put_in_cache Store thread in cache, if there is room in it
-+ Normally this is true in all cases except when we got
-+ out of resources initializing the current thread
-+
-+ NOTES
-+ If thread is cached, we will wait until thread is scheduled to be
-+ reused and then we will return.
-+ If thread is not cached, we end the thread.
-+
-+ RETURN
-+ 0 Signal to handle_one_connection to reuse connection
-+*/
-+
-+bool one_thread_per_connection_end(THD *thd, bool put_in_cache)
-+{
-+ DBUG_ENTER("one_thread_per_connection_end");
-+ unlink_thd(thd);
-+ if (put_in_cache)
-+ put_in_cache= cache_thread();
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+ if (put_in_cache)
-+ DBUG_RETURN(0); // Thread is reused
-+
-+ /* It's safe to broadcast outside a lock (COND... is not deleted here) */
-+ DBUG_PRINT("signal", ("Broadcasting COND_thread_count"));
-+ DBUG_LEAVE; // Must match DBUG_ENTER()
-+ my_thread_end();
-+ (void) pthread_cond_broadcast(&COND_thread_count);
-+
-+ pthread_exit(0);
-+ return 0; // Avoid compiler warnings
-+}
-+
-+
-+void flush_thread_cache()
-+{
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ kill_cached_threads++;
-+ while (cached_thread_count)
-+ {
-+ pthread_cond_broadcast(&COND_thread_cache);
-+ pthread_cond_wait(&COND_flush_thread_cache,&LOCK_thread_count);
-+ }
-+ kill_cached_threads--;
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+}
-+
-+
-+#ifdef THREAD_SPECIFIC_SIGPIPE
-+/**
-+ Aborts a thread nicely. Comes here on SIGPIPE.
-+
-+ @todo
-+ One should have to fix that thr_alarm know about this thread too.
-+*/
-+extern "C" sig_handler abort_thread(int sig __attribute__((unused)))
-+{
-+ THD *thd=current_thd;
-+ DBUG_ENTER("abort_thread");
-+ if (thd)
-+ thd->killed= THD::KILL_CONNECTION;
-+ DBUG_VOID_RETURN;
-+}
-+#endif
-+
-+
-+/******************************************************************************
-+ Setup a signal thread with handles all signals.
-+ Because Linux doesn't support schemas use a mutex to check that
-+ the signal thread is ready before continuing
-+******************************************************************************/
-+
-+#if defined(__WIN__)
-+
-+
-+/*
-+ On Windows, we use native SetConsoleCtrlHandler for handle events like Ctrl-C
-+ with graceful shutdown.
-+ Also, we do not use signal(), but SetUnhandledExceptionFilter instead - as it
-+ provides possibility to pass the exception to just-in-time debugger, collect
-+ dumps and potentially also the exception and thread context used to output
-+ callstack.
-+*/
-+
-+static BOOL WINAPI console_event_handler( DWORD type )
-+{
-+ DBUG_ENTER("console_event_handler");
-+#ifndef EMBEDDED_LIBRARY
-+ if(type == CTRL_C_EVENT)
-+ {
-+ /*
-+ Do not shutdown before startup is finished and shutdown
-+ thread is initialized. Otherwise there is a race condition
-+ between main thread doing initialization and CTRL-C thread doing
-+ cleanup, which can result into crash.
-+ */
-+#ifndef EMBEDDED_LIBRARY
-+ if(hEventShutdown)
-+ kill_mysql();
-+ else
-+#endif
-+ sql_print_warning("CTRL-C ignored during startup");
-+ DBUG_RETURN(TRUE);
-+ }
-+#endif
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ In Visual Studio 2005 and later, default SIGABRT handler will overwrite
-+ any unhandled exception filter set by the application and will try to
-+ call JIT debugger. This is not what we want, this we calling __debugbreak
-+ to stop in debugger, if process is being debugged or to generate
-+ EXCEPTION_BREAKPOINT and then handle_segfault will do its magic.
-+*/
-+
-+#if (_MSC_VER >= 1400)
-+static void my_sigabrt_handler(int sig)
-+{
-+ __debugbreak();
-+}
-+#endif /*_MSC_VER >=1400 */
-+
-+void win_install_sigabrt_handler(void)
-+{
-+#if (_MSC_VER >=1400)
-+ /*abort() should not override our exception filter*/
-+ _set_abort_behavior(0,_CALL_REPORTFAULT);
-+ signal(SIGABRT,my_sigabrt_handler);
-+#endif /* _MSC_VER >=1400 */
-+}
-+
-+#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
-+#define DEBUGGER_ATTACH_TIMEOUT 120
-+/*
-+ Wait for debugger to attach and break into debugger. If debugger is not attached,
-+ resume after timeout.
-+*/
-+static void wait_for_debugger(int timeout_sec)
-+{
-+ if(!IsDebuggerPresent())
-+ {
-+ int i;
-+ printf("Waiting for debugger to attach, pid=%u\n",GetCurrentProcessId());
-+ fflush(stdout);
-+ for(i= 0; i < timeout_sec; i++)
-+ {
-+ Sleep(1000);
-+ if(IsDebuggerPresent())
-+ {
-+ /* Break into debugger */
-+ __debugbreak();
-+ return;
-+ }
-+ }
-+ printf("pid=%u, debugger not attached after %d seconds, resuming\n",GetCurrentProcessId(),
-+ timeout_sec);
-+ fflush(stdout);
-+ }
-+}
-+#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
-+
-+LONG WINAPI my_unhandler_exception_filter(EXCEPTION_POINTERS *ex_pointers)
-+{
-+ static BOOL first_time= TRUE;
-+ if(!first_time)
-+ {
-+ /*
-+ This routine can be called twice, typically
-+ when detaching in JIT debugger.
-+ Return EXCEPTION_EXECUTE_HANDLER to terminate process.
-+ */
-+ return EXCEPTION_EXECUTE_HANDLER;
-+ }
-+ first_time= FALSE;
-+#ifdef DEBUG_UNHANDLED_EXCEPTION_FILTER
-+ /*
-+ Unfortunately there is no clean way to debug unhandled exception filters,
-+ as debugger does not stop there(also documented in MSDN)
-+ To overcome, one could put a MessageBox, but this will not work in service.
-+ Better solution is to print error message and sleep some minutes
-+ until debugger is attached
-+ */
-+ wait_for_debugger(DEBUGGER_ATTACH_TIMEOUT);
-+#endif /* DEBUG_UNHANDLED_EXCEPTION_FILTER */
-+ __try
-+ {
-+ my_set_exception_pointers(ex_pointers);
-+ handle_segfault(ex_pointers->ExceptionRecord->ExceptionCode);
-+ }
-+ __except(EXCEPTION_EXECUTE_HANDLER)
-+ {
-+ DWORD written;
-+ const char msg[] = "Got exception in exception handler!\n";
-+ WriteFile(GetStdHandle(STD_OUTPUT_HANDLE),msg, sizeof(msg)-1,
-+ &written,NULL);
-+ }
-+ /*
-+ Return EXCEPTION_CONTINUE_SEARCH to give JIT debugger
-+ (drwtsn32 or vsjitdebugger) possibility to attach,
-+ if JIT debugger is configured.
-+ Windows Error reporting might generate a dump here.
-+ */
-+ return EXCEPTION_CONTINUE_SEARCH;
-+}
-+
-+
-+static void init_signals(void)
-+{
-+ win_install_sigabrt_handler();
-+ if(opt_console)
-+ SetConsoleCtrlHandler(console_event_handler,TRUE);
-+
-+ /* Avoid MessageBox()es*/
-+ _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
-+ _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
-+ _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE);
-+ _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR);
-+ _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE);
-+ _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
-+
-+ /*
-+ Do not use SEM_NOGPFAULTERRORBOX in the following SetErrorMode (),
-+ because it would prevent JIT debugger and Windows error reporting
-+ from working. We need WER or JIT-debugging, since our own unhandled
-+ exception filter is not guaranteed to work in all situation
-+ (like heap corruption or stack overflow)
-+ */
-+ SetErrorMode(SetErrorMode(0) | SEM_FAILCRITICALERRORS
-+ | SEM_NOOPENFILEERRORBOX);
-+ SetUnhandledExceptionFilter(my_unhandler_exception_filter);
-+}
-+
-+
-+static void start_signal_handler(void)
-+{
-+#ifndef EMBEDDED_LIBRARY
-+ // Save vm id of this process
-+ if (!opt_bootstrap)
-+ create_pid_file();
-+#endif /* EMBEDDED_LIBRARY */
-+}
-+
-+
-+static void check_data_home(const char *path)
-+{}
-+
-+
-+#elif defined(__NETWARE__)
-+
-+/// down server event callback.
-+void mysql_down_server_cb(void *, void *)
-+{
-+ event_flag= TRUE;
-+ kill_server(0);
-+}
-+
-+
-+/// destroy callback resources.
-+void mysql_cb_destroy(void *)
-+{
-+ UnRegisterEventNotification(eh); // cleanup down event notification
-+ NX_UNWRAP_INTERFACE(ref);
-+ /* Deregister NSS volume deactivation event */
-+ NX_UNWRAP_INTERFACE(refneb);
-+ if (neb_consumer_id)
-+ UnRegisterConsumer(neb_consumer_id, NULL);
-+}
-+
-+
-+/// initialize callbacks.
-+void mysql_cb_init()
-+{
-+ // register for down server event
-+ void *handle = getnlmhandle();
-+ rtag_t rt= AllocateResourceTag(handle, "MySQL Down Server Callback",
-+ EventSignature);
-+ NX_WRAP_INTERFACE((void *)mysql_down_server_cb, 2, (void **)&ref);
-+ eh= RegisterForEventNotification(rt, EVENT_PRE_DOWN_SERVER,
-+ EVENT_PRIORITY_APPLICATION,
-+ NULL, ref, NULL);
-+
-+ /*
-+ Register for volume deactivation event
-+ Wrap the callback function, as it is called by non-LibC thread
-+ */
-+ (void *) NX_WRAP_INTERFACE(neb_event_callback, 1, &refneb);
-+ registerwithneb();
-+
-+ NXVmRegisterExitHandler(mysql_cb_destroy, NULL); // clean-up
-+}
-+
-+
-+/** To get the name of the NetWare volume having MySQL data folder. */
-+static void getvolumename()
-+{
-+ char *p;
-+ /*
-+ We assume that data path is already set.
-+ If not it won't come here. Terminate after volume name
-+ */
-+ if ((p= strchr(mysql_real_data_home, ':')))
-+ strmake(datavolname, mysql_real_data_home,
-+ (uint) (p - mysql_real_data_home));
-+}
-+
-+
-+/**
-+ Registering with NEB for NSS Volume Deactivation event.
-+*/
-+
-+static void registerwithneb()
-+{
-+
-+ ConsumerRegistrationInfo reg_info;
-+
-+ /* Clear NEB registration structure */
-+ bzero((char*) ®_info, sizeof(struct ConsumerRegistrationInfo));
-+
-+ /* Fill the NEB consumer information structure */
-+ reg_info.CRIVersion= 1; // NEB version
-+ /* NEB Consumer name */
-+ reg_info.CRIConsumerName= (BYTE *) "MySQL Database Server";
-+ /* Event of interest */
-+ reg_info.CRIEventName= (BYTE *) "NSS.ChangeVolState.Enter";
-+ reg_info.CRIUserParameter= NULL; // Consumer Info
-+ reg_info.CRIEventFlags= 0; // Event flags
-+ /* Consumer NLM handle */
-+ reg_info.CRIOwnerID= (LoadDefinitionStructure *)getnlmhandle();
-+ reg_info.CRIConsumerESR= NULL; // No consumer ESR required
-+ reg_info.CRISecurityToken= 0; // No security token for the event
-+ reg_info.CRIConsumerFlags= 0; // SMP_ENABLED_BIT;
-+ reg_info.CRIFilterName= 0; // No event filtering
-+ reg_info.CRIFilterDataLength= 0; // No filtering data
-+ reg_info.CRIFilterData= 0; // No filtering data
-+ /* Callback function for the event */
-+ (void *)reg_info.CRIConsumerCallback= (void *) refneb;
-+ reg_info.CRIOrder= 0; // Event callback order
-+ reg_info.CRIConsumerType= CHECK_CONSUMER; // Consumer type
-+
-+ /* Register for the event with NEB */
-+ if (RegisterConsumer(®_info))
-+ {
-+ consoleprintf("Failed to register for NSS Volume Deactivation event \n");
-+ return;
-+ }
-+ /* This ID is required for deregistration */
-+ neb_consumer_id= reg_info.CRIConsumerID;
-+
-+ /* Get MySQL data volume name, stored in global variable datavolname */
-+ getvolumename();
-+
-+ /*
-+ Get the NSS volume ID of the MySQL Data volume.
-+ Volume ID is stored in a global variable
-+ */
-+ getvolumeID((BYTE*) datavolname);
-+}
-+
-+
-+/**
-+ Callback for NSS Volume Deactivation event.
-+*/
-+
-+ulong neb_event_callback(struct EventBlock *eblock)
-+{
-+ EventChangeVolStateEnter_s *voldata;
-+ extern bool nw_panic;
-+
-+ voldata= (EventChangeVolStateEnter_s *)eblock->EBEventData;
-+
-+ /* Deactivation of a volume */
-+ if ((voldata->oldState == zVOLSTATE_ACTIVE &&
-+ voldata->newState == zVOLSTATE_DEACTIVE ||
-+ voldata->newState == zVOLSTATE_MAINTENANCE))
-+ {
-+ /*
-+ Ensure that we bring down MySQL server only for MySQL data
-+ volume deactivation
-+ */
-+ if (!memcmp(&voldata->volID, &datavolid, sizeof(VolumeID_t)))
-+ {
-+ consoleprintf("MySQL data volume is deactivated, shutting down MySQL Server \n");
-+ event_flag= TRUE;
-+ nw_panic = TRUE;
-+ event_flag= TRUE;
-+ kill_server(0);
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+#define ADMIN_VOL_PATH "_ADMIN:/Volumes/"
-+
-+/**
-+ Function to get NSS volume ID of the MySQL data.
-+*/
-+static void getvolumeID(BYTE *volumeName)
-+{
-+ char path[zMAX_FULL_NAME];
-+ Key_t rootKey= 0, fileKey= 0;
-+ QUAD getInfoMask;
-+ zInfo_s info;
-+ STATUS status;
-+
-+ /* Get the root key */
-+ if ((status= zRootKey(0, &rootKey)) != zOK)
-+ {
-+ consoleprintf("\nGetNSSVolumeProperties - Failed to get root key, status: %d\n.", (int) status);
-+ goto exit;
-+ }
-+
-+ /*
-+ Get the file key. This is the key to the volume object in the
-+ NSS admin volumes directory.
-+ */
-+
-+ strxmov(path, (const char *) ADMIN_VOL_PATH, (const char *) volumeName,
-+ NullS);
-+ if ((status= zOpen(rootKey, zNSS_TASK, zNSPACE_LONG|zMODE_UTF8,
-+ (BYTE *) path, zRR_READ_ACCESS, &fileKey)) != zOK)
-+ {
-+ consoleprintf("\nGetNSSVolumeProperties - Failed to get file, status: %d\n.", (int) status);
-+ goto exit;
-+ }
-+
-+ getInfoMask= zGET_IDS | zGET_VOLUME_INFO ;
-+ if ((status= zGetInfo(fileKey, getInfoMask, sizeof(info),
-+ zINFO_VERSION_A, &info)) != zOK)
-+ {
-+ consoleprintf("\nGetNSSVolumeProperties - Failed in zGetInfo, status: %d\n.", (int) status);
-+ goto exit;
-+ }
-+
-+ /* Copy the data to global variable */
-+ datavolid.timeLow= info.vol.volumeID.timeLow;
-+ datavolid.timeMid= info.vol.volumeID.timeMid;
-+ datavolid.timeHighAndVersion= info.vol.volumeID.timeHighAndVersion;
-+ datavolid.clockSeqHighAndReserved= info.vol.volumeID.clockSeqHighAndReserved;
-+ datavolid.clockSeqLow= info.vol.volumeID.clockSeqLow;
-+ /* This is guranteed to be 6-byte length (but sizeof() would be better) */
-+ memcpy(datavolid.node, info.vol.volumeID.node, (unsigned int) 6);
-+
-+exit:
-+ if (rootKey)
-+ zClose(rootKey);
-+ if (fileKey)
-+ zClose(fileKey);
-+}
-+
-+
-+static void init_signals(void)
-+{
-+ int signals[] = {SIGINT,SIGILL,SIGFPE,SIGSEGV,SIGTERM,SIGABRT};
-+
-+ for (uint i=0 ; i < sizeof(signals)/sizeof(int) ; i++)
-+ signal(signals[i], kill_server);
-+ mysql_cb_init(); // initialize callbacks
-+
-+}
-+
-+
-+static void start_signal_handler(void)
-+{
-+ // Save vm id of this process
-+ if (!opt_bootstrap)
-+ create_pid_file();
-+ // no signal handler
-+}
-+
-+
-+/**
-+ Warn if the data is on a Traditional volume.
-+
-+ @note
-+ Already done by mysqld_safe
-+*/
-+
-+static void check_data_home(const char *path)
-+{
-+}
-+
-+#endif /*__WIN__ || __NETWARE */
-+
-+#ifdef HAVE_LINUXTHREADS
-+#define UNSAFE_DEFAULT_LINUX_THREADS 200
-+#endif
-+
-+
-+#if BACKTRACE_DEMANGLE
-+#include <cxxabi.h>
-+extern "C" char *my_demangle(const char *mangled_name, int *status)
-+{
-+ return abi::__cxa_demangle(mangled_name, NULL, NULL, status);
-+}
-+#endif
-+
-+
-+extern "C" sig_handler handle_segfault(int sig)
-+{
-+ time_t curr_time;
-+ struct tm tm;
-+
-+ /*
-+ Strictly speaking, one needs a mutex here
-+ but since we have got SIGSEGV already, things are a mess
-+ so not having the mutex is not as bad as possibly using a buggy
-+ mutex - so we keep things simple
-+ */
-+ if (segfaulted)
-+ {
-+ fprintf(stderr, "Fatal " SIGNAL_FMT " while backtracing\n", sig);
-+ exit(1);
-+ }
-+
-+ segfaulted = 1;
-+
-+ curr_time= my_time(0);
-+ localtime_r(&curr_time, &tm);
-+
-+ fprintf(stderr,"\
-+%02d%02d%02d %2d:%02d:%02d - mysqld got " SIGNAL_FMT " ;\n\
-+This could be because you hit a bug. It is also possible that this binary\n\
-+or one of the libraries it was linked against is corrupt, improperly built,\n\
-+or misconfigured. This error can also be caused by malfunctioning hardware.\n",
-+ tm.tm_year % 100, tm.tm_mon+1, tm.tm_mday,
-+ tm.tm_hour, tm.tm_min, tm.tm_sec,
-+ sig);
-+ fprintf(stderr, "\
-+We will try our best to scrape up some info that will hopefully help diagnose\n\
-+the problem, but since we have already crashed, something is definitely wrong\n\
-+and this may fail.\n\n");
-+ fprintf(stderr, "key_buffer_size=%lu\n",
-+ (ulong) dflt_key_cache->key_cache_mem_size);
-+ fprintf(stderr, "read_buffer_size=%ld\n", (long) global_system_variables.read_buff_size);
-+ fprintf(stderr, "max_used_connections=%lu\n", max_used_connections);
-+ fprintf(stderr, "max_threads=%u\n", thread_scheduler.max_threads);
-+ fprintf(stderr, "threads_connected=%u\n", thread_count);
-+ fprintf(stderr, "It is possible that mysqld could use up to \n\
-+key_buffer_size + (read_buffer_size + sort_buffer_size)*max_threads = %lu K\n\
-+bytes of memory\n", ((ulong) dflt_key_cache->key_cache_mem_size +
-+ (global_system_variables.read_buff_size +
-+ global_system_variables.sortbuff_size) *
-+ thread_scheduler.max_threads +
-+ max_connections * sizeof(THD)) / 1024);
-+ fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
-+
-+#if defined(HAVE_LINUXTHREADS)
-+ if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS)
-+ {
-+ fprintf(stderr, "\
-+You seem to be running 32-bit Linux and have %d concurrent connections.\n\
-+If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\
-+yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\
-+the thread stack. Please read http://dev.mysql.com/doc/mysql/en/linux.html\n\n",
-+ thread_count);
-+ }
-+#endif /* HAVE_LINUXTHREADS */
-+
-+#ifdef HAVE_STACKTRACE
-+ THD *thd=current_thd;
-+
-+ if (!(test_flags & TEST_NO_STACKTRACE))
-+ {
-+ fprintf(stderr, "Thread pointer: 0x%lx\n", (long) thd);
-+ fprintf(stderr, "Attempting backtrace. You can use the following "
-+ "information to find out\nwhere mysqld died. If "
-+ "you see no messages after this, something went\n"
-+ "terribly wrong...\n");
-+ my_print_stacktrace(thd ? (uchar*) thd->thread_stack : NULL,
-+ my_thread_stack_size);
-+ }
-+ if (thd)
-+ {
-+ const char *kreason= "UNKNOWN";
-+ switch (thd->killed) {
-+ case THD::NOT_KILLED:
-+ kreason= "NOT_KILLED";
-+ break;
-+ case THD::KILL_BAD_DATA:
-+ kreason= "KILL_BAD_DATA";
-+ break;
-+ case THD::KILL_CONNECTION:
-+ kreason= "KILL_CONNECTION";
-+ break;
-+ case THD::KILL_QUERY:
-+ kreason= "KILL_QUERY";
-+ break;
-+ case THD::KILLED_NO_VALUE:
-+ kreason= "KILLED_NO_VALUE";
-+ break;
-+ }
-+ fprintf(stderr, "\nTrying to get some variables.\n"
-+ "Some pointers may be invalid and cause the dump to abort.\n");
-+ fprintf(stderr, "Query (%p): ", thd->query());
-+ my_safe_print_str(thd->query(), min(1024, thd->query_length()));
-+ fprintf(stderr, "Connection ID (thread ID): %lu\n", (ulong) thd->thread_id);
-+ fprintf(stderr, "Status: %s\n", kreason);
-+ fputc('\n', stderr);
-+ }
-+ fprintf(stderr, "\
-+The manual page at http://dev.mysql.com/doc/mysql/en/crashing.html contains\n\
-+information that should help you find out what is causing the crash.\n");
-+ fflush(stderr);
-+#endif /* HAVE_STACKTRACE */
-+
-+#ifdef HAVE_INITGROUPS
-+ if (calling_initgroups)
-+ fprintf(stderr, "\n\
-+This crash occured while the server was calling initgroups(). This is\n\
-+often due to the use of a mysqld that is statically linked against glibc\n\
-+and configured to use LDAP in /etc/nsswitch.conf. You will need to either\n\
-+upgrade to a version of glibc that does not have this problem (2.3.4 or\n\
-+later when used with nscd), disable LDAP in your nsswitch.conf, or use a\n\
-+mysqld that is not statically linked.\n");
-+#endif
-+
-+#ifdef HAVE_NPTL
-+ if (thd_lib_detected == THD_LIB_LT && !getenv("LD_ASSUME_KERNEL"))
-+ fprintf(stderr,"\n\
-+You are running a statically-linked LinuxThreads binary on an NPTL system.\n\
-+This can result in crashes on some distributions due to LT/NPTL conflicts.\n\
-+You should either build a dynamically-linked binary, or force LinuxThreads\n\
-+to be used with the LD_ASSUME_KERNEL environment variable. Please consult\n\
-+the documentation for your distribution on how to do that.\n");
-+#endif
-+
-+ if (locked_in_memory)
-+ {
-+ fprintf(stderr, "\n\
-+The \"--memlock\" argument, which was enabled, uses system calls that are\n\
-+unreliable and unstable on some operating systems and operating-system\n\
-+versions (notably, some versions of Linux). This crash could be due to use\n\
-+of those buggy OS calls. You should consider whether you really need the\n\
-+\"--memlock\" parameter and/or consult the OS distributer about \"mlockall\"\n\
-+bugs.\n");
-+ }
-+
-+#ifdef HAVE_WRITE_CORE
-+ if (test_flags & TEST_CORE_ON_SIGNAL)
-+ {
-+ fprintf(stderr, "Writing a core file\n");
-+ fflush(stderr);
-+ my_write_core(sig);
-+ }
-+#endif
-+
-+#ifndef __WIN__
-+ /* On Windows, do not terminate, but pass control to exception filter */
-+ exit(1);
-+#endif
-+}
-+
-+#if !defined(__WIN__) && !defined(__NETWARE__)
-+#ifndef SA_RESETHAND
-+#define SA_RESETHAND 0
-+#endif
-+#ifndef SA_NODEFER
-+#define SA_NODEFER 0
-+#endif
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+static void init_signals(void)
-+{
-+ sigset_t set;
-+ struct sigaction sa;
-+ DBUG_ENTER("init_signals");
-+
-+ my_sigset(THR_SERVER_ALARM,print_signal_warning); // Should never be called!
-+
-+ if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
-+ {
-+ sa.sa_flags = SA_RESETHAND | SA_NODEFER;
-+ sigemptyset(&sa.sa_mask);
-+ sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
-+
-+#ifdef HAVE_STACKTRACE
-+ my_init_stacktrace();
-+#endif
-+#if defined(__amiga__)
-+ sa.sa_handler=(void(*)())handle_segfault;
-+#else
-+ sa.sa_handler=handle_segfault;
-+#endif
-+ sigaction(SIGSEGV, &sa, NULL);
-+ sigaction(SIGABRT, &sa, NULL);
-+#ifdef SIGBUS
-+ sigaction(SIGBUS, &sa, NULL);
-+#endif
-+ sigaction(SIGILL, &sa, NULL);
-+ sigaction(SIGFPE, &sa, NULL);
-+ }
-+
-+#ifdef HAVE_GETRLIMIT
-+ if (test_flags & TEST_CORE_ON_SIGNAL)
-+ {
-+ /* Change limits so that we will get a core file */
-+ STRUCT_RLIMIT rl;
-+ rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
-+ if (setrlimit(RLIMIT_CORE, &rl) && global_system_variables.log_warnings)
-+ sql_print_warning("setrlimit could not change the size of core files to 'infinity'; We may not be able to generate a core file on signals");
-+ }
-+#endif
-+ (void) sigemptyset(&set);
-+ my_sigset(SIGPIPE,SIG_IGN);
-+ sigaddset(&set,SIGPIPE);
-+#ifndef IGNORE_SIGHUP_SIGQUIT
-+ sigaddset(&set,SIGQUIT);
-+ sigaddset(&set,SIGHUP);
-+#endif
-+ sigaddset(&set,SIGTERM);
-+
-+ /* Fix signals if blocked by parents (can happen on Mac OS X) */
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = 0;
-+ sa.sa_handler = print_signal_warning;
-+ sigaction(SIGTERM, &sa, (struct sigaction*) 0);
-+ sa.sa_flags = 0;
-+ sa.sa_handler = print_signal_warning;
-+ sigaction(SIGHUP, &sa, (struct sigaction*) 0);
-+#ifdef SIGTSTP
-+ sigaddset(&set,SIGTSTP);
-+#endif
-+ if (thd_lib_detected != THD_LIB_LT)
-+ sigaddset(&set,THR_SERVER_ALARM);
-+ if (test_flags & TEST_SIGINT)
-+ {
-+ my_sigset(thr_kill_signal, end_thread_signal);
-+ // May be SIGINT
-+ sigdelset(&set, thr_kill_signal);
-+ }
-+ else
-+ sigaddset(&set,SIGINT);
-+ sigprocmask(SIG_SETMASK,&set,NULL);
-+ pthread_sigmask(SIG_SETMASK,&set,NULL);
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+static void start_signal_handler(void)
-+{
-+ int error;
-+ pthread_attr_t thr_attr;
-+ DBUG_ENTER("start_signal_handler");
-+
-+ (void) pthread_attr_init(&thr_attr);
-+#if !defined(HAVE_DEC_3_2_THREADS)
-+ pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_SYSTEM);
-+ (void) pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
-+ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_attr_setprio(&thr_attr,INTERRUPT_PRIOR);
-+#if defined(__ia64__) || defined(__ia64)
-+ /*
-+ Peculiar things with ia64 platforms - it seems we only have half the
-+ stack size in reality, so we have to double it here
-+ */
-+ pthread_attr_setstacksize(&thr_attr,my_thread_stack_size*2);
-+#else
-+ pthread_attr_setstacksize(&thr_attr,my_thread_stack_size);
-+#endif
-+#endif
-+
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
-+ {
-+ sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
-+ error,errno);
-+ exit(1);
-+ }
-+ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+
-+ (void) pthread_attr_destroy(&thr_attr);
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/** This threads handles all signals and alarms. */
-+/* ARGSUSED */
-+pthread_handler_t signal_hand(void *arg __attribute__((unused)))
-+{
-+ sigset_t set;
-+ int sig;
-+ my_thread_init(); // Init new thread
-+ DBUG_ENTER("signal_hand");
-+ signal_thread_in_use= 1;
-+
-+ /*
-+ Setup alarm handler
-+ This should actually be '+ max_number_of_slaves' instead of +10,
-+ but the +10 should be quite safe.
-+ */
-+ init_thr_alarm(thread_scheduler.max_threads +
-+ global_system_variables.max_insert_delayed_threads + 10);
-+ if (thd_lib_detected != THD_LIB_LT && (test_flags & TEST_SIGINT))
-+ {
-+ (void) sigemptyset(&set); // Setup up SIGINT for debug
-+ (void) sigaddset(&set,SIGINT); // For debugging
-+ (void) pthread_sigmask(SIG_UNBLOCK,&set,NULL);
-+ }
-+ (void) sigemptyset(&set); // Setup up SIGINT for debug
-+#ifdef USE_ONE_SIGNAL_HAND
-+ (void) sigaddset(&set,THR_SERVER_ALARM); // For alarms
-+#endif
-+#ifndef IGNORE_SIGHUP_SIGQUIT
-+ (void) sigaddset(&set,SIGQUIT);
-+ (void) sigaddset(&set,SIGHUP);
-+#endif
-+ (void) sigaddset(&set,SIGTERM);
-+ (void) sigaddset(&set,SIGTSTP);
-+
-+ /* Save pid to this process (or thread on Linux) */
-+ if (!opt_bootstrap)
-+ create_pid_file();
-+
-+ /*
-+ signal to start_signal_handler that we are ready
-+ This works by waiting for start_signal_handler to free mutex,
-+ after which we signal it that we are ready.
-+ At this pointer there is no other threads running, so there
-+ should not be any other pthread_cond_signal() calls.
-+ */
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ (void) pthread_cond_broadcast(&COND_thread_count);
-+
-+ (void) pthread_sigmask(SIG_BLOCK,&set,NULL);
-+ for (;;)
-+ {
-+ int error; // Used when debugging
-+ if (shutdown_in_progress && !abort_loop)
-+ {
-+ sig= SIGTERM;
-+ error=0;
-+ }
-+ else
-+ while ((error=my_sigwait(&set,&sig)) == EINTR) ;
-+ if (cleanup_done)
-+ {
-+ DBUG_PRINT("quit",("signal_handler: calling my_thread_end()"));
-+ my_thread_end();
-+ signal_thread_in_use= 0;
-+ DBUG_LEAVE; // Must match DBUG_ENTER()
-+ pthread_exit(0); // Safety
-+ return 0; // Avoid compiler warnings
-+ }
-+ switch (sig) {
-+ case SIGTERM:
-+ case SIGQUIT:
-+ case SIGKILL:
-+#ifdef EXTRA_DEBUG
-+ sql_print_information("Got signal %d to shutdown mysqld",sig);
-+#endif
-+ /* switch to the old log message processing */
-+ logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
-+ opt_log ? LOG_FILE:LOG_NONE);
-+ DBUG_PRINT("info",("Got signal: %d abort_loop: %d",sig,abort_loop));
-+ if (!abort_loop)
-+ {
-+ abort_loop=1; // mark abort for threads
-+#ifdef USE_ONE_SIGNAL_HAND
-+ pthread_t tmp;
-+ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_attr_setprio(&connection_attrib,INTERRUPT_PRIOR);
-+ if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
-+ (void*) &sig))
-+ sql_print_error("Can't create thread to kill server");
-+#else
-+ kill_server((void*) sig); // MIT THREAD has a alarm thread
-+#endif
-+ }
-+ break;
-+ case SIGHUP:
-+ if (!abort_loop)
-+ {
-+ int not_used;
-+ mysql_print_status(); // Print some debug info
-+ reload_acl_and_cache((THD*) 0,
-+ (REFRESH_LOG | REFRESH_TABLES | REFRESH_FAST |
-+ REFRESH_GRANT |
-+ REFRESH_THREADS | REFRESH_HOSTS),
-+ (TABLE_LIST*) 0, ¬_used); // Flush logs
-+ }
-+ /* reenable logs after the options were reloaded */
-+ if (log_output_options & LOG_NONE)
-+ {
-+ logger.set_handlers(LOG_FILE,
-+ opt_slow_log ? LOG_TABLE : LOG_NONE,
-+ opt_log ? LOG_TABLE : LOG_NONE);
-+ }
-+ else
-+ {
-+ logger.set_handlers(LOG_FILE,
-+ opt_slow_log ? log_output_options : LOG_NONE,
-+ opt_log ? log_output_options : LOG_NONE);
-+ }
-+ break;
-+#ifdef USE_ONE_SIGNAL_HAND
-+ case THR_SERVER_ALARM:
-+ process_alarm(sig); // Trigger alarms.
-+ break;
-+#endif
-+ default:
-+#ifdef EXTRA_DEBUG
-+ sql_print_warning("Got signal: %d error: %d",sig,error); /* purecov: tested */
-+#endif
-+ break; /* purecov: tested */
-+ }
-+ }
-+ return(0); /* purecov: deadcode */
-+}
-+
-+static void check_data_home(const char *path)
-+{}
-+
-+#endif /*!EMBEDDED_LIBRARY*/
-+#endif /* __WIN__*/
-+
-+
-+/**
-+ All global error messages are sent here where the first one is stored
-+ for the client.
-+*/
-+/* ARGSUSED */
-+extern "C" int my_message_sql(uint error, const char *str, myf MyFlags);
-+
-+int my_message_sql(uint error, const char *str, myf MyFlags)
-+{
-+ THD *thd;
-+ DBUG_ENTER("my_message_sql");
-+ DBUG_PRINT("error", ("error: %u message: '%s'", error, str));
-+
-+ DBUG_ASSERT(str != NULL);
-+ /*
-+ An error should have a valid error number (!= 0), so it can be caught
-+ in stored procedures by SQL exception handlers.
-+ Calling my_error() with error == 0 is a bug.
-+ Remaining known places to fix:
-+ - storage/myisam/mi_create.c, my_printf_error()
-+ TODO:
-+ DBUG_ASSERT(error != 0);
-+ */
-+
-+ if (error == 0)
-+ {
-+ /* At least, prevent new abuse ... */
-+ DBUG_ASSERT(strncmp(str, "MyISAM table", 12) == 0);
-+ error= ER_UNKNOWN_ERROR;
-+ }
-+
-+ if ((thd= current_thd))
-+ {
-+ /*
-+ TODO: There are two exceptions mechanism (THD and sp_rcontext),
-+ this could be improved by having a common stack of handlers.
-+ */
-+ if (thd->handle_error(error, str,
-+ MYSQL_ERROR::WARN_LEVEL_ERROR))
-+ DBUG_RETURN(0);
-+
-+ thd->is_slave_error= 1; // needed to catch query errors during replication
-+
-+ /*
-+ thd->lex->current_select == 0 if lex structure is not inited
-+ (not query command (COM_QUERY))
-+ */
-+ if (thd->lex->current_select &&
-+ thd->lex->current_select->no_error && !thd->is_fatal_error)
-+ {
-+ DBUG_PRINT("error",
-+ ("Error converted to warning: current_select: no_error %d "
-+ "fatal_error: %d",
-+ (thd->lex->current_select ?
-+ thd->lex->current_select->no_error : 0),
-+ (int) thd->is_fatal_error));
-+ }
-+ else
-+ {
-+ if (! thd->main_da.is_error()) // Return only first message
-+ {
-+ thd->main_da.set_error_status(thd, error, str);
-+ }
-+ query_cache_abort(&thd->net);
-+ }
-+ /*
-+ If a continue handler is found, the error message will be cleared
-+ by the stored procedures code.
-+ */
-+ if (thd->spcont &&
-+ ! (MyFlags & ME_NO_SP_HANDLER) &&
-+ thd->spcont->handle_error(error, MYSQL_ERROR::WARN_LEVEL_ERROR, thd))
-+ {
-+ /*
-+ Do not push any warnings, a handled error must be completely
-+ silenced.
-+ */
-+ DBUG_RETURN(0);
-+ }
-+
-+ /* When simulating OOM, skip writing to error log to avoid mtr errors */
-+ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
-+
-+ if (!thd->no_warnings_for_error &&
-+ !(MyFlags & ME_NO_WARNING_FOR_ERROR))
-+ {
-+ /*
-+ Suppress infinite recursion if there a memory allocation error
-+ inside push_warning.
-+ */
-+ thd->no_warnings_for_error= TRUE;
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str);
-+ thd->no_warnings_for_error= FALSE;
-+ }
-+ }
-+
-+ /* When simulating OOM, skip writing to error log to avoid mtr errors */
-+ DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(0););
-+
-+ if (!thd || MyFlags & ME_NOREFRESH)
-+ sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
-+ DBUG_RETURN(0);
-+}
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+extern "C" void *my_str_malloc_mysqld(size_t size);
-+extern "C" void my_str_free_mysqld(void *ptr);
-+
-+void *my_str_malloc_mysqld(size_t size)
-+{
-+ return my_malloc(size, MYF(MY_FAE));
-+}
-+
-+
-+void my_str_free_mysqld(void *ptr)
-+{
-+ my_free((uchar*)ptr, MYF(MY_FAE));
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+#ifdef __WIN__
-+
-+pthread_handler_t handle_shutdown(void *arg)
-+{
-+ MSG msg;
-+ my_thread_init();
-+
-+ /* this call should create the message queue for this thread */
-+ PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
-+#if !defined(EMBEDDED_LIBRARY)
-+ if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0)
-+#endif /* EMBEDDED_LIBRARY */
-+ kill_server(MYSQL_KILL_SIGNAL);
-+ return 0;
-+}
-+#endif
-+
-+const char *load_default_groups[]= {
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+"mysql_cluster",
-+#endif
-+"mysqld","server", MYSQL_BASE_VERSION, 0, 0};
-+
-+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
-+static const int load_default_groups_sz=
-+sizeof(load_default_groups)/sizeof(load_default_groups[0]);
-+#endif
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+static
-+int
-+check_enough_stack_size()
-+{
-+ uchar stack_top;
-+
-+ return check_stack_overrun(current_thd, STACK_MIN_SIZE,
-+ &stack_top);
-+}
-+#endif
-+
-+
-+/**
-+ Initialize one of the global date/time format variables.
-+
-+ @param format_type What kind of format should be supported
-+ @param var_ptr Pointer to variable that should be updated
-+
-+ @note
-+ The default value is taken from either opt_date_time_formats[] or
-+ the ISO format (ANSI SQL)
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error
-+*/
-+
-+static bool init_global_datetime_format(timestamp_type format_type,
-+ DATE_TIME_FORMAT **var_ptr)
-+{
-+ /* Get command line option */
-+ const char *str= opt_date_time_formats[format_type];
-+
-+ if (!str) // No specified format
-+ {
-+ str= get_date_time_format_str(&known_date_time_formats[ISO_FORMAT],
-+ format_type);
-+ /*
-+ Set the "command line" option to point to the generated string so
-+ that we can set global formats back to default
-+ */
-+ opt_date_time_formats[format_type]= str;
-+ }
-+ if (!(*var_ptr= date_time_format_make(format_type, str, strlen(str))))
-+ {
-+ fprintf(stderr, "Wrong date/time format specifier: %s\n", str);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+SHOW_VAR com_status_vars[]= {
-+ {"admin_commands", (char*) offsetof(STATUS_VAR, com_other), SHOW_LONG_STATUS},
-+ {"assign_to_keycache", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ASSIGN_TO_KEYCACHE]), SHOW_LONG_STATUS},
-+ {"alter_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB]), SHOW_LONG_STATUS},
-+ {"alter_db_upgrade", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_DB_UPGRADE]), SHOW_LONG_STATUS},
-+ {"alter_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_EVENT]), SHOW_LONG_STATUS},
-+ {"alter_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_FUNCTION]), SHOW_LONG_STATUS},
-+ {"alter_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_PROCEDURE]), SHOW_LONG_STATUS},
-+ {"alter_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_SERVER]), SHOW_LONG_STATUS},
-+ {"alter_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLE]), SHOW_LONG_STATUS},
-+ {"alter_tablespace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ALTER_TABLESPACE]), SHOW_LONG_STATUS},
-+ {"analyze", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ANALYZE]), SHOW_LONG_STATUS},
-+ {"backup_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BACKUP_TABLE]), SHOW_LONG_STATUS},
-+ {"begin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BEGIN]), SHOW_LONG_STATUS},
-+ {"binlog", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_BINLOG_BASE64_EVENT]), SHOW_LONG_STATUS},
-+ {"call_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CALL]), SHOW_LONG_STATUS},
-+ {"change_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_DB]), SHOW_LONG_STATUS},
-+ {"change_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHANGE_MASTER]), SHOW_LONG_STATUS},
-+ {"check", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECK]), SHOW_LONG_STATUS},
-+ {"checksum", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CHECKSUM]), SHOW_LONG_STATUS},
-+ {"commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_COMMIT]), SHOW_LONG_STATUS},
-+ {"create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_DB]), SHOW_LONG_STATUS},
-+ {"create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_EVENT]), SHOW_LONG_STATUS},
-+ {"create_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SPFUNCTION]), SHOW_LONG_STATUS},
-+ {"create_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_INDEX]), SHOW_LONG_STATUS},
-+ {"create_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_PROCEDURE]), SHOW_LONG_STATUS},
-+ {"create_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_SERVER]), SHOW_LONG_STATUS},
-+ {"create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TABLE]), SHOW_LONG_STATUS},
-+ {"create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_TRIGGER]), SHOW_LONG_STATUS},
-+ {"create_udf", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_FUNCTION]), SHOW_LONG_STATUS},
-+ {"create_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_USER]), SHOW_LONG_STATUS},
-+ {"create_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_CREATE_VIEW]), SHOW_LONG_STATUS},
-+ {"dealloc_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DEALLOCATE_PREPARE]), SHOW_LONG_STATUS},
-+ {"delete", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE]), SHOW_LONG_STATUS},
-+ {"delete_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DELETE_MULTI]), SHOW_LONG_STATUS},
-+ {"do", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DO]), SHOW_LONG_STATUS},
-+ {"drop_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_DB]), SHOW_LONG_STATUS},
-+ {"drop_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_EVENT]), SHOW_LONG_STATUS},
-+ {"drop_function", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_FUNCTION]), SHOW_LONG_STATUS},
-+ {"drop_index", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_INDEX]), SHOW_LONG_STATUS},
-+ {"drop_procedure", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_PROCEDURE]), SHOW_LONG_STATUS},
-+ {"drop_server", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_SERVER]), SHOW_LONG_STATUS},
-+ {"drop_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TABLE]), SHOW_LONG_STATUS},
-+ {"drop_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_TRIGGER]), SHOW_LONG_STATUS},
-+ {"drop_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_USER]), SHOW_LONG_STATUS},
-+ {"drop_view", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_DROP_VIEW]), SHOW_LONG_STATUS},
-+ {"empty_query", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EMPTY_QUERY]), SHOW_LONG_STATUS},
-+ {"execute_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_EXECUTE]), SHOW_LONG_STATUS},
-+ {"flush", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_FLUSH]), SHOW_LONG_STATUS},
-+ {"grant", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_GRANT]), SHOW_LONG_STATUS},
-+ {"ha_close", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_CLOSE]), SHOW_LONG_STATUS},
-+ {"ha_open", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_OPEN]), SHOW_LONG_STATUS},
-+ {"ha_read", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HA_READ]), SHOW_LONG_STATUS},
-+ {"help", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_HELP]), SHOW_LONG_STATUS},
-+ {"insert", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT]), SHOW_LONG_STATUS},
-+ {"insert_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSERT_SELECT]), SHOW_LONG_STATUS},
-+ {"install_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_INSTALL_PLUGIN]), SHOW_LONG_STATUS},
-+ {"kill", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_KILL]), SHOW_LONG_STATUS},
-+ {"load", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD]), SHOW_LONG_STATUS},
-+ {"load_master_data", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_DATA]), SHOW_LONG_STATUS},
-+ {"load_master_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOAD_MASTER_TABLE]), SHOW_LONG_STATUS},
-+ {"lock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_LOCK_TABLES]), SHOW_LONG_STATUS},
-+ {"optimize", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_OPTIMIZE]), SHOW_LONG_STATUS},
-+ {"preload_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PRELOAD_KEYS]), SHOW_LONG_STATUS},
-+ {"prepare_sql", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PREPARE]), SHOW_LONG_STATUS},
-+ {"purge", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE]), SHOW_LONG_STATUS},
-+ {"purge_before_date", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_PURGE_BEFORE]), SHOW_LONG_STATUS},
-+ {"release_savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RELEASE_SAVEPOINT]), SHOW_LONG_STATUS},
-+ {"rename_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_TABLE]), SHOW_LONG_STATUS},
-+ {"rename_user", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RENAME_USER]), SHOW_LONG_STATUS},
-+ {"repair", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPAIR]), SHOW_LONG_STATUS},
-+ {"replace", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE]), SHOW_LONG_STATUS},
-+ {"replace_select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REPLACE_SELECT]), SHOW_LONG_STATUS},
-+ {"reset", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESET]), SHOW_LONG_STATUS},
-+ {"restore_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_RESTORE_TABLE]), SHOW_LONG_STATUS},
-+ {"revoke", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE]), SHOW_LONG_STATUS},
-+ {"revoke_all", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_REVOKE_ALL]), SHOW_LONG_STATUS},
-+ {"rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK]), SHOW_LONG_STATUS},
-+ {"rollback_to_savepoint",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_ROLLBACK_TO_SAVEPOINT]), SHOW_LONG_STATUS},
-+ {"savepoint", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SAVEPOINT]), SHOW_LONG_STATUS},
-+ {"select", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SELECT]), SHOW_LONG_STATUS},
-+ {"set_option", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SET_OPTION]), SHOW_LONG_STATUS},
-+ {"show_authors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_AUTHORS]), SHOW_LONG_STATUS},
-+ {"show_binlog_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOG_EVENTS]), SHOW_LONG_STATUS},
-+ {"show_binlogs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_BINLOGS]), SHOW_LONG_STATUS},
-+ {"show_charsets", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CHARSETS]), SHOW_LONG_STATUS},
-+ {"show_collations", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLLATIONS]), SHOW_LONG_STATUS},
-+ {"show_column_types", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_COLUMN_TYPES]), SHOW_LONG_STATUS},
-+ {"show_contributors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CONTRIBUTORS]), SHOW_LONG_STATUS},
-+ {"show_create_db", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_DB]), SHOW_LONG_STATUS},
-+ {"show_create_event", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_EVENT]), SHOW_LONG_STATUS},
-+ {"show_create_func", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_FUNC]), SHOW_LONG_STATUS},
-+ {"show_create_proc", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_PROC]), SHOW_LONG_STATUS},
-+ {"show_create_table", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE]), SHOW_LONG_STATUS},
-+ {"show_create_trigger", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_CREATE_TRIGGER]), SHOW_LONG_STATUS},
-+ {"show_databases", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_DATABASES]), SHOW_LONG_STATUS},
-+ {"show_engine_logs", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_LOGS]), SHOW_LONG_STATUS},
-+ {"show_engine_mutex", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_MUTEX]), SHOW_LONG_STATUS},
-+ {"show_engine_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ENGINE_STATUS]), SHOW_LONG_STATUS},
-+ {"show_events", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_EVENTS]), SHOW_LONG_STATUS},
-+ {"show_errors", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_ERRORS]), SHOW_LONG_STATUS},
-+ {"show_fields", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FIELDS]), SHOW_LONG_STATUS},
-+#ifndef DBUG_OFF
-+ {"show_function_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_FUNC_CODE]), SHOW_LONG_STATUS},
-+#endif
-+ {"show_function_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_FUNC]), SHOW_LONG_STATUS},
-+ {"show_grants", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_GRANTS]), SHOW_LONG_STATUS},
-+ {"show_keys", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_KEYS]), SHOW_LONG_STATUS},
-+ {"show_master_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_MASTER_STAT]), SHOW_LONG_STATUS},
-+ {"show_new_master", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_NEW_MASTER]), SHOW_LONG_STATUS},
-+ {"show_open_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_OPEN_TABLES]), SHOW_LONG_STATUS},
-+ {"show_plugins", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PLUGINS]), SHOW_LONG_STATUS},
-+ {"show_privileges", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PRIVILEGES]), SHOW_LONG_STATUS},
-+#ifndef DBUG_OFF
-+ {"show_procedure_code", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROC_CODE]), SHOW_LONG_STATUS},
-+#endif
-+ {"show_procedure_status",(char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS_PROC]), SHOW_LONG_STATUS},
-+ {"show_processlist", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROCESSLIST]), SHOW_LONG_STATUS},
-+ {"show_profile", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILE]), SHOW_LONG_STATUS},
-+ {"show_profiles", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_PROFILES]), SHOW_LONG_STATUS},
-+ {"show_slave_hosts", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_HOSTS]), SHOW_LONG_STATUS},
-+ {"show_slave_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_SLAVE_STAT]), SHOW_LONG_STATUS},
-+ {"show_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STATUS]), SHOW_LONG_STATUS},
-+ {"show_storage_engines", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_STORAGE_ENGINES]), SHOW_LONG_STATUS},
-+ {"show_table_status", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLE_STATUS]), SHOW_LONG_STATUS},
-+ {"show_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TABLES]), SHOW_LONG_STATUS},
-+ {"show_triggers", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_TRIGGERS]), SHOW_LONG_STATUS},
-+ {"show_variables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_VARIABLES]), SHOW_LONG_STATUS},
-+ {"show_warnings", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SHOW_WARNS]), SHOW_LONG_STATUS},
-+ {"slave_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_START]), SHOW_LONG_STATUS},
-+ {"slave_stop", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_SLAVE_STOP]), SHOW_LONG_STATUS},
-+ {"stmt_close", (char*) offsetof(STATUS_VAR, com_stmt_close), SHOW_LONG_STATUS},
-+ {"stmt_execute", (char*) offsetof(STATUS_VAR, com_stmt_execute), SHOW_LONG_STATUS},
-+ {"stmt_fetch", (char*) offsetof(STATUS_VAR, com_stmt_fetch), SHOW_LONG_STATUS},
-+ {"stmt_prepare", (char*) offsetof(STATUS_VAR, com_stmt_prepare), SHOW_LONG_STATUS},
-+ {"stmt_reprepare", (char*) offsetof(STATUS_VAR, com_stmt_reprepare), SHOW_LONG_STATUS},
-+ {"stmt_reset", (char*) offsetof(STATUS_VAR, com_stmt_reset), SHOW_LONG_STATUS},
-+ {"stmt_send_long_data", (char*) offsetof(STATUS_VAR, com_stmt_send_long_data), SHOW_LONG_STATUS},
-+ {"truncate", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_TRUNCATE]), SHOW_LONG_STATUS},
-+ {"uninstall_plugin", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNINSTALL_PLUGIN]), SHOW_LONG_STATUS},
-+ {"unlock_tables", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UNLOCK_TABLES]), SHOW_LONG_STATUS},
-+ {"update", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE]), SHOW_LONG_STATUS},
-+ {"update_multi", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_UPDATE_MULTI]), SHOW_LONG_STATUS},
-+ {"xa_commit", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_COMMIT]),SHOW_LONG_STATUS},
-+ {"xa_end", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_END]),SHOW_LONG_STATUS},
-+ {"xa_prepare", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_PREPARE]),SHOW_LONG_STATUS},
-+ {"xa_recover", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_RECOVER]),SHOW_LONG_STATUS},
-+ {"xa_rollback", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_ROLLBACK]),SHOW_LONG_STATUS},
-+ {"xa_start", (char*) offsetof(STATUS_VAR, com_stat[(uint) SQLCOM_XA_START]),SHOW_LONG_STATUS},
-+ {NullS, NullS, SHOW_LONG}
-+};
-+
-+static int init_common_variables(const char *conf_file_name, int argc,
-+ char **argv, const char **groups)
-+{
-+ char buff[FN_REFLEN], *s;
-+ umask(((~my_umask) & 0666));
-+ my_decimal_set_zero(&decimal_zero); // set decimal_zero constant;
-+ tzset(); // Set tzname
-+
-+ max_system_variables.pseudo_thread_id= (ulong)~0;
-+ server_start_time= flush_status_time= my_time(0);
-+
-+ rpl_filter= new Rpl_filter;
-+ binlog_filter= new Rpl_filter;
-+ if (!rpl_filter || !binlog_filter)
-+ {
-+ sql_perror("Could not allocate replication and binlog filters");
-+ return 1;
-+ }
-+
-+ if (init_thread_environment() ||
-+ mysql_init_variables())
-+ return 1;
-+
-+#ifdef HAVE_TZNAME
-+ {
-+ struct tm tm_tmp;
-+ localtime_r(&server_start_time,&tm_tmp);
-+ strmake(system_time_zone, tzname[tm_tmp.tm_isdst != 0 ? 1 : 0],
-+ sizeof(system_time_zone)-1);
-+
-+ }
-+#endif
-+ /*
-+ We set SYSTEM time zone as reasonable default and
-+ also for failure of my_tz_init() and bootstrap mode.
-+ If user explicitly set time zone with --default-time-zone
-+ option we will change this value in my_tz_init().
-+ */
-+ global_system_variables.time_zone= my_tz_SYSTEM;
-+
-+ /*
-+ Init mutexes for the global MYSQL_BIN_LOG objects.
-+ As safe_mutex depends on what MY_INIT() does, we can't init the mutexes of
-+ global MYSQL_BIN_LOGs in their constructors, because then they would be
-+ inited before MY_INIT(). So we do it here.
-+ */
-+ mysql_bin_log.init_pthread_objects();
-+
-+ /* TODO: remove this when my_time_t is 64 bit compatible */
-+ if (!IS_TIME_T_VALID_FOR_TIMESTAMP(server_start_time))
-+ {
-+ sql_print_error("This MySQL server doesn't support dates later then 2038");
-+ return 1;
-+ }
-+
-+ if (gethostname(glob_hostname,sizeof(glob_hostname)) < 0)
-+ {
-+ strmake(glob_hostname, STRING_WITH_LEN("localhost"));
-+ sql_print_warning("gethostname failed, using '%s' as hostname",
-+ glob_hostname);
-+ strmake(pidfile_name, STRING_WITH_LEN("mysql"));
-+ }
-+ else
-+ strmake(pidfile_name, glob_hostname, sizeof(pidfile_name)-5);
-+ strmov(fn_ext(pidfile_name),".pid"); // Add proper extension
-+
-+ /*
-+ Add server status variables to the dynamic list of
-+ status variables that is shown by SHOW STATUS.
-+ Later, in plugin_init, and mysql_install_plugin
-+ new entries could be added to that list.
-+ */
-+ if (add_status_vars(status_vars))
-+ return 1; // an error was already reported
-+
-+#ifndef DBUG_OFF
-+ /*
-+ We have few debug-only commands in com_status_vars, only visible in debug
-+ builds. for simplicity we enable the assert only in debug builds
-+
-+ There are 8 Com_ variables which don't have corresponding SQLCOM_ values:
-+ (TODO strictly speaking they shouldn't be here, should not have Com_ prefix
-+ that is. Perhaps Stmt_ ? Comstmt_ ? Prepstmt_ ?)
-+
-+ Com_admin_commands => com_other
-+ Com_stmt_close => com_stmt_close
-+ Com_stmt_execute => com_stmt_execute
-+ Com_stmt_fetch => com_stmt_fetch
-+ Com_stmt_prepare => com_stmt_prepare
-+ Com_stmt_reprepare => com_stmt_reprepare
-+ Com_stmt_reset => com_stmt_reset
-+ Com_stmt_send_long_data => com_stmt_send_long_data
-+
-+ With this correction the number of Com_ variables (number of elements in
-+ the array, excluding the last element - terminator) must match the number
-+ of SQLCOM_ constants.
-+ */
-+ compile_time_assert(sizeof(com_status_vars)/sizeof(com_status_vars[0]) - 1 ==
-+ SQLCOM_END + 8);
-+#endif
-+
-+ orig_argc=argc;
-+ orig_argv=argv;
-+ load_defaults(conf_file_name, groups, &argc, &argv);
-+ defaults_argv=argv;
-+ defaults_argc=argc;
-+ if (get_options(&defaults_argc, defaults_argv))
-+ return 1;
-+ set_server_version();
-+
-+ DBUG_PRINT("info",("%s Ver %s for %s on %s\n",my_progname,
-+ server_version, SYSTEM_TYPE,MACHINE_TYPE));
-+
-+#ifdef HAVE_LARGE_PAGES
-+ /* Initialize large page size */
-+ if (opt_large_pages && (opt_large_page_size= my_get_large_page_size()))
-+ {
-+ my_use_large_pages= 1;
-+ my_large_page_size= opt_large_page_size;
-+ }
-+#endif /* HAVE_LARGE_PAGES */
-+
-+ /* connections and databases needs lots of files */
-+ {
-+ uint files, wanted_files, max_open_files;
-+
-+ /* MyISAM requires two file handles per table. */
-+ wanted_files= 10+max_connections+table_cache_size*2;
-+ /*
-+ We are trying to allocate no less than max_connections*5 file
-+ handles (i.e. we are trying to set the limit so that they will
-+ be available). In addition, we allocate no less than how much
-+ was already allocated. However below we report a warning and
-+ recompute values only if we got less file handles than were
-+ explicitly requested. No warning and re-computation occur if we
-+ can't get max_connections*5 but still got no less than was
-+ requested (value of wanted_files).
-+ */
-+ max_open_files= max(max(wanted_files, max_connections*5),
-+ open_files_limit);
-+ files= my_set_max_open_files(max_open_files);
-+
-+ if (files < wanted_files)
-+ {
-+ if (!open_files_limit)
-+ {
-+ /*
-+ If we have requested too much file handles than we bring
-+ max_connections in supported bounds.
-+ */
-+ max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
-+ max_connections);
-+ /*
-+ Decrease table_cache_size according to max_connections, but
-+ not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
-+ never increase table_cache_size automatically (that could
-+ happen if max_connections is decreased above).
-+ */
-+ table_cache_size= (ulong) min(max((files-10-max_connections)/2,
-+ TABLE_OPEN_CACHE_MIN),
-+ table_cache_size);
-+ DBUG_PRINT("warning",
-+ ("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
-+ files, max_connections, table_cache_size));
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Changed limits: max_open_files: %u max_connections: %ld table_cache: %ld",
-+ files, max_connections, table_cache_size);
-+ }
-+ else if (global_system_variables.log_warnings)
-+ sql_print_warning("Could not increase number of max_open_files to more than %u (request: %u)", files, wanted_files);
-+ }
-+ open_files_limit= files;
-+ }
-+ unireg_init(opt_specialflag); /* Set up extern variabels */
-+ if (init_errmessage()) /* Read error messages from file */
-+ return 1;
-+ init_client_errs();
-+ lex_init();
-+ if (item_create_init())
-+ return 1;
-+ item_init();
-+ if (set_var_init())
-+ return 1;
-+#ifdef HAVE_REPLICATION
-+ if (init_replication_sys_vars())
-+ return 1;
-+#endif
-+ mysys_uses_curses=0;
-+#ifdef USE_REGEX
-+#ifndef EMBEDDED_LIBRARY
-+ my_regex_init(&my_charset_latin1, check_enough_stack_size);
-+#else
-+ my_regex_init(&my_charset_latin1, NULL);
-+#endif
-+#endif
-+ /*
-+ Process a comma-separated character set list and choose
-+ the first available character set. This is mostly for
-+ test purposes, to be able to start "mysqld" even if
-+ the requested character set is not available (see bug#18743).
-+ */
-+ for (;;)
-+ {
-+ char *next_character_set_name= strchr(default_character_set_name, ',');
-+ if (next_character_set_name)
-+ *next_character_set_name++= '\0';
-+ if (!(default_charset_info=
-+ get_charset_by_csname(default_character_set_name,
-+ MY_CS_PRIMARY, MYF(MY_WME))))
-+ {
-+ if (next_character_set_name)
-+ {
-+ default_character_set_name= next_character_set_name;
-+ default_collation_name= 0; // Ignore collation
-+ }
-+ else
-+ return 1; // Eof of the list
-+ }
-+ else
-+ break;
-+ }
-+
-+ if (default_collation_name)
-+ {
-+ CHARSET_INFO *default_collation;
-+ default_collation= get_charset_by_name(default_collation_name, MYF(0));
-+ if (!default_collation)
-+ {
-+ sql_print_error(ER(ER_UNKNOWN_COLLATION), default_collation_name);
-+ return 1;
-+ }
-+ if (!my_charset_same(default_charset_info, default_collation))
-+ {
-+ sql_print_error(ER(ER_COLLATION_CHARSET_MISMATCH),
-+ default_collation_name,
-+ default_charset_info->csname);
-+ return 1;
-+ }
-+ default_charset_info= default_collation;
-+ }
-+ /* Set collactions that depends on the default collation */
-+ global_system_variables.collation_server= default_charset_info;
-+ global_system_variables.collation_database= default_charset_info;
-+ global_system_variables.collation_connection= default_charset_info;
-+ global_system_variables.character_set_results= default_charset_info;
-+ global_system_variables.character_set_client= default_charset_info;
-+
-+ if (!(character_set_filesystem=
-+ get_charset_by_csname(character_set_filesystem_name,
-+ MY_CS_PRIMARY, MYF(MY_WME))))
-+ return 1;
-+ global_system_variables.character_set_filesystem= character_set_filesystem;
-+
-+ if (!(my_default_lc_time_names=
-+ my_locale_by_name(lc_time_names_name)))
-+ {
-+ sql_print_error("Unknown locale: '%s'", lc_time_names_name);
-+ return 1;
-+ }
-+ global_system_variables.lc_time_names= my_default_lc_time_names;
-+
-+ sys_init_connect.value_length= 0;
-+ if ((sys_init_connect.value= opt_init_connect))
-+ sys_init_connect.value_length= strlen(opt_init_connect);
-+ else
-+ sys_init_connect.value=my_strdup("",MYF(0));
-+ sys_init_connect.is_os_charset= TRUE;
-+
-+ sys_init_slave.value_length= 0;
-+ if ((sys_init_slave.value= opt_init_slave))
-+ sys_init_slave.value_length= strlen(opt_init_slave);
-+ else
-+ sys_init_slave.value=my_strdup("",MYF(0));
-+ sys_init_slave.is_os_charset= TRUE;
-+
-+ /* check log options and issue warnings if needed */
-+ if (opt_log && opt_logname && !(log_output_options & LOG_FILE) &&
-+ !(log_output_options & LOG_NONE))
-+ sql_print_warning("Although a path was specified for the "
-+ "--log option, log tables are used. "
-+ "To enable logging to files use the --log-output option.");
-+
-+ if (opt_slow_log && opt_slow_logname && !(log_output_options & LOG_FILE)
-+ && !(log_output_options & LOG_NONE))
-+ sql_print_warning("Although a path was specified for the "
-+ "--log_slow_queries option, log tables are used. "
-+ "To enable logging to files use the --log-output=file option.");
-+
-+ s= opt_logname ? opt_logname : make_default_log_name(buff, ".log");
-+ sys_var_general_log_path.value= my_strdup(s, MYF(0));
-+ sys_var_general_log_path.value_length= strlen(s);
-+
-+ s= opt_slow_logname ? opt_slow_logname : make_default_log_name(buff, "-slow.log");
-+ sys_var_slow_log_path.value= my_strdup(s, MYF(0));
-+ sys_var_slow_log_path.value_length= strlen(s);
-+
-+#if defined(ENABLED_DEBUG_SYNC)
-+ /* Initialize the debug sync facility. See debug_sync.cc. */
-+ if (debug_sync_init())
-+ return 1; /* purecov: tested */
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+
-+#if (ENABLE_TEMP_POOL)
-+ if (use_temp_pool && bitmap_init(&temp_pool,0,1024,1))
-+ return 1;
-+#else
-+ use_temp_pool= 0;
-+#endif
-+
-+ if (my_database_names_init())
-+ return 1;
-+
-+ /*
-+ Ensure that lower_case_table_names is set on system where we have case
-+ insensitive names. If this is not done the users MyISAM tables will
-+ get corrupted if accesses with names of different case.
-+ */
-+ DBUG_PRINT("info", ("lower_case_table_names: %d", lower_case_table_names));
-+ lower_case_file_system= test_if_case_insensitive(mysql_real_data_home);
-+ if (!lower_case_table_names && lower_case_file_system == 1)
-+ {
-+ if (lower_case_table_names_used)
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("\
-+You have forced lower_case_table_names to 0 through a command-line \
-+option, even though your file system '%s' is case insensitive. This means \
-+that you can corrupt a MyISAM table by accessing it with different cases. \
-+You should consider changing lower_case_table_names to 1 or 2",
-+ mysql_real_data_home);
-+ }
-+ else
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Setting lower_case_table_names=2 because file system for %s is case insensitive", mysql_real_data_home);
-+ lower_case_table_names= 2;
-+ }
-+ }
-+ else if (lower_case_table_names == 2 &&
-+ !(lower_case_file_system=
-+ (test_if_case_insensitive(mysql_real_data_home) == 1)))
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("lower_case_table_names was set to 2, even though your "
-+ "the file system '%s' is case sensitive. Now setting "
-+ "lower_case_table_names to 0 to avoid future problems.",
-+ mysql_real_data_home);
-+ lower_case_table_names= 0;
-+ }
-+ else
-+ {
-+ lower_case_file_system=
-+ (test_if_case_insensitive(mysql_real_data_home) == 1);
-+ }
-+
-+ /* Reset table_alias_charset, now that lower_case_table_names is set. */
-+ table_alias_charset= (lower_case_table_names ?
-+ files_charset_info :
-+ &my_charset_bin);
-+
-+ return 0;
-+}
-+
-+
-+static int init_thread_environment()
-+{
-+ (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW);
-+ (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW);
-+ (void) pthread_mutex_init(&LOCK_Acl,MY_MUTEX_INIT_SLOW);
-+ (void) pthread_mutex_init(&LOCK_open, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW);
-+ (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW);
-+ (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
-+ (void) my_rwlock_init(&LOCK_system_variables_hash, NULL);
-+ (void) pthread_mutex_init(&LOCK_global_read_lock, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_prepared_stmt_count, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_uuid_generator, MY_MUTEX_INIT_FAST);
-+ (void) pthread_mutex_init(&LOCK_connection_count, MY_MUTEX_INIT_FAST);
-+#ifdef HAVE_OPENSSL
-+ (void) pthread_mutex_init(&LOCK_des_key_file,MY_MUTEX_INIT_FAST);
-+#ifndef HAVE_YASSL
-+ openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
-+ sizeof(openssl_lock_t));
-+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
-+ (void) my_rwlock_init(&openssl_stdlocks[i].lock, NULL);
-+ CRYPTO_set_dynlock_create_callback(openssl_dynlock_create);
-+ CRYPTO_set_dynlock_destroy_callback(openssl_dynlock_destroy);
-+ CRYPTO_set_dynlock_lock_callback(openssl_lock);
-+ CRYPTO_set_locking_callback(openssl_lock_function);
-+ CRYPTO_set_id_callback(openssl_id_function);
-+#endif
-+#endif
-+ (void) my_rwlock_init(&LOCK_sys_init_connect, NULL);
-+ (void) my_rwlock_init(&LOCK_sys_init_slave, NULL);
-+ (void) my_rwlock_init(&LOCK_grant, NULL);
-+ (void) pthread_cond_init(&COND_thread_count,NULL);
-+ (void) pthread_cond_init(&COND_refresh,NULL);
-+ (void) pthread_cond_init(&COND_global_read_lock,NULL);
-+ (void) pthread_cond_init(&COND_thread_cache,NULL);
-+ (void) pthread_cond_init(&COND_flush_thread_cache,NULL);
-+ (void) pthread_cond_init(&COND_manager,NULL);
-+#ifdef HAVE_REPLICATION
-+ (void) pthread_mutex_init(&LOCK_rpl_status, MY_MUTEX_INIT_FAST);
-+ (void) pthread_cond_init(&COND_rpl_status, NULL);
-+#endif
-+ (void) pthread_mutex_init(&LOCK_server_started, MY_MUTEX_INIT_FAST);
-+ (void) pthread_cond_init(&COND_server_started,NULL);
-+ sp_cache_init();
-+#ifdef HAVE_EVENT_SCHEDULER
-+ Events::init_mutexes();
-+#endif
-+ /* Parameter for threads created for connections */
-+ (void) pthread_attr_init(&connection_attrib);
-+ (void) pthread_attr_setdetachstate(&connection_attrib,
-+ PTHREAD_CREATE_DETACHED);
-+ pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM);
-+ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_attr_setprio(&connection_attrib,WAIT_PRIOR);
-+
-+ if (pthread_key_create(&THR_THD,NULL) ||
-+ pthread_key_create(&THR_MALLOC,NULL))
-+ {
-+ sql_print_error("Can't create thread-keys");
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
-+static unsigned long openssl_id_function()
-+{
-+ return (unsigned long) pthread_self();
-+}
-+
-+
-+static openssl_lock_t *openssl_dynlock_create(const char *file, int line)
-+{
-+ openssl_lock_t *lock= new openssl_lock_t;
-+ my_rwlock_init(&lock->lock, NULL);
-+ return lock;
-+}
-+
-+
-+static void openssl_dynlock_destroy(openssl_lock_t *lock, const char *file,
-+ int line)
-+{
-+ rwlock_destroy(&lock->lock);
-+ delete lock;
-+}
-+
-+
-+static void openssl_lock_function(int mode, int n, const char *file, int line)
-+{
-+ if (n < 0 || n > CRYPTO_num_locks())
-+ {
-+ /* Lock number out of bounds. */
-+ sql_print_error("Fatal: OpenSSL interface problem (n = %d)", n);
-+ abort();
-+ }
-+ openssl_lock(mode, &openssl_stdlocks[n], file, line);
-+}
-+
-+
-+static void openssl_lock(int mode, openssl_lock_t *lock, const char *file,
-+ int line)
-+{
-+ int err;
-+ char const *what;
-+
-+ switch (mode) {
-+ case CRYPTO_LOCK|CRYPTO_READ:
-+ what = "read lock";
-+ err = rw_rdlock(&lock->lock);
-+ break;
-+ case CRYPTO_LOCK|CRYPTO_WRITE:
-+ what = "write lock";
-+ err = rw_wrlock(&lock->lock);
-+ break;
-+ case CRYPTO_UNLOCK|CRYPTO_READ:
-+ case CRYPTO_UNLOCK|CRYPTO_WRITE:
-+ what = "unlock";
-+ err = rw_unlock(&lock->lock);
-+ break;
-+ default:
-+ /* Unknown locking mode. */
-+ sql_print_error("Fatal: OpenSSL interface problem (mode=0x%x)", mode);
-+ abort();
-+ }
-+ if (err)
-+ {
-+ sql_print_error("Fatal: can't %s OpenSSL lock", what);
-+ abort();
-+ }
-+}
-+#endif /* HAVE_OPENSSL */
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+static void init_ssl()
-+{
-+#ifdef HAVE_OPENSSL
-+ if (opt_use_ssl)
-+ {
-+ enum enum_ssl_init_error error= SSL_INITERR_NOERROR;
-+
-+ /* having ssl_acceptor_fd != 0 signals the use of SSL */
-+ ssl_acceptor_fd= new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert,
-+ opt_ssl_ca, opt_ssl_capath,
-+ opt_ssl_cipher, &error);
-+ DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
-+ if (!ssl_acceptor_fd)
-+ {
-+ sql_print_warning("Failed to setup SSL");
-+ sql_print_warning("SSL error: %s", sslGetErrString(error));
-+ opt_use_ssl = 0;
-+ have_ssl= SHOW_OPTION_DISABLED;
-+ }
-+ }
-+ else
-+ {
-+ have_ssl= SHOW_OPTION_DISABLED;
-+ }
-+ if (des_key_file)
-+ load_des_key_file(des_key_file);
-+#endif /* HAVE_OPENSSL */
-+}
-+
-+
-+static void end_ssl()
-+{
-+#ifdef HAVE_OPENSSL
-+ if (ssl_acceptor_fd)
-+ {
-+ free_vio_ssl_acceptor_fd(ssl_acceptor_fd);
-+ ssl_acceptor_fd= 0;
-+ }
-+#endif /* HAVE_OPENSSL */
-+}
-+
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+static int init_server_components()
-+{
-+ DBUG_ENTER("init_server_components");
-+ /*
-+ We need to call each of these following functions to ensure that
-+ all things are initialized so that unireg_abort() doesn't fail
-+ */
-+ if (table_cache_init() | table_def_init() | hostname_cache_init())
-+ unireg_abort(1);
-+
-+ query_cache_result_size_limit(query_cache_limit);
-+ query_cache_set_min_res_unit(query_cache_min_res_unit);
-+ query_cache_init();
-+ query_cache_resize(query_cache_size);
-+ randominit(&sql_rand,(ulong) server_start_time,(ulong) server_start_time/2);
-+ setup_fpu();
-+ init_thr_lock();
-+#ifdef HAVE_REPLICATION
-+ init_slave_list();
-+#endif
-+
-+ /* Setup logs */
-+
-+ /*
-+ Enable old-fashioned error log, except when the user has requested
-+ help information. Since the implementation of plugin server
-+ variables the help output is now written much later.
-+ */
-+ if (opt_error_log && !opt_help)
-+ {
-+ if (!log_error_file_ptr[0])
-+ fn_format(log_error_file, pidfile_name, mysql_data_home, ".err",
-+ MY_REPLACE_EXT); /* replace '.<domain>' by '.err', bug#4997 */
-+ else
-+ fn_format(log_error_file, log_error_file_ptr, mysql_data_home, ".err",
-+ MY_UNPACK_FILENAME | MY_SAFE_PATH);
-+ if (!log_error_file[0])
-+ opt_error_log= 1; // Too long file name
-+ else
-+ {
-+ my_bool res;
-+#ifndef EMBEDDED_LIBRARY
-+ res= reopen_fstreams(log_error_file, stdout, stderr);
-+#else
-+ res= reopen_fstreams(log_error_file, NULL, stderr);
-+#endif
-+
-+ if (!res)
-+ setbuf(stderr, NULL);
-+ }
-+ }
-+
-+ if (xid_cache_init())
-+ {
-+ sql_print_error("Out of memory");
-+ unireg_abort(1);
-+ }
-+
-+ /* need to configure logging before initializing storage engines */
-+ if (opt_update_log)
-+ {
-+ /*
-+ Update log is removed since 5.0. But we still accept the option.
-+ The idea is if the user already uses the binlog and the update log,
-+ we completely ignore any option/variable related to the update log, like
-+ if the update log did not exist. But if the user uses only the update
-+ log, then we translate everything into binlog for him (with warnings).
-+ Implementation of the above :
-+ - If mysqld is started with --log-update and --log-bin,
-+ ignore --log-update (print a warning), push a warning when SQL_LOG_UPDATE
-+ is used, and turn off --sql-bin-update-same.
-+ This will completely ignore SQL_LOG_UPDATE
-+ - If mysqld is started with --log-update only,
-+ change it to --log-bin (with the filename passed to log-update,
-+ plus '-bin') (print a warning), push a warning when SQL_LOG_UPDATE is
-+ used, and turn on --sql-bin-update-same.
-+ This will translate SQL_LOG_UPDATE to SQL_LOG_BIN.
-+
-+ Note that we tell the user that --sql-bin-update-same is deprecated and
-+ does nothing, and we don't take into account if he used this option or
-+ not; but internally we give this variable a value to have the behaviour
-+ we want (i.e. have SQL_LOG_UPDATE influence SQL_LOG_BIN or not).
-+ As sql-bin-update-same, log-update and log-bin cannot be changed by the
-+ user after starting the server (they are not variables), the user will
-+ not later interfere with the settings we do here.
-+ */
-+ if (opt_bin_log)
-+ {
-+ opt_sql_bin_update= 0;
-+ sql_print_error("The update log is no longer supported by MySQL in \
-+version 5.0 and above. It is replaced by the binary log.");
-+ }
-+ else
-+ {
-+ opt_sql_bin_update= 1;
-+ opt_bin_log= 1;
-+ if (opt_update_logname)
-+ {
-+ /* as opt_bin_log==0, no need to free opt_bin_logname */
-+ if (!(opt_bin_logname= my_strdup(opt_update_logname, MYF(MY_WME))))
-+ {
-+ sql_print_error("Out of memory");
-+ return EXIT_OUT_OF_MEMORY;
-+ }
-+ sql_print_error("The update log is no longer supported by MySQL in \
-+version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
-+with --log-bin='%s' instead.",opt_bin_logname);
-+ }
-+ else
-+ sql_print_error("The update log is no longer supported by MySQL in \
-+version 5.0 and above. It is replaced by the binary log. Now starting MySQL \
-+with --log-bin instead.");
-+ }
-+ }
-+ if (opt_log_slave_updates && !opt_bin_log)
-+ {
-+ sql_print_error("You need to use --log-bin to make "
-+ "--log-slave-updates work.");
-+ unireg_abort(1);
-+ }
-+ if (!opt_bin_log)
-+ {
-+ if (opt_binlog_format_id != BINLOG_FORMAT_UNSPEC)
-+ {
-+ sql_print_error("You need to use --log-bin to make "
-+ "--binlog-format work.");
-+ unireg_abort(1);
-+ }
-+ else
-+ {
-+ global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
-+ }
-+ }
-+ else
-+ if (opt_binlog_format_id == BINLOG_FORMAT_UNSPEC)
-+ global_system_variables.binlog_format= BINLOG_FORMAT_STMT;
-+ else
-+ {
-+ DBUG_ASSERT(global_system_variables.binlog_format != BINLOG_FORMAT_UNSPEC);
-+ }
-+
-+ /* Check that we have not let the format to unspecified at this point */
-+ DBUG_ASSERT((uint)global_system_variables.binlog_format <=
-+ array_elements(binlog_format_names)-1);
-+
-+#ifdef HAVE_REPLICATION
-+ if (opt_log_slave_updates && replicate_same_server_id)
-+ {
-+ sql_print_error("\
-+using --replicate-same-server-id in conjunction with \
-+--log-slave-updates is impossible, it would lead to infinite loops in this \
-+server.");
-+ unireg_abort(1);
-+ }
-+#endif
-+
-+ if (opt_bin_log)
-+ {
-+ /* Reports an error and aborts, if the --log-bin's path
-+ is a directory.*/
-+ if (opt_bin_logname &&
-+ opt_bin_logname[strlen(opt_bin_logname) - 1] == FN_LIBCHAR)
-+ {
-+ sql_print_error("Path '%s' is a directory name, please specify \
-+a file name for --log-bin option", opt_bin_logname);
-+ unireg_abort(1);
-+ }
-+
-+ /* Reports an error and aborts, if the --log-bin-index's path
-+ is a directory.*/
-+ if (opt_binlog_index_name &&
-+ opt_binlog_index_name[strlen(opt_binlog_index_name) - 1]
-+ == FN_LIBCHAR)
-+ {
-+ sql_print_error("Path '%s' is a directory name, please specify \
-+a file name for --log-bin-index option", opt_binlog_index_name);
-+ unireg_abort(1);
-+ }
-+
-+ char buf[FN_REFLEN];
-+ const char *ln;
-+ ln= mysql_bin_log.generate_name(opt_bin_logname, "-bin", 1, buf);
-+ if (!opt_bin_logname && !opt_binlog_index_name)
-+ {
-+ /*
-+ User didn't give us info to name the binlog index file.
-+ Picking `hostname`-bin.index like did in 4.x, causes replication to
-+ fail if the hostname is changed later. So, we would like to instead
-+ require a name. But as we don't want to break many existing setups, we
-+ only give warning, not error.
-+ */
-+ sql_print_warning("No argument was provided to --log-bin, and "
-+ "--log-bin-index was not used; so replication "
-+ "may break when this MySQL server acts as a "
-+ "master and has his hostname changed!! Please "
-+ "use '--log-bin=%s' to avoid this problem.", ln);
-+ }
-+ if (ln == buf)
-+ {
-+ my_free(opt_bin_logname, MYF(MY_ALLOW_ZERO_PTR));
-+ opt_bin_logname=my_strdup(buf, MYF(0));
-+ }
-+ if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
-+ {
-+ unireg_abort(1);
-+ }
-+ }
-+
-+ /* call ha_init_key_cache() on all key caches to init them */
-+ process_key_caches(&ha_init_key_cache);
-+
-+ /* Allow storage engine to give real error messages */
-+ if (ha_init_errors())
-+ DBUG_RETURN(1);
-+
-+ {
-+ if (plugin_init(&defaults_argc, defaults_argv,
-+ (opt_noacl ? PLUGIN_INIT_SKIP_PLUGIN_TABLE : 0) |
-+ (opt_help ? PLUGIN_INIT_SKIP_INITIALIZATION : 0)))
-+ {
-+ sql_print_error("Failed to initialize plugins.");
-+ unireg_abort(1);
-+ }
-+ plugins_are_initialized= TRUE; /* Don't separate from init function */
-+ }
-+
-+ if (opt_help)
-+ unireg_abort(0);
-+
-+ /* we do want to exit if there are any other unknown options */
-+ if (defaults_argc > 1)
-+ {
-+ int ho_error;
-+ char **tmp_argv= defaults_argv;
-+ struct my_option no_opts[]=
-+ {
-+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-+ };
-+ /*
-+ We need to eat any 'loose' arguments first before we conclude
-+ that there are unprocessed options.
-+ But we need to preserve defaults_argv pointer intact for
-+ free_defaults() to work. Thus we use a copy here.
-+ */
-+ my_getopt_skip_unknown= 0;
-+
-+ if ((ho_error= handle_options(&defaults_argc, &tmp_argv, no_opts,
-+ mysqld_get_one_option)))
-+ unireg_abort(ho_error);
-+ my_getopt_skip_unknown= TRUE;
-+
-+ if (defaults_argc)
-+ {
-+ fprintf(stderr, "%s: Too many arguments (first extra is '%s').\n"
-+ "Use --verbose --help to get a list of available options\n",
-+ my_progname, *tmp_argv);
-+ unireg_abort(1);
-+ }
-+ }
-+
-+ /* if the errmsg.sys is not loaded, terminate to maintain behaviour */
-+ if (!errmesg[0][0])
-+ unireg_abort(1);
-+
-+ /* We have to initialize the storage engines before CSV logging */
-+ if (ha_init())
-+ {
-+ sql_print_error("Can't init databases");
-+ unireg_abort(1);
-+ }
-+
-+#ifdef WITH_CSV_STORAGE_ENGINE
-+ if (opt_bootstrap)
-+ log_output_options= LOG_FILE;
-+ else
-+ logger.init_log_tables();
-+
-+ if (log_output_options & LOG_NONE)
-+ {
-+ /*
-+ Issue a warining if there were specified additional options to the
-+ log-output along with NONE. Probably this wasn't what user wanted.
-+ */
-+ if ((log_output_options & LOG_NONE) && (log_output_options & ~LOG_NONE))
-+ sql_print_warning("There were other values specified to "
-+ "log-output besides NONE. Disabling slow "
-+ "and general logs anyway.");
-+ logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
-+ }
-+ else
-+ {
-+ /* fall back to the log files if tables are not present */
-+ LEX_STRING csv_name={C_STRING_WITH_LEN("csv")};
-+ if (!plugin_is_ready(&csv_name, MYSQL_STORAGE_ENGINE_PLUGIN))
-+ {
-+ /* purecov: begin inspected */
-+ sql_print_error("CSV engine is not present, falling back to the "
-+ "log files");
-+ log_output_options= (log_output_options & ~LOG_TABLE) | LOG_FILE;
-+ /* purecov: end */
-+ }
-+
-+ logger.set_handlers(LOG_FILE, opt_slow_log ? log_output_options:LOG_NONE,
-+ opt_log ? log_output_options:LOG_NONE);
-+ }
-+#else
-+ logger.set_handlers(LOG_FILE, opt_slow_log ? LOG_FILE:LOG_NONE,
-+ opt_log ? LOG_FILE:LOG_NONE);
-+#endif
-+
-+ /*
-+ Check that the default storage engine is actually available.
-+ */
-+ if (default_storage_engine_str)
-+ {
-+ LEX_STRING name= { default_storage_engine_str,
-+ strlen(default_storage_engine_str) };
-+ plugin_ref plugin;
-+ handlerton *hton;
-+
-+ if ((plugin= ha_resolve_by_name(0, &name)))
-+ hton= plugin_data(plugin, handlerton*);
-+ else
-+ {
-+ sql_print_error("Unknown/unsupported table type: %s",
-+ default_storage_engine_str);
-+ unireg_abort(1);
-+ }
-+ if (!ha_storage_engine_is_enabled(hton))
-+ {
-+ if (!opt_bootstrap)
-+ {
-+ sql_print_error("Default storage engine (%s) is not available",
-+ default_storage_engine_str);
-+ unireg_abort(1);
-+ }
-+ DBUG_ASSERT(global_system_variables.table_plugin);
-+ }
-+ else
-+ {
-+ /*
-+ Need to unlock as global_system_variables.table_plugin
-+ was acquired during plugin_init()
-+ */
-+ plugin_unlock(0, global_system_variables.table_plugin);
-+ global_system_variables.table_plugin= plugin;
-+ }
-+ }
-+
-+ tc_log= (total_ha_2pc > 1 ? (opt_bin_log ?
-+ (TC_LOG *) &mysql_bin_log :
-+ (TC_LOG *) &tc_log_mmap) :
-+ (TC_LOG *) &tc_log_dummy);
-+
-+ if (tc_log->open(opt_bin_log ? opt_bin_logname : opt_tc_log_file))
-+ {
-+ sql_print_error("Can't init tc log");
-+ unireg_abort(1);
-+ }
-+
-+ if (ha_recover(0))
-+ {
-+ unireg_abort(1);
-+ }
-+
-+ if (opt_bin_log && mysql_bin_log.open(opt_bin_logname, LOG_BIN, 0,
-+ WRITE_CACHE, 0, max_binlog_size, 0, TRUE))
-+ unireg_abort(1);
-+
-+#ifdef HAVE_REPLICATION
-+ if (opt_bin_log && expire_logs_days)
-+ {
-+ time_t purge_time= server_start_time - expire_logs_days*24*60*60;
-+ if (purge_time >= 0)
-+ mysql_bin_log.purge_logs_before_date(purge_time);
-+ }
-+#endif
-+#ifdef __NETWARE__
-+ /* Increasing stacksize of threads on NetWare */
-+ pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
-+#endif
-+
-+ if (opt_myisam_log)
-+ (void) mi_log(1);
-+
-+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && !defined(EMBEDDED_LIBRARY)
-+ if (locked_in_memory && !getuid())
-+ {
-+ if (setreuid((uid_t)-1, 0) == -1)
-+ { // this should never happen
-+ sql_perror("setreuid");
-+ unireg_abort(1);
-+ }
-+ if (mlockall(MCL_CURRENT))
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Failed to lock memory. Errno: %d\n",errno);
-+ locked_in_memory= 0;
-+ }
-+ if (user_info)
-+ set_user(mysqld_user, user_info);
-+ }
-+ else
-+#endif
-+ locked_in_memory=0;
-+
-+ ft_init_stopwords();
-+
-+ init_max_user_conn();
-+ init_update_queries();
-+ DBUG_RETURN(0);
-+}
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+static void create_shutdown_thread()
-+{
-+#ifdef __WIN__
-+ hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
-+ pthread_t hThread;
-+ if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
-+ sql_print_warning("Can't create thread to handle shutdown requests");
-+
-+ // On "Stop Service" we have to do regular shutdown
-+ Service.SetShutdownEvent(hEventShutdown);
-+#endif /* __WIN__ */
-+}
-+
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+#if (defined(__NT__) || defined(HAVE_SMEM)) && !defined(EMBEDDED_LIBRARY)
-+static void handle_connections_methods()
-+{
-+ pthread_t hThread;
-+ DBUG_ENTER("handle_connections_methods");
-+#ifdef __NT__
-+ if (hPipe == INVALID_HANDLE_VALUE &&
-+ (!have_tcpip || opt_disable_networking) &&
-+ !opt_enable_shared_memory)
-+ {
-+ sql_print_error("TCP/IP, --shared-memory, or --named-pipe should be configured on NT OS");
-+ unireg_abort(1); // Will not return
-+ }
-+#endif
-+
-+ pthread_mutex_lock(&LOCK_thread_count);
-+ (void) pthread_cond_init(&COND_handler_count,NULL);
-+ handler_count=0;
-+#ifdef __NT__
-+ if (hPipe != INVALID_HANDLE_VALUE)
-+ {
-+ handler_count++;
-+ if (pthread_create(&hThread,&connection_attrib,
-+ handle_connections_namedpipes, 0))
-+ {
-+ sql_print_warning("Can't create thread to handle named pipes");
-+ handler_count--;
-+ }
-+ }
-+#endif /* __NT__ */
-+ if (have_tcpip && !opt_disable_networking)
-+ {
-+ handler_count++;
-+ if (pthread_create(&hThread,&connection_attrib,
-+ handle_connections_sockets, 0))
-+ {
-+ sql_print_warning("Can't create thread to handle TCP/IP");
-+ handler_count--;
-+ }
-+ }
-+#ifdef HAVE_SMEM
-+ if (opt_enable_shared_memory)
-+ {
-+ handler_count++;
-+ if (pthread_create(&hThread,&connection_attrib,
-+ handle_connections_shared_memory, 0))
-+ {
-+ sql_print_warning("Can't create thread to handle shared memory");
-+ handler_count--;
-+ }
-+ }
-+#endif
-+
-+ while (handler_count > 0)
-+ pthread_cond_wait(&COND_handler_count,&LOCK_thread_count);
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+ DBUG_VOID_RETURN;
-+}
-+
-+void decrement_handler_count()
-+{
-+ pthread_mutex_lock(&LOCK_thread_count);
-+ handler_count--;
-+ pthread_cond_signal(&COND_handler_count);
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+ my_thread_end();
-+}
-+#else
-+#define decrement_handler_count()
-+#endif /* defined(__NT__) || defined(HAVE_SMEM) */
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+#ifndef DBUG_OFF
-+/*
-+ Debugging helper function to keep the locale database
-+ (see sql_locale.cc) and max_month_name_length and
-+ max_day_name_length variable values in consistent state.
-+*/
-+static void test_lc_time_sz()
-+{
-+ DBUG_ENTER("test_lc_time_sz");
-+ for (MY_LOCALE **loc= my_locales; *loc; loc++)
-+ {
-+ uint max_month_len= 0;
-+ uint max_day_len = 0;
-+ for (const char **month= (*loc)->month_names->type_names; *month; month++)
-+ {
-+ set_if_bigger(max_month_len,
-+ my_numchars_mb(&my_charset_utf8_general_ci,
-+ *month, *month + strlen(*month)));
-+ }
-+ for (const char **day= (*loc)->day_names->type_names; *day; day++)
-+ {
-+ set_if_bigger(max_day_len,
-+ my_numchars_mb(&my_charset_utf8_general_ci,
-+ *day, *day + strlen(*day)));
-+ }
-+ if ((*loc)->max_month_name_length != max_month_len ||
-+ (*loc)->max_day_name_length != max_day_len)
-+ {
-+ DBUG_PRINT("Wrong max day name(or month name) length for locale:",
-+ ("%s", (*loc)->name));
-+ DBUG_ASSERT(0);
-+ }
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+#endif//DBUG_OFF
-+
-+
-+#ifdef __WIN__
-+int win_main(int argc, char **argv)
-+#else
-+int main(int argc, char **argv)
-+#endif
-+{
-+ MY_INIT(argv[0]); // init my_sys library & pthreads
-+ /* nothing should come before this line ^^^ */
-+
-+ /* Set signal used to kill MySQL */
-+#if defined(SIGUSR2)
-+ thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
-+#else
-+ thr_kill_signal= SIGINT;
-+#endif
-+
-+ /*
-+ Perform basic logger initialization logger. Should be called after
-+ MY_INIT, as it initializes mutexes. Log tables are inited later.
-+ */
-+ logger.init_base();
-+
-+#ifdef _CUSTOMSTARTUPCONFIG_
-+ if (_cust_check_startup())
-+ {
-+ / * _cust_check_startup will report startup failure error * /
-+ exit(1);
-+ }
-+#endif
-+
-+#ifdef __WIN__
-+ /*
-+ Before performing any socket operation (like retrieving hostname
-+ in init_common_variables we have to call WSAStartup
-+ */
-+ {
-+ WSADATA WsaData;
-+ if (SOCKET_ERROR == WSAStartup (0x0101, &WsaData))
-+ {
-+ /* errors are not read yet, so we use english text here */
-+ my_message(ER_WSAS_FAILED, "WSAStartup Failed", MYF(0));
-+ unireg_abort(1);
-+ }
-+ }
-+#endif /* __WIN__ */
-+
-+ if (init_common_variables(MYSQL_CONFIG_NAME,
-+ argc, argv, load_default_groups))
-+ unireg_abort(1); // Will do exit
-+
-+ init_signals();
-+ if (!(opt_specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_setprio(pthread_self(),CONNECT_PRIOR);
-+#if defined(__ia64__) || defined(__ia64)
-+ /*
-+ Peculiar things with ia64 platforms - it seems we only have half the
-+ stack size in reality, so we have to double it here
-+ */
-+ pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size*2);
-+#else
-+ pthread_attr_setstacksize(&connection_attrib,my_thread_stack_size);
-+#endif
-+#ifdef HAVE_PTHREAD_ATTR_GETSTACKSIZE
-+ {
-+ /* Retrieve used stack size; Needed for checking stack overflows */
-+ size_t stack_size= 0;
-+ pthread_attr_getstacksize(&connection_attrib, &stack_size);
-+#if defined(__ia64__) || defined(__ia64)
-+ stack_size/= 2;
-+#endif
-+ /* We must check if stack_size = 0 as Solaris 2.9 can return 0 here */
-+ if (stack_size && stack_size < my_thread_stack_size)
-+ {
-+ if (global_system_variables.log_warnings)
-+ sql_print_warning("Asked for %lu thread stack, but got %ld",
-+ my_thread_stack_size, (long) stack_size);
-+#if defined(__ia64__) || defined(__ia64)
-+ my_thread_stack_size= stack_size*2;
-+#else
-+ my_thread_stack_size= stack_size;
-+#endif
-+ }
-+ }
-+#endif
-+#ifdef __NETWARE__
-+ /* Increasing stacksize of threads on NetWare */
-+ pthread_attr_setstacksize(&connection_attrib, NW_THD_STACKSIZE);
-+#endif
-+
-+ (void) thr_setconcurrency(concurrency); // 10 by default
-+
-+ select_thread=pthread_self();
-+ select_thread_in_use=1;
-+
-+#ifdef HAVE_LIBWRAP
-+ libwrapName= my_progname+dirname_length(my_progname);
-+ openlog(libwrapName, LOG_PID, LOG_AUTH);
-+#endif
-+
-+#ifndef DBUG_OFF
-+ test_lc_time_sz();
-+#endif
-+
-+ /*
-+ We have enough space for fiddling with the argv, continue
-+ */
-+ check_data_home(mysql_real_data_home);
-+ if (my_setwd(mysql_real_data_home,MYF(MY_WME)) && !opt_help)
-+ unireg_abort(1); /* purecov: inspected */
-+ mysql_data_home= mysql_data_home_buff;
-+ mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
-+ mysql_data_home[1]=0;
-+ mysql_data_home_len= 2;
-+
-+ if ((user_info= check_user(mysqld_user)))
-+ {
-+#if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT)
-+ if (locked_in_memory) // getuid() == 0 here
-+ set_effective_user(user_info);
-+ else
-+#endif
-+ set_user(mysqld_user, user_info);
-+ }
-+
-+ if (opt_bin_log && !server_id)
-+ {
-+ server_id= !master_host ? 1 : 2;
-+#ifdef EXTRA_DEBUG
-+ switch (server_id) {
-+ case 1:
-+ sql_print_warning("\
-+You have enabled the binary log, but you haven't set server-id to \
-+a non-zero value: we force server id to 1; updates will be logged to the \
-+binary log, but connections from slaves will not be accepted.");
-+ break;
-+ case 2:
-+ sql_print_warning("\
-+You should set server-id to a non-0 value if master_host is set; \
-+we force server id to 2, but this MySQL server will not act as a slave.");
-+ break;
-+ }
-+#endif
-+ }
-+
-+ if (init_server_components())
-+ unireg_abort(1);
-+
-+ init_ssl();
-+ network_init();
-+
-+#ifdef __WIN__
-+ if (!opt_console)
-+ {
-+ if (reopen_fstreams(log_error_file, stdout, stderr))
-+ unireg_abort(1);
-+ setbuf(stderr, NULL);
-+ FreeConsole(); // Remove window
-+ }
-+#endif
-+
-+ /*
-+ Initialize my_str_malloc() and my_str_free()
-+ */
-+ my_str_malloc= &my_str_malloc_mysqld;
-+ my_str_free= &my_str_free_mysqld;
-+
-+ /*
-+ init signals & alarm
-+ After this we can't quit by a simple unireg_abort
-+ */
-+ error_handler_hook= my_message_sql;
-+ start_signal_handler(); // Creates pidfile
-+
-+ if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
-+ my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
-+ {
-+ abort_loop=1;
-+ select_thread_in_use=0;
-+#ifndef __NETWARE__
-+ (void) pthread_kill(signal_thread, MYSQL_KILL_SIGNAL);
-+#endif /* __NETWARE__ */
-+
-+ if (!opt_bootstrap)
-+ (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore
-+
-+ if (unix_sock != INVALID_SOCKET)
-+ unlink(mysqld_unix_port);
-+ exit(1);
-+ }
-+ if (!opt_noacl)
-+ (void) grant_init();
-+
-+ if (!opt_bootstrap)
-+ servers_init(0);
-+
-+ if (!opt_noacl)
-+ {
-+#ifdef HAVE_DLOPEN
-+ udf_init();
-+#endif
-+ }
-+
-+ init_status_vars();
-+ if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
-+ opt_skip_slave_start= 1;
-+ /*
-+ init_slave() must be called after the thread keys are created.
-+ Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
-+ places) assume that active_mi != 0, so let's fail if it's 0 (out of
-+ memory); a message has already been printed.
-+ */
-+ if (init_slave() && !active_mi)
-+ {
-+ unireg_abort(1);
-+ }
-+
-+ execute_ddl_log_recovery();
-+
-+ if (Events::init(opt_noacl || opt_bootstrap))
-+ unireg_abort(1);
-+
-+ if (opt_bootstrap)
-+ {
-+ select_thread_in_use= 0; // Allow 'kill' to work
-+ bootstrap(stdin);
-+ unireg_abort(bootstrap_error ? 1 : 0);
-+ }
-+ if (opt_init_file)
-+ {
-+ if (read_init_file(opt_init_file))
-+ unireg_abort(1);
-+ }
-+
-+ create_shutdown_thread();
-+ start_handle_manager();
-+
-+ sql_print_information(ER(ER_STARTUP),my_progname,server_version,
-+ ((unix_sock == INVALID_SOCKET) ? (char*) ""
-+ : mysqld_unix_port),
-+ mysqld_port,
-+ MYSQL_COMPILATION_COMMENT);
-+#if defined(_WIN32) && !defined(EMBEDDED_LIBRARY)
-+ Service.SetRunning();
-+#endif
-+
-+
-+ /* Signal threads waiting for server to be started */
-+ pthread_mutex_lock(&LOCK_server_started);
-+ mysqld_server_started= 1;
-+ pthread_cond_signal(&COND_server_started);
-+ pthread_mutex_unlock(&LOCK_server_started);
-+
-+#if defined(__NT__) || defined(HAVE_SMEM)
-+ handle_connections_methods();
-+#else
-+#ifdef __WIN__
-+ if (!have_tcpip || opt_disable_networking)
-+ {
-+ sql_print_error("TCP/IP unavailable or disabled with --skip-networking; no available interfaces");
-+ unireg_abort(1);
-+ }
-+#endif
-+ handle_connections_sockets(0);
-+#endif /* __NT__ */
-+
-+ /* (void) pthread_attr_destroy(&connection_attrib); */
-+
-+ DBUG_PRINT("quit",("Exiting main thread"));
-+
-+#ifndef __WIN__
-+#ifdef EXTRA_DEBUG2
-+ sql_print_error("Before Lock_thread_count");
-+#endif
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ DBUG_PRINT("quit", ("Got thread_count mutex"));
-+ select_thread_in_use=0; // For close_connections
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ (void) pthread_cond_broadcast(&COND_thread_count);
-+#ifdef EXTRA_DEBUG2
-+ sql_print_error("After lock_thread_count");
-+#endif
-+#endif /* __WIN__ */
-+
-+ /* Wait until cleanup is done */
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ while (!ready_to_exit)
-+ pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+
-+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
-+ if (Service.IsNT() && start_mode)
-+ Service.Stop();
-+ else
-+ {
-+ Service.SetShutdownEvent(0);
-+ if (hEventShutdown)
-+ CloseHandle(hEventShutdown);
-+ }
-+#endif
-+ clean_up(1);
-+ wait_for_signal_thread_to_end();
-+ clean_up_mutexes();
-+ my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0);
-+
-+ exit(0);
-+ return(0); /* purecov: deadcode */
-+}
-+
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+/****************************************************************************
-+ Main and thread entry function for Win32
-+ (all this is needed only to run mysqld as a service on WinNT)
-+****************************************************************************/
-+
-+#if defined(__WIN__) && !defined(EMBEDDED_LIBRARY)
-+int mysql_service(void *p)
-+{
-+ if (use_opt_args)
-+ win_main(opt_argc, opt_argv);
-+ else
-+ win_main(Service.my_argc, Service.my_argv);
-+ return 0;
-+}
-+
-+
-+/* Quote string if it contains space, else copy */
-+
-+static char *add_quoted_string(char *to, const char *from, char *to_end)
-+{
-+ uint length= (uint) (to_end-to);
-+
-+ if (!strchr(from, ' '))
-+ return strmake(to, from, length-1);
-+ return strxnmov(to, length-1, "\"", from, "\"", NullS);
-+}
-+
-+
-+/**
-+ Handle basic handling of services, like installation and removal.
-+
-+ @param argv Pointer to argument list
-+ @param servicename Internal name of service
-+ @param displayname Display name of service (in taskbar ?)
-+ @param file_path Path to this program
-+ @param startup_option Startup option to mysqld
-+
-+ @retval
-+ 0 option handled
-+ @retval
-+ 1 Could not handle option
-+*/
-+
-+static bool
-+default_service_handling(char **argv,
-+ const char *servicename,
-+ const char *displayname,
-+ const char *file_path,
-+ const char *extra_opt,
-+ const char *account_name)
-+{
-+ char path_and_service[FN_REFLEN+FN_REFLEN+32], *pos, *end;
-+ const char *opt_delim;
-+ end= path_and_service + sizeof(path_and_service)-3;
-+
-+ /* We have to quote filename if it contains spaces */
-+ pos= add_quoted_string(path_and_service, file_path, end);
-+ if (*extra_opt)
-+ {
-+ /*
-+ Add option after file_path. There will be zero or one extra option. It's
-+ assumed to be --defaults-file=file but isn't checked. The variable (not
-+ the option name) should be quoted if it contains a string.
-+ */
-+ *pos++= ' ';
-+ if (opt_delim= strchr(extra_opt, '='))
-+ {
-+ size_t length= ++opt_delim - extra_opt;
-+ pos= strnmov(pos, extra_opt, length);
-+ }
-+ else
-+ opt_delim= extra_opt;
-+
-+ pos= add_quoted_string(pos, opt_delim, end);
-+ }
-+ /* We must have servicename last */
-+ *pos++= ' ';
-+ (void) add_quoted_string(pos, servicename, end);
-+
-+ if (Service.got_service_option(argv, "install"))
-+ {
-+ Service.Install(1, servicename, displayname, path_and_service,
-+ account_name);
-+ return 0;
-+ }
-+ if (Service.got_service_option(argv, "install-manual"))
-+ {
-+ Service.Install(0, servicename, displayname, path_and_service,
-+ account_name);
-+ return 0;
-+ }
-+ if (Service.got_service_option(argv, "remove"))
-+ {
-+ Service.Remove(servicename);
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+
-+int main(int argc, char **argv)
-+{
-+ /*
-+ When several instances are running on the same machine, we
-+ need to have an unique named hEventShudown through the
-+ application PID e.g.: MySQLShutdown1890; MySQLShutdown2342
-+ */
-+ int10_to_str((int) GetCurrentProcessId(),strmov(shutdown_event_name,
-+ "MySQLShutdown"), 10);
-+
-+ /* Must be initialized early for comparison of service name */
-+ system_charset_info= &my_charset_utf8_general_ci;
-+
-+ if (Service.GetOS()) /* true NT family */
-+ {
-+ char file_path[FN_REFLEN];
-+ my_path(file_path, argv[0], ""); /* Find name in path */
-+ fn_format(file_path,argv[0],file_path,"",
-+ MY_REPLACE_DIR | MY_UNPACK_FILENAME | MY_RESOLVE_SYMLINKS);
-+
-+ if (argc == 2)
-+ {
-+ if (!default_service_handling(argv, MYSQL_SERVICENAME, MYSQL_SERVICENAME,
-+ file_path, "", NULL))
-+ return 0;
-+ if (Service.IsService(argv[1])) /* Start an optional service */
-+ {
-+ /*
-+ Only add the service name to the groups read from the config file
-+ if it's not "MySQL". (The default service name should be 'mysqld'
-+ but we started a bad tradition by calling it MySQL from the start
-+ and we are now stuck with it.
-+ */
-+ if (my_strcasecmp(system_charset_info, argv[1],"mysql"))
-+ load_default_groups[load_default_groups_sz-2]= argv[1];
-+ start_mode= 1;
-+ Service.Init(argv[1], mysql_service);
-+ return 0;
-+ }
-+ }
-+ else if (argc == 3) /* install or remove any optional service */
-+ {
-+ if (!default_service_handling(argv, argv[2], argv[2], file_path, "",
-+ NULL))
-+ return 0;
-+ if (Service.IsService(argv[2]))
-+ {
-+ /*
-+ mysqld was started as
-+ mysqld --defaults-file=my_path\my.ini service-name
-+ */
-+ use_opt_args=1;
-+ opt_argc= 2; // Skip service-name
-+ opt_argv=argv;
-+ start_mode= 1;
-+ if (my_strcasecmp(system_charset_info, argv[2],"mysql"))
-+ load_default_groups[load_default_groups_sz-2]= argv[2];
-+ Service.Init(argv[2], mysql_service);
-+ return 0;
-+ }
-+ }
-+ else if (argc == 4 || argc == 5)
-+ {
-+ /*
-+ This may seem strange, because we handle --local-service while
-+ preserving 4.1's behavior of allowing any one other argument that is
-+ passed to the service on startup. (The assumption is that this is
-+ --defaults-file=file, but that was not enforced in 4.1, so we don't
-+ enforce it here.)
-+ */
-+ const char *extra_opt= NullS;
-+ const char *account_name = NullS;
-+ int index;
-+ for (index = 3; index < argc; index++)
-+ {
-+ if (!strcmp(argv[index], "--local-service"))
-+ account_name= "NT AUTHORITY\\LocalService";
-+ else
-+ extra_opt= argv[index];
-+ }
-+
-+ if (argc == 4 || account_name)
-+ if (!default_service_handling(argv, argv[2], argv[2], file_path,
-+ extra_opt, account_name))
-+ return 0;
-+ }
-+ else if (argc == 1 && Service.IsService(MYSQL_SERVICENAME))
-+ {
-+ /* start the default service */
-+ start_mode= 1;
-+ Service.Init(MYSQL_SERVICENAME, mysql_service);
-+ return 0;
-+ }
-+ }
-+ /* Start as standalone server */
-+ Service.my_argc=argc;
-+ Service.my_argv=argv;
-+ mysql_service(NULL);
-+ return 0;
-+}
-+#endif
-+
-+
-+/**
-+ Execute all commands from a file. Used by the mysql_install_db script to
-+ create MySQL privilege tables without having to start a full MySQL server.
-+*/
-+
-+static void bootstrap(FILE *file)
-+{
-+ DBUG_ENTER("bootstrap");
-+
-+ THD *thd= new THD;
-+ thd->bootstrap=1;
-+ my_net_init(&thd->net,(st_vio*) 0);
-+ thd->max_client_packet_length= thd->net.max_packet;
-+ thd->security_ctx->master_access= ~(ulong)0;
-+ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
-+ thread_count++;
-+ in_bootstrap= TRUE;
-+
-+ bootstrap_file=file;
-+#ifndef EMBEDDED_LIBRARY // TODO: Enable this
-+ if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
-+ (void*) thd))
-+ {
-+ sql_print_warning("Can't create thread to handle bootstrap");
-+ bootstrap_error=-1;
-+ DBUG_VOID_RETURN;
-+ }
-+ /* Wait for thread to die */
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ while (in_bootstrap)
-+ {
-+ (void) pthread_cond_wait(&COND_thread_count,&LOCK_thread_count);
-+ DBUG_PRINT("quit",("One thread died (count=%u)",thread_count));
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+#else
-+ thd->mysql= 0;
-+ handle_bootstrap((void *)thd);
-+#endif
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+static bool read_init_file(char *file_name)
-+{
-+ FILE *file;
-+ DBUG_ENTER("read_init_file");
-+ DBUG_PRINT("enter",("name: %s",file_name));
-+ if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
-+ DBUG_RETURN(TRUE);
-+ bootstrap(file);
-+ (void) my_fclose(file,MYF(MY_WME));
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/*
-+ Simple scheduler that use the main thread to handle the request
-+
-+ NOTES
-+ This is only used for debugging, when starting mysqld with
-+ --thread-handling=no-threads or --one-thread
-+
-+ When we enter this function, LOCK_thread_count is hold!
-+*/
-+
-+void handle_connection_in_main_thread(THD *thd)
-+{
-+ safe_mutex_assert_owner(&LOCK_thread_count);
-+ thread_cache_size=0; // Safety
-+ threads.append(thd);
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+ thd->start_utime= my_micro_time();
-+ handle_one_connection(thd);
-+}
-+
-+
-+/*
-+ Scheduler that uses one thread per connection
-+*/
-+
-+void create_thread_to_handle_connection(THD *thd)
-+{
-+ if (cached_thread_count > wake_thread)
-+ {
-+ /* Get thread from cache */
-+ thread_cache.append(thd);
-+ wake_thread++;
-+ pthread_cond_signal(&COND_thread_cache);
-+ }
-+ else
-+ {
-+ char error_message_buff[MYSQL_ERRMSG_SIZE];
-+ /* Create new thread to handle connection */
-+ int error;
-+ thread_created++;
-+ threads.append(thd);
-+ DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
-+ thd->prior_thr_create_utime= thd->start_utime= my_micro_time();
-+ if ((error=pthread_create(&thd->real_id,&connection_attrib,
-+ handle_one_connection,
-+ (void*) thd)))
-+ {
-+ /* purecov: begin inspected */
-+ DBUG_PRINT("error",
-+ ("Can't create thread to handle request (error %d)",
-+ error));
-+ thread_count--;
-+ thd->killed= THD::KILL_CONNECTION; // Safety
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+
-+ pthread_mutex_lock(&LOCK_connection_count);
-+ --connection_count;
-+ pthread_mutex_unlock(&LOCK_connection_count);
-+
-+ statistic_increment(aborted_connects,&LOCK_status);
-+ /* Can't use my_error() since store_globals has not been called. */
-+ my_snprintf(error_message_buff, sizeof(error_message_buff),
-+ ER(ER_CANT_CREATE_THREAD), error);
-+ net_send_error(thd, ER_CANT_CREATE_THREAD, error_message_buff);
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ close_connection(thd,0,0);
-+ delete thd;
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ return;
-+ /* purecov: end */
-+ }
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ DBUG_PRINT("info",("Thread created"));
-+}
-+
-+
-+/**
-+ Create new thread to handle incoming connection.
-+
-+ This function will create new thread to handle the incoming
-+ connection. If there are idle cached threads one will be used.
-+ 'thd' will be pushed into 'threads'.
-+
-+ In single-threaded mode (\#define ONE_THREAD) connection will be
-+ handled inside this function.
-+
-+ @param[in,out] thd Thread handle of future thread.
-+*/
-+
-+static void create_new_thread(THD *thd)
-+{
-+ NET *net=&thd->net;
-+ DBUG_ENTER("create_new_thread");
-+
-+ if (protocol_version > 9)
-+ net->return_errno=1;
-+
-+ /*
-+ Don't allow too many connections. We roughly check here that we allow
-+ only (max_connections + 1) connections.
-+ */
-+
-+ pthread_mutex_lock(&LOCK_connection_count);
-+
-+ if (connection_count >= max_connections + 1 || abort_loop)
-+ {
-+ pthread_mutex_unlock(&LOCK_connection_count);
-+
-+ DBUG_PRINT("error",("Too many connections"));
-+ close_connection(thd, ER_CON_COUNT_ERROR, 1);
-+ delete thd;
-+ DBUG_VOID_RETURN;
-+ }
-+
-+ ++connection_count;
-+
-+ if (connection_count > max_used_connections)
-+ max_used_connections= connection_count;
-+
-+ pthread_mutex_unlock(&LOCK_connection_count);
-+
-+ /* Start a new thread to handle connection. */
-+
-+ pthread_mutex_lock(&LOCK_thread_count);
-+
-+ /*
-+ The initialization of thread_id is done in create_embedded_thd() for
-+ the embedded library.
-+ TODO: refactor this to avoid code duplication there
-+ */
-+ thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
-+
-+ thread_count++;
-+
-+ thread_scheduler.add_connection(thd);
-+
-+ DBUG_VOID_RETURN;
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+#ifdef SIGNALS_DONT_BREAK_READ
-+inline void kill_broken_server()
-+{
-+ /* hack to get around signals ignored in syscalls for problem OS's */
-+ if (
-+#if !defined(__NETWARE__)
-+ unix_sock == INVALID_SOCKET ||
-+#endif
-+ (!opt_disable_networking && ip_sock == INVALID_SOCKET))
-+ {
-+ select_thread_in_use = 0;
-+ /* The following call will never return */
-+ kill_server(IF_NETWARE(MYSQL_KILL_SIGNAL, (void*) MYSQL_KILL_SIGNAL));
-+ }
-+}
-+#define MAYBE_BROKEN_SYSCALL kill_broken_server();
-+#else
-+#define MAYBE_BROKEN_SYSCALL
-+#endif
-+
-+ /* Handle new connections and spawn new process to handle them */
-+
-+#ifndef EMBEDDED_LIBRARY
-+pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused)))
-+{
-+ my_socket sock,new_sock;
-+ uint error_count=0;
-+ uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
-+ fd_set readFDs,clientFDs;
-+ THD *thd;
-+ struct sockaddr_in cAddr;
-+ int ip_flags=0,socket_flags=0,flags;
-+ st_vio *vio_tmp;
-+ DBUG_ENTER("handle_connections_sockets");
-+
-+ LINT_INIT(new_sock);
-+
-+ (void) my_pthread_getprio(pthread_self()); // For debugging
-+
-+ FD_ZERO(&clientFDs);
-+ if (ip_sock != INVALID_SOCKET)
-+ {
-+ FD_SET(ip_sock,&clientFDs);
-+#ifdef HAVE_FCNTL
-+ ip_flags = fcntl(ip_sock, F_GETFL, 0);
-+#endif
-+ }
-+#ifdef HAVE_SYS_UN_H
-+ FD_SET(unix_sock,&clientFDs);
-+#ifdef HAVE_FCNTL
-+ socket_flags=fcntl(unix_sock, F_GETFL, 0);
-+#endif
-+#endif
-+
-+ DBUG_PRINT("general",("Waiting for connections."));
-+ MAYBE_BROKEN_SYSCALL;
-+ while (!abort_loop)
-+ {
-+ readFDs=clientFDs;
-+#ifdef HPUX10
-+ if (select(max_used_connection,(int*) &readFDs,0,0,0) < 0)
-+ continue;
-+#else
-+ if (select((int) max_used_connection,&readFDs,0,0,0) < 0)
-+ {
-+ if (socket_errno != SOCKET_EINTR)
-+ {
-+ if (!select_errors++ && !abort_loop) /* purecov: inspected */
-+ sql_print_error("mysqld: Got error %d from select",socket_errno); /* purecov: inspected */
-+ }
-+ MAYBE_BROKEN_SYSCALL
-+ continue;
-+ }
-+#endif /* HPUX10 */
-+ if (abort_loop)
-+ {
-+ MAYBE_BROKEN_SYSCALL;
-+ break;
-+ }
-+
-+ /* Is this a new connection request ? */
-+#ifdef HAVE_SYS_UN_H
-+ if (FD_ISSET(unix_sock,&readFDs))
-+ {
-+ sock = unix_sock;
-+ flags= socket_flags;
-+ }
-+ else
-+#endif
-+ {
-+ sock = ip_sock;
-+ flags= ip_flags;
-+ }
-+
-+#if !defined(NO_FCNTL_NONBLOCK)
-+ if (!(test_flags & TEST_BLOCKING))
-+ {
-+#if defined(O_NONBLOCK)
-+ fcntl(sock, F_SETFL, flags | O_NONBLOCK);
-+#elif defined(O_NDELAY)
-+ fcntl(sock, F_SETFL, flags | O_NDELAY);
-+#endif
-+ }
-+#endif /* NO_FCNTL_NONBLOCK */
-+ for (uint retry=0; retry < MAX_ACCEPT_RETRY; retry++)
-+ {
-+ size_socket length=sizeof(struct sockaddr_in);
-+ new_sock = accept(sock, my_reinterpret_cast(struct sockaddr *) (&cAddr),
-+ &length);
-+#ifdef __NETWARE__
-+ // TODO: temporary fix, waiting for TCP/IP fix - DEFECT000303149
-+ if ((new_sock == INVALID_SOCKET) && (socket_errno == EINVAL))
-+ {
-+ kill_server(SIGTERM);
-+ }
-+#endif
-+ if (new_sock != INVALID_SOCKET ||
-+ (socket_errno != SOCKET_EINTR && socket_errno != SOCKET_EAGAIN))
-+ break;
-+ MAYBE_BROKEN_SYSCALL;
-+#if !defined(NO_FCNTL_NONBLOCK)
-+ if (!(test_flags & TEST_BLOCKING))
-+ {
-+ if (retry == MAX_ACCEPT_RETRY - 1)
-+ fcntl(sock, F_SETFL, flags); // Try without O_NONBLOCK
-+ }
-+#endif
-+ }
-+#if !defined(NO_FCNTL_NONBLOCK)
-+ if (!(test_flags & TEST_BLOCKING))
-+ fcntl(sock, F_SETFL, flags);
-+#endif
-+ if (new_sock == INVALID_SOCKET)
-+ {
-+ if ((error_count++ & 255) == 0) // This can happen often
-+ sql_perror("Error in accept");
-+ MAYBE_BROKEN_SYSCALL;
-+ if (socket_errno == SOCKET_ENFILE || socket_errno == SOCKET_EMFILE)
-+ sleep(1); // Give other threads some time
-+ continue;
-+ }
-+
-+#ifdef HAVE_LIBWRAP
-+ {
-+ if (sock == ip_sock)
-+ {
-+ struct request_info req;
-+ signal(SIGCHLD, SIG_DFL);
-+ request_init(&req, RQ_DAEMON, libwrapName, RQ_FILE, new_sock, NULL);
-+ my_fromhost(&req);
-+ if (!my_hosts_access(&req))
-+ {
-+ /*
-+ This may be stupid but refuse() includes an exit(0)
-+ which we surely don't want...
-+ clean_exit() - same stupid thing ...
-+ */
-+ syslog(deny_severity, "refused connect from %s",
-+ my_eval_client(&req));
-+
-+ /*
-+ C++ sucks (the gibberish in front just translates the supplied
-+ sink function pointer in the req structure from a void (*sink)();
-+ to a void(*sink)(int) if you omit the cast, the C++ compiler
-+ will cry...
-+ */
-+ if (req.sink)
-+ ((void (*)(int))req.sink)(req.fd);
-+
-+ (void) shutdown(new_sock, SHUT_RDWR);
-+ (void) closesocket(new_sock);
-+ continue;
-+ }
-+ }
-+ }
-+#endif /* HAVE_LIBWRAP */
-+
-+ {
-+ size_socket dummyLen;
-+ struct sockaddr dummy;
-+ dummyLen = sizeof(struct sockaddr);
-+ if (getsockname(new_sock,&dummy, &dummyLen) < 0)
-+ {
-+ sql_perror("Error on new connection socket");
-+ (void) shutdown(new_sock, SHUT_RDWR);
-+ (void) closesocket(new_sock);
-+ continue;
-+ }
-+ }
-+
-+ /*
-+ ** Don't allow too many connections
-+ */
-+
-+ if (!(thd= new THD))
-+ {
-+ (void) shutdown(new_sock, SHUT_RDWR);
-+ VOID(closesocket(new_sock));
-+ continue;
-+ }
-+ if (!(vio_tmp=vio_new(new_sock,
-+ sock == unix_sock ? VIO_TYPE_SOCKET :
-+ VIO_TYPE_TCPIP,
-+ sock == unix_sock ? VIO_LOCALHOST: 0)) ||
-+ my_net_init(&thd->net,vio_tmp))
-+ {
-+ /*
-+ Only delete the temporary vio if we didn't already attach it to the
-+ NET object. The destructor in THD will delete any initialized net
-+ structure.
-+ */
-+ if (vio_tmp && thd->net.vio != vio_tmp)
-+ vio_delete(vio_tmp);
-+ else
-+ {
-+ (void) shutdown(new_sock, SHUT_RDWR);
-+ (void) closesocket(new_sock);
-+ }
-+ delete thd;
-+ continue;
-+ }
-+ if (sock == unix_sock)
-+ thd->security_ctx->host=(char*) my_localhost;
-+
-+ create_new_thread(thd);
-+ }
-+ DBUG_LEAVE;
-+ decrement_handler_count();
-+ return 0;
-+}
-+
-+
-+#ifdef __NT__
-+pthread_handler_t handle_connections_namedpipes(void *arg)
-+{
-+ HANDLE hConnectedPipe;
-+ OVERLAPPED connectOverlapped= {0};
-+ THD *thd;
-+ my_thread_init();
-+ DBUG_ENTER("handle_connections_namedpipes");
-+ connectOverlapped.hEvent= CreateEvent(NULL, TRUE, FALSE, NULL);
-+ if (!connectOverlapped.hEvent)
-+ {
-+ sql_print_error("Can't create event, last error=%u", GetLastError());
-+ unireg_abort(1);
-+ }
-+ DBUG_PRINT("general",("Waiting for named pipe connections."));
-+ while (!abort_loop)
-+ {
-+ /* wait for named pipe connection */
-+ BOOL fConnected= ConnectNamedPipe(hPipe, &connectOverlapped);
-+ if (!fConnected && (GetLastError() == ERROR_IO_PENDING))
-+ {
-+ /*
-+ ERROR_IO_PENDING says async IO has started but not yet finished.
-+ GetOverlappedResult will wait for completion.
-+ */
-+ DWORD bytes;
-+ fConnected= GetOverlappedResult(hPipe, &connectOverlapped,&bytes, TRUE);
-+ }
-+ if (abort_loop)
-+ break;
-+ if (!fConnected)
-+ fConnected = GetLastError() == ERROR_PIPE_CONNECTED;
-+ if (!fConnected)
-+ {
-+ CloseHandle(hPipe);
-+ if ((hPipe= CreateNamedPipe(pipe_name,
-+ PIPE_ACCESS_DUPLEX |
-+ FILE_FLAG_OVERLAPPED,
-+ PIPE_TYPE_BYTE |
-+ PIPE_READMODE_BYTE |
-+ PIPE_WAIT,
-+ PIPE_UNLIMITED_INSTANCES,
-+ (int) global_system_variables.
-+ net_buffer_length,
-+ (int) global_system_variables.
-+ net_buffer_length,
-+ NMPWAIT_USE_DEFAULT_WAIT,
-+ &saPipeSecurity)) ==
-+ INVALID_HANDLE_VALUE)
-+ {
-+ sql_perror("Can't create new named pipe!");
-+ break; // Abort
-+ }
-+ }
-+ hConnectedPipe = hPipe;
-+ /* create new pipe for new connection */
-+ if ((hPipe = CreateNamedPipe(pipe_name,
-+ PIPE_ACCESS_DUPLEX |
-+ FILE_FLAG_OVERLAPPED,
-+ PIPE_TYPE_BYTE |
-+ PIPE_READMODE_BYTE |
-+ PIPE_WAIT,
-+ PIPE_UNLIMITED_INSTANCES,
-+ (int) global_system_variables.net_buffer_length,
-+ (int) global_system_variables.net_buffer_length,
-+ NMPWAIT_USE_DEFAULT_WAIT,
-+ &saPipeSecurity)) ==
-+ INVALID_HANDLE_VALUE)
-+ {
-+ sql_perror("Can't create new named pipe!");
-+ hPipe=hConnectedPipe;
-+ continue; // We have to try again
-+ }
-+
-+ if (!(thd = new THD))
-+ {
-+ DisconnectNamedPipe(hConnectedPipe);
-+ CloseHandle(hConnectedPipe);
-+ continue;
-+ }
-+ if (!(thd->net.vio= vio_new_win32pipe(hConnectedPipe)) ||
-+ my_net_init(&thd->net, thd->net.vio))
-+ {
-+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+ delete thd;
-+ continue;
-+ }
-+ /* Host is unknown */
-+ thd->security_ctx->host= my_strdup(my_localhost, MYF(0));
-+ create_new_thread(thd);
-+ }
-+ CloseHandle(connectOverlapped.hEvent);
-+ DBUG_LEAVE;
-+ decrement_handler_count();
-+ return 0;
-+}
-+#endif /* __NT__ */
-+
-+
-+#ifdef HAVE_SMEM
-+
-+/**
-+ Thread of shared memory's service.
-+
-+ @param arg Arguments of thread
-+*/
-+pthread_handler_t handle_connections_shared_memory(void *arg)
-+{
-+ /* file-mapping object, use for create shared memory */
-+ HANDLE handle_connect_file_map= 0;
-+ char *handle_connect_map= 0; // pointer on shared memory
-+ HANDLE event_connect_answer= 0;
-+ ulong smem_buffer_length= shared_memory_buffer_length + 4;
-+ ulong connect_number= 1;
-+ char *tmp= NULL;
-+ char *suffix_pos;
-+ char connect_number_char[22], *p;
-+ const char *errmsg= 0;
-+ SECURITY_ATTRIBUTES *sa_event= 0, *sa_mapping= 0;
-+ my_thread_init();
-+ DBUG_ENTER("handle_connections_shared_memorys");
-+ DBUG_PRINT("general",("Waiting for allocated shared memory."));
-+
-+ /*
-+ get enough space base-name + '_' + longest suffix we might ever send
-+ */
-+ if (!(tmp= (char *)my_malloc(strlen(shared_memory_base_name) + 32L, MYF(MY_FAE))))
-+ goto error;
-+
-+ if (my_security_attr_create(&sa_event, &errmsg,
-+ GENERIC_ALL, SYNCHRONIZE | EVENT_MODIFY_STATE))
-+ goto error;
-+
-+ if (my_security_attr_create(&sa_mapping, &errmsg,
-+ GENERIC_ALL, FILE_MAP_READ | FILE_MAP_WRITE))
-+ goto error;
-+
-+ /*
-+ The name of event and file-mapping events create agree next rule:
-+ shared_memory_base_name+unique_part
-+ Where:
-+ shared_memory_base_name is unique value for each server
-+ unique_part is unique value for each object (events and file-mapping)
-+ */
-+ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",NullS);
-+ strmov(suffix_pos, "CONNECT_REQUEST");
-+ if ((smem_event_connect_request= CreateEvent(sa_event,
-+ FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create request event";
-+ goto error;
-+ }
-+ strmov(suffix_pos, "CONNECT_ANSWER");
-+ if ((event_connect_answer= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg="Could not create answer event";
-+ goto error;
-+ }
-+ strmov(suffix_pos, "CONNECT_DATA");
-+ if ((handle_connect_file_map=
-+ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
-+ PAGE_READWRITE, 0, sizeof(connect_number), tmp)) == 0)
-+ {
-+ errmsg= "Could not create file mapping";
-+ goto error;
-+ }
-+ if ((handle_connect_map= (char *)MapViewOfFile(handle_connect_file_map,
-+ FILE_MAP_WRITE,0,0,
-+ sizeof(DWORD))) == 0)
-+ {
-+ errmsg= "Could not create shared memory service";
-+ goto error;
-+ }
-+
-+ while (!abort_loop)
-+ {
-+ /* Wait a request from client */
-+ WaitForSingleObject(smem_event_connect_request,INFINITE);
-+
-+ /*
-+ it can be after shutdown command
-+ */
-+ if (abort_loop)
-+ goto error;
-+
-+ HANDLE handle_client_file_map= 0;
-+ char *handle_client_map= 0;
-+ HANDLE event_client_wrote= 0;
-+ HANDLE event_client_read= 0; // for transfer data server <-> client
-+ HANDLE event_server_wrote= 0;
-+ HANDLE event_server_read= 0;
-+ HANDLE event_conn_closed= 0;
-+ THD *thd= 0;
-+
-+ p= int10_to_str(connect_number, connect_number_char, 10);
-+ /*
-+ The name of event and file-mapping events create agree next rule:
-+ shared_memory_base_name+unique_part+number_of_connection
-+ Where:
-+ shared_memory_base_name is uniquel value for each server
-+ unique_part is unique value for each object (events and file-mapping)
-+ number_of_connection is connection-number between server and client
-+ */
-+ suffix_pos= strxmov(tmp,shared_memory_base_name,"_",connect_number_char,
-+ "_",NullS);
-+ strmov(suffix_pos, "DATA");
-+ if ((handle_client_file_map=
-+ CreateFileMapping(INVALID_HANDLE_VALUE, sa_mapping,
-+ PAGE_READWRITE, 0, smem_buffer_length, tmp)) == 0)
-+ {
-+ errmsg= "Could not create file mapping";
-+ goto errorconn;
-+ }
-+ if ((handle_client_map= (char*)MapViewOfFile(handle_client_file_map,
-+ FILE_MAP_WRITE,0,0,
-+ smem_buffer_length)) == 0)
-+ {
-+ errmsg= "Could not create memory map";
-+ goto errorconn;
-+ }
-+ strmov(suffix_pos, "CLIENT_WROTE");
-+ if ((event_client_wrote= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create client write event";
-+ goto errorconn;
-+ }
-+ strmov(suffix_pos, "CLIENT_READ");
-+ if ((event_client_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create client read event";
-+ goto errorconn;
-+ }
-+ strmov(suffix_pos, "SERVER_READ");
-+ if ((event_server_read= CreateEvent(sa_event, FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create server read event";
-+ goto errorconn;
-+ }
-+ strmov(suffix_pos, "SERVER_WROTE");
-+ if ((event_server_wrote= CreateEvent(sa_event,
-+ FALSE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create server write event";
-+ goto errorconn;
-+ }
-+ strmov(suffix_pos, "CONNECTION_CLOSED");
-+ if ((event_conn_closed= CreateEvent(sa_event,
-+ TRUE, FALSE, tmp)) == 0)
-+ {
-+ errmsg= "Could not create closed connection event";
-+ goto errorconn;
-+ }
-+ if (abort_loop)
-+ goto errorconn;
-+ if (!(thd= new THD))
-+ goto errorconn;
-+ /* Send number of connection to client */
-+ int4store(handle_connect_map, connect_number);
-+ if (!SetEvent(event_connect_answer))
-+ {
-+ errmsg= "Could not send answer event";
-+ goto errorconn;
-+ }
-+ /* Set event that client should receive data */
-+ if (!SetEvent(event_client_read))
-+ {
-+ errmsg= "Could not set client to read mode";
-+ goto errorconn;
-+ }
-+ if (!(thd->net.vio= vio_new_win32shared_memory(handle_client_file_map,
-+ handle_client_map,
-+ event_client_wrote,
-+ event_client_read,
-+ event_server_wrote,
-+ event_server_read,
-+ event_conn_closed)) ||
-+ my_net_init(&thd->net, thd->net.vio))
-+ {
-+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+ errmsg= 0;
-+ goto errorconn;
-+ }
-+ thd->security_ctx->host= my_strdup(my_localhost, MYF(0)); /* Host is unknown */
-+ create_new_thread(thd);
-+ connect_number++;
-+ continue;
-+
-+errorconn:
-+ /* Could not form connection; Free used handlers/memort and retry */
-+ if (errmsg)
-+ {
-+ char buff[180];
-+ strxmov(buff, "Can't create shared memory connection: ", errmsg, ".",
-+ NullS);
-+ sql_perror(buff);
-+ }
-+ if (handle_client_file_map)
-+ CloseHandle(handle_client_file_map);
-+ if (handle_client_map)
-+ UnmapViewOfFile(handle_client_map);
-+ if (event_server_wrote)
-+ CloseHandle(event_server_wrote);
-+ if (event_server_read)
-+ CloseHandle(event_server_read);
-+ if (event_client_wrote)
-+ CloseHandle(event_client_wrote);
-+ if (event_client_read)
-+ CloseHandle(event_client_read);
-+ if (event_conn_closed)
-+ CloseHandle(event_conn_closed);
-+ delete thd;
-+ }
-+
-+ /* End shared memory handling */
-+error:
-+ if (tmp)
-+ my_free(tmp, MYF(0));
-+
-+ if (errmsg)
-+ {
-+ char buff[180];
-+ strxmov(buff, "Can't create shared memory service: ", errmsg, ".", NullS);
-+ sql_perror(buff);
-+ }
-+ my_security_attr_free(sa_event);
-+ my_security_attr_free(sa_mapping);
-+ if (handle_connect_map) UnmapViewOfFile(handle_connect_map);
-+ if (handle_connect_file_map) CloseHandle(handle_connect_file_map);
-+ if (event_connect_answer) CloseHandle(event_connect_answer);
-+ if (smem_event_connect_request) CloseHandle(smem_event_connect_request);
-+ DBUG_LEAVE;
-+ decrement_handler_count();
-+ return 0;
-+}
-+#endif /* HAVE_SMEM */
-+#endif /* EMBEDDED_LIBRARY */
-+
-+
-+/****************************************************************************
-+ Handle start options
-+******************************************************************************/
-+
-+enum options_mysqld
-+{
-+ OPT_ISAM_LOG=256, OPT_SKIP_NEW,
-+ OPT_SKIP_GRANT, OPT_SKIP_LOCK,
-+ OPT_ENABLE_LOCK, OPT_USE_LOCKING,
-+ OPT_SOCKET, OPT_UPDATE_LOG,
-+ OPT_BIN_LOG, OPT_SKIP_RESOLVE,
-+ OPT_SKIP_NETWORKING, OPT_BIN_LOG_INDEX,
-+ OPT_BIND_ADDRESS, OPT_PID_FILE,
-+ OPT_SKIP_PRIOR, OPT_BIG_TABLES,
-+ OPT_STANDALONE, OPT_ONE_THREAD,
-+ OPT_CONSOLE, OPT_LOW_PRIORITY_UPDATES,
-+ OPT_SKIP_HOST_CACHE, OPT_SHORT_LOG_FORMAT,
-+ OPT_FLUSH, OPT_SAFE,
-+ OPT_BOOTSTRAP, OPT_SKIP_SHOW_DB,
-+ OPT_STORAGE_ENGINE, OPT_INIT_FILE,
-+ OPT_DELAY_KEY_WRITE_ALL, OPT_SLOW_QUERY_LOG,
-+ OPT_DELAY_KEY_WRITE, OPT_CHARSETS_DIR,
-+ OPT_MASTER_HOST, OPT_MASTER_USER,
-+ OPT_MASTER_PASSWORD, OPT_MASTER_PORT,
-+ OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY,
-+ OPT_MASTER_RETRY_COUNT, OPT_LOG_TC, OPT_LOG_TC_SIZE,
-+ OPT_MASTER_SSL, OPT_MASTER_SSL_KEY,
-+ OPT_MASTER_SSL_CERT, OPT_MASTER_SSL_CAPATH,
-+ OPT_MASTER_SSL_CIPHER, OPT_MASTER_SSL_CA,
-+ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB,
-+ OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES,
-+ OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB,
-+ OPT_BINLOG_FORMAT,
-+#ifndef DBUG_OFF
-+ OPT_BINLOG_SHOW_XID,
-+#endif
-+ OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
-+ OPT_WANT_CORE, OPT_CONCURRENT_INSERT,
-+ OPT_MEMLOCK, OPT_MYISAM_RECOVER,
-+ OPT_REPLICATE_REWRITE_DB, OPT_SERVER_ID,
-+ OPT_SKIP_SLAVE_START, OPT_SAFE_SHOW_DB,
-+ OPT_SAFEMALLOC_MEM_LIMIT, OPT_REPLICATE_DO_TABLE,
-+ OPT_REPLICATE_IGNORE_TABLE, OPT_REPLICATE_WILD_DO_TABLE,
-+ OPT_REPLICATE_WILD_IGNORE_TABLE, OPT_REPLICATE_SAME_SERVER_ID,
-+ OPT_DISCONNECT_SLAVE_EVENT_COUNT, OPT_TC_HEURISTIC_RECOVER,
-+ OPT_ABORT_SLAVE_EVENT_COUNT,
-+ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
-+ OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
-+ OPT_ENGINE_CONDITION_PUSHDOWN, OPT_NDB_CONNECTSTRING,
-+ OPT_NDB_USE_EXACT_COUNT, OPT_NDB_USE_TRANSACTIONS,
-+ OPT_NDB_FORCE_SEND, OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
-+ OPT_NDB_SHM, OPT_NDB_OPTIMIZED_NODE_SELECTION, OPT_NDB_CACHE_CHECK_TIME,
-+ OPT_NDB_MGMD, OPT_NDB_NODEID,
-+ OPT_NDB_DISTRIBUTION,
-+ OPT_NDB_INDEX_STAT_ENABLE,
-+ OPT_NDB_EXTRA_LOGGING,
-+ OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
-+ OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
-+ OPT_NDB_USE_COPYING_ALTER_TABLE,
-+ OPT_SKIP_SAFEMALLOC,
-+ OPT_TEMP_POOL, OPT_TX_ISOLATION, OPT_COMPLETION_TYPE,
-+ OPT_SKIP_STACK_TRACE, OPT_SKIP_SYMLINKS,
-+ OPT_MAX_BINLOG_DUMP_EVENTS, OPT_SPORADIC_BINLOG_DUMP_FAIL,
-+ OPT_SAFE_USER_CREATE, OPT_SQL_MODE,
-+ OPT_HAVE_NAMED_PIPE,
-+ OPT_DO_PSTACK, OPT_EVENT_SCHEDULER, OPT_REPORT_HOST,
-+ OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT,
-+ OPT_SHOW_SLAVE_AUTH_INFO,
-+ OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE,
-+ OPT_RPL_RECOVERY_RANK,OPT_INIT_RPL_ROLE,
-+ OPT_RELAY_LOG, OPT_RELAY_LOG_INDEX, OPT_RELAY_LOG_INFO_FILE,
-+ OPT_SLAVE_SKIP_ERRORS, OPT_DES_KEY_FILE, OPT_LOCAL_INFILE,
-+ OPT_SSL_SSL, OPT_SSL_KEY, OPT_SSL_CERT, OPT_SSL_CA,
-+ OPT_SSL_CAPATH, OPT_SSL_CIPHER,
-+ OPT_BACK_LOG, OPT_BINLOG_CACHE_SIZE,
-+ OPT_CONNECT_TIMEOUT, OPT_DELAYED_INSERT_TIMEOUT,
-+ OPT_DELAYED_INSERT_LIMIT, OPT_DELAYED_QUEUE_SIZE,
-+ OPT_FLUSH_TIME, OPT_FT_MIN_WORD_LEN, OPT_FT_BOOLEAN_SYNTAX,
-+ OPT_FT_MAX_WORD_LEN, OPT_FT_QUERY_EXPANSION_LIMIT, OPT_FT_STOPWORD_FILE,
-+ OPT_INTERACTIVE_TIMEOUT, OPT_JOIN_BUFF_SIZE,
-+ OPT_KEY_BUFFER_SIZE, OPT_KEY_CACHE_BLOCK_SIZE,
-+ OPT_KEY_CACHE_DIVISION_LIMIT, OPT_KEY_CACHE_AGE_THRESHOLD,
-+ OPT_LONG_QUERY_TIME,
-+ OPT_LOWER_CASE_TABLE_NAMES, OPT_MAX_ALLOWED_PACKET,
-+ OPT_MAX_BINLOG_CACHE_SIZE, OPT_MAX_BINLOG_SIZE,
-+ OPT_MAX_CONNECTIONS, OPT_MAX_CONNECT_ERRORS,
-+ OPT_MAX_DELAYED_THREADS, OPT_MAX_HEP_TABLE_SIZE,
-+ OPT_MAX_JOIN_SIZE, OPT_MAX_PREPARED_STMT_COUNT,
-+ OPT_MAX_RELAY_LOG_SIZE, OPT_MAX_SORT_LENGTH,
-+ OPT_MAX_SEEKS_FOR_KEY, OPT_MAX_TMP_TABLES, OPT_MAX_USER_CONNECTIONS,
-+ OPT_MAX_LENGTH_FOR_SORT_DATA,
-+ OPT_MAX_WRITE_LOCK_COUNT, OPT_BULK_INSERT_BUFFER_SIZE,
-+ OPT_MAX_ERROR_COUNT, OPT_MULTI_RANGE_COUNT, OPT_MYISAM_DATA_POINTER_SIZE,
-+ OPT_MYISAM_BLOCK_SIZE, OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
-+ OPT_MYISAM_MAX_SORT_FILE_SIZE, OPT_MYISAM_SORT_BUFFER_SIZE,
-+ OPT_MYISAM_USE_MMAP, OPT_MYISAM_REPAIR_THREADS,
-+ OPT_MYISAM_MMAP_SIZE,
-+ OPT_MYISAM_STATS_METHOD,
-+ OPT_NET_BUFFER_LENGTH, OPT_NET_RETRY_COUNT,
-+ OPT_NET_READ_TIMEOUT, OPT_NET_WRITE_TIMEOUT,
-+ OPT_OPEN_FILES_LIMIT,
-+ OPT_PRELOAD_BUFFER_SIZE,
-+ OPT_QUERY_CACHE_LIMIT, OPT_QUERY_CACHE_MIN_RES_UNIT, OPT_QUERY_CACHE_SIZE,
-+ OPT_QUERY_CACHE_TYPE, OPT_QUERY_CACHE_WLOCK_INVALIDATE, OPT_RECORD_BUFFER,
-+ OPT_RECORD_RND_BUFFER, OPT_DIV_PRECINCREMENT, OPT_RELAY_LOG_SPACE_LIMIT,
-+ OPT_RELAY_LOG_PURGE,
-+ OPT_SLAVE_NET_TIMEOUT, OPT_SLAVE_COMPRESSED_PROTOCOL, OPT_SLOW_LAUNCH_TIME,
-+ OPT_SLAVE_TRANS_RETRIES, OPT_READONLY, OPT_DEBUGGING,
-+ OPT_SORT_BUFFER, OPT_TABLE_OPEN_CACHE, OPT_TABLE_DEF_CACHE,
-+ OPT_THREAD_CONCURRENCY, OPT_THREAD_CACHE_SIZE,
-+ OPT_TMP_TABLE_SIZE, OPT_THREAD_STACK,
-+ OPT_WAIT_TIMEOUT,
-+ OPT_ERROR_LOG_FILE,
-+ OPT_DEFAULT_WEEK_FORMAT,
-+ OPT_RANGE_ALLOC_BLOCK_SIZE, OPT_ALLOW_SUSPICIOUS_UDFS,
-+ OPT_QUERY_ALLOC_BLOCK_SIZE, OPT_QUERY_PREALLOC_SIZE,
-+ OPT_TRANS_ALLOC_BLOCK_SIZE, OPT_TRANS_PREALLOC_SIZE,
-+ OPT_SYNC_FRM, OPT_SYNC_BINLOG,
-+ OPT_SYNC_REPLICATION,
-+ OPT_SYNC_REPLICATION_SLAVE_ID,
-+ OPT_SYNC_REPLICATION_TIMEOUT,
-+ OPT_ENABLE_SHARED_MEMORY,
-+ OPT_SHARED_MEMORY_BASE_NAME,
-+ OPT_OLD_PASSWORDS,
-+ OPT_OLD_ALTER_TABLE,
-+ OPT_EXPIRE_LOGS_DAYS,
-+ OPT_GROUP_CONCAT_MAX_LEN,
-+ OPT_DEFAULT_COLLATION,
-+ OPT_DEFAULT_COLLATION_OLD,
-+ OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
-+ OPT_CHARACTER_SET_FILESYSTEM,
-+ OPT_LC_TIME_NAMES,
-+ OPT_INIT_CONNECT,
-+ OPT_INIT_SLAVE,
-+ OPT_SECURE_AUTH,
-+ OPT_DATE_FORMAT,
-+ OPT_TIME_FORMAT,
-+ OPT_DATETIME_FORMAT,
-+ OPT_LOG_QUERIES_NOT_USING_INDEXES,
-+ OPT_DEFAULT_TIME_ZONE,
-+ OPT_SYSDATE_IS_NOW,
-+ OPT_OPTIMIZER_SEARCH_DEPTH,
-+ OPT_OPTIMIZER_PRUNE_LEVEL,
-+ OPT_OPTIMIZER_SWITCH,
-+ OPT_UPDATABLE_VIEWS_WITH_LIMIT,
-+ OPT_SP_AUTOMATIC_PRIVILEGES,
-+ OPT_MAX_SP_RECURSION_DEPTH,
-+ OPT_AUTO_INCREMENT, OPT_AUTO_INCREMENT_OFFSET,
-+ OPT_ENABLE_LARGE_PAGES,
-+ OPT_TIMED_MUTEXES,
-+ OPT_OLD_STYLE_USER_LIMITS,
-+ OPT_LOG_SLOW_ADMIN_STATEMENTS,
-+ OPT_TABLE_LOCK_WAIT_TIMEOUT,
-+ OPT_PLUGIN_LOAD,
-+ OPT_PLUGIN_DIR,
-+ OPT_SYMBOLIC_LINKS,
-+ OPT_WARNINGS,
-+ OPT_RECORD_BUFFER_OLD,
-+ OPT_LOG_OUTPUT,
-+ OPT_PORT_OPEN_TIMEOUT,
-+ OPT_PROFILING,
-+ OPT_KEEP_FILES_ON_CREATE,
-+ OPT_GENERAL_LOG,
-+ OPT_SLOW_LOG,
-+ OPT_THREAD_HANDLING,
-+ OPT_INNODB_ROLLBACK_ON_TIMEOUT,
-+ OPT_SECURE_FILE_PRIV,
-+ OPT_MIN_EXAMINED_ROW_LIMIT,
-+ OPT_LOG_SLOW_SLAVE_STATEMENTS,
-+#if defined(ENABLED_DEBUG_SYNC)
-+ OPT_DEBUG_SYNC_TIMEOUT,
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+ OPT_OLD_MODE,
-+ OPT_SLAVE_EXEC_MODE,
-+ OPT_GENERAL_LOG_FILE,
-+ OPT_SLOW_QUERY_LOG_FILE,
-+ OPT_IGNORE_BUILTIN_INNODB,
-+ OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-+ OPT_DEFAULT_CHARACTER_SET_OLD,
-+ OPT_MAX_LONG_DATA_SIZE
-+};
-+
-+
-+#define LONG_TIMEOUT ((ulong) 3600L*24L*365L)
-+
-+struct my_option my_long_options[] =
-+{
-+ {"help", '?', "Display this help and exit.",
-+ &opt_help, &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
-+ 0, 0},
-+#ifdef HAVE_REPLICATION
-+ {"abort-slave-event-count", OPT_ABORT_SLAVE_EVENT_COUNT,
-+ "Option used by mysql-test for debugging and testing of replication.",
-+ &abort_slave_event_count, &abort_slave_event_count,
-+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#endif /* HAVE_REPLICATION */
-+ {"allow-suspicious-udfs", OPT_ALLOW_SUSPICIOUS_UDFS,
-+ "Allows use of UDFs consisting of only one symbol xxx() "
-+ "without corresponding xxx_init() or xxx_deinit(). That also means "
-+ "that one can load any function from any library, for example exit() "
-+ "from libc.so",
-+ &opt_allow_suspicious_udfs, &opt_allow_suspicious_udfs,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"ansi", 'a', "Use ANSI SQL syntax instead of MySQL syntax. This mode "
-+ "will also set transaction isolation level 'serializable'.", 0, 0, 0,
-+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"auto-increment-increment", OPT_AUTO_INCREMENT,
-+ "Auto-increment columns are incremented by this.",
-+ &global_system_variables.auto_increment_increment,
-+ &max_system_variables.auto_increment_increment, 0, GET_ULONG,
-+ OPT_ARG, 1, 1, 65535, 0, 1, 0 },
-+ {"auto-increment-offset", OPT_AUTO_INCREMENT_OFFSET,
-+ "Offset added to Auto-increment columns. Used when auto-increment-increment != 1.",
-+ &global_system_variables.auto_increment_offset,
-+ &max_system_variables.auto_increment_offset, 0, GET_ULONG, OPT_ARG,
-+ 1, 1, 65535, 0, 1, 0 },
-+ {"automatic-sp-privileges", OPT_SP_AUTOMATIC_PRIVILEGES,
-+ "Creating and dropping stored procedures alters ACLs. Disable with --skip-automatic-sp-privileges.",
-+ &sp_automatic_privileges, &sp_automatic_privileges,
-+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-+ {"basedir", 'b',
-+ "Path to installation directory. All paths are usually resolved relative to this.",
-+ &mysql_home_ptr, &mysql_home_ptr, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"big-tables", OPT_BIG_TABLES,
-+ "Allow big result sets by saving all temporary sets on file (solves most 'table full' errors).",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"bind-address", OPT_BIND_ADDRESS, "IP address to bind to.",
-+ &my_bind_addr_str, &my_bind_addr_str, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"binlog_format", OPT_BINLOG_FORMAT,
-+ "Does not have any effect without '--log-bin'. "
-+ "Tell the master the form of binary logging to use: either 'row' for "
-+ "row-based binary logging, 'statement' for statement-based binary "
-+ "logging, or 'mixed'. 'mixed' is statement-based binary logging except "
-+ "for statements where only row-based is correct: Statements that involve "
-+ "user-defined functions (i.e., UDFs) or the UUID() function."
-+#ifdef HAVE_NDB_BINLOG
-+ "If ndbcluster is enabled and binlog_format is `mixed', the format switches"
-+ " to 'row' and back implicitly per each query accessing a NDB table."
-+#endif
-+ , &opt_binlog_format, &opt_binlog_format,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"binlog-do-db", OPT_BINLOG_DO_DB,
-+ "Tells the master it should log updates for the specified database, "
-+ "and exclude all others not explicitly mentioned.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"binlog-ignore-db", OPT_BINLOG_IGNORE_DB,
-+ "Tells the master that updates to the given database should not be logged to the binary log.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"binlog-row-event-max-size", OPT_BINLOG_ROWS_EVENT_MAX_SIZE,
-+ "The maximum size of a row-based binary log event in bytes. Rows will be "
-+ "grouped into events smaller than this size if possible. "
-+ "The value has to be a multiple of 256.",
-+ &opt_binlog_rows_event_max_size, &opt_binlog_rows_event_max_size,
-+ 0, GET_ULONG, REQUIRED_ARG,
-+ /* def_value */ 1024, /* min_value */ 256, /* max_value */ ULONG_MAX,
-+ /* sub_size */ 0, /* block_size */ 256,
-+ /* app_type */ 0
-+ },
-+#ifndef DISABLE_GRANT_OPTIONS
-+ {"bootstrap", OPT_BOOTSTRAP, "Used by mysql installation scripts.", 0, 0, 0,
-+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"character-set-client-handshake", OPT_CHARACTER_SET_CLIENT_HANDSHAKE,
-+ "Don't ignore client side character set value sent during handshake.",
-+ &opt_character_set_client_handshake,
-+ &opt_character_set_client_handshake,
-+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-+ {"character-set-filesystem", OPT_CHARACTER_SET_FILESYSTEM,
-+ "Set the filesystem character set.",
-+ &character_set_filesystem_name,
-+ &character_set_filesystem_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"character-set-server", 'C', "Set the default character set.",
-+ &default_character_set_name, &default_character_set_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"character-sets-dir", OPT_CHARSETS_DIR,
-+ "Directory where character sets are.", &charsets_dir,
-+ &charsets_dir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"chroot", 'r', "Chroot mysqld daemon during startup.",
-+ &mysqld_chroot, &mysqld_chroot, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"collation-server", OPT_DEFAULT_COLLATION, "Set the default collation.",
-+ &default_collation_name, &default_collation_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"completion-type", OPT_COMPLETION_TYPE, "Default completion type.",
-+ &global_system_variables.completion_type,
-+ &max_system_variables.completion_type, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, 2, 0, 1, 0},
-+ {"concurrent-insert", OPT_CONCURRENT_INSERT,
-+ "Use concurrent insert with MyISAM. Disable with --concurrent-insert=0.",
-+ &myisam_concurrent_insert, &myisam_concurrent_insert,
-+ 0, GET_ULONG, OPT_ARG, 1, 0, 2, 0, 0, 0},
-+ {"console", OPT_CONSOLE, "Write error output on screen; don't remove the console window on windows.",
-+ &opt_console, &opt_console, 0, GET_BOOL, NO_ARG, 0, 0, 0,
-+ 0, 0, 0},
-+ {"core-file", OPT_WANT_CORE, "Write core on errors.", 0, 0, 0, GET_NO_ARG,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"datadir", 'h', "Path to the database root.", &mysql_data_home,
-+ &mysql_data_home, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef DBUG_OFF
-+ {"debug", '#', "Debug log.", &default_dbug_option,
-+ &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"default-character-set", OPT_DEFAULT_CHARACTER_SET_OLD,
-+ "Set the default character set (deprecated option, use --character-set-server instead).",
-+ &default_character_set_name, &default_character_set_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"default-collation", OPT_DEFAULT_COLLATION_OLD, "Set the default collation "
-+ "(deprecated option, use --collation-server instead).",
-+ &default_collation_name, &default_collation_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"default-storage-engine", OPT_STORAGE_ENGINE,
-+ "Set the default storage engine (table type) for tables.",
-+ &default_storage_engine_str, &default_storage_engine_str,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"default-table-type", OPT_STORAGE_ENGINE,
-+ "(deprecated) Use --default-storage-engine.",
-+ &default_storage_engine_str, &default_storage_engine_str,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"default-time-zone", OPT_DEFAULT_TIME_ZONE, "Set the default time zone.",
-+ &default_tz_name, &default_tz_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"delay-key-write", OPT_DELAY_KEY_WRITE, "Type of DELAY_KEY_WRITE.",
-+ 0,0,0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"delay-key-write-for-all-tables", OPT_DELAY_KEY_WRITE_ALL,
-+ "Don't flush key buffers between writes for any MyISAM table. "
-+ "(Deprecated option, use --delay-key-write=all instead.)",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_OPENSSL
-+ {"des-key-file", OPT_DES_KEY_FILE,
-+ "Load keys for des_encrypt() and des_encrypt from given file.",
-+ &des_key_file, &des_key_file, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+#endif /* HAVE_OPENSSL */
-+#ifdef HAVE_REPLICATION
-+ {"disconnect-slave-event-count", OPT_DISCONNECT_SLAVE_EVENT_COUNT,
-+ "Option used by mysql-test for debugging and testing of replication.",
-+ &disconnect_slave_event_count, &disconnect_slave_event_count,
-+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#endif /* HAVE_REPLICATION */
-+ {"enable-locking", OPT_ENABLE_LOCK,
-+ "Deprecated option, use --external-locking instead.",
-+ &opt_external_locking, &opt_external_locking,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef __NT__
-+ {"enable-named-pipe", OPT_HAVE_NAMED_PIPE, "Enable the named pipe (NT).",
-+ &opt_enable_named_pipe, &opt_enable_named_pipe, 0, GET_BOOL,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+#ifdef HAVE_STACK_TRACE_ON_SEGV
-+ {"enable-pstack", OPT_DO_PSTACK, "Print a symbolic stack trace on failure. "
-+ "This option is deprecated and has no effect; a symbolic stack trace will "
-+ "be printed after a crash whenever possible.", &opt_do_pstack, &opt_do_pstack,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif /* HAVE_STACK_TRACE_ON_SEGV */
-+ {"engine-condition-pushdown",
-+ OPT_ENGINE_CONDITION_PUSHDOWN,
-+ "Push supported query conditions to the storage engine.",
-+ &global_system_variables.engine_condition_pushdown,
-+ &global_system_variables.engine_condition_pushdown,
-+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
-+ /* See how it's handled in get_one_option() */
-+ {"event-scheduler", OPT_EVENT_SCHEDULER, "Enable/disable the event scheduler.",
-+ NULL, NULL, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"exit-info", 'T', "Used for debugging. Use at your own risk.", 0, 0, 0,
-+ GET_LONG, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"external-locking", OPT_USE_LOCKING, "Use system (external) locking "
-+ "(disabled by default). With this option enabled you can run myisamchk "
-+ "to test (not repair) tables while the MySQL server is running. "
-+ "Disable with --skip-external-locking.",
-+ &opt_external_locking, &opt_external_locking,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"flush", OPT_FLUSH, "Flush tables to disk between SQL commands.", 0, 0, 0,
-+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ /* We must always support the next option to make scripts like mysqltest
-+ easier to do */
-+ {"gdb", OPT_DEBUGGING,
-+ "Set up signals usable for debugging.",
-+ &opt_debugging, &opt_debugging,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"general_log", OPT_GENERAL_LOG,
-+ "Enable/disable general log.", &opt_log,
-+ &opt_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_LARGE_PAGES
-+ {"large-pages", OPT_ENABLE_LARGE_PAGES, "Enable support for large pages. "
-+ "Disable with --skip-large-pages.", &opt_large_pages, &opt_large_pages,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"ignore-builtin-innodb", OPT_IGNORE_BUILTIN_INNODB ,
-+ "Disable initialization of builtin InnoDB plugin.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"init-connect", OPT_INIT_CONNECT,
-+ "Command(s) that are executed for each new connection.",
-+ &opt_init_connect, &opt_init_connect, 0, GET_STR_ALLOC,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef DISABLE_GRANT_OPTIONS
-+ {"init-file", OPT_INIT_FILE, "Read SQL commands from this file at startup.",
-+ &opt_init_file, &opt_init_file, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"init-rpl-role", OPT_INIT_RPL_ROLE, "Set the replication role.", 0, 0, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"init-slave", OPT_INIT_SLAVE, "Command(s) that are executed by a slave server \
-+each time the SQL thread starts.",
-+ &opt_init_slave, &opt_init_slave, 0, GET_STR_ALLOC,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"language", 'L',
-+ "Client error messages in given language. May be given as a full path.",
-+ &language_ptr, &language_ptr, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"lc-time-names", OPT_LC_TIME_NAMES,
-+ "Set the language used for the month names and the days of the week.",
-+ &lc_time_names_name, &lc_time_names_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-+ {"local-infile", OPT_LOCAL_INFILE,
-+ "Enable/disable LOAD DATA LOCAL INFILE (takes values 1 or 0).",
-+ &opt_local_infile, &opt_local_infile, 0, GET_BOOL, OPT_ARG,
-+ 1, 0, 0, 0, 0, 0},
-+ {"log", 'l', "Log connections and queries to file (deprecated option, use "
-+ "--general_log/--general_log_file instead).", &opt_logname,
-+ &opt_logname, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"general_log_file", OPT_GENERAL_LOG_FILE,
-+ "Log connections and queries to given file.", &opt_logname,
-+ &opt_logname, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-bin", OPT_BIN_LOG,
-+ "Log update queries in binary format. Optional (but strongly recommended "
-+ "to avoid replication problems if server's hostname changes) argument "
-+ "should be the chosen location for the binary log files.",
-+ &opt_bin_logname, &opt_bin_logname, 0, GET_STR_ALLOC,
-+ OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-bin-index", OPT_BIN_LOG_INDEX,
-+ "File that holds the names for last binary log files.",
-+ &opt_binlog_index_name, &opt_binlog_index_name, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef TO_BE_REMOVED_IN_5_1_OR_6_0
-+ /*
-+ In 5.0.6 we introduced the below option, then in 5.0.16 we renamed it to
-+ log-bin-trust-function-creators but kept also the old name for
-+ compatibility; the behaviour was also changed to apply only to functions
-+ (and triggers). In a future release this old name could be removed.
-+ */
-+ {"log-bin-trust-routine-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD,
-+ "(deprecated) Use log-bin-trust-function-creators.",
-+ &trust_function_creators, &trust_function_creators, 0,
-+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ /*
-+ This option starts with "log-bin" to emphasize that it is specific of
-+ binary logging.
-+ */
-+ {"log-bin-trust-function-creators", OPT_LOG_BIN_TRUST_FUNCTION_CREATORS,
-+ "If equal to 0 (the default), then when --log-bin is used, creation of "
-+ "a stored function (or trigger) is allowed only to users having the SUPER "
-+ "privilege, and only if this stored function (trigger) may not break "
-+ "binary logging."
-+ "Note that if ALL connections to this server ALWAYS use row-based binary "
-+ "logging, the security issues do not exist and the binary logging cannot "
-+ "break, so you can safely set this to 1."
-+ ,&trust_function_creators, &trust_function_creators, 0,
-+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-error", OPT_ERROR_LOG_FILE, "Error log file.",
-+ &log_error_file_ptr, &log_error_file_ptr, 0, GET_STR,
-+ OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-isam", OPT_ISAM_LOG, "Log all MyISAM changes to file.",
-+ &myisam_log_filename, &myisam_log_filename, 0, GET_STR,
-+ OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-long-format", '0',
-+ "Log some extra information to update log. Please note that this option "
-+ "is deprecated; see --log-short-format option.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef WITH_CSV_STORAGE_ENGINE
-+ {"log-output", OPT_LOG_OUTPUT,
-+ "Syntax: log-output[=value[,value...]], where \"value\" could be TABLE, "
-+ "FILE or NONE.",
-+ &log_output_str, &log_output_str, 0,
-+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"log-queries-not-using-indexes", OPT_LOG_QUERIES_NOT_USING_INDEXES,
-+ "Log queries that are executed without benefit of any index to the slow log if it is open.",
-+ &opt_log_queries_not_using_indexes, &opt_log_queries_not_using_indexes,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-short-format", OPT_SHORT_LOG_FORMAT,
-+ "Don't log extra information to update and slow-query logs.",
-+ &opt_short_log_format, &opt_short_log_format,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-slave-updates", OPT_LOG_SLAVE_UPDATES,
-+ "Tells the slave to log the updates from the slave thread to the binary log. "
-+ "You will need to turn it on if you plan to daisy-chain the slaves.",
-+ &opt_log_slave_updates, &opt_log_slave_updates, 0, GET_BOOL,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-slow-admin-statements", OPT_LOG_SLOW_ADMIN_STATEMENTS,
-+ "Log slow OPTIMIZE, ANALYZE, ALTER and other administrative statements "
-+ "to the slow log if it is open.", &opt_log_slow_admin_statements,
-+ &opt_log_slow_admin_statements, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-slow-slave-statements", OPT_LOG_SLOW_SLAVE_STATEMENTS,
-+ "Log slow statements executed by slave thread to the slow log if it is open.",
-+ &opt_log_slow_slave_statements,
-+ &opt_log_slow_slave_statements,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log_slow_queries", OPT_SLOW_QUERY_LOG,
-+ "Log slow queries to a table or log file. Defaults logging to table "
-+ "mysql.slow_log or hostname-slow.log if --log-output=file is used. "
-+ "Must be enabled to activate other slow log options. "
-+ "(deprecated option, use --slow_query_log/--slow_query_log_file instead)",
-+ &opt_slow_logname, &opt_slow_logname, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"slow_query_log_file", OPT_SLOW_QUERY_LOG_FILE,
-+ "Log slow queries to given log file. Defaults logging to hostname-slow.log. "
-+ "Must be enabled to activate other slow log options.",
-+ &opt_slow_logname, &opt_slow_logname, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-tc", OPT_LOG_TC,
-+ "Path to transaction coordinator log (used for transactions that affect "
-+ "more than one storage engine, when binary log is disabled).",
-+ &opt_tc_log_file, &opt_tc_log_file, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_MMAP
-+ {"log-tc-size", OPT_LOG_TC_SIZE, "Size of transaction coordinator log.",
-+ &opt_tc_log_size, &opt_tc_log_size, 0, GET_ULONG,
-+ REQUIRED_ARG, TC_LOG_MIN_SIZE, TC_LOG_MIN_SIZE, ULONG_MAX, 0,
-+ TC_LOG_PAGE_SIZE, 0},
-+#endif
-+ {"log-update", OPT_UPDATE_LOG,
-+ "The update log is deprecated since version 5.0, is replaced by the binary "
-+ "log and this option just turns on --log-bin instead.",
-+ &opt_update_logname, &opt_update_logname, 0, GET_STR,
-+ OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"log-warnings", 'W', "Log some not critical warnings to the log file.",
-+ &global_system_variables.log_warnings,
-+ &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0,
-+ 0, 0, 0},
-+ {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES,
-+ "INSERT/DELETE/UPDATE has lower priority than selects.",
-+ &global_system_variables.low_priority_updates,
-+ &max_system_variables.low_priority_updates,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"master-connect-retry", OPT_MASTER_CONNECT_RETRY,
-+ "The number of seconds the slave thread will sleep before retrying to "
-+ "connect to the master, in case the master goes down or the connection "
-+ "is lost.",
-+ &master_connect_retry, &master_connect_retry, 0, GET_UINT,
-+ REQUIRED_ARG, 60, 0, 0, 0, 0, 0},
-+ {"master-host", OPT_MASTER_HOST,
-+ "Master hostname or IP address for replication. If not set, the slave "
-+ "thread will not be started. Note that the setting of master-host will "
-+ "be ignored if there exists a valid master.info file.",
-+ &master_host, &master_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
-+ 0, 0, 0, 0},
-+ {"master-info-file", OPT_MASTER_INFO_FILE,
-+ "The location and name of the file that remembers the master and where "
-+ "the I/O replication thread is in the master's binlogs.",
-+ &master_info_file, &master_info_file, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"master-password", OPT_MASTER_PASSWORD,
-+ "The password the slave thread will authenticate with when connecting to "
-+ "the master. If not set, an empty password is assumed. The value in "
-+ "master.info will take precedence if it can be read.",
-+ &master_password, &master_password, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"master-port", OPT_MASTER_PORT,
-+ "The port the master is listening on. If not set, the compiled setting of "
-+ "MYSQL_PORT is assumed. If you have not tinkered with configure options, "
-+ "this should be 3306. The value in master.info will take precedence if it "
-+ "can be read.", &master_port, &master_port, 0, GET_UINT, REQUIRED_ARG,
-+ MYSQL_PORT, 0, 0, 0, 0, 0},
-+ {"master-retry-count", OPT_MASTER_RETRY_COUNT,
-+ "The number of tries the slave will make to connect to the master before giving up.",
-+ &master_retry_count, &master_retry_count, 0, GET_ULONG,
-+ REQUIRED_ARG, 3600*24, 0, 0, 0, 0, 0},
-+ {"master-ssl", OPT_MASTER_SSL,
-+ "Enable the slave to connect to the master using SSL.",
-+ &master_ssl, &master_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
-+ 0, 0},
-+ {"master-ssl-ca", OPT_MASTER_SSL_CA,
-+ "Master SSL CA file. Only applies if you have enabled master-ssl.",
-+ &master_ssl_ca, &master_ssl_ca, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"master-ssl-capath", OPT_MASTER_SSL_CAPATH,
-+ "Master SSL CA path. Only applies if you have enabled master-ssl.",
-+ &master_ssl_capath, &master_ssl_capath, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"master-ssl-cert", OPT_MASTER_SSL_CERT,
-+ "Master SSL certificate file name. Only applies if you have enabled "
-+ "master-ssl.",
-+ &master_ssl_cert, &master_ssl_cert, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"master-ssl-cipher", OPT_MASTER_SSL_CIPHER,
-+ "Master SSL cipher. Only applies if you have enabled master-ssl.",
-+ &master_ssl_cipher, &master_ssl_capath, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"master-ssl-key", OPT_MASTER_SSL_KEY,
-+ "Master SSL keyfile name. Only applies if you have enabled master-ssl.",
-+ &master_ssl_key, &master_ssl_key, 0, GET_STR, OPT_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"master-user", OPT_MASTER_USER,
-+ "The username the slave thread will use for authentication when "
-+ "connecting to the master. The user must have FILE privilege. "
-+ "If the master user is not set, user test is assumed. The value "
-+ "in master.info will take precedence if it can be read.",
-+ &master_user, &master_user, 0, GET_STR, REQUIRED_ARG, 0, 0,
-+ 0, 0, 0, 0},
-+#ifdef HAVE_REPLICATION
-+ {"max-binlog-dump-events", OPT_MAX_BINLOG_DUMP_EVENTS,
-+ "Option used by mysql-test for debugging and testing of replication.",
-+ &max_binlog_dump_events, &max_binlog_dump_events, 0,
-+ GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#endif /* HAVE_REPLICATION */
-+ {"memlock", OPT_MEMLOCK, "Lock mysqld in memory.", &locked_in_memory,
-+ &locked_in_memory, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"myisam-recover", OPT_MYISAM_RECOVER,
-+ "Syntax: myisam-recover[=option[,option...]], where option can be DEFAULT, BACKUP, FORCE or QUICK.",
-+ &myisam_recover_options_str, &myisam_recover_options_str, 0,
-+ GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+ {"ndb-connectstring", OPT_NDB_CONNECTSTRING,
-+ "Connect string for ndbcluster.",
-+ &opt_ndb_connectstring, &opt_ndb_connectstring,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"ndb-mgmd-host", OPT_NDB_MGMD,
-+ "Set host and port for ndb_mgmd. Syntax: hostname[:port]",
-+ &opt_ndb_mgmd, &opt_ndb_mgmd,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"ndb-nodeid", OPT_NDB_NODEID,
-+ "Nodeid for this mysqlserver in the cluster.",
-+ &opt_ndb_nodeid,
-+ &opt_ndb_nodeid,
-+ 0, GET_INT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"ndb-autoincrement-prefetch-sz", OPT_NDB_AUTOINCREMENT_PREFETCH_SZ,
-+ "Specify number of autoincrement values that are prefetched.",
-+ &global_system_variables.ndb_autoincrement_prefetch_sz,
-+ &max_system_variables.ndb_autoincrement_prefetch_sz,
-+ 0, GET_ULONG, REQUIRED_ARG, 1, 1, 256, 0, 0, 0},
-+ {"ndb-force-send", OPT_NDB_FORCE_SEND,
-+ "Force send of buffers to ndb immediately without waiting for "
-+ "other threads.",
-+ &global_system_variables.ndb_force_send,
-+ &global_system_variables.ndb_force_send,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb_force_send", OPT_NDB_FORCE_SEND,
-+ "same as --ndb-force-send.",
-+ &global_system_variables.ndb_force_send,
-+ &global_system_variables.ndb_force_send,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb-extra-logging", OPT_NDB_EXTRA_LOGGING,
-+ "Turn on more logging in the error log.",
-+ &ndb_extra_logging,
-+ &ndb_extra_logging,
-+ 0, GET_INT, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_NDB_BINLOG
-+ {"ndb-report-thresh-binlog-epoch-slip", OPT_NDB_REPORT_THRESH_BINLOG_EPOCH_SLIP,
-+ "Threshold on number of epochs to be behind before reporting binlog status. "
-+ "E.g., 3 means that if the difference between what epoch has been received "
-+ "from the storage nodes and what has been applied to the binlog is 3 or more, "
-+ "a status message will be sent to the cluster log.",
-+ &ndb_report_thresh_binlog_epoch_slip,
-+ &ndb_report_thresh_binlog_epoch_slip,
-+ 0, GET_ULONG, REQUIRED_ARG, 3, 0, 256, 0, 0, 0},
-+ {"ndb-report-thresh-binlog-mem-usage", OPT_NDB_REPORT_THRESH_BINLOG_MEM_USAGE,
-+ "Threshold on percentage of free memory before reporting binlog status. E.g., "
-+ "10 means that if amount of available memory for receiving binlog data from "
-+ "the storage nodes goes below 10%, "
-+ "a status message will be sent to the cluster log.",
-+ &ndb_report_thresh_binlog_mem_usage,
-+ &ndb_report_thresh_binlog_mem_usage,
-+ 0, GET_ULONG, REQUIRED_ARG, 10, 0, 100, 0, 0, 0},
-+#endif
-+ {"ndb-use-exact-count", OPT_NDB_USE_EXACT_COUNT,
-+ "Use exact records count during query planning and for fast "
-+ "select count(*), disable for faster queries.",
-+ &global_system_variables.ndb_use_exact_count,
-+ &global_system_variables.ndb_use_exact_count,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb_use_exact_count", OPT_NDB_USE_EXACT_COUNT,
-+ "Same as --ndb-use-exact-count.",
-+ &global_system_variables.ndb_use_exact_count,
-+ &global_system_variables.ndb_use_exact_count,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb-use-transactions", OPT_NDB_USE_TRANSACTIONS,
-+ "Use transactions for large inserts, if enabled then large "
-+ "inserts will be split into several smaller transactions",
-+ &global_system_variables.ndb_use_transactions,
-+ &global_system_variables.ndb_use_transactions,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb_use_transactions", OPT_NDB_USE_TRANSACTIONS,
-+ "Same as --ndb-use-transactions.",
-+ &global_system_variables.ndb_use_transactions,
-+ &global_system_variables.ndb_use_transactions,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ {"ndb-shm", OPT_NDB_SHM,
-+ "Use shared memory connections when available.",
-+ &opt_ndb_shm, &opt_ndb_shm,
-+ 0, GET_BOOL, OPT_ARG, OPT_NDB_SHM_DEFAULT, 0, 0, 0, 0, 0},
-+ {"ndb-optimized-node-selection", OPT_NDB_OPTIMIZED_NODE_SELECTION,
-+ "Select nodes for transactions in a more optimal way.",
-+ &opt_ndb_optimized_node_selection,
-+ &opt_ndb_optimized_node_selection,
-+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
-+ { "ndb-cache-check-time", OPT_NDB_CACHE_CHECK_TIME,
-+ "A dedicated thread is created to, at the given milliseconds interval, "
-+ "invalidate the query cache if another MySQL server in the cluster has "
-+ "changed the data in the database.",
-+ &opt_ndb_cache_check_time, &opt_ndb_cache_check_time, 0, GET_ULONG, REQUIRED_ARG,
-+ 0, 0, LONG_TIMEOUT, 0, 1, 0},
-+ {"ndb-index-stat-enable", OPT_NDB_INDEX_STAT_ENABLE,
-+ "Use ndb index statistics in query optimization.",
-+ &global_system_variables.ndb_index_stat_enable,
-+ &max_system_variables.ndb_index_stat_enable,
-+ 0, GET_BOOL, OPT_ARG, 0, 0, 1, 0, 0, 0},
-+#endif
-+ {"ndb-use-copying-alter-table",
-+ OPT_NDB_USE_COPYING_ALTER_TABLE,
-+ "Force ndbcluster to always copy tables at alter table "
-+ "(should only be used if on-line alter table fails).",
-+ &global_system_variables.ndb_use_copying_alter_table,
-+ &global_system_variables.ndb_use_copying_alter_table,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"new", 'n', "Use very new, possibly 'unsafe', functions.",
-+ &global_system_variables.new_mode,
-+ &max_system_variables.new_mode,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef NOT_YET
-+ {"no-mix-table-types", OPT_NO_MIX_TYPE,
-+ "Don't allow commands that use two different table types.",
-+ &opt_no_mix_types, &opt_no_mix_types, 0, GET_BOOL, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"old-alter-table", OPT_OLD_ALTER_TABLE,
-+ "Use old, non-optimized alter table.",
-+ &global_system_variables.old_alter_table,
-+ &max_system_variables.old_alter_table, 0, GET_BOOL, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"old-passwords", OPT_OLD_PASSWORDS, "Use old password "
-+ "encryption method (needed for 4.0 and older clients).",
-+ &global_system_variables.old_passwords,
-+ &max_system_variables.old_passwords, 0, GET_BOOL, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"one-thread", OPT_ONE_THREAD,
-+ "(Deprecated): Only use one thread (for debugging under Linux). Use "
-+ "thread-handling=no-threads instead.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"old-style-user-limits", OPT_OLD_STYLE_USER_LIMITS,
-+ "Enable old-style user limits (before 5.0.3, user resources were counted "
-+ "per each user+host vs. per account).",
-+ &opt_old_style_user_limits, &opt_old_style_user_limits,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"pid-file", OPT_PID_FILE, "Pid file used by safe_mysqld.",
-+ &pidfile_name_ptr, &pidfile_name_ptr, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"port", 'P', "Port number to use for connection or 0 for default to, in "
-+ "order of preference, my.cnf, $MYSQL_TCP_PORT, "
-+#if MYSQL_PORT_DEFAULT == 0
-+ "/etc/services, "
-+#endif
-+ "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").",
-+ &mysqld_port,
-+ &mysqld_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"port-open-timeout", OPT_PORT_OPEN_TIMEOUT,
-+ "Maximum time in seconds to wait for the port to become free. "
-+ "(Default: No wait).", &mysqld_port_timeout,
-+ &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory.",
-+ &global_system_variables.profiling_history_size,
-+ &max_system_variables.profiling_history_size,
-+ 0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
-+#endif
-+ {"relay-log", OPT_RELAY_LOG,
-+ "The location and name to use for relay logs.",
-+ &opt_relay_logname, &opt_relay_logname, 0,
-+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"relay-log-index", OPT_RELAY_LOG_INDEX,
-+ "The location and name to use for the file that keeps a list of the last \
-+relay logs.",
-+ &opt_relaylog_index_name, &opt_relaylog_index_name, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"relay-log-info-file", OPT_RELAY_LOG_INFO_FILE,
-+ "The location and name of the file that remembers where the SQL replication \
-+thread is in the relay logs.",
-+ &relay_log_info_file, &relay_log_info_file, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-do-db", OPT_REPLICATE_DO_DB,
-+ "Tells the slave thread to restrict replication to the specified database. "
-+ "To specify more than one database, use the directive multiple times, "
-+ "once for each database. Note that this will only work if you do not use "
-+ "cross-database queries such as UPDATE some_db.some_table SET foo='bar' "
-+ "while having selected a different or no database. If you need cross "
-+ "database updates to work, make sure you have 3.23.28 or later, and use "
-+ "replicate-wild-do-table=db_name.%.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-do-table", OPT_REPLICATE_DO_TABLE,
-+ "Tells the slave thread to restrict replication to the specified table. "
-+ "To specify more than one table, use the directive multiple times, once "
-+ "for each table. This will work for cross-database updates, in contrast "
-+ "to replicate-do-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-ignore-db", OPT_REPLICATE_IGNORE_DB,
-+ "Tells the slave thread to not replicate to the specified database. To "
-+ "specify more than one database to ignore, use the directive multiple "
-+ "times, once for each database. This option will not work if you use "
-+ "cross database updates. If you need cross database updates to work, "
-+ "make sure you have 3.23.28 or later, and use replicate-wild-ignore-"
-+ "table=db_name.%. ", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-ignore-table", OPT_REPLICATE_IGNORE_TABLE,
-+ "Tells the slave thread to not replicate to the specified table. To specify "
-+ "more than one table to ignore, use the directive multiple times, once for "
-+ "each table. This will work for cross-database updates, in contrast to "
-+ "replicate-ignore-db.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-rewrite-db", OPT_REPLICATE_REWRITE_DB,
-+ "Updates to a database with a different name than the original. Example: "
-+ "replicate-rewrite-db=master_db_name->slave_db_name.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_REPLICATION
-+ {"replicate-same-server-id", OPT_REPLICATE_SAME_SERVER_ID,
-+ "In replication, if set to 1, do not skip events having our server id. "
-+ "Default value is 0 (to break infinite loops in circular replication). "
-+ "Can't be set to 1 if --log-slave-updates is used.",
-+ &replicate_same_server_id, &replicate_same_server_id,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"replicate-wild-do-table", OPT_REPLICATE_WILD_DO_TABLE,
-+ "Tells the slave thread to restrict replication to the tables that match "
-+ "the specified wildcard pattern. To specify more than one table, use the "
-+ "directive multiple times, once for each table. This will work for cross-"
-+ "database updates. Example: replicate-wild-do-table=foo%.bar% will "
-+ "replicate only updates to tables in all databases that start with foo "
-+ "and whose table names start with bar.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"replicate-wild-ignore-table", OPT_REPLICATE_WILD_IGNORE_TABLE,
-+ "Tells the slave thread to not replicate to the tables that match the "
-+ "given wildcard pattern. To specify more than one table to ignore, use "
-+ "the directive multiple times, once for each table. This will work for "
-+ "cross-database updates. Example: replicate-wild-ignore-table=foo%.bar% "
-+ "will not do updates to tables in databases that start with foo and whose "
-+ "table names start with bar.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ // In replication, we may need to tell the other servers how to connect
-+ {"report-host", OPT_REPORT_HOST,
-+ "Hostname or IP of the slave to be reported to the master during slave "
-+ "registration. Will appear in the output of SHOW SLAVE HOSTS. Leave unset "
-+ "if you do not want the slave to register itself with the master. Note that "
-+ "it is not sufficient for the master to simply read the IP of the slave "
-+ "from the socket once the slave connects. Due to NAT and other routing "
-+ "issues, that IP may not be valid for connecting to the slave from the "
-+ "master or other hosts.",
-+ &report_host, &report_host, 0, GET_STR, REQUIRED_ARG, 0, 0,
-+ 0, 0, 0, 0},
-+ {"report-password", OPT_REPORT_PASSWORD, "Undocumented.",
-+ &report_password, &report_password, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"report-port", OPT_REPORT_PORT,
-+ "Port for connecting to slave reported to the master during slave "
-+ "registration. Set it only if the slave is listening on a non-default "
-+ "port or if you have a special tunnel from the master or other clients "
-+ "to the slave. If not sure, leave this option unset.",
-+ &report_port, &report_port, 0, GET_UINT, REQUIRED_ARG,
-+ MYSQL_PORT, 0, 0, 0, 0, 0},
-+ {"report-user", OPT_REPORT_USER, "Undocumented.", &report_user,
-+ &report_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"rpl-recovery-rank", OPT_RPL_RECOVERY_RANK, "Undocumented.",
-+ &rpl_recovery_rank, &rpl_recovery_rank, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef TO_BE_DELETED
-+ {"safe-show-database", OPT_SAFE_SHOW_DB,
-+ "Deprecated option; use GRANT SHOW DATABASES instead.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"safe-user-create", OPT_SAFE_USER_CREATE,
-+ "Don't allow new user creation by the user who has no write privileges to the mysql.user table.",
-+ &opt_safe_user_create, &opt_safe_user_create, 0, GET_BOOL,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"safemalloc-mem-limit", OPT_SAFEMALLOC_MEM_LIMIT,
-+ "Simulate memory shortage when compiled with the --with-debug=full option.",
-+ 0, 0, 0, GET_ULL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"secure-auth", OPT_SECURE_AUTH, "Disallow authentication for accounts that have old (pre-4.1) passwords.",
-+ &opt_secure_auth, &opt_secure_auth, 0, GET_BOOL, NO_ARG,
-+ my_bool(0), 0, 0, 0, 0, 0},
-+ {"secure-file-priv", OPT_SECURE_FILE_PRIV,
-+ "Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory.",
-+ &opt_secure_file_priv, &opt_secure_file_priv, 0,
-+ GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"server-id", OPT_SERVER_ID,
-+ "Uniquely identifies the server instance in the community of replication partners.",
-+ &server_id, &server_id, 0, GET_ULONG, REQUIRED_ARG, 0, 0, UINT_MAX32,
-+ 0, 0, 0},
-+ {"set-variable", 'O',
-+ "Change the value of a variable. Please note that this option is deprecated; "
-+ "you can set variables directly with --variable-name=value.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_SMEM
-+ {"shared-memory", OPT_ENABLE_SHARED_MEMORY,
-+ "Enable the shared memory.",&opt_enable_shared_memory, &opt_enable_shared_memory,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+#ifdef HAVE_SMEM
-+ {"shared-memory-base-name",OPT_SHARED_MEMORY_BASE_NAME,
-+ "Base name of shared memory.", &shared_memory_base_name, &shared_memory_base_name,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"show-slave-auth-info", OPT_SHOW_SLAVE_AUTH_INFO,
-+ "Show user and password in SHOW SLAVE HOSTS on this master.",
-+ &opt_show_slave_auth_info, &opt_show_slave_auth_info, 0,
-+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef DISABLE_GRANT_OPTIONS
-+ {"skip-grant-tables", OPT_SKIP_GRANT,
-+ "Start without grant tables. This gives all users FULL ACCESS to all tables.",
-+ &opt_noacl, &opt_noacl, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
-+ 0},
-+#endif
-+ {"skip-host-cache", OPT_SKIP_HOST_CACHE, "Don't cache host names.", 0, 0, 0,
-+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"skip-locking", OPT_SKIP_LOCK,
-+ "Deprecated option, use --skip-external-locking instead.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"skip-name-resolve", OPT_SKIP_RESOLVE,
-+ "Don't resolve hostnames. All hostnames are IP's or 'localhost'.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"skip-networking", OPT_SKIP_NETWORKING,
-+ "Don't allow connection with TCP/IP.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0,
-+ 0, 0, 0},
-+ {"skip-new", OPT_SKIP_NEW, "Don't use new, possibly wrong routines.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+#ifndef DBUG_OFF
-+#ifdef SAFEMALLOC
-+ {"skip-safemalloc", OPT_SKIP_SAFEMALLOC,
-+ "Don't use the memory allocation checking.", 0, 0, 0, GET_NO_ARG, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+#endif
-+#endif
-+ {"skip-show-database", OPT_SKIP_SHOW_DB,
-+ "Don't allow 'SHOW DATABASE' commands.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
-+ 0, 0, 0, 0},
-+ {"skip-slave-start", OPT_SKIP_SLAVE_START,
-+ "If set, slave is not autostarted.", &opt_skip_slave_start,
-+ &opt_skip_slave_start, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"skip-stack-trace", OPT_SKIP_STACK_TRACE,
-+ "Don't print a stack trace on failure.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0,
-+ 0, 0, 0, 0},
-+ {"skip-symlink", OPT_SKIP_SYMLINKS, "Don't allow symlinking of tables. "
-+ "Deprecated option. Use --skip-symbolic-links instead.",
-+ 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"skip-thread-priority", OPT_SKIP_PRIOR,
-+ "Don't give threads different priorities. Deprecated option.", 0, 0, 0, GET_NO_ARG, NO_ARG,
-+ DEFAULT_SKIP_THREAD_PRIORITY, 0, 0, 0, 0, 0},
-+#ifdef HAVE_REPLICATION
-+ {"slave-load-tmpdir", OPT_SLAVE_LOAD_TMPDIR,
-+ "The location where the slave should put its temporary files when "
-+ "replicating a LOAD DATA INFILE command.",
-+ &slave_load_tmpdir, &slave_load_tmpdir, 0, GET_STR_ALLOC,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"slave-skip-errors", OPT_SLAVE_SKIP_ERRORS,
-+ "Tells the slave thread to continue replication when a query event returns an error from the provided list.",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"slave-exec-mode", OPT_SLAVE_EXEC_MODE,
-+ "Modes for how replication events should be executed. Legal values are "
-+ "STRICT (default) and IDEMPOTENT. In IDEMPOTENT mode, replication will "
-+ "not stop for operations that are idempotent. In STRICT mode, replication "
-+ "will stop on any unexpected difference between the master and the slave.",
-+ &slave_exec_mode_str, &slave_exec_mode_str, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"slow-query-log", OPT_SLOW_LOG,
-+ "Enable/disable slow query log.", &opt_slow_log,
-+ &opt_slow_log, 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"socket", OPT_SOCKET, "Socket file to use for connection.",
-+ &mysqld_unix_port, &mysqld_unix_port, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#ifdef HAVE_REPLICATION
-+ {"sporadic-binlog-dump-fail", OPT_SPORADIC_BINLOG_DUMP_FAIL,
-+ "Option used by mysql-test for debugging and testing of replication.",
-+ &opt_sporadic_binlog_dump_fail,
-+ &opt_sporadic_binlog_dump_fail, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0,
-+ 0},
-+#endif /* HAVE_REPLICATION */
-+ {"sql-bin-update-same", OPT_SQL_BIN_UPDATE_SAME,
-+ "The update log is deprecated since version 5.0, is replaced by the "
-+ "binary log and this option does nothing anymore.",
-+ 0, 0, 0, GET_DISABLED, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"sql-mode", OPT_SQL_MODE,
-+ "Syntax: sql-mode=option[,option[,option...]] where option can be one "
-+ "of: REAL_AS_FLOAT, PIPES_AS_CONCAT, ANSI_QUOTES, IGNORE_SPACE, "
-+ "ONLY_FULL_GROUP_BY, NO_UNSIGNED_SUBTRACTION.",
-+ &sql_mode_str, &sql_mode_str, 0, GET_STR, REQUIRED_ARG, 0,
-+ 0, 0, 0, 0, 0},
-+#ifdef HAVE_OPENSSL
-+#include "sslopt-longopts.h"
-+#endif
-+#ifdef __WIN__
-+ {"standalone", OPT_STANDALONE,
-+ "Dummy option to start as a standalone program (NT).", 0, 0, 0, GET_NO_ARG,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+#endif
-+ {"symbolic-links", 's', "Enable symbolic link support.",
-+ &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
-+ /*
-+ The system call realpath() produces warnings under valgrind and
-+ purify. These are not suppressed: instead we disable symlinks
-+ option if compiled with valgrind support.
-+ */
-+ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
-+ {"sysdate-is-now", OPT_SYSDATE_IS_NOW,
-+ "Non-default option to alias SYSDATE() to NOW() to make it safe-replicable. "
-+ "Since 5.0, SYSDATE() returns a `dynamic' value different for different "
-+ "invocations, even within the same statement.",
-+ &global_system_variables.sysdate_is_now,
-+ 0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+ {"tc-heuristic-recover", OPT_TC_HEURISTIC_RECOVER,
-+ "Decision to use in heuristic recover process. Possible values are COMMIT "
-+ "or ROLLBACK.", &opt_tc_heuristic_recover, &opt_tc_heuristic_recover,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+#if defined(ENABLED_DEBUG_SYNC)
-+ {"debug-sync-timeout", OPT_DEBUG_SYNC_TIMEOUT,
-+ "Enable the debug sync facility "
-+ "and optionally specify a default wait timeout in seconds. "
-+ "A zero value keeps the facility disabled.",
-+ &opt_debug_sync_timeout, 0,
-+ 0, GET_UINT, OPT_ARG, 0, 0, UINT_MAX, 0, 0, 0},
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+ {"temp-pool", OPT_TEMP_POOL,
-+#if (ENABLE_TEMP_POOL)
-+ "Using this option will cause most temporary files created to use a small "
-+ "set of names, rather than a unique name for each new file.",
-+#else
-+ "This option is ignored on this OS.",
-+#endif
-+ &use_temp_pool, &use_temp_pool, 0, GET_BOOL, NO_ARG, 1,
-+ 0, 0, 0, 0, 0},
-+ {"timed_mutexes", OPT_TIMED_MUTEXES,
-+ "Specify whether to time mutexes (only InnoDB mutexes are currently supported).",
-+ &timed_mutexes, &timed_mutexes, 0, GET_BOOL, NO_ARG, 0,
-+ 0, 0, 0, 0, 0},
-+ {"tmpdir", 't',
-+ "Path for temporary files. Several paths may be specified, separated by a "
-+#if defined(__WIN__) || defined(__NETWARE__)
-+ "semicolon (;)"
-+#else
-+ "colon (:)"
-+#endif
-+ ", in this case they are used in a round-robin fashion.",
-+ &opt_mysql_tmpdir, &opt_mysql_tmpdir, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"transaction-isolation", OPT_TX_ISOLATION,
-+ "Default transaction isolation level.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0,
-+ 0, 0, 0, 0, 0},
-+ {"use-symbolic-links", OPT_SYMBOLIC_LINKS, "Enable symbolic link support. "
-+ "Deprecated option; use --symbolic-links instead.",
-+ &my_use_symdir, &my_use_symdir, 0, GET_BOOL, NO_ARG,
-+ IF_PURIFY(0,1), 0, 0, 0, 0, 0},
-+ {"user", 'u', "Run mysqld daemon as user.", 0, 0, 0, GET_STR, REQUIRED_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"verbose", 'v', "Used with --help option for detailed help.",
-+ &opt_verbose, &opt_verbose, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"version", 'V', "Output version information and exit.", 0, 0, 0, GET_NO_ARG,
-+ NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {"warnings", OPT_WARNINGS, "Deprecated; use --log-warnings instead.",
-+ &global_system_variables.log_warnings,
-+ &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG,
-+ 1, 0, ULONG_MAX, 0, 0, 0},
-+ {"back_log", OPT_BACK_LOG,
-+ "The number of outstanding connection requests MySQL can have. This "
-+ "comes into play when the main MySQL thread gets very many connection "
-+ "requests in a very short time.", &back_log, &back_log, 0, GET_ULONG,
-+ REQUIRED_ARG, 50, 1, 65535, 0, 1, 0 },
-+ {"binlog_cache_size", OPT_BINLOG_CACHE_SIZE,
-+ "The size of the cache to hold the SQL statements for the binary log "
-+ "during a transaction. If you often use big, multi-statement "
-+ "transactions you can increase this to get more performance.",
-+ &binlog_cache_size, &binlog_cache_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 32*1024L, IO_SIZE, ULONG_MAX, 0, IO_SIZE, 0},
-+ {"bulk_insert_buffer_size", OPT_BULK_INSERT_BUFFER_SIZE,
-+ "Size of tree cache used in bulk insert optimization. Note that this "
-+ "is a limit per thread.", &global_system_variables.bulk_insert_buff_size,
-+ &max_system_variables.bulk_insert_buff_size,
-+ 0, GET_ULONG, REQUIRED_ARG, 8192*1024, 0, ULONG_MAX, 0, 1, 0},
-+ {"connect_timeout", OPT_CONNECT_TIMEOUT,
-+ "The number of seconds the mysqld server is waiting for a connect packet "
-+ "before responding with 'Bad handshake'.", &connect_timeout, &connect_timeout,
-+ 0, GET_ULONG, REQUIRED_ARG, CONNECT_TIMEOUT, 2, LONG_TIMEOUT, 0, 1, 0 },
-+ { "date_format", OPT_DATE_FORMAT,
-+ "The DATE format (for future).",
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_DATE],
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ { "datetime_format", OPT_DATETIME_FORMAT,
-+ "The DATETIME/TIMESTAMP format (for future).",
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_DATETIME],
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ { "default_week_format", OPT_DEFAULT_WEEK_FORMAT,
-+ "The default week format used by WEEK() functions.",
-+ &global_system_variables.default_week_format,
-+ &max_system_variables.default_week_format,
-+ 0, GET_ULONG, REQUIRED_ARG, 0, 0, 7L, 0, 1, 0},
-+ {"delayed_insert_limit", OPT_DELAYED_INSERT_LIMIT,
-+ "After inserting delayed_insert_limit rows, the INSERT DELAYED handler "
-+ "will check if there are any SELECT statements pending. If so, it allows "
-+ "these to execute before continuing.",
-+ &delayed_insert_limit, &delayed_insert_limit, 0, GET_ULONG,
-+ REQUIRED_ARG, DELAYED_LIMIT, 1, ULONG_MAX, 0, 1, 0},
-+ {"delayed_insert_timeout", OPT_DELAYED_INSERT_TIMEOUT,
-+ "How long a INSERT DELAYED thread should wait for INSERT statements before terminating.",
-+ &delayed_insert_timeout, &delayed_insert_timeout, 0,
-+ GET_ULONG, REQUIRED_ARG, DELAYED_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
-+ { "delayed_queue_size", OPT_DELAYED_QUEUE_SIZE,
-+ "What size queue (in rows) should be allocated for handling INSERT DELAYED. "
-+ "If the queue becomes full, any client that does INSERT DELAYED will wait "
-+ "until there is room in the queue again.",
-+ &delayed_queue_size, &delayed_queue_size, 0, GET_ULONG,
-+ REQUIRED_ARG, DELAYED_QUEUE_SIZE, 1, ULONG_MAX, 0, 1, 0},
-+ {"div_precision_increment", OPT_DIV_PRECINCREMENT,
-+ "Precision of the result of '/' operator will be increased on that value.",
-+ &global_system_variables.div_precincrement,
-+ &max_system_variables.div_precincrement, 0, GET_ULONG,
-+ REQUIRED_ARG, 4, 0, DECIMAL_MAX_SCALE, 0, 0, 0},
-+ {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS,
-+ "If non-zero, binary logs will be purged after expire_logs_days "
-+ "days; possible purges happen at startup and at binary log rotation.",
-+ &expire_logs_days, &expire_logs_days, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, 99, 0, 1, 0},
-+ { "flush_time", OPT_FLUSH_TIME,
-+ "A dedicated thread is created to flush all tables at the given interval.",
-+ &flush_time, &flush_time, 0, GET_ULONG, REQUIRED_ARG,
-+ FLUSH_TIME, 0, LONG_TIMEOUT, 0, 1, 0},
-+ { "ft_boolean_syntax", OPT_FT_BOOLEAN_SYNTAX,
-+ "List of operators for MATCH ... AGAINST ( ... IN BOOLEAN MODE).",
-+ 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ { "ft_max_word_len", OPT_FT_MAX_WORD_LEN,
-+ "The maximum length of the word to be included in a FULLTEXT index. "
-+ "Note: FULLTEXT indexes must be rebuilt after changing this variable.",
-+ &ft_max_word_len, &ft_max_word_len, 0, GET_ULONG,
-+ REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0},
-+ { "ft_min_word_len", OPT_FT_MIN_WORD_LEN,
-+ "The minimum length of the word to be included in a FULLTEXT index. "
-+ "Note: FULLTEXT indexes must be rebuilt after changing this variable.",
-+ &ft_min_word_len, &ft_min_word_len, 0, GET_ULONG,
-+ REQUIRED_ARG, 4, 1, HA_FT_MAXCHARLEN, 0, 1, 0},
-+ { "ft_query_expansion_limit", OPT_FT_QUERY_EXPANSION_LIMIT,
-+ "Number of best matches to use for query expansion.",
-+ &ft_query_expansion_limit, &ft_query_expansion_limit, 0, GET_ULONG,
-+ REQUIRED_ARG, 20, 0, 1000, 0, 1, 0},
-+ { "ft_stopword_file", OPT_FT_STOPWORD_FILE,
-+ "Use stopwords from this file instead of built-in list.",
-+ &ft_stopword_file, &ft_stopword_file, 0, GET_STR,
-+ REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ { "group_concat_max_len", OPT_GROUP_CONCAT_MAX_LEN,
-+ "The maximum length of the result of function group_concat.",
-+ &global_system_variables.group_concat_max_len,
-+ &max_system_variables.group_concat_max_len, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024, 4, ULONG_MAX, 0, 1, 0},
-+ {"interactive_timeout", OPT_INTERACTIVE_TIMEOUT,
-+ "The number of seconds the server waits for activity on an interactive "
-+ "connection before closing it.",
-+ &global_system_variables.net_interactive_timeout,
-+ &max_system_variables.net_interactive_timeout, 0,
-+ GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
-+ {"join_buffer_size", OPT_JOIN_BUFF_SIZE,
-+ "The size of the buffer that is used for full joins.",
-+ &global_system_variables.join_buff_size,
-+ &max_system_variables.join_buff_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ULONG_MAX,
-+ MALLOC_OVERHEAD, IO_SIZE, 0},
-+ {"keep_files_on_create", OPT_KEEP_FILES_ON_CREATE,
-+ "Don't overwrite stale .MYD and .MYI even if no directory is specified.",
-+ &global_system_variables.keep_files_on_create,
-+ &max_system_variables.keep_files_on_create,
-+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
-+ {"key_buffer_size", OPT_KEY_BUFFER_SIZE,
-+ "The size of the buffer used for index blocks for MyISAM tables. Increase "
-+ "this to get better index handling (for all reads and multiple writes) to "
-+ "as much as you can afford; 1GB on a 4GB machine that mainly runs MySQL is "
-+ "quite common.",
-+ &dflt_key_cache_var.param_buff_size, NULL, NULL, (GET_ULL | GET_ASK_ADDR),
-+ REQUIRED_ARG, KEY_CACHE_SIZE, 0, SIZE_T_MAX, MALLOC_OVERHEAD,
-+ IO_SIZE, 0},
-+ {"key_cache_age_threshold", OPT_KEY_CACHE_AGE_THRESHOLD,
-+ "This characterizes the number of hits a hot block has to be untouched "
-+ "until it is considered aged enough to be downgraded to a warm block. "
-+ "This specifies the percentage ratio of that number of hits to the total "
-+ "number of blocks in key cache.",
-+ &dflt_key_cache_var.param_age_threshold, NULL, NULL,
-+ (GET_ULONG | GET_ASK_ADDR), REQUIRED_ARG, 300, 100, ULONG_MAX, 0, 100, 0},
-+ {"key_cache_block_size", OPT_KEY_CACHE_BLOCK_SIZE,
-+ "The default size of key cache blocks.",
-+ &dflt_key_cache_var.param_block_size, NULL, NULL, (GET_ULONG | GET_ASK_ADDR),
-+ REQUIRED_ARG, KEY_CACHE_BLOCK_SIZE, 512, 1024 * 16, 0, 512, 0},
-+ {"key_cache_division_limit", OPT_KEY_CACHE_DIVISION_LIMIT,
-+ "The minimum percentage of warm blocks in key cache.",
-+ &dflt_key_cache_var.param_division_limit, NULL, NULL,
-+ (GET_ULONG | GET_ASK_ADDR) , REQUIRED_ARG, 100, 1, 100, 0, 1, 0},
-+ {"long_query_time", OPT_LONG_QUERY_TIME,
-+ "Log all queries that have taken more than long_query_time seconds to "
-+ "execute. The argument will be treated as a decimal value with "
-+ "microsecond precision.",
-+ &long_query_time, &long_query_time, 0, GET_DOUBLE,
-+ REQUIRED_ARG, 10, 0, LONG_TIMEOUT, 0, 0, 0},
-+ {"lower_case_table_names", OPT_LOWER_CASE_TABLE_NAMES,
-+ "If set to 1, table names are stored in lowercase on disk and table names "
-+ "will be case-insensitive. Should be set to 2 if you are using a case-"
-+ "insensitive file system.",
-+ &lower_case_table_names, &lower_case_table_names, 0, GET_UINT, OPT_ARG,
-+#ifdef FN_NO_CASE_SENCE
-+ 1
-+#else
-+ 0
-+#endif
-+ , 0, 2, 0, 1, 0},
-+ {"max_allowed_packet", OPT_MAX_ALLOWED_PACKET,
-+ "The maximum packet length to send to or receive from server.",
-+ &global_system_variables.max_allowed_packet,
-+ &max_system_variables.max_allowed_packet, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024*1024L, 1024, 1024L*1024L*1024L, MALLOC_OVERHEAD, 1024, 0},
-+ {"max_binlog_cache_size", OPT_MAX_BINLOG_CACHE_SIZE,
-+ "Can be used to restrict the total size used to cache a multi-transaction query.",
-+ &max_binlog_cache_size, &max_binlog_cache_size, 0,
-+ GET_ULL, REQUIRED_ARG, ULONG_MAX, IO_SIZE, ULONGLONG_MAX, 0, IO_SIZE, 0},
-+ {"max_binlog_size", OPT_MAX_BINLOG_SIZE,
-+ "Binary log will be rotated automatically when the size exceeds this "
-+ "value. Will also apply to relay logs if max_relay_log_size is 0. "
-+ "The minimum value for this variable is 4096.",
-+ &max_binlog_size, &max_binlog_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024*1024L*1024L, IO_SIZE, 1024*1024L*1024L, 0, IO_SIZE, 0},
-+ {"max_connect_errors", OPT_MAX_CONNECT_ERRORS,
-+ "If there is more than this number of interrupted connections from a host "
-+ "this host will be blocked from further connections.",
-+ &max_connect_errors, &max_connect_errors, 0, GET_ULONG,
-+ REQUIRED_ARG, MAX_CONNECT_ERRORS, 1, ULONG_MAX, 0, 1, 0},
-+ // Default max_connections of 151 is larger than Apache's default max
-+ // children, to avoid "too many connections" error in a common setup
-+ {"max_connections", OPT_MAX_CONNECTIONS,
-+ "The number of simultaneous clients allowed.", &max_connections,
-+ &max_connections, 0, GET_ULONG, REQUIRED_ARG, 151, 1, 100000, 0, 1, 0},
-+ {"max_delayed_threads", OPT_MAX_DELAYED_THREADS,
-+ "Don't start more than this number of threads to handle INSERT DELAYED "
-+ "statements. If set to zero, which means INSERT DELAYED is not used.",
-+ &global_system_variables.max_insert_delayed_threads,
-+ &max_system_variables.max_insert_delayed_threads,
-+ 0, GET_ULONG, REQUIRED_ARG, 20, 0, 16384, 0, 1, 0},
-+ {"max_error_count", OPT_MAX_ERROR_COUNT,
-+ "Max number of errors/warnings to store for a statement.",
-+ &global_system_variables.max_error_count,
-+ &max_system_variables.max_error_count,
-+ 0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
-+ {"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
-+ "Don't allow creation of heap tables bigger than this.",
-+ &global_system_variables.max_heap_table_size,
-+ &max_system_variables.max_heap_table_size, 0, GET_ULL,
-+ REQUIRED_ARG, 16*1024*1024L, 16384, MAX_MEM_TABLE_SIZE,
-+ MALLOC_OVERHEAD, 1024, 0},
-+ {"max_join_size", OPT_MAX_JOIN_SIZE,
-+ "Joins that are probably going to read more than max_join_size records return an error.",
-+ &global_system_variables.max_join_size,
-+ &max_system_variables.max_join_size, 0, GET_HA_ROWS, REQUIRED_ARG,
-+ HA_POS_ERROR, 1, HA_POS_ERROR, 0, 1, 0},
-+ {"max_length_for_sort_data", OPT_MAX_LENGTH_FOR_SORT_DATA,
-+ "Max number of bytes in sorted records.",
-+ &global_system_variables.max_length_for_sort_data,
-+ &max_system_variables.max_length_for_sort_data, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
-+ {"max_long_data_size", OPT_MAX_LONG_DATA_SIZE,
-+ "The maximum size of prepared statement parameter which can be provided "
-+ "through mysql_send_long_data() API call. "
-+ "Deprecated option; use max_allowed_packet instead.",
-+ &max_long_data_size,
-+ &max_long_data_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024*1024L, 1024, UINT_MAX32, MALLOC_OVERHEAD, 1, 0},
-+ {"max_prepared_stmt_count", OPT_MAX_PREPARED_STMT_COUNT,
-+ "Maximum number of prepared statements in the server.",
-+ &max_prepared_stmt_count, &max_prepared_stmt_count,
-+ 0, GET_ULONG, REQUIRED_ARG, 16382, 0, 1*1024*1024, 0, 1, 0},
-+ {"max_relay_log_size", OPT_MAX_RELAY_LOG_SIZE,
-+ "If non-zero: relay log will be rotated automatically when the size "
-+ "exceeds this value; if zero (the default): when the size exceeds "
-+ "max_binlog_size. 0 excepted, the minimum value for this variable is 4096.",
-+ &max_relay_log_size, &max_relay_log_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 0L, 0L, 1024*1024L*1024L, 0, IO_SIZE, 0},
-+ { "max_seeks_for_key", OPT_MAX_SEEKS_FOR_KEY,
-+ "Limit assumed max number of seeks when looking up rows based on a key.",
-+ &global_system_variables.max_seeks_for_key,
-+ &max_system_variables.max_seeks_for_key, 0, GET_ULONG,
-+ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0 },
-+ {"max_sort_length", OPT_MAX_SORT_LENGTH,
-+ "The number of bytes to use when sorting BLOB or TEXT values (only the "
-+ "first max_sort_length bytes of each value are used; the rest are ignored).",
-+ &global_system_variables.max_sort_length,
-+ &max_system_variables.max_sort_length, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024, 4, 8192*1024L, 0, 1, 0},
-+ {"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
-+ "Maximum stored procedure recursion depth. (discussed with docs).",
-+ &global_system_variables.max_sp_recursion_depth,
-+ &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
-+ OPT_ARG, 0, 0, 255, 0, 1, 0 },
-+ {"max_tmp_tables", OPT_MAX_TMP_TABLES,
-+ "Maximum number of temporary tables a client can keep open at a time.",
-+ &global_system_variables.max_tmp_tables,
-+ &max_system_variables.max_tmp_tables, 0, GET_ULONG,
-+ REQUIRED_ARG, 32, 1, ULONG_MAX, 0, 1, 0},
-+ {"max_user_connections", OPT_MAX_USER_CONNECTIONS,
-+ "The maximum number of active connections for a single user (0 = no limit).",
-+ &max_user_connections, &max_user_connections, 0, GET_UINT,
-+ REQUIRED_ARG, 0, 0, UINT_MAX, 0, 1, 0},
-+ {"max_write_lock_count", OPT_MAX_WRITE_LOCK_COUNT,
-+ "After this many write locks, allow some read locks to run in between.",
-+ &max_write_lock_count, &max_write_lock_count, 0, GET_ULONG,
-+ REQUIRED_ARG, ULONG_MAX, 1, ULONG_MAX, 0, 1, 0},
-+ {"min_examined_row_limit", OPT_MIN_EXAMINED_ROW_LIMIT,
-+ "Don't log queries which examine less than min_examined_row_limit rows to file.",
-+ &global_system_variables.min_examined_row_limit,
-+ &max_system_variables.min_examined_row_limit, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1L, 0},
-+ {"multi_range_count", OPT_MULTI_RANGE_COUNT,
-+ "Number of key ranges to request at once.",
-+ &global_system_variables.multi_range_count,
-+ &max_system_variables.multi_range_count, 0,
-+ GET_ULONG, REQUIRED_ARG, 256, 1, ULONG_MAX, 0, 1, 0},
-+ {"myisam_block_size", OPT_MYISAM_BLOCK_SIZE,
-+ "Block size to be used for MyISAM index pages.",
-+ &opt_myisam_block_size, &opt_myisam_block_size, 0, GET_ULONG, REQUIRED_ARG,
-+ MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH,
-+ 0, MI_MIN_KEY_BLOCK_LENGTH, 0},
-+ {"myisam_data_pointer_size", OPT_MYISAM_DATA_POINTER_SIZE,
-+ "Default pointer size to be used for MyISAM tables.",
-+ &myisam_data_pointer_size,
-+ &myisam_data_pointer_size, 0, GET_ULONG, REQUIRED_ARG,
-+ 6, 2, 7, 0, 1, 0},
-+ {"myisam_max_extra_sort_file_size", OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE,
-+ "This is a deprecated option that does nothing anymore. "
-+ "It will be removed in MySQL " VER_CELOSIA,
-+ &global_system_variables.myisam_max_extra_sort_file_size,
-+ &max_system_variables.myisam_max_extra_sort_file_size,
-+ 0, GET_ULL, REQUIRED_ARG, (ulonglong) INT_MAX32,
-+ 0, (ulonglong) MAX_FILE_SIZE, 0, 1, 0},
-+ {"myisam_max_sort_file_size", OPT_MYISAM_MAX_SORT_FILE_SIZE,
-+ "Don't use the fast sort index method to created index if the temporary "
-+ "file would get bigger than this.",
-+ &global_system_variables.myisam_max_sort_file_size,
-+ &max_system_variables.myisam_max_sort_file_size, 0,
-+ GET_ULL, REQUIRED_ARG, (longlong) LONG_MAX, 0, (ulonglong) MAX_FILE_SIZE,
-+ 0, 1024*1024, 0},
-+ {"myisam_mmap_size", OPT_MYISAM_MMAP_SIZE,
-+ "Can be used to restrict the total memory used for memory mmaping of myisam files",
-+ &myisam_mmap_size, &myisam_mmap_size, 0,
-+ GET_ULL, REQUIRED_ARG, SIZE_T_MAX, MEMMAP_EXTRA_MARGIN, SIZE_T_MAX, 0, 1, 0},
-+ {"myisam_repair_threads", OPT_MYISAM_REPAIR_THREADS,
-+ "Specifies whether several threads should be used when repairing MyISAM "
-+ "tables. For values > 1, one thread is used per index. The value of 1 "
-+ "disables parallel repair.",
-+ &global_system_variables.myisam_repair_threads,
-+ &max_system_variables.myisam_repair_threads, 0,
-+ GET_ULONG, REQUIRED_ARG, 1, 1, ULONG_MAX, 0, 1, 0},
-+ {"myisam_sort_buffer_size", OPT_MYISAM_SORT_BUFFER_SIZE,
-+ "The buffer that is allocated when sorting the index when doing a REPAIR "
-+ "or when creating indexes with CREATE INDEX or ALTER TABLE.",
-+ &global_system_variables.myisam_sort_buff_size,
-+ &max_system_variables.myisam_sort_buff_size, 0,
-+ GET_ULONG, REQUIRED_ARG, 8192 * 1024, 4096, ~0L, 0, 1, 0},
-+ {"myisam_use_mmap", OPT_MYISAM_USE_MMAP,
-+ "Use memory mapping for reading and writing MyISAM tables.",
-+ &opt_myisam_use_mmap, &opt_myisam_use_mmap, 0, GET_BOOL, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"myisam_stats_method", OPT_MYISAM_STATS_METHOD,
-+ "Specifies how MyISAM index statistics collection code should threat NULLs. "
-+ "Possible values of name are \"nulls_unequal\" (default behavior for 4.1/5.0), "
-+ "\"nulls_equal\" (emulate 4.0 behavior), and \"nulls_ignored\".",
-+ &myisam_stats_method_str, &myisam_stats_method_str, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"net_buffer_length", OPT_NET_BUFFER_LENGTH,
-+ "Buffer length for TCP/IP and socket communication.",
-+ &global_system_variables.net_buffer_length,
-+ &max_system_variables.net_buffer_length, 0, GET_ULONG,
-+ REQUIRED_ARG, 16384, 1024, 1024*1024L, 0, 1024, 0},
-+ {"net_read_timeout", OPT_NET_READ_TIMEOUT,
-+ "Number of seconds to wait for more data from a connection before aborting the read.",
-+ &global_system_variables.net_read_timeout,
-+ &max_system_variables.net_read_timeout, 0, GET_ULONG,
-+ REQUIRED_ARG, NET_READ_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
-+ {"net_retry_count", OPT_NET_RETRY_COUNT,
-+ "If a read on a communication port is interrupted, retry this many times before giving up.",
-+ &global_system_variables.net_retry_count,
-+ &max_system_variables.net_retry_count,0,
-+ GET_ULONG, REQUIRED_ARG, MYSQLD_NET_RETRY_COUNT, 1, ULONG_MAX, 0, 1, 0},
-+ {"net_write_timeout", OPT_NET_WRITE_TIMEOUT,
-+ "Number of seconds to wait for a block to be written to a connection before "
-+ "aborting the write.",
-+ &global_system_variables.net_write_timeout,
-+ &max_system_variables.net_write_timeout, 0, GET_ULONG,
-+ REQUIRED_ARG, NET_WRITE_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
-+ { "old", OPT_OLD_MODE, "Use compatible behavior.",
-+ &global_system_variables.old_mode,
-+ &max_system_variables.old_mode, 0, GET_BOOL, NO_ARG,
-+ 0, 0, 0, 0, 0, 0},
-+ {"open_files_limit", OPT_OPEN_FILES_LIMIT,
-+ "If this is not 0, then mysqld will use this value to reserve file "
-+ "descriptors to use with setrlimit(). If this value is 0 then mysqld "
-+ "will reserve max_connections*5 or max_connections + table_cache*2 "
-+ "(whichever is larger) number of files.",
-+ &open_files_limit, &open_files_limit, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, OS_FILE_LIMIT, 0, 1, 0},
-+ {"optimizer_prune_level", OPT_OPTIMIZER_PRUNE_LEVEL,
-+ "Controls the heuristic(s) applied during query optimization to prune "
-+ "less-promising partial plans from the optimizer search space. Meaning: "
-+ "0 - do not apply any heuristic, thus perform exhaustive search; 1 - "
-+ "prune plans based on number of retrieved rows.",
-+ &global_system_variables.optimizer_prune_level,
-+ &max_system_variables.optimizer_prune_level,
-+ 0, GET_ULONG, OPT_ARG, 1, 0, 1, 0, 1, 0},
-+ {"optimizer_search_depth", OPT_OPTIMIZER_SEARCH_DEPTH,
-+ "Maximum depth of search performed by the query optimizer. Values larger "
-+ "than the number of relations in a query result in better query plans, "
-+ "but take longer to compile a query. Smaller values than the number of "
-+ "tables in a relation result in faster optimization, but may produce "
-+ "very bad query plans. If set to 0, the system will automatically pick "
-+ "a reasonable value; if set to MAX_TABLES+2, the optimizer will switch "
-+ "to the original find_best (used for testing/comparison).",
-+ &global_system_variables.optimizer_search_depth,
-+ &max_system_variables.optimizer_search_depth,
-+ 0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
-+ {"optimizer_switch", OPT_OPTIMIZER_SWITCH,
-+ "optimizer_switch=option=val[,option=val...], where option={index_merge, "
-+ "index_merge_union, index_merge_sort_union, index_merge_intersection} and "
-+ "val={on, off, default}.",
-+ &optimizer_switch_str, &optimizer_switch_str, 0, GET_STR, REQUIRED_ARG,
-+ /*OPTIMIZER_SWITCH_DEFAULT*/0, 0, 0, 0, 0, 0},
-+ {"plugin_dir", OPT_PLUGIN_DIR,
-+ "Directory for plugins.",
-+ &opt_plugin_dir_ptr, &opt_plugin_dir_ptr, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"plugin-load", OPT_PLUGIN_LOAD,
-+ "Optional semicolon-separated list of plugins to load, where each plugin is "
-+ "identified as name=library, where name is the plugin name and library "
-+ "is the plugin library in plugin_dir.",
-+ &opt_plugin_load, &opt_plugin_load, 0,
-+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"preload_buffer_size", OPT_PRELOAD_BUFFER_SIZE,
-+ "The size of the buffer that is allocated when preloading indexes.",
-+ &global_system_variables.preload_buff_size,
-+ &max_system_variables.preload_buff_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 32*1024L, 1024, 1024*1024*1024L, 0, 1, 0},
-+ {"query_alloc_block_size", OPT_QUERY_ALLOC_BLOCK_SIZE,
-+ "Allocation block size for query parsing and execution.",
-+ &global_system_variables.query_alloc_block_size,
-+ &max_system_variables.query_alloc_block_size, 0, GET_ULONG,
-+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
-+#ifdef HAVE_QUERY_CACHE
-+ {"query_cache_limit", OPT_QUERY_CACHE_LIMIT,
-+ "Don't cache results that are bigger than this.",
-+ &query_cache_limit, &query_cache_limit, 0, GET_ULONG,
-+ REQUIRED_ARG, 1024*1024L, 0, ULONG_MAX, 0, 1, 0},
-+ {"query_cache_min_res_unit", OPT_QUERY_CACHE_MIN_RES_UNIT,
-+ "Minimal size of unit in which space for results is allocated (last unit "
-+ "will be trimmed after writing all result data).",
-+ &query_cache_min_res_unit, &query_cache_min_res_unit,
-+ 0, GET_ULONG, REQUIRED_ARG, QUERY_CACHE_MIN_RESULT_DATA_SIZE,
-+ 0, ULONG_MAX, 0, 1, 0},
-+#endif /*HAVE_QUERY_CACHE*/
-+ {"query_cache_size", OPT_QUERY_CACHE_SIZE,
-+ "The memory allocated to store results from old queries.",
-+ &query_cache_size, &query_cache_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, (longlong) ULONG_MAX, 0, 1024, 0},
-+#ifdef HAVE_QUERY_CACHE
-+ {"query_cache_type", OPT_QUERY_CACHE_TYPE,
-+ "0 = OFF = Don't cache or retrieve results. 1 = ON = Cache all results "
-+ "except SELECT SQL_NO_CACHE ... queries. 2 = DEMAND = Cache only SELECT "
-+ "SQL_CACHE ... queries.", &global_system_variables.query_cache_type,
-+ &max_system_variables.query_cache_type,
-+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 2, 0, 1, 0},
-+ {"query_cache_wlock_invalidate", OPT_QUERY_CACHE_WLOCK_INVALIDATE,
-+ "Invalidate queries in query cache on LOCK for write.",
-+ &global_system_variables.query_cache_wlock_invalidate,
-+ &max_system_variables.query_cache_wlock_invalidate,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+#endif /*HAVE_QUERY_CACHE*/
-+ {"query_prealloc_size", OPT_QUERY_PREALLOC_SIZE,
-+ "Persistent buffer for query parsing and execution.",
-+ &global_system_variables.query_prealloc_size,
-+ &max_system_variables.query_prealloc_size, 0, GET_ULONG,
-+ REQUIRED_ARG, QUERY_ALLOC_PREALLOC_SIZE, QUERY_ALLOC_PREALLOC_SIZE,
-+ ULONG_MAX, 0, 1024, 0},
-+ {"range_alloc_block_size", OPT_RANGE_ALLOC_BLOCK_SIZE,
-+ "Allocation block size for storing ranges during optimization.",
-+ &global_system_variables.range_alloc_block_size,
-+ &max_system_variables.range_alloc_block_size, 0, GET_ULONG,
-+ REQUIRED_ARG, RANGE_ALLOC_BLOCK_SIZE, RANGE_ALLOC_BLOCK_SIZE, ULONG_MAX,
-+ 0, 1024, 0},
-+ {"read_buffer_size", OPT_RECORD_BUFFER,
-+ "Each thread that does a sequential scan allocates a buffer of this size "
-+ "for each table it scans. If you do many sequential scans, you may want "
-+ "to increase this value.", &global_system_variables.read_buff_size,
-+ &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
-+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE,
-+ 0},
-+ {"read_only", OPT_READONLY,
-+ "Make all non-temporary tables read-only, with the exception of replication "
-+ "(slave) threads and users with the SUPER privilege.",
-+ &opt_readonly,
-+ &opt_readonly,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+ {"read_rnd_buffer_size", OPT_RECORD_RND_BUFFER,
-+ "When reading rows in sorted order after a sort, the rows are read through "
-+ "this buffer to avoid disk seeks. If not set, then it's set to the value of "
-+ "record_buffer.",
-+ &global_system_variables.read_rnd_buff_size,
-+ &max_system_variables.read_rnd_buff_size, 0,
-+ GET_ULONG, REQUIRED_ARG, 256*1024L, IO_SIZE*2+MALLOC_OVERHEAD,
-+ INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
-+ {"record_buffer", OPT_RECORD_BUFFER_OLD,
-+ "Alias for read_buffer_size. This variable is deprecated and will be removed in a future release.",
-+ &global_system_variables.read_buff_size,
-+ &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
-+ 128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, INT_MAX32, MALLOC_OVERHEAD, IO_SIZE, 0},
-+#ifdef HAVE_REPLICATION
-+ {"relay_log_purge", OPT_RELAY_LOG_PURGE,
-+ "0 = do not purge relay logs. 1 = purge them as soon as they are no more needed.",
-+ &relay_log_purge,
-+ &relay_log_purge, 0, GET_BOOL, NO_ARG,
-+ 1, 0, 1, 0, 1, 0},
-+ {"relay_log_space_limit", OPT_RELAY_LOG_SPACE_LIMIT,
-+ "Maximum space to use for all relay logs.",
-+ &relay_log_space_limit,
-+ &relay_log_space_limit, 0, GET_ULL, REQUIRED_ARG, 0L, 0L,
-+ (longlong) ULONG_MAX, 0, 1, 0},
-+ {"slave_compressed_protocol", OPT_SLAVE_COMPRESSED_PROTOCOL,
-+ "Use compression on master/slave protocol.",
-+ &opt_slave_compressed_protocol,
-+ &opt_slave_compressed_protocol,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 1, 0},
-+ {"slave_net_timeout", OPT_SLAVE_NET_TIMEOUT,
-+ "Number of seconds to wait for more data from a master/slave connection before aborting the read.",
-+ &slave_net_timeout, &slave_net_timeout, 0,
-+ GET_ULONG, REQUIRED_ARG, SLAVE_NET_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0},
-+ {"slave_transaction_retries", OPT_SLAVE_TRANS_RETRIES,
-+ "Number of times the slave SQL thread will retry a transaction in case "
-+ "it failed with a deadlock or elapsed lock wait timeout, "
-+ "before giving up and stopping.",
-+ &slave_trans_retries, &slave_trans_retries, 0,
-+ GET_ULONG, REQUIRED_ARG, 10L, 0L, (longlong) ULONG_MAX, 0, 1, 0},
-+#endif /* HAVE_REPLICATION */
-+ {"slow_launch_time", OPT_SLOW_LAUNCH_TIME,
-+ "If creating the thread takes longer than this value (in seconds), "
-+ "the Slow_launch_threads counter will be incremented.",
-+ &slow_launch_time, &slow_launch_time, 0, GET_ULONG,
-+ REQUIRED_ARG, 2L, 0L, LONG_TIMEOUT, 0, 1, 0},
-+ {"sort_buffer_size", OPT_SORT_BUFFER,
-+ "Each thread that needs to do a sort allocates a buffer of this size.",
-+ &global_system_variables.sortbuff_size,
-+ &max_system_variables.sortbuff_size, 0, GET_ULONG, REQUIRED_ARG,
-+ MAX_SORT_MEMORY, MIN_SORT_MEMORY+MALLOC_OVERHEAD*2, ~0L, MALLOC_OVERHEAD,
-+ 1, 0},
-+ {"sync-binlog", OPT_SYNC_BINLOG,
-+ "Synchronously flush binary log to disk after every #th event. "
-+ "Use 0 (default) to disable synchronous flushing.",
-+ &sync_binlog_period, &sync_binlog_period, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, ULONG_MAX, 0, 1, 0},
-+ {"sync-frm", OPT_SYNC_FRM, "Sync .frm to disk on create. Enabled by default.",
-+ &opt_sync_frm, &opt_sync_frm, 0, GET_BOOL, NO_ARG, 1, 0,
-+ 0, 0, 0, 0},
-+ {"table_cache", OPT_TABLE_OPEN_CACHE,
-+ "Deprecated; use --table_open_cache instead.",
-+ &table_cache_size, &table_cache_size, 0, GET_ULONG,
-+ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
-+ {"table_definition_cache", OPT_TABLE_DEF_CACHE,
-+ "The number of cached table definitions.",
-+ &table_def_size, &table_def_size,
-+ 0, GET_ULONG, REQUIRED_ARG, TABLE_DEF_CACHE_DEFAULT, TABLE_DEF_CACHE_MIN,
-+ 512*1024L, 0, 1, 0},
-+ {"table_open_cache", OPT_TABLE_OPEN_CACHE,
-+ "The number of cached open tables.",
-+ &table_cache_size, &table_cache_size, 0, GET_ULONG,
-+ REQUIRED_ARG, TABLE_OPEN_CACHE_DEFAULT, 1, 512*1024L, 0, 1, 0},
-+ {"table_lock_wait_timeout", OPT_TABLE_LOCK_WAIT_TIMEOUT,
-+ "Timeout in seconds to wait for a table level lock before returning an "
-+ "error. Used only if the connection has active cursors.",
-+ &table_lock_wait_timeout, &table_lock_wait_timeout,
-+ 0, GET_ULONG, REQUIRED_ARG, 50, 1, 1024 * 1024 * 1024, 0, 1, 0},
-+ {"thread_cache_size", OPT_THREAD_CACHE_SIZE,
-+ "How many threads we should keep in a cache for reuse.",
-+ &thread_cache_size, &thread_cache_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 0, 0, 16384, 0, 1, 0},
-+ {"thread_concurrency", OPT_THREAD_CONCURRENCY,
-+ "Permits the application to give the threads system a hint for the "
-+ "desired number of threads that should be run at the same time.",
-+ &concurrency, &concurrency, 0, GET_ULONG, REQUIRED_ARG,
-+ DEFAULT_CONCURRENCY, 1, 512, 0, 1, 0},
-+#if HAVE_POOL_OF_THREADS == 1
-+ {"thread_pool_size", OPT_THREAD_CACHE_SIZE,
-+ "How many threads we should create to handle query requests in case of "
-+ "'thread_handling=pool-of-threads'.",
-+ &thread_pool_size, &thread_pool_size, 0, GET_ULONG,
-+ REQUIRED_ARG, 20, 1, 16384, 0, 1, 0},
-+#endif
-+ {"thread_stack", OPT_THREAD_STACK,
-+ "The stack size for each thread.", &my_thread_stack_size,
-+ &my_thread_stack_size, 0, GET_ULONG, REQUIRED_ARG,DEFAULT_THREAD_STACK,
-+ 1024L*128L, ULONG_MAX, 0, 1024, 0},
-+ { "time_format", OPT_TIME_FORMAT,
-+ "The TIME format (for future).",
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
-+ &opt_date_time_formats[MYSQL_TIMESTAMP_TIME],
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"tmp_table_size", OPT_TMP_TABLE_SIZE,
-+ "If an internal in-memory temporary table exceeds this size, MySQL will"
-+ " automatically convert it to an on-disk MyISAM table.",
-+ &global_system_variables.tmp_table_size,
-+ &max_system_variables.tmp_table_size, 0, GET_ULL,
-+ REQUIRED_ARG, 16*1024*1024L, 1024, MAX_MEM_TABLE_SIZE, 0, 1, 0},
-+ {"transaction_alloc_block_size", OPT_TRANS_ALLOC_BLOCK_SIZE,
-+ "Allocation block size for transactions to be stored in binary log.",
-+ &global_system_variables.trans_alloc_block_size,
-+ &max_system_variables.trans_alloc_block_size, 0, GET_ULONG,
-+ REQUIRED_ARG, QUERY_ALLOC_BLOCK_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
-+ {"transaction_prealloc_size", OPT_TRANS_PREALLOC_SIZE,
-+ "Persistent buffer for transactions to be stored in binary log.",
-+ &global_system_variables.trans_prealloc_size,
-+ &max_system_variables.trans_prealloc_size, 0, GET_ULONG,
-+ REQUIRED_ARG, TRANS_ALLOC_PREALLOC_SIZE, 1024, ULONG_MAX, 0, 1024, 0},
-+ {"thread_handling", OPT_THREAD_HANDLING,
-+ "Define threads usage for handling queries: "
-+ "one-thread-per-connection or no-threads.", 0, 0,
-+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
-+ {"updatable_views_with_limit", OPT_UPDATABLE_VIEWS_WITH_LIMIT,
-+ "1 = YES = Don't issue an error message (warning only) if a VIEW without "
-+ "presence of a key of the underlying table is used in queries with a "
-+ "LIMIT clause for updating. 0 = NO = Prohibit update of a VIEW, which "
-+ "does not contain a key of the underlying table and the query uses a "
-+ "LIMIT clause (usually get from GUI tools).",
-+ &global_system_variables.updatable_views_with_limit,
-+ &max_system_variables.updatable_views_with_limit,
-+ 0, GET_ULONG, REQUIRED_ARG, 1, 0, 1, 0, 1, 0},
-+ {"wait_timeout", OPT_WAIT_TIMEOUT,
-+ "The number of seconds the server waits for activity on a connection before closing it.",
-+ &global_system_variables.net_wait_timeout,
-+ &max_system_variables.net_wait_timeout, 0, GET_ULONG,
-+ REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, IF_WIN(INT_MAX32/1000, LONG_TIMEOUT),
-+ 0, 1, 0},
-+ {"binlog-direct-non-transactional-updates", OPT_BINLOG_DIRECT_NON_TRANS_UPDATE,
-+ "Causes updates to non-transactional engines using statement format to be "
-+ "written directly to binary log. Before using this option, make sure that "
-+ "there are no dependencies between transactional and non-transactional "
-+ "tables such as in the statement INSERT INTO t_myisam SELECT * FROM "
-+ "t_innodb; otherwise, slaves may diverge from the master.",
-+ &global_system_variables.binlog_direct_non_trans_update,
-+ &max_system_variables.binlog_direct_non_trans_update,
-+ 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-+ {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
-+};
-+
-+
-+static int show_queries(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONGLONG;
-+ var->value= (char *)&thd->query_id;
-+ return 0;
-+}
-+
-+
-+static int show_net_compression(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_MY_BOOL;
-+ var->value= (char *)&thd->net.compress;
-+ return 0;
-+}
-+
-+static int show_starttime(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (long) (thd->query_start() - server_start_time);
-+ return 0;
-+}
-+
-+#ifdef COMMUNITY_SERVER
-+static int show_flushstatustime(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (long) (thd->query_start() - flush_status_time);
-+ return 0;
-+}
-+#endif
-+
-+#ifdef HAVE_REPLICATION
-+static int show_rpl_status(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_CHAR;
-+ var->value= const_cast<char*>(rpl_status_type[(int)rpl_status]);
-+ return 0;
-+}
-+
-+static int show_slave_running(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_MY_BOOL;
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ var->value= buff;
-+ *((my_bool *)buff)= (my_bool) (active_mi &&
-+ active_mi->slave_running == MYSQL_SLAVE_RUN_CONNECT &&
-+ active_mi->rli.slave_running);
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ return 0;
-+}
-+
-+static int show_slave_retried_trans(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ /*
-+ TODO: with multimaster, have one such counter per line in
-+ SHOW SLAVE STATUS, and have the sum over all lines here.
-+ */
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ if (active_mi)
-+ {
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ pthread_mutex_lock(&active_mi->rli.data_lock);
-+ *((long *)buff)= (long)active_mi->rli.retried_trans;
-+ pthread_mutex_unlock(&active_mi->rli.data_lock);
-+ }
-+ else
-+ var->type= SHOW_UNDEF;
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ return 0;
-+}
-+#endif /* HAVE_REPLICATION */
-+
-+static int show_open_tables(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (long)cached_open_tables();
-+ return 0;
-+}
-+
-+static int show_prepared_stmt_count(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ pthread_mutex_lock(&LOCK_prepared_stmt_count);
-+ *((long *)buff)= (long)prepared_stmt_count;
-+ pthread_mutex_unlock(&LOCK_prepared_stmt_count);
-+ return 0;
-+}
-+
-+static int show_table_definitions(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (long)cached_table_definitions();
-+ return 0;
-+}
-+
-+#ifdef HAVE_OPENSSL
-+/* Functions relying on CTX */
-+static int show_ssl_ctx_sess_accept(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_accept(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_accept_good(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_connect_good(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_accept_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_connect_renegotiate(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_cb_hits(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_hits(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_cache_full(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_misses(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_timeouts(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_number(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_connect(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_sess_get_cache_size(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_get_verify_mode(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ *((long *)buff)= (!ssl_acceptor_fd ? 0 :
-+ SSL_CTX_get_verify_depth(ssl_acceptor_fd->ssl_context));
-+ return 0;
-+}
-+
-+static int show_ssl_ctx_get_session_cache_mode(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_CHAR;
-+ if (!ssl_acceptor_fd)
-+ var->value= const_cast<char*>("NONE");
-+ else
-+ switch (SSL_CTX_get_session_cache_mode(ssl_acceptor_fd->ssl_context))
-+ {
-+ case SSL_SESS_CACHE_OFF:
-+ var->value= const_cast<char*>("OFF"); break;
-+ case SSL_SESS_CACHE_CLIENT:
-+ var->value= const_cast<char*>("CLIENT"); break;
-+ case SSL_SESS_CACHE_SERVER:
-+ var->value= const_cast<char*>("SERVER"); break;
-+ case SSL_SESS_CACHE_BOTH:
-+ var->value= const_cast<char*>("BOTH"); break;
-+ case SSL_SESS_CACHE_NO_AUTO_CLEAR:
-+ var->value= const_cast<char*>("NO_AUTO_CLEAR"); break;
-+ case SSL_SESS_CACHE_NO_INTERNAL_LOOKUP:
-+ var->value= const_cast<char*>("NO_INTERNAL_LOOKUP"); break;
-+ default:
-+ var->value= const_cast<char*>("Unknown"); break;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ Functions relying on SSL
-+ Note: In the show_ssl_* functions, we need to check if we have a
-+ valid vio-object since this isn't always true, specifically
-+ when session_status or global_status is requested from
-+ inside an Event.
-+ */
-+static int show_ssl_get_version(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_CHAR;
-+ if( thd->vio_ok() && thd->net.vio->ssl_arg )
-+ var->value= const_cast<char*>(SSL_get_version((SSL*) thd->net.vio->ssl_arg));
-+ else
-+ var->value= (char *)"";
-+ return 0;
-+}
-+
-+static int show_ssl_session_reused(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ if( thd->vio_ok() && thd->net.vio->ssl_arg )
-+ *((long *)buff)= (long)SSL_session_reused((SSL*) thd->net.vio->ssl_arg);
-+ else
-+ *((long *)buff)= 0;
-+ return 0;
-+}
-+
-+static int show_ssl_get_default_timeout(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ if( thd->vio_ok() && thd->net.vio->ssl_arg )
-+ *((long *)buff)= (long)SSL_get_default_timeout((SSL*)thd->net.vio->ssl_arg);
-+ else
-+ *((long *)buff)= 0;
-+ return 0;
-+}
-+
-+static int show_ssl_get_verify_mode(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ if( thd->net.vio && thd->net.vio->ssl_arg )
-+ *((long *)buff)= (long)SSL_get_verify_mode((SSL*)thd->net.vio->ssl_arg);
-+ else
-+ *((long *)buff)= 0;
-+ return 0;
-+}
-+
-+static int show_ssl_get_verify_depth(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_LONG;
-+ var->value= buff;
-+ if( thd->vio_ok() && thd->net.vio->ssl_arg )
-+ *((long *)buff)= (long)SSL_get_verify_depth((SSL*)thd->net.vio->ssl_arg);
-+ else
-+ *((long *)buff)= 0;
-+ return 0;
-+}
-+
-+static int show_ssl_get_cipher(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_CHAR;
-+ if( thd->vio_ok() && thd->net.vio->ssl_arg )
-+ var->value= const_cast<char*>(SSL_get_cipher((SSL*) thd->net.vio->ssl_arg));
-+ else
-+ var->value= (char *)"";
-+ return 0;
-+}
-+
-+static int show_ssl_get_cipher_list(THD *thd, SHOW_VAR *var, char *buff)
-+{
-+ var->type= SHOW_CHAR;
-+ var->value= buff;
-+ if (thd->vio_ok() && thd->net.vio->ssl_arg)
-+ {
-+ int i;
-+ const char *p;
-+ char *end= buff + SHOW_VAR_FUNC_BUFF_SIZE;
-+ for (i=0; (p= SSL_get_cipher_list((SSL*) thd->net.vio->ssl_arg,i)) &&
-+ buff < end; i++)
-+ {
-+ buff= strnmov(buff, p, end-buff-1);
-+ *buff++= ':';
-+ }
-+ if (i)
-+ buff--;
-+ }
-+ *buff=0;
-+ return 0;
-+}
-+
-+#endif /* HAVE_OPENSSL */
-+
-+
-+/*
-+ Variables shown by SHOW STATUS in alphabetical order
-+*/
-+
-+SHOW_VAR status_vars[]= {
-+ {"Aborted_clients", (char*) &aborted_threads, SHOW_LONG},
-+ {"Aborted_connects", (char*) &aborted_connects, SHOW_LONG},
-+ {"Binlog_cache_disk_use", (char*) &binlog_cache_disk_use, SHOW_LONG},
-+ {"Binlog_cache_use", (char*) &binlog_cache_use, SHOW_LONG},
-+ {"Bytes_received", (char*) offsetof(STATUS_VAR, bytes_received), SHOW_LONGLONG_STATUS},
-+ {"Bytes_sent", (char*) offsetof(STATUS_VAR, bytes_sent), SHOW_LONGLONG_STATUS},
-+ {"Com", (char*) com_status_vars, SHOW_ARRAY},
-+ {"Compression", (char*) &show_net_compression, SHOW_FUNC},
-+ {"Connections", (char*) &thread_id, SHOW_LONG_NOFLUSH},
-+ {"Created_tmp_disk_tables", (char*) offsetof(STATUS_VAR, created_tmp_disk_tables), SHOW_LONG_STATUS},
-+ {"Created_tmp_files", (char*) &my_tmp_file_created, SHOW_LONG},
-+ {"Created_tmp_tables", (char*) offsetof(STATUS_VAR, created_tmp_tables), SHOW_LONG_STATUS},
-+ {"Delayed_errors", (char*) &delayed_insert_errors, SHOW_LONG},
-+ {"Delayed_insert_threads", (char*) &delayed_insert_threads, SHOW_LONG_NOFLUSH},
-+ {"Delayed_writes", (char*) &delayed_insert_writes, SHOW_LONG},
-+ {"Flush_commands", (char*) &refresh_version, SHOW_LONG_NOFLUSH},
-+ {"Handler_commit", (char*) offsetof(STATUS_VAR, ha_commit_count), SHOW_LONG_STATUS},
-+ {"Handler_delete", (char*) offsetof(STATUS_VAR, ha_delete_count), SHOW_LONG_STATUS},
-+ {"Handler_discover", (char*) offsetof(STATUS_VAR, ha_discover_count), SHOW_LONG_STATUS},
-+ {"Handler_prepare", (char*) offsetof(STATUS_VAR, ha_prepare_count), SHOW_LONG_STATUS},
-+ {"Handler_read_first", (char*) offsetof(STATUS_VAR, ha_read_first_count), SHOW_LONG_STATUS},
-+ {"Handler_read_key", (char*) offsetof(STATUS_VAR, ha_read_key_count), SHOW_LONG_STATUS},
-+ {"Handler_read_next", (char*) offsetof(STATUS_VAR, ha_read_next_count), SHOW_LONG_STATUS},
-+ {"Handler_read_prev", (char*) offsetof(STATUS_VAR, ha_read_prev_count), SHOW_LONG_STATUS},
-+ {"Handler_read_rnd", (char*) offsetof(STATUS_VAR, ha_read_rnd_count), SHOW_LONG_STATUS},
-+ {"Handler_read_rnd_next", (char*) offsetof(STATUS_VAR, ha_read_rnd_next_count), SHOW_LONG_STATUS},
-+ {"Handler_rollback", (char*) offsetof(STATUS_VAR, ha_rollback_count), SHOW_LONG_STATUS},
-+ {"Handler_savepoint", (char*) offsetof(STATUS_VAR, ha_savepoint_count), SHOW_LONG_STATUS},
-+ {"Handler_savepoint_rollback",(char*) offsetof(STATUS_VAR, ha_savepoint_rollback_count), SHOW_LONG_STATUS},
-+ {"Handler_update", (char*) offsetof(STATUS_VAR, ha_update_count), SHOW_LONG_STATUS},
-+ {"Handler_write", (char*) offsetof(STATUS_VAR, ha_write_count), SHOW_LONG_STATUS},
-+ {"Key_blocks_not_flushed", (char*) offsetof(KEY_CACHE, global_blocks_changed), SHOW_KEY_CACHE_LONG},
-+ {"Key_blocks_unused", (char*) offsetof(KEY_CACHE, blocks_unused), SHOW_KEY_CACHE_LONG},
-+ {"Key_blocks_used", (char*) offsetof(KEY_CACHE, blocks_used), SHOW_KEY_CACHE_LONG},
-+ {"Key_read_requests", (char*) offsetof(KEY_CACHE, global_cache_r_requests), SHOW_KEY_CACHE_LONGLONG},
-+ {"Key_reads", (char*) offsetof(KEY_CACHE, global_cache_read), SHOW_KEY_CACHE_LONGLONG},
-+ {"Key_write_requests", (char*) offsetof(KEY_CACHE, global_cache_w_requests), SHOW_KEY_CACHE_LONGLONG},
-+ {"Key_writes", (char*) offsetof(KEY_CACHE, global_cache_write), SHOW_KEY_CACHE_LONGLONG},
-+ {"Last_query_cost", (char*) offsetof(STATUS_VAR, last_query_cost), SHOW_DOUBLE_STATUS},
-+ {"Max_used_connections", (char*) &max_used_connections, SHOW_LONG},
-+ {"Not_flushed_delayed_rows", (char*) &delayed_rows_in_use, SHOW_LONG_NOFLUSH},
-+ {"Open_files", (char*) &my_file_opened, SHOW_LONG_NOFLUSH},
-+ {"Open_streams", (char*) &my_stream_opened, SHOW_LONG_NOFLUSH},
-+ {"Open_table_definitions", (char*) &show_table_definitions, SHOW_FUNC},
-+ {"Open_tables", (char*) &show_open_tables, SHOW_FUNC},
-+ {"Opened_files", (char*) &my_file_total_opened, SHOW_LONG_NOFLUSH},
-+ {"Opened_tables", (char*) offsetof(STATUS_VAR, opened_tables), SHOW_LONG_STATUS},
-+ {"Opened_table_definitions", (char*) offsetof(STATUS_VAR, opened_shares), SHOW_LONG_STATUS},
-+ {"Prepared_stmt_count", (char*) &show_prepared_stmt_count, SHOW_FUNC},
-+#ifdef HAVE_QUERY_CACHE
-+ {"Qcache_free_blocks", (char*) &query_cache.free_memory_blocks, SHOW_LONG_NOFLUSH},
-+ {"Qcache_free_memory", (char*) &query_cache.free_memory, SHOW_LONG_NOFLUSH},
-+ {"Qcache_hits", (char*) &query_cache.hits, SHOW_LONG},
-+ {"Qcache_inserts", (char*) &query_cache.inserts, SHOW_LONG},
-+ {"Qcache_lowmem_prunes", (char*) &query_cache.lowmem_prunes, SHOW_LONG},
-+ {"Qcache_not_cached", (char*) &query_cache.refused, SHOW_LONG},
-+ {"Qcache_queries_in_cache", (char*) &query_cache.queries_in_cache, SHOW_LONG_NOFLUSH},
-+ {"Qcache_total_blocks", (char*) &query_cache.total_blocks, SHOW_LONG_NOFLUSH},
-+#endif /*HAVE_QUERY_CACHE*/
-+ {"Queries", (char*) &show_queries, SHOW_FUNC},
-+ {"Questions", (char*) offsetof(STATUS_VAR, questions), SHOW_LONG_STATUS},
-+#ifdef HAVE_REPLICATION
-+ {"Rpl_status", (char*) &show_rpl_status, SHOW_FUNC},
-+#endif
-+ {"Select_full_join", (char*) offsetof(STATUS_VAR, select_full_join_count), SHOW_LONG_STATUS},
-+ {"Select_full_range_join", (char*) offsetof(STATUS_VAR, select_full_range_join_count), SHOW_LONG_STATUS},
-+ {"Select_range", (char*) offsetof(STATUS_VAR, select_range_count), SHOW_LONG_STATUS},
-+ {"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
-+ {"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
-+ {"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
-+#ifdef HAVE_REPLICATION
-+ {"Slave_retried_transactions",(char*) &show_slave_retried_trans, SHOW_FUNC},
-+ {"Slave_running", (char*) &show_slave_running, SHOW_FUNC},
-+#endif
-+ {"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
-+ {"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
-+ {"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
-+ {"Sort_range", (char*) offsetof(STATUS_VAR, filesort_range_count), SHOW_LONG_STATUS},
-+ {"Sort_rows", (char*) offsetof(STATUS_VAR, filesort_rows), SHOW_LONG_STATUS},
-+ {"Sort_scan", (char*) offsetof(STATUS_VAR, filesort_scan_count), SHOW_LONG_STATUS},
-+#ifdef HAVE_OPENSSL
-+ {"Ssl_accept_renegotiates", (char*) &show_ssl_ctx_sess_accept_renegotiate, SHOW_FUNC},
-+ {"Ssl_accepts", (char*) &show_ssl_ctx_sess_accept, SHOW_FUNC},
-+ {"Ssl_callback_cache_hits", (char*) &show_ssl_ctx_sess_cb_hits, SHOW_FUNC},
-+ {"Ssl_cipher", (char*) &show_ssl_get_cipher, SHOW_FUNC},
-+ {"Ssl_cipher_list", (char*) &show_ssl_get_cipher_list, SHOW_FUNC},
-+ {"Ssl_client_connects", (char*) &show_ssl_ctx_sess_connect, SHOW_FUNC},
-+ {"Ssl_connect_renegotiates", (char*) &show_ssl_ctx_sess_connect_renegotiate, SHOW_FUNC},
-+ {"Ssl_ctx_verify_depth", (char*) &show_ssl_ctx_get_verify_depth, SHOW_FUNC},
-+ {"Ssl_ctx_verify_mode", (char*) &show_ssl_ctx_get_verify_mode, SHOW_FUNC},
-+ {"Ssl_default_timeout", (char*) &show_ssl_get_default_timeout, SHOW_FUNC},
-+ {"Ssl_finished_accepts", (char*) &show_ssl_ctx_sess_accept_good, SHOW_FUNC},
-+ {"Ssl_finished_connects", (char*) &show_ssl_ctx_sess_connect_good, SHOW_FUNC},
-+ {"Ssl_session_cache_hits", (char*) &show_ssl_ctx_sess_hits, SHOW_FUNC},
-+ {"Ssl_session_cache_misses", (char*) &show_ssl_ctx_sess_misses, SHOW_FUNC},
-+ {"Ssl_session_cache_mode", (char*) &show_ssl_ctx_get_session_cache_mode, SHOW_FUNC},
-+ {"Ssl_session_cache_overflows", (char*) &show_ssl_ctx_sess_cache_full, SHOW_FUNC},
-+ {"Ssl_session_cache_size", (char*) &show_ssl_ctx_sess_get_cache_size, SHOW_FUNC},
-+ {"Ssl_session_cache_timeouts", (char*) &show_ssl_ctx_sess_timeouts, SHOW_FUNC},
-+ {"Ssl_sessions_reused", (char*) &show_ssl_session_reused, SHOW_FUNC},
-+ {"Ssl_used_session_cache_entries",(char*) &show_ssl_ctx_sess_number, SHOW_FUNC},
-+ {"Ssl_verify_depth", (char*) &show_ssl_get_verify_depth, SHOW_FUNC},
-+ {"Ssl_verify_mode", (char*) &show_ssl_get_verify_mode, SHOW_FUNC},
-+ {"Ssl_version", (char*) &show_ssl_get_version, SHOW_FUNC},
-+#endif /* HAVE_OPENSSL */
-+ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG},
-+ {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG},
-+#ifdef HAVE_MMAP
-+ {"Tc_log_max_pages_used", (char*) &tc_log_max_pages_used, SHOW_LONG},
-+ {"Tc_log_page_size", (char*) &tc_log_page_size, SHOW_LONG},
-+ {"Tc_log_page_waits", (char*) &tc_log_page_waits, SHOW_LONG},
-+#endif
-+ {"Threads_cached", (char*) &cached_thread_count, SHOW_LONG_NOFLUSH},
-+ {"Threads_connected", (char*) &thread_count, SHOW_INT},
-+ {"Threads_created", (char*) &thread_created, SHOW_LONG_NOFLUSH},
-+ {"Threads_running", (char*) &thread_running, SHOW_INT},
-+ {"Uptime", (char*) &show_starttime, SHOW_FUNC},
-+#ifdef COMMUNITY_SERVER
-+ {"Uptime_since_flush_status",(char*) &show_flushstatustime, SHOW_FUNC},
-+#endif
-+ {NullS, NullS, SHOW_LONG}
-+};
-+
-+#ifndef EMBEDDED_LIBRARY
-+static void print_version(void)
-+{
-+ set_server_version();
-+ /*
-+ Note: the instance manager keys off the string 'Ver' so it can find the
-+ version from the output of 'mysqld --version', so don't change it!
-+ */
-+ printf("%s Ver %s for %s on %s (%s)\n",my_progname,
-+ server_version,SYSTEM_TYPE,MACHINE_TYPE, MYSQL_COMPILATION_COMMENT);
-+}
-+
-+static void usage(void)
-+{
-+ if (!(default_charset_info= get_charset_by_csname(default_character_set_name,
-+ MY_CS_PRIMARY,
-+ MYF(MY_WME))))
-+ exit(1);
-+ if (!default_collation_name)
-+ default_collation_name= (char*) default_charset_info->name;
-+ print_version();
-+ puts("\
-+Copyright (C) 2000-2008 MySQL AB, by Monty and others.\n\
-+Copyright (C) 2008 Sun Microsystems, Inc.\n\
-+This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\
-+and you are welcome to modify and redistribute it under the GPL license\n\n\
-+Starts the MySQL database server.\n");
-+
-+ printf("Usage: %s [OPTIONS]\n", my_progname);
-+ if (!opt_verbose)
-+ puts("\nFor more help options (several pages), use mysqld --verbose --help.");
-+ else
-+ {
-+#ifdef __WIN__
-+ puts("NT and Win32 specific options:\n\
-+ --install Install the default service (NT).\n\
-+ --install-manual Install the default service started manually (NT).\n\
-+ --install service_name Install an optional service (NT).\n\
-+ --install-manual service_name Install an optional service started manually (NT).\n\
-+ --remove Remove the default service from the service list (NT).\n\
-+ --remove service_name Remove the service_name from the service list (NT).\n\
-+ --enable-named-pipe Only to be used for the default server (NT).\n\
-+ --standalone Dummy option to start as a standalone server (NT).\
-+");
-+ puts("");
-+#endif
-+ print_defaults(MYSQL_CONFIG_NAME,load_default_groups);
-+ puts("");
-+ set_ports();
-+
-+ /* Print out all the options including plugin supplied options */
-+ my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
-+
-+ if (! plugins_are_initialized)
-+ {
-+ puts("\n\
-+Plugins have parameters that are not reflected in this list\n\
-+because execution stopped before plugins were initialized.");
-+ }
-+
-+ puts("\n\
-+To see what values a running MySQL server is using, type\n\
-+'mysqladmin variables' instead of 'mysqld --verbose --help'.");
-+ }
-+}
-+#endif /*!EMBEDDED_LIBRARY*/
-+
-+
-+/**
-+ Initialize all MySQL global variables to default values.
-+
-+ We don't need to set numeric variables refered to in my_long_options
-+ as these are initialized by my_getopt.
-+
-+ @note
-+ The reason to set a lot of global variables to zero is to allow one to
-+ restart the embedded server with a clean environment
-+ It's also needed on some exotic platforms where global variables are
-+ not set to 0 when a program starts.
-+
-+ We don't need to set numeric variables refered to in my_long_options
-+ as these are initialized by my_getopt.
-+*/
-+
-+static int mysql_init_variables(void)
-+{
-+ int error;
-+ /* Things reset to zero */
-+ opt_skip_slave_start= opt_reckless_slave = 0;
-+ mysql_home[0]= pidfile_name[0]= log_error_file[0]= 0;
-+ myisam_test_invalid_symlink= test_if_data_home_dir;
-+ opt_log= opt_slow_log= 0;
-+ opt_update_log= 0;
-+ log_output_options= find_bit_type(log_output_str, &log_output_typelib);
-+ opt_bin_log= 0;
-+ opt_disable_networking= opt_skip_show_db=0;
-+ opt_skip_name_resolve= 0;
-+ opt_ignore_builtin_innodb= 0;
-+ opt_logname= opt_update_logname= opt_binlog_index_name= opt_slow_logname= 0;
-+ opt_tc_log_file= (char *)"tc.log"; // no hostname in tc_log file name !
-+ opt_secure_auth= 0;
-+ opt_secure_file_priv= 0;
-+ opt_bootstrap= opt_myisam_log= 0;
-+ mqh_used= 0;
-+ segfaulted= kill_in_progress= 0;
-+ cleanup_done= 0;
-+ defaults_argc= 0;
-+ defaults_argv= 0;
-+ server_id_supplied= 0;
-+ test_flags= select_errors= dropping_tables= ha_open_options=0;
-+ thread_count= thread_running= kill_cached_threads= wake_thread=0;
-+ slave_open_temp_tables= 0;
-+ cached_thread_count= 0;
-+ opt_endinfo= using_udf_functions= 0;
-+ opt_using_transactions= 0;
-+ abort_loop= select_thread_in_use= signal_thread_in_use= 0;
-+ ready_to_exit= shutdown_in_progress= grant_option= 0;
-+ aborted_threads= aborted_connects= 0;
-+ delayed_insert_threads= delayed_insert_writes= delayed_rows_in_use= 0;
-+ delayed_insert_errors= thread_created= 0;
-+ specialflag= 0;
-+ binlog_cache_use= binlog_cache_disk_use= 0;
-+ max_used_connections= slow_launch_threads = 0;
-+ mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
-+ prepared_stmt_count= 0;
-+ errmesg= 0;
-+ mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
-+ bzero((uchar*) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
-+ bzero((char *) &global_status_var, sizeof(global_status_var));
-+ opt_large_pages= 0;
-+#if defined(ENABLED_DEBUG_SYNC)
-+ opt_debug_sync_timeout= 0;
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+ key_map_full.set_all();
-+
-+ /* Character sets */
-+ system_charset_info= &my_charset_utf8_general_ci;
-+ files_charset_info= &my_charset_utf8_general_ci;
-+ national_charset_info= &my_charset_utf8_general_ci;
-+ table_alias_charset= &my_charset_bin;
-+ character_set_filesystem= &my_charset_bin;
-+
-+ opt_date_time_formats[0]= opt_date_time_formats[1]= opt_date_time_formats[2]= 0;
-+
-+ /* Things with default values that are not zero */
-+ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
-+ slave_exec_mode_options= find_bit_type_or_exit(slave_exec_mode_str,
-+ &slave_exec_mode_typelib,
-+ NULL, &error);
-+ /* Default mode string must not yield a error. */
-+ DBUG_ASSERT(!error);
-+ if (error)
-+ return 1;
-+ opt_specialflag= SPECIAL_ENGLISH;
-+ unix_sock= ip_sock= INVALID_SOCKET;
-+ mysql_home_ptr= mysql_home;
-+ pidfile_name_ptr= pidfile_name;
-+ log_error_file_ptr= log_error_file;
-+ language_ptr= language;
-+ mysql_data_home= mysql_real_data_home;
-+ thd_startup_options= (OPTION_AUTO_IS_NULL | OPTION_BIN_LOG |
-+ OPTION_QUOTE_SHOW_CREATE | OPTION_SQL_NOTES);
-+ protocol_version= PROTOCOL_VERSION;
-+ what_to_log= ~ (1L << (uint) COM_TIME);
-+ refresh_version= 1L; /* Increments on each reload */
-+ global_query_id= thread_id= 1L;
-+ strmov(server_version, MYSQL_SERVER_VERSION);
-+ myisam_recover_options_str= sql_mode_str= "OFF";
-+ myisam_stats_method_str= "nulls_unequal";
-+ my_bind_addr = htonl(INADDR_ANY);
-+ threads.empty();
-+ thread_cache.empty();
-+ key_caches.empty();
-+ if (!(dflt_key_cache= get_or_create_key_cache(default_key_cache_base.str,
-+ default_key_cache_base.length)))
-+ {
-+ sql_print_error("Cannot allocate the keycache");
-+ return 1;
-+ }
-+ /* set key_cache_hash.default_value = dflt_key_cache */
-+ multi_keycache_init();
-+
-+ /* Set directory paths */
-+ strmake(language, LANGUAGE, sizeof(language)-1);
-+ strmake(mysql_real_data_home, get_relative_path(MYSQL_DATADIR),
-+ sizeof(mysql_real_data_home)-1);
-+ mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
-+ mysql_data_home_buff[1]=0;
-+ mysql_data_home_len= 2;
-+
-+ /* Replication parameters */
-+ master_user= (char*) "test";
-+ master_password= master_host= 0;
-+ master_info_file= (char*) "master.info",
-+ relay_log_info_file= (char*) "relay-log.info";
-+ master_ssl_key= master_ssl_cert= master_ssl_ca=
-+ master_ssl_capath= master_ssl_cipher= 0;
-+ report_user= report_password = report_host= 0; /* TO BE DELETED */
-+ opt_relay_logname= opt_relaylog_index_name= 0;
-+
-+ /* Variables in libraries */
-+ charsets_dir= 0;
-+ default_character_set_name= (char*) MYSQL_DEFAULT_CHARSET_NAME;
-+ default_collation_name= compiled_default_collation_name;
-+ sys_charset_system.value= (char*) system_charset_info->csname;
-+ character_set_filesystem_name= (char*) "binary";
-+ lc_time_names_name= (char*) "en_US";
-+ /* Set default values for some option variables */
-+ default_storage_engine_str= (char*) "MyISAM";
-+ global_system_variables.table_plugin= NULL;
-+ global_system_variables.tx_isolation= ISO_REPEATABLE_READ;
-+ global_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
-+ max_system_variables.select_limit= (ulonglong) HA_POS_ERROR;
-+ global_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
-+ max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR;
-+ global_system_variables.old_passwords= 0;
-+ global_system_variables.old_alter_table= 0;
-+ global_system_variables.binlog_format= BINLOG_FORMAT_UNSPEC;
-+ /*
-+ Default behavior for 4.1 and 5.0 is to treat NULL values as unequal
-+ when collecting index statistics for MyISAM tables.
-+ */
-+ global_system_variables.myisam_stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
-+
-+ global_system_variables.optimizer_switch= OPTIMIZER_SWITCH_DEFAULT;
-+ /* Variables that depends on compile options */
-+#ifndef DBUG_OFF
-+ default_dbug_option=IF_WIN("d:t:i:O,\\mysqld.trace",
-+ "d:t:i:o,/tmp/mysqld.trace");
-+#endif
-+ opt_error_log= IF_WIN(1,0);
-+#ifdef COMMUNITY_SERVER
-+ have_community_features = SHOW_OPTION_YES;
-+#else
-+ have_community_features = SHOW_OPTION_NO;
-+#endif
-+ global_system_variables.ndb_index_stat_enable=FALSE;
-+ max_system_variables.ndb_index_stat_enable=TRUE;
-+ global_system_variables.ndb_index_stat_cache_entries=32;
-+ max_system_variables.ndb_index_stat_cache_entries=~0L;
-+ global_system_variables.ndb_index_stat_update_freq=20;
-+ max_system_variables.ndb_index_stat_update_freq=~0L;
-+#ifdef HAVE_OPENSSL
-+ have_ssl=SHOW_OPTION_YES;
-+#else
-+ have_ssl=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_BROKEN_REALPATH
-+ have_symlink=SHOW_OPTION_NO;
-+#else
-+ have_symlink=SHOW_OPTION_YES;
-+#endif
-+#ifdef HAVE_DLOPEN
-+ have_dlopen=SHOW_OPTION_YES;
-+#else
-+ have_dlopen=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_QUERY_CACHE
-+ have_query_cache=SHOW_OPTION_YES;
-+#else
-+ have_query_cache=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_SPATIAL
-+ have_geometry=SHOW_OPTION_YES;
-+#else
-+ have_geometry=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_RTREE_KEYS
-+ have_rtree_keys=SHOW_OPTION_YES;
-+#else
-+ have_rtree_keys=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_CRYPT
-+ have_crypt=SHOW_OPTION_YES;
-+#else
-+ have_crypt=SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_COMPRESS
-+ have_compress= SHOW_OPTION_YES;
-+#else
-+ have_compress= SHOW_OPTION_NO;
-+#endif
-+#ifdef HAVE_LIBWRAP
-+ libwrapName= NullS;
-+#endif
-+#ifdef HAVE_OPENSSL
-+ des_key_file = 0;
-+ ssl_acceptor_fd= 0;
-+#endif
-+#ifdef HAVE_SMEM
-+ shared_memory_base_name= default_shared_memory_base_name;
-+#endif
-+#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
-+ opt_specialflag |= SPECIAL_NO_PRIOR;
-+#endif
-+
-+#if defined(__WIN__) || defined(__NETWARE__)
-+ /* Allow Win32 and NetWare users to move MySQL anywhere */
-+ {
-+ char prg_dev[LIBLEN];
-+#if defined __WIN__
-+ char executing_path_name[LIBLEN];
-+ if (!test_if_hard_path(my_progname))
-+ {
-+ // we don't want to use GetModuleFileName inside of my_path since
-+ // my_path is a generic path dereferencing function and here we care
-+ // only about the executing binary.
-+ GetModuleFileName(NULL, executing_path_name, sizeof(executing_path_name));
-+ my_path(prg_dev, executing_path_name, NULL);
-+ }
-+ else
-+#endif
-+ my_path(prg_dev,my_progname,"mysql/bin");
-+ strcat(prg_dev,"/../"); // Remove 'bin' to get base dir
-+ cleanup_dirname(mysql_home,prg_dev);
-+ }
-+#else
-+ const char *tmpenv;
-+ if (!(tmpenv = getenv("MY_BASEDIR_VERSION")))
-+ tmpenv = DEFAULT_MYSQL_HOME;
-+ (void) strmake(mysql_home, tmpenv, sizeof(mysql_home)-1);
-+#endif
-+ return 0;
-+}
-+
-+
-+my_bool
-+mysqld_get_one_option(int optid,
-+ const struct my_option *opt __attribute__((unused)),
-+ char *argument)
-+{
-+ int error;
-+
-+ switch(optid) {
-+ case '#':
-+#ifndef DBUG_OFF
-+ DBUG_SET_INITIAL(argument ? argument : default_dbug_option);
-+#endif
-+ opt_endinfo=1; /* unireg: memory allocation */
-+ break;
-+ case '0':
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-long-format", "--log-short-format");
-+ break;
-+ case 'a':
-+ global_system_variables.sql_mode= fix_sql_mode(MODE_ANSI);
-+ global_system_variables.tx_isolation= ISO_SERIALIZABLE;
-+ break;
-+ case 'b':
-+ strmake(mysql_home,argument,sizeof(mysql_home)-1);
-+ break;
-+ case OPT_DEFAULT_CHARACTER_SET_OLD: // --default-character-set
-+ WARN_DEPRECATED(NULL, VER_CELOSIA,
-+ "--default-character-set",
-+ "--character-set-server");
-+ /* Fall through */
-+ case 'C':
-+ if (default_collation_name == compiled_default_collation_name)
-+ default_collation_name= 0;
-+ break;
-+ case 'l':
-+ WARN_DEPRECATED(NULL, "7.0", "--log", "'--general_log'/'--general_log_file'");
-+ opt_log=1;
-+ break;
-+ case 'h':
-+ strmake(mysql_real_data_home,argument, sizeof(mysql_real_data_home)-1);
-+ /* Correct pointer set by my_getopt (for embedded library) */
-+ mysql_data_home= mysql_real_data_home;
-+ mysql_data_home_len= strlen(mysql_data_home);
-+ break;
-+ case 'u':
-+ if (!mysqld_user || !strcmp(mysqld_user, argument))
-+ mysqld_user= argument;
-+ else
-+ sql_print_warning("Ignoring user change to '%s' because the user was set to '%s' earlier on the command line\n", argument, mysqld_user);
-+ break;
-+ case 'L':
-+ strmake(language, argument, sizeof(language)-1);
-+ break;
-+ case 'O':
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--set-variable", "--variable-name=value");
-+ break;
-+#ifdef HAVE_REPLICATION
-+ case OPT_SLAVE_SKIP_ERRORS:
-+ init_slave_skip_errors(argument);
-+ break;
-+ case OPT_SLAVE_EXEC_MODE:
-+ slave_exec_mode_options= find_bit_type_or_exit(argument,
-+ &slave_exec_mode_typelib,
-+ "", &error);
-+ if (error)
-+ return 1;
-+ break;
-+#endif
-+ case OPT_SAFEMALLOC_MEM_LIMIT:
-+#if !defined(DBUG_OFF) && defined(SAFEMALLOC)
-+ sf_malloc_mem_limit = atoi(argument);
-+#endif
-+ break;
-+#include <sslopt-case.h>
-+#ifndef EMBEDDED_LIBRARY
-+ case 'V':
-+ print_version();
-+ exit(0);
-+#endif /*EMBEDDED_LIBRARY*/
-+ case OPT_WARNINGS:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--warnings", "--log-warnings");
-+ /* Note: fall-through to 'W' */
-+ case 'W':
-+ if (!argument)
-+ global_system_variables.log_warnings++;
-+ else if (argument == disabled_my_option)
-+ global_system_variables.log_warnings= 0L;
-+ else
-+ global_system_variables.log_warnings= atoi(argument);
-+ break;
-+ case 'T':
-+ test_flags= argument ? (uint) atoi(argument) : 0;
-+ opt_endinfo=1;
-+ break;
-+ case (int) OPT_DEFAULT_COLLATION_OLD:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--default-collation", "--collation-server");
-+ break;
-+ case (int) OPT_SAFE_SHOW_DB:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--safe-show-database", "GRANT SHOW DATABASES");
-+ break;
-+ case (int) OPT_LOG_BIN_TRUST_FUNCTION_CREATORS_OLD:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-bin-trust-routine-creators", "--log-bin-trust-function-creators");
-+ break;
-+ case (int) OPT_ENABLE_LOCK:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--enable-locking", "--external-locking");
-+ break;
-+ case (int) OPT_BIG_TABLES:
-+ thd_startup_options|=OPTION_BIG_TABLES;
-+ break;
-+ case (int) OPT_IGNORE_BUILTIN_INNODB:
-+ opt_ignore_builtin_innodb= 1;
-+ break;
-+ case (int) OPT_ISAM_LOG:
-+ opt_myisam_log=1;
-+ break;
-+ case (int) OPT_UPDATE_LOG:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--log-update", "--log-bin");
-+ opt_update_log=1;
-+ break;
-+ case (int) OPT_BIN_LOG:
-+ opt_bin_log= test(argument != disabled_my_option);
-+ break;
-+ case (int) OPT_ERROR_LOG_FILE:
-+ opt_error_log= 1;
-+ break;
-+#ifdef HAVE_REPLICATION
-+ case (int) OPT_INIT_RPL_ROLE:
-+ {
-+ int role;
-+ role= find_type_or_exit(argument, &rpl_role_typelib, opt->name);
-+ rpl_status = (role == 1) ? RPL_AUTH_MASTER : RPL_IDLE_SLAVE;
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_IGNORE_DB:
-+ {
-+ rpl_filter->add_ignore_db(argument);
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_DO_DB:
-+ {
-+ rpl_filter->add_do_db(argument);
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_REWRITE_DB:
-+ {
-+ char* key = argument,*p, *val;
-+
-+ if (!(p= strstr(argument, "->")))
-+ {
-+ sql_print_error("Bad syntax in replicate-rewrite-db - missing '->'!\n");
-+ return 1;
-+ }
-+ val= p--;
-+ while (my_isspace(mysqld_charset, *p) && p > argument)
-+ *p-- = 0;
-+ if (p == argument)
-+ {
-+ sql_print_error("Bad syntax in replicate-rewrite-db - empty FROM db!\n");
-+ return 1;
-+ }
-+ *val= 0;
-+ val+= 2;
-+ while (*val && my_isspace(mysqld_charset, *val))
-+ val++;
-+ if (!*val)
-+ {
-+ sql_print_error("Bad syntax in replicate-rewrite-db - empty TO db!\n");
-+ return 1;
-+ }
-+
-+ rpl_filter->add_db_rewrite(key, val);
-+ break;
-+ }
-+
-+ case (int)OPT_BINLOG_IGNORE_DB:
-+ {
-+ binlog_filter->add_ignore_db(argument);
-+ break;
-+ }
-+ case OPT_BINLOG_FORMAT:
-+ {
-+ int id;
-+ id= find_type_or_exit(argument, &binlog_format_typelib, opt->name);
-+ global_system_variables.binlog_format= opt_binlog_format_id= id - 1;
-+ break;
-+ }
-+ case (int)OPT_BINLOG_DO_DB:
-+ {
-+ binlog_filter->add_do_db(argument);
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_DO_TABLE:
-+ {
-+ if (rpl_filter->add_do_table(argument))
-+ {
-+ sql_print_error("Could not add do table rule '%s'!\n", argument);
-+ return 1;
-+ }
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_WILD_DO_TABLE:
-+ {
-+ if (rpl_filter->add_wild_do_table(argument))
-+ {
-+ sql_print_error("Could not add do table rule '%s'!\n", argument);
-+ return 1;
-+ }
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_WILD_IGNORE_TABLE:
-+ {
-+ if (rpl_filter->add_wild_ignore_table(argument))
-+ {
-+ sql_print_error("Could not add ignore table rule '%s'!\n", argument);
-+ return 1;
-+ }
-+ break;
-+ }
-+ case (int)OPT_REPLICATE_IGNORE_TABLE:
-+ {
-+ if (rpl_filter->add_ignore_table(argument))
-+ {
-+ sql_print_error("Could not add ignore table rule '%s'!\n", argument);
-+ return 1;
-+ }
-+ break;
-+ }
-+#endif /* HAVE_REPLICATION */
-+ case (int) OPT_SLOW_QUERY_LOG:
-+ WARN_DEPRECATED(NULL, "7.0", "--log_slow_queries", "'--slow_query_log'/'--slow_query_log_file'");
-+ opt_slow_log= 1;
-+ break;
-+#ifdef WITH_CSV_STORAGE_ENGINE
-+ case OPT_LOG_OUTPUT:
-+ {
-+ if (!argument || !argument[0])
-+ {
-+ log_output_options= LOG_FILE;
-+ log_output_str= log_output_typelib.type_names[1];
-+ }
-+ else
-+ {
-+ log_output_str= argument;
-+ log_output_options=
-+ find_bit_type_or_exit(argument, &log_output_typelib, opt->name, &error);
-+ if (error)
-+ return 1;
-+ }
-+ break;
-+ }
-+#endif
-+ case OPT_EVENT_SCHEDULER:
-+#ifndef HAVE_EVENT_SCHEDULER
-+ sql_perror("Event scheduler is not supported in embedded build.");
-+#else
-+ if (Events::set_opt_event_scheduler(argument))
-+ return 1;
-+#endif
-+ break;
-+ case (int) OPT_SKIP_NEW:
-+ opt_specialflag|= SPECIAL_NO_NEW_FUNC;
-+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
-+ myisam_concurrent_insert=0;
-+ myisam_recover_options= HA_RECOVER_NONE;
-+ sp_automatic_privileges=0;
-+ my_use_symdir=0;
-+ ha_open_options&= ~(HA_OPEN_ABORT_IF_CRASHED | HA_OPEN_DELAY_KEY_WRITE);
-+#ifdef HAVE_QUERY_CACHE
-+ query_cache_size=0;
-+#endif
-+ break;
-+ case (int) OPT_SAFE:
-+ opt_specialflag|= SPECIAL_SAFE_MODE;
-+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
-+ myisam_recover_options= HA_RECOVER_DEFAULT;
-+ ha_open_options&= ~(HA_OPEN_DELAY_KEY_WRITE);
-+ break;
-+ case (int) OPT_SKIP_PRIOR:
-+ opt_specialflag|= SPECIAL_NO_PRIOR;
-+ sql_print_warning("The --skip-thread-priority startup option is deprecated "
-+ "and will be removed in MySQL 7.0. MySQL 6.0 and up do not "
-+ "give threads different priorities.");
-+ break;
-+ case (int) OPT_SKIP_LOCK:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-locking", "--skip-external-locking");
-+ opt_external_locking=0;
-+ break;
-+ case (int) OPT_SQL_BIN_UPDATE_SAME:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--sql-bin-update-same", "the binary log");
-+ break;
-+ case (int) OPT_RECORD_BUFFER_OLD:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "record_buffer", "read_buffer_size");
-+ break;
-+ case (int) OPT_SYMBOLIC_LINKS:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--use-symbolic-links", "--symbolic-links");
-+ break;
-+ case (int) OPT_SKIP_HOST_CACHE:
-+ opt_specialflag|= SPECIAL_NO_HOST_CACHE;
-+ break;
-+ case (int) OPT_SKIP_RESOLVE:
-+ opt_skip_name_resolve= 1;
-+ opt_specialflag|=SPECIAL_NO_RESOLVE;
-+ break;
-+ case (int) OPT_SKIP_NETWORKING:
-+#if defined(__NETWARE__)
-+ sql_perror("Can't start server: skip-networking option is currently not supported on NetWare");
-+ return 1;
-+#endif
-+ opt_disable_networking=1;
-+ mysqld_port=0;
-+ break;
-+ case (int) OPT_SKIP_SHOW_DB:
-+ opt_skip_show_db=1;
-+ opt_specialflag|=SPECIAL_SKIP_SHOW_DB;
-+ break;
-+ case (int) OPT_WANT_CORE:
-+ test_flags |= TEST_CORE_ON_SIGNAL;
-+ break;
-+ case (int) OPT_SKIP_STACK_TRACE:
-+ test_flags|=TEST_NO_STACKTRACE;
-+ break;
-+ case (int) OPT_SKIP_SYMLINKS:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--skip-symlink", "--skip-symbolic-links");
-+ my_use_symdir=0;
-+ break;
-+ case (int) OPT_BIND_ADDRESS:
-+ if ((my_bind_addr= (ulong) inet_addr(argument)) == INADDR_NONE)
-+ {
-+ struct hostent *ent;
-+ if (argument[0])
-+ ent=gethostbyname(argument);
-+ else
-+ {
-+ char myhostname[255];
-+ if (gethostname(myhostname,sizeof(myhostname)) < 0)
-+ {
-+ sql_perror("Can't start server: cannot get my own hostname!");
-+ return 1;
-+ }
-+ ent=gethostbyname(myhostname);
-+ }
-+ if (!ent)
-+ {
-+ sql_perror("Can't start server: cannot resolve hostname!");
-+ return 1;
-+ }
-+ my_bind_addr = (ulong) ((in_addr*)ent->h_addr_list[0])->s_addr;
-+ }
-+ break;
-+ case (int) OPT_PID_FILE:
-+ strmake(pidfile_name, argument, sizeof(pidfile_name)-1);
-+ break;
-+#ifdef __WIN__
-+ case (int) OPT_STANDALONE: /* Dummy option for NT */
-+ break;
-+#endif
-+ /*
-+ The following change issues a deprecation warning if the slave
-+ configuration is specified either in the my.cnf file or on
-+ the command-line. See BUG#21490.
-+ */
-+ case OPT_MASTER_HOST:
-+ case OPT_MASTER_USER:
-+ case OPT_MASTER_PASSWORD:
-+ case OPT_MASTER_PORT:
-+ case OPT_MASTER_CONNECT_RETRY:
-+ case OPT_MASTER_SSL:
-+ case OPT_MASTER_SSL_KEY:
-+ case OPT_MASTER_SSL_CERT:
-+ case OPT_MASTER_SSL_CAPATH:
-+ case OPT_MASTER_SSL_CIPHER:
-+ case OPT_MASTER_SSL_CA:
-+ if (!slave_warning_issued) //only show the warning once
-+ {
-+ slave_warning_issued = true;
-+ WARN_DEPRECATED(NULL, "6.0", "for replication startup options",
-+ "'CHANGE MASTER'");
-+ }
-+ break;
-+ case OPT_CONSOLE:
-+ if (opt_console)
-+ opt_error_log= 0; // Force logs to stdout
-+ break;
-+ case (int) OPT_FLUSH:
-+ myisam_flush=1;
-+ flush_time=0; // No auto flush
-+ break;
-+ case OPT_LOW_PRIORITY_UPDATES:
-+ thr_upgraded_concurrent_insert_lock= TL_WRITE_LOW_PRIORITY;
-+ global_system_variables.low_priority_updates=1;
-+ break;
-+ case OPT_BOOTSTRAP:
-+ opt_noacl=opt_bootstrap=1;
-+ break;
-+ case OPT_SERVER_ID:
-+ server_id_supplied = 1;
-+ break;
-+ case OPT_DELAY_KEY_WRITE_ALL:
-+ WARN_DEPRECATED(NULL, VER_CELOSIA,
-+ "--delay-key-write-for-all-tables",
-+ "--delay-key-write=ALL");
-+ if (argument != disabled_my_option)
-+ argument= (char*) "ALL";
-+ /* Fall through */
-+ case OPT_DELAY_KEY_WRITE:
-+ if (argument == disabled_my_option)
-+ delay_key_write_options= (uint) DELAY_KEY_WRITE_NONE;
-+ else if (! argument)
-+ delay_key_write_options= (uint) DELAY_KEY_WRITE_ON;
-+ else
-+ {
-+ int type;
-+ type= find_type_or_exit(argument, &delay_key_write_typelib, opt->name);
-+ delay_key_write_options= (uint) type-1;
-+ }
-+ break;
-+ case OPT_MYISAM_MAX_EXTRA_SORT_FILE_SIZE:
-+ sql_print_warning("--myisam_max_extra_sort_file_size is deprecated and "
-+ "does nothing in this version. It will be removed in "
-+ "a future release.");
-+ break;
-+ case OPT_CHARSETS_DIR:
-+ strmake(mysql_charsets_dir, argument, sizeof(mysql_charsets_dir)-1);
-+ charsets_dir = mysql_charsets_dir;
-+ break;
-+ case OPT_TX_ISOLATION:
-+ {
-+ int type;
-+ type= find_type_or_exit(argument, &tx_isolation_typelib, opt->name);
-+ global_system_variables.tx_isolation= (type-1);
-+ break;
-+ }
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+ case OPT_NDB_MGMD:
-+ case OPT_NDB_NODEID:
-+ {
-+ int len= my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
-+ sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
-+ "%s%s%s",opt_ndb_constrbuf_len > 0 ? ",":"",
-+ optid == OPT_NDB_NODEID ? "nodeid=" : "",
-+ argument);
-+ opt_ndb_constrbuf_len+= len;
-+ }
-+ /* fall through to add the connectstring to the end
-+ * and set opt_ndbcluster_connectstring
-+ */
-+ case OPT_NDB_CONNECTSTRING:
-+ if (opt_ndb_connectstring && opt_ndb_connectstring[0])
-+ my_snprintf(opt_ndb_constrbuf+opt_ndb_constrbuf_len,
-+ sizeof(opt_ndb_constrbuf)-opt_ndb_constrbuf_len,
-+ "%s%s", opt_ndb_constrbuf_len > 0 ? ",":"",
-+ opt_ndb_connectstring);
-+ else
-+ opt_ndb_constrbuf[opt_ndb_constrbuf_len]= 0;
-+ opt_ndbcluster_connectstring= opt_ndb_constrbuf;
-+ break;
-+ case OPT_NDB_DISTRIBUTION:
-+ int id;
-+ id= find_type_or_exit(argument, &ndb_distribution_typelib, opt->name);
-+ opt_ndb_distribution_id= (enum ndb_distribution)(id-1);
-+ break;
-+ case OPT_NDB_EXTRA_LOGGING:
-+ if (!argument)
-+ ndb_extra_logging++;
-+ else if (argument == disabled_my_option)
-+ ndb_extra_logging= 0L;
-+ else
-+ ndb_extra_logging= atoi(argument);
-+ break;
-+#endif
-+ case OPT_MYISAM_RECOVER:
-+ {
-+ if (!argument)
-+ {
-+ myisam_recover_options= HA_RECOVER_DEFAULT;
-+ myisam_recover_options_str= myisam_recover_typelib.type_names[0];
-+ }
-+ else if (!argument[0])
-+ {
-+ myisam_recover_options= HA_RECOVER_NONE;
-+ myisam_recover_options_str= "OFF";
-+ }
-+ else
-+ {
-+ myisam_recover_options_str=argument;
-+ myisam_recover_options=
-+ find_bit_type_or_exit(argument, &myisam_recover_typelib, opt->name,
-+ &error);
-+ if (error)
-+ return 1;
-+ }
-+ ha_open_options|=HA_OPEN_ABORT_IF_CRASHED;
-+ break;
-+ }
-+ case OPT_CONCURRENT_INSERT:
-+ /* The following code is mainly here to emulate old behavior */
-+ if (!argument) /* --concurrent-insert */
-+ myisam_concurrent_insert= 1;
-+ else if (argument == disabled_my_option)
-+ myisam_concurrent_insert= 0; /* --skip-concurrent-insert */
-+ break;
-+ case OPT_TC_HEURISTIC_RECOVER:
-+ tc_heuristic_recover= find_type_or_exit(argument,
-+ &tc_heuristic_recover_typelib,
-+ opt->name);
-+ break;
-+ case OPT_MYISAM_STATS_METHOD:
-+ {
-+ ulong method_conv;
-+ int method;
-+ LINT_INIT(method_conv);
-+
-+ myisam_stats_method_str= argument;
-+ method= find_type_or_exit(argument, &myisam_stats_method_typelib,
-+ opt->name);
-+ switch (method-1) {
-+ case 2:
-+ method_conv= MI_STATS_METHOD_IGNORE_NULLS;
-+ break;
-+ case 1:
-+ method_conv= MI_STATS_METHOD_NULLS_EQUAL;
-+ break;
-+ case 0:
-+ default:
-+ method_conv= MI_STATS_METHOD_NULLS_NOT_EQUAL;
-+ break;
-+ }
-+ global_system_variables.myisam_stats_method= method_conv;
-+ break;
-+ }
-+ case OPT_SQL_MODE:
-+ {
-+ sql_mode_str= argument;
-+ global_system_variables.sql_mode=
-+ find_bit_type_or_exit(argument, &sql_mode_typelib, opt->name, &error);
-+ if (error)
-+ return 1;
-+ global_system_variables.sql_mode= fix_sql_mode(global_system_variables.
-+ sql_mode);
-+ break;
-+ }
-+ case OPT_OPTIMIZER_SWITCH:
-+ {
-+ bool not_used;
-+ char *error= 0;
-+ uint error_len= 0;
-+ optimizer_switch_str= argument;
-+ global_system_variables.optimizer_switch=
-+ (ulong)find_set_from_flags(&optimizer_switch_typelib,
-+ optimizer_switch_typelib.count,
-+ global_system_variables.optimizer_switch,
-+ global_system_variables.optimizer_switch,
-+ argument, strlen(argument), NULL,
-+ &error, &error_len, ¬_used);
-+ if (error)
-+ {
-+ char buf[512];
-+ char *cbuf= buf;
-+ cbuf += my_snprintf(buf, 512, "Error in parsing optimizer_switch setting near %*s\n", error_len, error);
-+ sql_perror(buf);
-+ return 1;
-+ }
-+ break;
-+ }
-+ case OPT_ONE_THREAD:
-+ global_system_variables.thread_handling=
-+ SCHEDULER_ONE_THREAD_PER_CONNECTION;
-+ break;
-+ case OPT_THREAD_HANDLING:
-+ {
-+ global_system_variables.thread_handling=
-+ find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1;
-+ break;
-+ }
-+ case OPT_FT_BOOLEAN_SYNTAX:
-+ if (ft_boolean_check_syntax_string((uchar*) argument))
-+ {
-+ sql_print_error("Invalid ft-boolean-syntax string: %s\n", argument);
-+ return 1;
-+ }
-+ strmake(ft_boolean_syntax, argument, sizeof(ft_boolean_syntax)-1);
-+ break;
-+ case OPT_SKIP_SAFEMALLOC:
-+#ifdef SAFEMALLOC
-+ sf_malloc_quick=1;
-+#endif
-+ break;
-+ case OPT_LOWER_CASE_TABLE_NAMES:
-+ lower_case_table_names= argument ? atoi(argument) : 1;
-+ lower_case_table_names_used= 1;
-+ break;
-+#ifdef HAVE_STACK_TRACE_ON_SEGV
-+ case OPT_DO_PSTACK:
-+ sql_print_warning("'--enable-pstack' is deprecated and will be removed "
-+ "in a future release. A symbolic stack trace will be "
-+ "printed after a crash whenever possible.");
-+ break;
-+#endif
-+#if defined(ENABLED_DEBUG_SYNC)
-+ case OPT_DEBUG_SYNC_TIMEOUT:
-+ /*
-+ Debug Sync Facility. See debug_sync.cc.
-+ Default timeout for WAIT_FOR action.
-+ Default value is zero (facility disabled).
-+ If option is given without an argument, supply a non-zero value.
-+ */
-+ if (!argument)
-+ {
-+ /* purecov: begin tested */
-+ opt_debug_sync_timeout= DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT;
-+ /* purecov: end */
-+ }
-+ break;
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+ case OPT_MAX_LONG_DATA_SIZE:
-+ max_long_data_size_used= true;
-+ WARN_DEPRECATED(NULL, VER_CELOSIA, "--max_long_data_size", "--max_allowed_packet");
-+ break;
-+ }
-+ return 0;
-+}
-+
-+
-+/** Handle arguments for multiple key caches. */
-+C_MODE_START
-+static void* mysql_getopt_value(const char *, uint,
-+ const struct my_option *, int *);
-+C_MODE_END
-+
-+static void*
-+mysql_getopt_value(const char *keyname, uint key_length,
-+ const struct my_option *option, int *error)
-+{
-+ if (error)
-+ *error= 0;
-+ switch (option->id) {
-+ case OPT_KEY_BUFFER_SIZE:
-+ case OPT_KEY_CACHE_BLOCK_SIZE:
-+ case OPT_KEY_CACHE_DIVISION_LIMIT:
-+ case OPT_KEY_CACHE_AGE_THRESHOLD:
-+ {
-+ KEY_CACHE *key_cache;
-+ if (!(key_cache= get_or_create_key_cache(keyname, key_length)))
-+ {
-+ if (error)
-+ *error= EXIT_OUT_OF_MEMORY;
-+ return 0;
-+ }
-+ switch (option->id) {
-+ case OPT_KEY_BUFFER_SIZE:
-+ return &key_cache->param_buff_size;
-+ case OPT_KEY_CACHE_BLOCK_SIZE:
-+ return &key_cache->param_block_size;
-+ case OPT_KEY_CACHE_DIVISION_LIMIT:
-+ return &key_cache->param_division_limit;
-+ case OPT_KEY_CACHE_AGE_THRESHOLD:
-+ return &key_cache->param_age_threshold;
-+ }
-+ }
-+ }
-+ return option->value;
-+}
-+
-+
-+extern "C" void option_error_reporter(enum loglevel level, const char *format, ...);
-+
-+void option_error_reporter(enum loglevel level, const char *format, ...)
-+{
-+ va_list args;
-+ va_start(args, format);
-+
-+ /* Don't print warnings for --loose options during bootstrap */
-+ if (level == ERROR_LEVEL || !opt_bootstrap ||
-+ global_system_variables.log_warnings)
-+ {
-+ vprint_msg_to_log(level, format, args);
-+ }
-+ va_end(args);
-+}
-+
-+
-+/**
-+ @todo
-+ - FIXME add EXIT_TOO_MANY_ARGUMENTS to "mysys_err.h" and return that code?
-+*/
-+static int get_options(int *argc,char **argv)
-+{
-+ int ho_error;
-+
-+ my_getopt_register_get_addr(mysql_getopt_value);
-+ strmake(def_ft_boolean_syntax, ft_boolean_syntax,
-+ sizeof(ft_boolean_syntax)-1);
-+ my_getopt_error_reporter= option_error_reporter;
-+
-+ /* Skip unknown options so that they may be processed later by plugins */
-+ my_getopt_skip_unknown= TRUE;
-+
-+ if ((ho_error= handle_options(argc, &argv, my_long_options,
-+ mysqld_get_one_option)))
-+ return ho_error;
-+ (*argc)++; /* add back one for the progname handle_options removes */
-+ /* no need to do this for argv as we are discarding it. */
-+
-+ if ((opt_log_slow_admin_statements || opt_log_queries_not_using_indexes ||
-+ opt_log_slow_slave_statements) &&
-+ !opt_slow_log)
-+ sql_print_warning("options --log-slow-admin-statements, --log-queries-not-using-indexes and --log-slow-slave-statements have no effect if --log_slow_queries is not set");
-+ if (global_system_variables.net_buffer_length >
-+ global_system_variables.max_allowed_packet)
-+ {
-+ sql_print_warning("net_buffer_length (%lu) is set to be larger "
-+ "than max_allowed_packet (%lu). Please rectify.",
-+ global_system_variables.net_buffer_length,
-+ global_system_variables.max_allowed_packet);
-+ }
-+
-+#if defined(HAVE_BROKEN_REALPATH)
-+ my_use_symdir=0;
-+ my_disable_symlinks=1;
-+ have_symlink=SHOW_OPTION_NO;
-+#else
-+ if (!my_use_symdir)
-+ {
-+ my_disable_symlinks=1;
-+ have_symlink=SHOW_OPTION_DISABLED;
-+ }
-+#endif
-+ if (opt_debugging)
-+ {
-+ /* Allow break with SIGINT, no core or stack trace */
-+ test_flags|= TEST_SIGINT | TEST_NO_STACKTRACE;
-+ test_flags&= ~TEST_CORE_ON_SIGNAL;
-+ }
-+ /* Set global MyISAM variables from delay_key_write_options */
-+ fix_delay_key_write((THD*) 0, OPT_GLOBAL);
-+ /* Set global slave_exec_mode from its option */
-+ fix_slave_exec_mode();
-+
-+#ifndef EMBEDDED_LIBRARY
-+ if (mysqld_chroot)
-+ set_root(mysqld_chroot);
-+#else
-+ global_system_variables.thread_handling = SCHEDULER_NO_THREADS;
-+ max_allowed_packet= global_system_variables.max_allowed_packet;
-+ net_buffer_length= global_system_variables.net_buffer_length;
-+#endif
-+ if (fix_paths())
-+ return 1;
-+
-+ /*
-+ Set some global variables from the global_system_variables
-+ In most cases the global variables will not be used
-+ */
-+ my_disable_locking= myisam_single_user= test(opt_external_locking == 0);
-+ my_default_record_cache_size=global_system_variables.read_buff_size;
-+ myisam_max_temp_length=
-+ (my_off_t) global_system_variables.myisam_max_sort_file_size;
-+
-+ /* Set global variables based on startup options */
-+ myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size);
-+
-+ /* long_query_time is in microseconds */
-+ global_system_variables.long_query_time= max_system_variables.long_query_time=
-+ (longlong) (long_query_time * 1000000.0);
-+
-+ if (opt_short_log_format)
-+ opt_specialflag|= SPECIAL_SHORT_LOG_FORMAT;
-+
-+ if (init_global_datetime_format(MYSQL_TIMESTAMP_DATE,
-+ &global_system_variables.date_format) ||
-+ init_global_datetime_format(MYSQL_TIMESTAMP_TIME,
-+ &global_system_variables.time_format) ||
-+ init_global_datetime_format(MYSQL_TIMESTAMP_DATETIME,
-+ &global_system_variables.datetime_format))
-+ return 1;
-+
-+#ifdef EMBEDDED_LIBRARY
-+ one_thread_scheduler(&thread_scheduler);
-+#else
-+ if (global_system_variables.thread_handling <=
-+ SCHEDULER_ONE_THREAD_PER_CONNECTION)
-+ one_thread_per_connection_scheduler(&thread_scheduler);
-+ else if (global_system_variables.thread_handling == SCHEDULER_NO_THREADS)
-+ one_thread_scheduler(&thread_scheduler);
-+ else
-+ pool_of_threads_scheduler(&thread_scheduler); /* purecov: tested */
-+#endif
-+
-+ /*
-+ If max_long_data_size is not specified explicitly use
-+ value of max_allowed_packet.
-+ */
-+ if (!max_long_data_size_used)
-+ max_long_data_size= global_system_variables.max_allowed_packet;
-+
-+ return 0;
-+}
-+
-+
-+/*
-+ Create version name for running mysqld version
-+ We automaticly add suffixes -debug, -embedded and -log to the version
-+ name to make the version more descriptive.
-+ (MYSQL_SERVER_SUFFIX is set by the compilation environment)
-+*/
-+
-+static void set_server_version(void)
-+{
-+ char *end= strxmov(server_version, MYSQL_SERVER_VERSION,
-+ MYSQL_SERVER_SUFFIX_STR, NullS);
-+#ifdef EMBEDDED_LIBRARY
-+ end= strmov(end, "-embedded");
-+#endif
-+#ifndef DBUG_OFF
-+ if (!strstr(MYSQL_SERVER_SUFFIX_STR, "-debug"))
-+ end= strmov(end, "-debug");
-+#endif
-+ if (opt_log || opt_update_log || opt_slow_log || opt_bin_log)
-+ strmov(end, "-log"); // This may slow down system
-+}
-+
-+
-+static char *get_relative_path(const char *path)
-+{
-+ if (test_if_hard_path(path) &&
-+ is_prefix(path,DEFAULT_MYSQL_HOME) &&
-+ strcmp(DEFAULT_MYSQL_HOME,FN_ROOTDIR))
-+ {
-+ path+=(uint) strlen(DEFAULT_MYSQL_HOME);
-+ while (*path == FN_LIBCHAR)
-+ path++;
-+ }
-+ return (char*) path;
-+}
-+
-+
-+/**
-+ Fix filename and replace extension where 'dir' is relative to
-+ mysql_real_data_home.
-+ @return
-+ 1 if len(path) > FN_REFLEN
-+*/
-+
-+bool
-+fn_format_relative_to_data_home(char * to, const char *name,
-+ const char *dir, const char *extension)
-+{
-+ char tmp_path[FN_REFLEN];
-+ if (!test_if_hard_path(dir))
-+ {
-+ strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home,
-+ dir, NullS);
-+ dir=tmp_path;
-+ }
-+ return !fn_format(to, name, dir, extension,
-+ MY_APPEND_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH);
-+}
-+
-+
-+/**
-+ Test a file path to determine if the path is compatible with the secure file
-+ path restriction.
-+
-+ @param path null terminated character string
-+
-+ @return
-+ @retval TRUE The path is secure
-+ @retval FALSE The path isn't secure
-+*/
-+
-+bool is_secure_file_path(char *path)
-+{
-+ char buff1[FN_REFLEN], buff2[FN_REFLEN];
-+ /*
-+ All paths are secure if opt_secure_file_path is 0
-+ */
-+ if (!opt_secure_file_priv)
-+ return TRUE;
-+
-+ if (strlen(path) >= FN_REFLEN)
-+ return FALSE;
-+
-+ if (my_realpath(buff1, path, 0))
-+ {
-+ /*
-+ The supplied file path might have been a file and not a directory.
-+ */
-+ int length= (int)dirname_length(path);
-+ if (length >= FN_REFLEN)
-+ return FALSE;
-+ memcpy(buff2, path, length);
-+ buff2[length]= '\0';
-+ if (length == 0 || my_realpath(buff1, buff2, 0))
-+ return FALSE;
-+ }
-+ convert_dirname(buff2, buff1, NullS);
-+ if (strncmp(opt_secure_file_priv, buff2, strlen(opt_secure_file_priv)))
-+ return FALSE;
-+ return TRUE;
-+}
-+
-+static int fix_paths(void)
-+{
-+ char buff[FN_REFLEN],*pos;
-+ convert_dirname(mysql_home,mysql_home,NullS);
-+ /* Resolve symlinks to allow 'mysql_home' to be a relative symlink */
-+ my_realpath(mysql_home,mysql_home,MYF(0));
-+ /* Ensure that mysql_home ends in FN_LIBCHAR */
-+ pos=strend(mysql_home);
-+ if (pos[-1] != FN_LIBCHAR)
-+ {
-+ pos[0]= FN_LIBCHAR;
-+ pos[1]= 0;
-+ }
-+ convert_dirname(language,language,NullS);
-+ convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS);
-+ (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir
-+ (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home);
-+ (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home);
-+ (void) my_load_path(opt_plugin_dir, opt_plugin_dir_ptr ? opt_plugin_dir_ptr :
-+ get_relative_path(PLUGINDIR), mysql_home);
-+ opt_plugin_dir_ptr= opt_plugin_dir;
-+
-+ my_realpath(mysql_unpacked_real_data_home, mysql_real_data_home, MYF(0));
-+ mysql_unpacked_real_data_home_len=
-+ (int) strlen(mysql_unpacked_real_data_home);
-+ if (mysql_unpacked_real_data_home[mysql_unpacked_real_data_home_len-1] == FN_LIBCHAR)
-+ --mysql_unpacked_real_data_home_len;
-+
-+ char *sharedir=get_relative_path(SHAREDIR);
-+ if (test_if_hard_path(sharedir))
-+ strmake(buff,sharedir,sizeof(buff)-1); /* purecov: tested */
-+ else
-+ strxnmov(buff,sizeof(buff)-1,mysql_home,sharedir,NullS);
-+ convert_dirname(buff,buff,NullS);
-+ (void) my_load_path(language,language,buff);
-+
-+ /* If --character-sets-dir isn't given, use shared library dir */
-+ if (charsets_dir != mysql_charsets_dir)
-+ {
-+ strxnmov(mysql_charsets_dir, sizeof(mysql_charsets_dir)-1, buff,
-+ CHARSET_DIR, NullS);
-+ }
-+ (void) my_load_path(mysql_charsets_dir, mysql_charsets_dir, buff);
-+ convert_dirname(mysql_charsets_dir, mysql_charsets_dir, NullS);
-+ charsets_dir=mysql_charsets_dir;
-+
-+ if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
-+ return 1;
-+#ifdef HAVE_REPLICATION
-+ if (!slave_load_tmpdir)
-+ {
-+ if (!(slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE))))
-+ return 1;
-+ }
-+#endif /* HAVE_REPLICATION */
-+ /*
-+ Convert the secure-file-priv option to system format, allowing
-+ a quick strcmp to check if read or write is in an allowed dir
-+ */
-+ if (opt_secure_file_priv)
-+ {
-+ if (*opt_secure_file_priv == 0)
-+ {
-+ opt_secure_file_priv= 0;
-+ }
-+ else
-+ {
-+ if (strlen(opt_secure_file_priv) >= FN_REFLEN)
-+ opt_secure_file_priv[FN_REFLEN-1]= '\0';
-+ if (my_realpath(buff, opt_secure_file_priv, 0))
-+ {
-+ sql_print_warning("Failed to normalize the argument for --secure-file-priv.");
-+ return 1;
-+ }
-+ char *secure_file_real_path= (char *)my_malloc(FN_REFLEN, MYF(MY_FAE));
-+ convert_dirname(secure_file_real_path, buff, NullS);
-+ my_free(opt_secure_file_priv, MYF(0));
-+ opt_secure_file_priv= secure_file_real_path;
-+ }
-+ }
-+
-+ return 0;
-+}
-+
-+
-+static ulong find_bit_type_or_exit(const char *x, TYPELIB *bit_lib,
-+ const char *option, int *error)
-+{
-+ ulong result;
-+ const char **ptr;
-+
-+ *error= 0;
-+ if ((result= find_bit_type(x, bit_lib)) == ~(ulong) 0)
-+ {
-+ char *buff= (char *) my_alloca(2048);
-+ char *cbuf;
-+ ptr= bit_lib->type_names;
-+ cbuf= buff + ((!*x) ?
-+ my_snprintf(buff, 2048, "No option given to %s\n", option) :
-+ my_snprintf(buff, 2048, "Wrong option to %s. Option(s) given: %s\n",
-+ option, x));
-+ cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), "Alternatives are: '%s'", *ptr);
-+ while (*++ptr)
-+ cbuf+= my_snprintf(cbuf, 2048 - (cbuf-buff), ",'%s'", *ptr);
-+ my_snprintf(cbuf, 2048 - (cbuf-buff), "\n");
-+ sql_perror(buff);
-+ *error= 1;
-+ my_afree(buff);
-+ return 0;
-+ }
-+
-+ return result;
-+}
-+
-+
-+/**
-+ @return
-+ a bitfield from a string of substrings separated by ','
-+ or
-+ ~(ulong) 0 on error.
-+*/
-+
-+static ulong find_bit_type(const char *x, TYPELIB *bit_lib)
-+{
-+ bool found_end;
-+ int found_count;
-+ const char *end,*i,*j;
-+ const char **array, *pos;
-+ ulong found,found_int,bit;
-+ DBUG_ENTER("find_bit_type");
-+ DBUG_PRINT("enter",("x: '%s'",x));
-+
-+ found=0;
-+ found_end= 0;
-+ pos=(char *) x;
-+ while (*pos == ' ') pos++;
-+ found_end= *pos == 0;
-+ while (!found_end)
-+ {
-+ if (!*(end=strcend(pos,','))) /* Let end point at fieldend */
-+ {
-+ while (end > pos && end[-1] == ' ')
-+ end--; /* Skip end-space */
-+ found_end=1;
-+ }
-+ found_int=0; found_count=0;
-+ for (array=bit_lib->type_names, bit=1 ; (i= *array++) ; bit<<=1)
-+ {
-+ j=pos;
-+ while (j != end)
-+ {
-+ if (my_toupper(mysqld_charset,*i++) !=
-+ my_toupper(mysqld_charset,*j++))
-+ goto skip;
-+ }
-+ found_int=bit;
-+ if (! *i)
-+ {
-+ found_count=1;
-+ break;
-+ }
-+ else if (j != pos) // Half field found
-+ {
-+ found_count++; // Could be one of two values
-+ }
-+skip: ;
-+ }
-+ if (found_count != 1)
-+ DBUG_RETURN(~(ulong) 0); // No unique value
-+ found|=found_int;
-+ pos=end+1;
-+ }
-+
-+ DBUG_PRINT("exit",("bit-field: %ld",(ulong) found));
-+ DBUG_RETURN(found);
-+} /* find_bit_type */
-+
-+
-+/**
-+ Check if file system used for databases is case insensitive.
-+
-+ @param dir_name Directory to test
-+
-+ @retval
-+ -1 Don't know (Test failed)
-+ @retval
-+ 0 File system is case sensitive
-+ @retval
-+ 1 File system is case insensitive
-+*/
-+
-+static int test_if_case_insensitive(const char *dir_name)
-+{
-+ int result= 0;
-+ File file;
-+ char buff[FN_REFLEN], buff2[FN_REFLEN];
-+ MY_STAT stat_info;
-+ DBUG_ENTER("test_if_case_insensitive");
-+
-+ fn_format(buff, glob_hostname, dir_name, ".lower-test",
-+ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
-+ fn_format(buff2, glob_hostname, dir_name, ".LOWER-TEST",
-+ MY_UNPACK_FILENAME | MY_REPLACE_EXT | MY_REPLACE_DIR);
-+ (void) my_delete(buff2, MYF(0));
-+ if ((file= my_create(buff, 0666, O_RDWR, MYF(0))) < 0)
-+ {
-+ sql_print_warning("Can't create test file %s", buff);
-+ DBUG_RETURN(-1);
-+ }
-+ my_close(file, MYF(0));
-+ if (my_stat(buff2, &stat_info, MYF(0)))
-+ result= 1; // Can access file
-+ (void) my_delete(buff, MYF(MY_WME));
-+ DBUG_PRINT("exit", ("result: %d", result));
-+ DBUG_RETURN(result);
-+}
-+
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/**
-+ Create file to store pid number.
-+*/
-+static void create_pid_file()
-+{
-+ File file;
-+ if ((file = my_create(pidfile_name,0664,
-+ O_WRONLY | O_TRUNC, MYF(MY_WME))) >= 0)
-+ {
-+ char buff[21], *end;
-+ end= int10_to_str((long) getpid(), buff, 10);
-+ *end++= '\n';
-+ if (!my_write(file, (uchar*) buff, (uint) (end-buff), MYF(MY_WME | MY_NABP)))
-+ {
-+ (void) my_close(file, MYF(0));
-+ return;
-+ }
-+ (void) my_close(file, MYF(0));
-+ }
-+ sql_perror("Can't start server: can't create PID file");
-+ exit(1);
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+/** Clear most status variables. */
-+void refresh_status(THD *thd)
-+{
-+ pthread_mutex_lock(&LOCK_status);
-+
-+ /* Add thread's status variabes to global status */
-+ add_to_status(&global_status_var, &thd->status_var);
-+
-+ /* Reset thread's status variables */
-+ bzero((uchar*) &thd->status_var, sizeof(thd->status_var));
-+
-+ /* Reset some global variables */
-+ reset_status_vars();
-+
-+ /* Reset the counters of all key caches (default and named). */
-+ process_key_caches(reset_key_cache_counters);
-+#ifdef COMMUNITY_SERVER
-+ flush_status_time= time((time_t*) 0);
-+#endif
-+ pthread_mutex_unlock(&LOCK_status);
-+
-+ /*
-+ Set max_used_connections to the number of currently open
-+ connections. Lock LOCK_thread_count out of LOCK_status to avoid
-+ deadlocks. Status reset becomes not atomic, but status data is
-+ not exact anyway.
-+ */
-+ pthread_mutex_lock(&LOCK_thread_count);
-+ max_used_connections= thread_count-delayed_insert_threads;
-+ pthread_mutex_unlock(&LOCK_thread_count);
-+}
-+
-+
-+/*****************************************************************************
-+ Instantiate variables for missing storage engines
-+ This section should go away soon
-+*****************************************************************************/
-+
-+#ifndef WITH_NDBCLUSTER_STORAGE_ENGINE
-+ulong ndb_cache_check_time;
-+ulong ndb_extra_logging;
-+#endif
-+
-+/*****************************************************************************
-+ Instantiate templates
-+*****************************************************************************/
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+/* Used templates */
-+template class I_List<THD>;
-+template class I_List_iterator<THD>;
-+template class I_List<i_string>;
-+template class I_List<i_string_pair>;
-+template class I_List<NAMED_LIST>;
-+template class I_List<Statement>;
-+template class I_List_iterator<Statement>;
-+#endif
diff -urN mysql-old/sql/net_serv.cc mysql/sql/net_serv.cc
--- mysql-old/sql/net_serv.cc 2011-05-10 17:45:45.633349043 +0000
+++ mysql/sql/net_serv.cc 2011-05-10 17:56:01.466682376 +0000
@@ -21909,4367 +1921,6 @@ diff -urN mysql-old/sql/set_var.cc mysql/sql/set_var.cc
goto err;
}
return FALSE;
-diff -urN mysql-old/sql/set_var.cc.orig mysql/sql/set_var.cc.orig
---- mysql-old/sql/set_var.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/set_var.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,4357 @@
-+/* Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+/**
-+ @file
-+
-+ @brief
-+ Handling of MySQL SQL variables
-+
-+ @details
-+ To add a new variable, one has to do the following:
-+
-+ - Use one of the 'sys_var... classes from set_var.h or write a specific
-+ one for the variable type.
-+ - Define it in the 'variable definition list' in this file.
-+ - If the variable is thread specific, add it to 'system_variables' struct.
-+ If not, add it to mysqld.cc and an declaration in 'mysql_priv.h'
-+ - If the variable should be changed from the command line, add a definition
-+ of it in the my_option structure list in mysqld.cc
-+ - Don't forget to initialize new fields in global_system_variables and
-+ max_system_variables!
-+
-+ @todo
-+ Add full support for the variable character_set (for 4.1)
-+
-+ @todo
-+ When updating myisam_delay_key_write, we should do a 'flush tables'
-+ of all MyISAM tables to ensure that they are reopen with the
-+ new attribute.
-+
-+ @note
-+ Be careful with var->save_result: sys_var::check() only updates
-+ ulonglong_value; so other members of the union are garbage then; to use
-+ them you must first assign a value to them (in specific ::check() for
-+ example).
-+*/
-+
-+#ifdef USE_PRAGMA_IMPLEMENTATION
-+#pragma implementation // gcc: Class implementation
-+#endif
-+
-+#include "mysql_priv.h"
-+#include <mysql.h>
-+#include "slave.h"
-+#include "rpl_mi.h"
-+#include <my_getopt.h>
-+#include <thr_alarm.h>
-+#include <myisam.h>
-+#include <my_dir.h>
-+
-+#include "events.h"
-+
-+/* WITH_NDBCLUSTER_STORAGE_ENGINE */
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+extern ulong ndb_cache_check_time;
-+extern char opt_ndb_constrbuf[];
-+extern ulong ndb_extra_logging;
-+#endif
-+
-+#ifdef HAVE_NDB_BINLOG
-+extern ulong ndb_report_thresh_binlog_epoch_slip;
-+extern ulong ndb_report_thresh_binlog_mem_usage;
-+#endif
-+
-+extern CHARSET_INFO *character_set_filesystem;
-+
-+
-+static HASH system_variable_hash;
-+
-+const char *bool_type_names[]= { "OFF", "ON", NullS };
-+TYPELIB bool_typelib=
-+{
-+ array_elements(bool_type_names)-1, "", bool_type_names, NULL
-+};
-+
-+const char *delay_key_write_type_names[]= { "OFF", "ON", "ALL", NullS };
-+TYPELIB delay_key_write_typelib=
-+{
-+ array_elements(delay_key_write_type_names)-1, "",
-+ delay_key_write_type_names, NULL
-+};
-+
-+static const char *slave_exec_mode_names[]= { "STRICT", "IDEMPOTENT", NullS };
-+static unsigned int slave_exec_mode_names_len[]= { sizeof("STRICT") - 1,
-+ sizeof("IDEMPOTENT") - 1, 0 };
-+TYPELIB slave_exec_mode_typelib=
-+{
-+ array_elements(slave_exec_mode_names)-1, "",
-+ slave_exec_mode_names, slave_exec_mode_names_len
-+};
-+
-+static int sys_check_ftb_syntax(THD *thd, set_var *var);
-+static bool sys_update_ftb_syntax(THD *thd, set_var * var);
-+static void sys_default_ftb_syntax(THD *thd, enum_var_type type);
-+static bool sys_update_init_connect(THD*, set_var*);
-+static void sys_default_init_connect(THD*, enum_var_type type);
-+static bool sys_update_init_slave(THD*, set_var*);
-+static void sys_default_init_slave(THD*, enum_var_type type);
-+static bool set_option_bit(THD *thd, set_var *var);
-+static bool set_option_log_bin_bit(THD *thd, set_var *var);
-+static bool set_option_autocommit(THD *thd, set_var *var);
-+static int check_log_update(THD *thd, set_var *var);
-+static bool set_log_update(THD *thd, set_var *var);
-+static int check_pseudo_thread_id(THD *thd, set_var *var);
-+void fix_binlog_format_after_update(THD *thd, enum_var_type type);
-+static void fix_low_priority_updates(THD *thd, enum_var_type type);
-+static int check_tx_isolation(THD *thd, set_var *var);
-+static void fix_tx_isolation(THD *thd, enum_var_type type);
-+static int check_completion_type(THD *thd, set_var *var);
-+static void fix_completion_type(THD *thd, enum_var_type type);
-+static void fix_net_read_timeout(THD *thd, enum_var_type type);
-+static void fix_net_write_timeout(THD *thd, enum_var_type type);
-+static void fix_net_retry_count(THD *thd, enum_var_type type);
-+static void fix_max_join_size(THD *thd, enum_var_type type);
-+static void fix_query_cache_size(THD *thd, enum_var_type type);
-+static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type);
-+static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type);
-+static void fix_max_binlog_size(THD *thd, enum_var_type type);
-+static void fix_max_relay_log_size(THD *thd, enum_var_type type);
-+static void fix_max_connections(THD *thd, enum_var_type type);
-+static int check_max_delayed_threads(THD *thd, set_var *var);
-+static void fix_thd_mem_root(THD *thd, enum_var_type type);
-+static void fix_trans_mem_root(THD *thd, enum_var_type type);
-+static void fix_server_id(THD *thd, enum_var_type type);
-+bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
-+ const char *name, longlong val);
-+static KEY_CACHE *create_key_cache(const char *name, uint length);
-+void fix_sql_mode_var(THD *thd, enum_var_type type);
-+static uchar *get_error_count(THD *thd);
-+static uchar *get_warning_count(THD *thd);
-+static uchar *get_tmpdir(THD *thd);
-+static int sys_check_log_path(THD *thd, set_var *var);
-+static bool sys_update_general_log_path(THD *thd, set_var * var);
-+static void sys_default_general_log_path(THD *thd, enum_var_type type);
-+static bool sys_update_slow_log_path(THD *thd, set_var * var);
-+static void sys_default_slow_log_path(THD *thd, enum_var_type type);
-+static uchar *get_myisam_mmap_size(THD *thd);
-+static int check_max_allowed_packet(THD *thd, set_var *var);
-+static int check_net_buffer_length(THD *thd, set_var *var);
-+
-+/*
-+ Variable definition list
-+
-+ These are variables that can be set from the command line, in
-+ alphabetic order.
-+
-+ The variables are linked into the list. A variable is added to
-+ it in the constructor (see sys_var class for details).
-+*/
-+
-+static sys_var_chain vars = { NULL, NULL };
-+
-+static sys_var_thd_ulong
-+sys_auto_increment_increment(&vars, "auto_increment_increment",
-+ &SV::auto_increment_increment, NULL, NULL,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_thd_ulong
-+sys_auto_increment_offset(&vars, "auto_increment_offset",
-+ &SV::auto_increment_offset, NULL, NULL,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+
-+static sys_var_bool_ptr sys_automatic_sp_privileges(&vars, "automatic_sp_privileges",
-+ &sp_automatic_privileges);
-+
-+static sys_var_const sys_back_log(&vars, "back_log",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*) &back_log);
-+static sys_var_const_os_str sys_basedir(&vars, "basedir", mysql_home);
-+static sys_var_long_ptr sys_binlog_cache_size(&vars, "binlog_cache_size",
-+ &binlog_cache_size);
-+static sys_var_thd_binlog_format sys_binlog_format(&vars, "binlog_format",
-+ &SV::binlog_format);
-+static sys_var_thd_bool sys_binlog_direct_non_trans_update(&vars, "binlog_direct_non_transactional_updates",
-+ &SV::binlog_direct_non_trans_update);
-+static sys_var_thd_ulong sys_bulk_insert_buff_size(&vars, "bulk_insert_buffer_size",
-+ &SV::bulk_insert_buff_size);
-+static sys_var_const_os sys_character_sets_dir(&vars,
-+ "character_sets_dir",
-+ OPT_GLOBAL, SHOW_CHAR,
-+ (uchar*)
-+ mysql_charsets_dir);
-+static sys_var_character_set_sv
-+sys_character_set_server(&vars, "character_set_server",
-+ &SV::collation_server, &default_charset_info, 0,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+sys_var_const_str sys_charset_system(&vars, "character_set_system",
-+ (char *)my_charset_utf8_general_ci.name);
-+static sys_var_character_set_database
-+sys_character_set_database(&vars, "character_set_database",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_character_set_client
-+sys_character_set_client(&vars, "character_set_client",
-+ &SV::character_set_client,
-+ &default_charset_info,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_character_set_sv
-+sys_character_set_connection(&vars, "character_set_connection",
-+ &SV::collation_connection,
-+ &default_charset_info, 0,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_character_set_sv sys_character_set_results(&vars, "character_set_results",
-+ &SV::character_set_results,
-+ &default_charset_info, true);
-+static sys_var_character_set_sv sys_character_set_filesystem(&vars, "character_set_filesystem",
-+ &SV::character_set_filesystem,
-+ &character_set_filesystem);
-+static sys_var_thd_ulong sys_completion_type(&vars, "completion_type",
-+ &SV::completion_type,
-+ check_completion_type,
-+ fix_completion_type);
-+static sys_var_collation_sv
-+sys_collation_connection(&vars, "collation_connection",
-+ &SV::collation_connection, &default_charset_info,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_collation_sv
-+sys_collation_database(&vars, "collation_database", &SV::collation_database,
-+ &default_charset_info,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_collation_sv
-+sys_collation_server(&vars, "collation_server", &SV::collation_server,
-+ &default_charset_info,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_long_ptr sys_concurrent_insert(&vars, "concurrent_insert",
-+ &myisam_concurrent_insert);
-+static sys_var_long_ptr sys_connect_timeout(&vars, "connect_timeout",
-+ &connect_timeout);
-+static sys_var_const_os_str sys_datadir(&vars, "datadir", mysql_real_data_home);
-+#ifndef DBUG_OFF
-+static sys_var_thd_dbug sys_dbug(&vars, "debug");
-+#endif
-+static sys_var_enum sys_delay_key_write(&vars, "delay_key_write",
-+ &delay_key_write_options,
-+ &delay_key_write_typelib,
-+ fix_delay_key_write);
-+static sys_var_long_ptr sys_delayed_insert_limit(&vars, "delayed_insert_limit",
-+ &delayed_insert_limit);
-+static sys_var_long_ptr sys_delayed_insert_timeout(&vars, "delayed_insert_timeout",
-+ &delayed_insert_timeout);
-+static sys_var_long_ptr sys_delayed_queue_size(&vars, "delayed_queue_size",
-+ &delayed_queue_size);
-+
-+#ifdef HAVE_EVENT_SCHEDULER
-+static sys_var_event_scheduler sys_event_scheduler(&vars, "event_scheduler");
-+#endif
-+
-+static sys_var_long_ptr sys_expire_logs_days(&vars, "expire_logs_days",
-+ &expire_logs_days);
-+static sys_var_bool_ptr sys_flush(&vars, "flush", &myisam_flush);
-+static sys_var_long_ptr sys_flush_time(&vars, "flush_time", &flush_time);
-+static sys_var_str sys_ft_boolean_syntax(&vars, "ft_boolean_syntax",
-+ sys_check_ftb_syntax,
-+ sys_update_ftb_syntax,
-+ sys_default_ftb_syntax,
-+ ft_boolean_syntax);
-+static sys_var_const sys_ft_max_word_len(&vars, "ft_max_word_len",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*) &ft_max_word_len);
-+static sys_var_const sys_ft_min_word_len(&vars, "ft_min_word_len",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*) &ft_min_word_len);
-+static sys_var_const sys_ft_query_expansion_limit(&vars,
-+ "ft_query_expansion_limit",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*)
-+ &ft_query_expansion_limit);
-+static sys_var_const sys_ft_stopword_file(&vars, "ft_stopword_file",
-+ OPT_GLOBAL, SHOW_CHAR_PTR,
-+ (uchar*) &ft_stopword_file);
-+
-+static sys_var_const sys_ignore_builtin_innodb(&vars, "ignore_builtin_innodb",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_ignore_builtin_innodb);
-+
-+sys_var_str sys_init_connect(&vars, "init_connect", 0,
-+ sys_update_init_connect,
-+ sys_default_init_connect,0);
-+static sys_var_const sys_init_file(&vars, "init_file",
-+ OPT_GLOBAL, SHOW_CHAR_PTR,
-+ (uchar*) &opt_init_file);
-+sys_var_str sys_init_slave(&vars, "init_slave", 0,
-+ sys_update_init_slave,
-+ sys_default_init_slave,0);
-+static sys_var_thd_ulong sys_interactive_timeout(&vars, "interactive_timeout",
-+ &SV::net_interactive_timeout);
-+static sys_var_thd_ulong sys_join_buffer_size(&vars, "join_buffer_size",
-+ &SV::join_buff_size);
-+static sys_var_key_buffer_size sys_key_buffer_size(&vars, "key_buffer_size");
-+static sys_var_key_cache_long sys_key_cache_block_size(&vars, "key_cache_block_size",
-+ offsetof(KEY_CACHE,
-+ param_block_size));
-+static sys_var_key_cache_long sys_key_cache_division_limit(&vars, "key_cache_division_limit",
-+ offsetof(KEY_CACHE,
-+ param_division_limit));
-+static sys_var_key_cache_long sys_key_cache_age_threshold(&vars, "key_cache_age_threshold",
-+ offsetof(KEY_CACHE,
-+ param_age_threshold));
-+static sys_var_const sys_language(&vars, "language",
-+ OPT_GLOBAL, SHOW_CHAR,
-+ (uchar*) language);
-+static sys_var_const sys_large_files_support(&vars, "large_files_support",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_large_files);
-+static sys_var_const sys_large_page_size(&vars, "large_page_size",
-+ OPT_GLOBAL, SHOW_INT,
-+ (uchar*) &opt_large_page_size);
-+static sys_var_const sys_large_pages(&vars, "large_pages",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*) &opt_large_pages);
-+static sys_var_bool_ptr sys_local_infile(&vars, "local_infile",
-+ &opt_local_infile);
-+#ifdef HAVE_MLOCKALL
-+static sys_var_const sys_locked_in_memory(&vars, "locked_in_memory",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*) &locked_in_memory);
-+#endif
-+static sys_var_const sys_log_bin(&vars, "log_bin",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_bin_log);
-+static sys_var_trust_routine_creators
-+sys_trust_routine_creators(&vars, "log_bin_trust_routine_creators",
-+ &trust_function_creators);
-+static sys_var_bool_ptr
-+sys_trust_function_creators(&vars, "log_bin_trust_function_creators",
-+ &trust_function_creators);
-+static sys_var_const sys_log_error(&vars, "log_error",
-+ OPT_GLOBAL, SHOW_CHAR,
-+ (uchar*) log_error_file);
-+static sys_var_bool_ptr
-+ sys_log_queries_not_using_indexes(&vars, "log_queries_not_using_indexes",
-+ &opt_log_queries_not_using_indexes);
-+static sys_var_thd_ulong sys_log_warnings(&vars, "log_warnings", &SV::log_warnings);
-+static sys_var_microseconds sys_var_long_query_time(&vars, "long_query_time",
-+ &SV::long_query_time);
-+static sys_var_thd_bool sys_low_priority_updates(&vars, "low_priority_updates",
-+ &SV::low_priority_updates,
-+ fix_low_priority_updates);
-+#ifndef TO_BE_DELETED /* Alias for the low_priority_updates */
-+static sys_var_thd_bool sys_sql_low_priority_updates(&vars, "sql_low_priority_updates",
-+ &SV::low_priority_updates,
-+ fix_low_priority_updates);
-+#endif
-+static sys_var_const sys_lower_case_file_system(&vars,
-+ "lower_case_file_system",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*)
-+ &lower_case_file_system);
-+static sys_var_const sys_lower_case_table_names(&vars,
-+ "lower_case_table_names",
-+ OPT_GLOBAL, SHOW_INT,
-+ (uchar*)
-+ &lower_case_table_names);
-+static sys_var_thd_ulong_session_readonly sys_max_allowed_packet(&vars, "max_allowed_packet",
-+ &SV::max_allowed_packet,
-+ check_max_allowed_packet);
-+static sys_var_ulonglong_ptr sys_max_binlog_cache_size(&vars, "max_binlog_cache_size",
-+ &max_binlog_cache_size);
-+static sys_var_long_ptr sys_max_binlog_size(&vars, "max_binlog_size",
-+ &max_binlog_size,
-+ fix_max_binlog_size);
-+static sys_var_long_ptr sys_max_connections(&vars, "max_connections",
-+ &max_connections,
-+ fix_max_connections);
-+static sys_var_long_ptr sys_max_connect_errors(&vars, "max_connect_errors",
-+ &max_connect_errors);
-+static sys_var_thd_ulong sys_max_insert_delayed_threads(&vars, "max_insert_delayed_threads",
-+ &SV::max_insert_delayed_threads,
-+ check_max_delayed_threads,
-+ fix_max_connections);
-+static sys_var_thd_ulong sys_max_delayed_threads(&vars, "max_delayed_threads",
-+ &SV::max_insert_delayed_threads,
-+ check_max_delayed_threads,
-+ fix_max_connections);
-+static sys_var_thd_ulong sys_max_error_count(&vars, "max_error_count",
-+ &SV::max_error_count);
-+static sys_var_thd_ulonglong sys_max_heap_table_size(&vars, "max_heap_table_size",
-+ &SV::max_heap_table_size);
-+static sys_var_thd_ulong sys_pseudo_thread_id(&vars, "pseudo_thread_id",
-+ &SV::pseudo_thread_id,
-+ check_pseudo_thread_id, 0,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_thd_ha_rows sys_max_join_size(&vars, "max_join_size",
-+ &SV::max_join_size,
-+ fix_max_join_size);
-+static sys_var_thd_ulong sys_max_seeks_for_key(&vars, "max_seeks_for_key",
-+ &SV::max_seeks_for_key);
-+static sys_var_thd_ulong sys_max_length_for_sort_data(&vars, "max_length_for_sort_data",
-+ &SV::max_length_for_sort_data);
-+static sys_var_const sys_max_long_data_size(&vars,
-+ "max_long_data_size",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*)
-+ &max_long_data_size);
-+
-+#ifndef TO_BE_DELETED /* Alias for max_join_size */
-+static sys_var_thd_ha_rows sys_sql_max_join_size(&vars, "sql_max_join_size",
-+ &SV::max_join_size,
-+ fix_max_join_size);
-+#endif
-+static sys_var_long_ptr_global
-+sys_max_prepared_stmt_count(&vars, "max_prepared_stmt_count",
-+ &max_prepared_stmt_count,
-+ &LOCK_prepared_stmt_count);
-+static sys_var_long_ptr sys_max_relay_log_size(&vars, "max_relay_log_size",
-+ &max_relay_log_size,
-+ fix_max_relay_log_size);
-+static sys_var_thd_ulong sys_max_sort_length(&vars, "max_sort_length",
-+ &SV::max_sort_length);
-+static sys_var_thd_ulong sys_max_sp_recursion_depth(&vars, "max_sp_recursion_depth",
-+ &SV::max_sp_recursion_depth);
-+static sys_var_max_user_conn sys_max_user_connections(&vars, "max_user_connections");
-+static sys_var_thd_ulong sys_max_tmp_tables(&vars, "max_tmp_tables",
-+ &SV::max_tmp_tables);
-+static sys_var_long_ptr sys_max_write_lock_count(&vars, "max_write_lock_count",
-+ &max_write_lock_count);
-+static sys_var_thd_ulong sys_min_examined_row_limit(&vars, "min_examined_row_limit",
-+ &SV::min_examined_row_limit);
-+static sys_var_thd_ulong sys_multi_range_count(&vars, "multi_range_count",
-+ &SV::multi_range_count);
-+static sys_var_long_ptr sys_myisam_data_pointer_size(&vars, "myisam_data_pointer_size",
-+ &myisam_data_pointer_size);
-+static sys_var_thd_ulonglong sys_myisam_max_sort_file_size(&vars, "myisam_max_sort_file_size", &SV::myisam_max_sort_file_size, fix_myisam_max_sort_file_size, 1);
-+static sys_var_const sys_myisam_recover_options(&vars, "myisam_recover_options",
-+ OPT_GLOBAL, SHOW_CHAR_PTR,
-+ (uchar*)
-+ &myisam_recover_options_str);
-+static sys_var_thd_ulong sys_myisam_repair_threads(&vars, "myisam_repair_threads", &SV::myisam_repair_threads);
-+static sys_var_thd_ulong sys_myisam_sort_buffer_size(&vars, "myisam_sort_buffer_size", &SV::myisam_sort_buff_size);
-+static sys_var_bool_ptr sys_myisam_use_mmap(&vars, "myisam_use_mmap",
-+ &opt_myisam_use_mmap);
-+
-+static sys_var_thd_enum sys_myisam_stats_method(&vars, "myisam_stats_method",
-+ &SV::myisam_stats_method,
-+ &myisam_stats_method_typelib,
-+ NULL);
-+
-+#ifdef __NT__
-+/* purecov: begin inspected */
-+static sys_var_const sys_named_pipe(&vars, "named_pipe",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*) &opt_enable_named_pipe);
-+/* purecov: end */
-+#endif
-+static sys_var_thd_ulong_session_readonly sys_net_buffer_length(&vars, "net_buffer_length",
-+ &SV::net_buffer_length,
-+ check_net_buffer_length);
-+static sys_var_thd_ulong sys_net_read_timeout(&vars, "net_read_timeout",
-+ &SV::net_read_timeout,
-+ 0, fix_net_read_timeout);
-+static sys_var_thd_ulong sys_net_write_timeout(&vars, "net_write_timeout",
-+ &SV::net_write_timeout,
-+ 0, fix_net_write_timeout);
-+static sys_var_thd_ulong sys_net_retry_count(&vars, "net_retry_count",
-+ &SV::net_retry_count,
-+ 0, fix_net_retry_count);
-+static sys_var_thd_bool sys_new_mode(&vars, "new", &SV::new_mode);
-+static sys_var_bool_ptr_readonly sys_old_mode(&vars, "old",
-+ &global_system_variables.old_mode);
-+/* these two cannot be static */
-+sys_var_thd_bool sys_old_alter_table(&vars, "old_alter_table",
-+ &SV::old_alter_table);
-+sys_var_thd_bool sys_old_passwords(&vars, "old_passwords", &SV::old_passwords);
-+static sys_var_const sys_open_files_limit(&vars, "open_files_limit",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*)
-+ &open_files_limit);
-+static sys_var_thd_ulong sys_optimizer_prune_level(&vars, "optimizer_prune_level",
-+ &SV::optimizer_prune_level);
-+static sys_var_thd_ulong sys_optimizer_search_depth(&vars, "optimizer_search_depth",
-+ &SV::optimizer_search_depth);
-+static sys_var_thd_optimizer_switch sys_optimizer_switch(&vars, "optimizer_switch",
-+ &SV::optimizer_switch);
-+static sys_var_const sys_pid_file(&vars, "pid_file",
-+ OPT_GLOBAL, SHOW_CHAR,
-+ (uchar*) pidfile_name);
-+static sys_var_const_os sys_plugin_dir(&vars, "plugin_dir",
-+ OPT_GLOBAL, SHOW_CHAR,
-+ (uchar*) opt_plugin_dir);
-+static sys_var_const sys_port(&vars, "port",
-+ OPT_GLOBAL, SHOW_INT,
-+ (uchar*) &mysqld_port);
-+static sys_var_thd_ulong sys_preload_buff_size(&vars, "preload_buffer_size",
-+ &SV::preload_buff_size);
-+static sys_var_const sys_protocol_version(&vars, "protocol_version",
-+ OPT_GLOBAL, SHOW_INT,
-+ (uchar*)
-+ &protocol_version);
-+static sys_var_thd_ulong sys_read_buff_size(&vars, "read_buffer_size",
-+ &SV::read_buff_size);
-+static sys_var_opt_readonly sys_readonly(&vars, "read_only", &opt_readonly);
-+static sys_var_thd_ulong sys_read_rnd_buff_size(&vars, "read_rnd_buffer_size",
-+ &SV::read_rnd_buff_size);
-+static sys_var_thd_ulong sys_div_precincrement(&vars, "div_precision_increment",
-+ &SV::div_precincrement);
-+static sys_var_long_ptr sys_rpl_recovery_rank(&vars, "rpl_recovery_rank",
-+ &rpl_recovery_rank);
-+static sys_var_long_ptr sys_query_cache_size(&vars, "query_cache_size",
-+ &query_cache_size,
-+ fix_query_cache_size);
-+
-+static sys_var_thd_ulong sys_range_alloc_block_size(&vars, "range_alloc_block_size",
-+ &SV::range_alloc_block_size);
-+static sys_var_thd_ulong sys_query_alloc_block_size(&vars, "query_alloc_block_size",
-+ &SV::query_alloc_block_size,
-+ 0, fix_thd_mem_root);
-+static sys_var_thd_ulong sys_query_prealloc_size(&vars, "query_prealloc_size",
-+ &SV::query_prealloc_size,
-+ 0, fix_thd_mem_root);
-+#ifdef HAVE_SMEM
-+/* purecov: begin tested */
-+static sys_var_const sys_shared_memory(&vars, "shared_memory",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*)
-+ &opt_enable_shared_memory);
-+static sys_var_const sys_shared_memory_base_name(&vars,
-+ "shared_memory_base_name",
-+ OPT_GLOBAL, SHOW_CHAR_PTR,
-+ (uchar*)
-+ &shared_memory_base_name);
-+/* purecov: end */
-+#endif
-+static sys_var_const sys_skip_external_locking(&vars,
-+ "skip_external_locking",
-+ OPT_GLOBAL, SHOW_MY_BOOL,
-+ (uchar*)
-+ &my_disable_locking);
-+static sys_var_const sys_skip_networking(&vars, "skip_networking",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_disable_networking);
-+static sys_var_const sys_skip_show_database(&vars, "skip_show_database",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_skip_show_db);
-+
-+static sys_var_const sys_skip_name_resolve(&vars, "skip_name_resolve",
-+ OPT_GLOBAL, SHOW_BOOL,
-+ (uchar*) &opt_skip_name_resolve);
-+
-+static sys_var_const sys_socket(&vars, "socket",
-+ OPT_GLOBAL, SHOW_CHAR_PTR,
-+ (uchar*) &mysqld_unix_port);
-+
-+#ifdef HAVE_THR_SETCONCURRENCY
-+/* purecov: begin tested */
-+static sys_var_const sys_thread_concurrency(&vars, "thread_concurrency",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*) &concurrency);
-+/* purecov: end */
-+#endif
-+static sys_var_const sys_thread_stack(&vars, "thread_stack",
-+ OPT_GLOBAL, SHOW_LONG,
-+ (uchar*) &my_thread_stack_size);
-+static sys_var_readonly_os sys_tmpdir(&vars, "tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
-+static sys_var_thd_ulong sys_trans_alloc_block_size(&vars, "transaction_alloc_block_size",
-+ &SV::trans_alloc_block_size,
-+ 0, fix_trans_mem_root);
-+static sys_var_thd_ulong sys_trans_prealloc_size(&vars, "transaction_prealloc_size",
-+ &SV::trans_prealloc_size,
-+ 0, fix_trans_mem_root);
-+sys_var_enum_const sys_thread_handling(&vars, "thread_handling",
-+ &SV::thread_handling,
-+ &thread_handling_typelib,
-+ NULL);
-+
-+#ifdef HAVE_QUERY_CACHE
-+static sys_var_long_ptr sys_query_cache_limit(&vars, "query_cache_limit",
-+ &query_cache.query_cache_limit);
-+static sys_var_long_ptr sys_query_cache_min_res_unit(&vars, "query_cache_min_res_unit",
-+ &query_cache_min_res_unit,
-+ fix_query_cache_min_res_unit);
-+static sys_var_thd_enum sys_query_cache_type(&vars, "query_cache_type",
-+ &SV::query_cache_type,
-+ &query_cache_type_typelib);
-+static sys_var_thd_bool
-+sys_query_cache_wlock_invalidate(&vars, "query_cache_wlock_invalidate",
-+ &SV::query_cache_wlock_invalidate);
-+#endif /* HAVE_QUERY_CACHE */
-+static sys_var_bool_ptr sys_secure_auth(&vars, "secure_auth", &opt_secure_auth);
-+static sys_var_const_str_ptr sys_secure_file_priv(&vars, "secure_file_priv",
-+ &opt_secure_file_priv);
-+static sys_var_long_ptr sys_server_id(&vars, "server_id", &server_id, fix_server_id);
-+static sys_var_bool_ptr sys_slave_compressed_protocol(&vars, "slave_compressed_protocol",
-+ &opt_slave_compressed_protocol);
-+static sys_var_set_slave_mode slave_exec_mode(&vars,
-+ "slave_exec_mode",
-+ &slave_exec_mode_options,
-+ &slave_exec_mode_typelib,
-+ 0);
-+static sys_var_long_ptr sys_slow_launch_time(&vars, "slow_launch_time",
-+ &slow_launch_time);
-+static sys_var_thd_ulong sys_sort_buffer(&vars, "sort_buffer_size",
-+ &SV::sortbuff_size);
-+/*
-+ sql_mode should *not* have binlog_mode=SESSION_VARIABLE_IN_BINLOG:
-+ even though it is written to the binlog, the slave ignores the
-+ MODE_NO_DIR_IN_CREATE variable, so slave's value differs from
-+ master's (see log_event.cc: Query_log_event::do_apply_event()).
-+*/
-+static sys_var_thd_sql_mode sys_sql_mode(&vars, "sql_mode",
-+ &SV::sql_mode);
-+#ifdef HAVE_OPENSSL
-+extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
-+ *opt_ssl_key;
-+static sys_var_const_os_str_ptr sys_ssl_ca(&vars, "ssl_ca", &opt_ssl_ca);
-+static sys_var_const_os_str_ptr sys_ssl_capath(&vars, "ssl_capath", &opt_ssl_capath);
-+static sys_var_const_os_str_ptr sys_ssl_cert(&vars, "ssl_cert", &opt_ssl_cert);
-+static sys_var_const_os_str_ptr sys_ssl_cipher(&vars, "ssl_cipher", &opt_ssl_cipher);
-+static sys_var_const_os_str_ptr sys_ssl_key(&vars, "ssl_key", &opt_ssl_key);
-+#else
-+static sys_var_const_os_str sys_ssl_ca(&vars, "ssl_ca", NULL);
-+static sys_var_const_os_str sys_ssl_capath(&vars, "ssl_capath", NULL);
-+static sys_var_const_os_str sys_ssl_cert(&vars, "ssl_cert", NULL);
-+static sys_var_const_os_str sys_ssl_cipher(&vars, "ssl_cipher", NULL);
-+static sys_var_const_os_str sys_ssl_key(&vars, "ssl_key", NULL);
-+#endif
-+static sys_var_thd_enum
-+sys_updatable_views_with_limit(&vars, "updatable_views_with_limit",
-+ &SV::updatable_views_with_limit,
-+ &updatable_views_with_limit_typelib);
-+
-+static sys_var_thd_table_type sys_table_type(&vars, "table_type",
-+ &SV::table_plugin);
-+static sys_var_thd_storage_engine sys_storage_engine(&vars, "storage_engine",
-+ &SV::table_plugin);
-+static sys_var_bool_ptr sys_sync_frm(&vars, "sync_frm", &opt_sync_frm);
-+static sys_var_const_str sys_system_time_zone(&vars, "system_time_zone",
-+ system_time_zone);
-+static sys_var_long_ptr sys_table_def_size(&vars, "table_definition_cache",
-+ &table_def_size);
-+static sys_var_long_ptr sys_table_cache_size(&vars, "table_open_cache",
-+ &table_cache_size);
-+static sys_var_long_ptr sys_table_lock_wait_timeout(&vars, "table_lock_wait_timeout",
-+ &table_lock_wait_timeout);
-+
-+#if defined(ENABLED_DEBUG_SYNC)
-+/* Debug Sync Facility. Implemented in debug_sync.cc. */
-+static sys_var_debug_sync sys_debug_sync(&vars, "debug_sync");
-+#endif /* defined(ENABLED_DEBUG_SYNC) */
-+
-+static sys_var_long_ptr sys_thread_cache_size(&vars, "thread_cache_size",
-+ &thread_cache_size);
-+#if HAVE_POOL_OF_THREADS == 1
-+sys_var_long_ptr sys_thread_pool_size(&vars, "thread_pool_size",
-+ &thread_pool_size);
-+#endif
-+static sys_var_thd_enum sys_tx_isolation(&vars, "tx_isolation",
-+ &SV::tx_isolation,
-+ &tx_isolation_typelib,
-+ fix_tx_isolation,
-+ check_tx_isolation);
-+static sys_var_thd_ulonglong sys_tmp_table_size(&vars, "tmp_table_size",
-+ &SV::tmp_table_size);
-+static sys_var_bool_ptr sys_timed_mutexes(&vars, "timed_mutexes",
-+ &timed_mutexes);
-+static sys_var_const_str sys_version(&vars, "version", server_version);
-+static sys_var_const_str sys_version_comment(&vars, "version_comment",
-+ MYSQL_COMPILATION_COMMENT);
-+static sys_var_const_str sys_version_compile_machine(&vars, "version_compile_machine",
-+ MACHINE_TYPE);
-+static sys_var_const_str sys_version_compile_os(&vars, "version_compile_os",
-+ SYSTEM_TYPE);
-+static sys_var_thd_ulong sys_net_wait_timeout(&vars, "wait_timeout",
-+ &SV::net_wait_timeout);
-+
-+/* Condition pushdown to storage engine */
-+static sys_var_thd_bool
-+sys_engine_condition_pushdown(&vars, "engine_condition_pushdown",
-+ &SV::engine_condition_pushdown);
-+
-+#ifdef WITH_NDBCLUSTER_STORAGE_ENGINE
-+/* ndb thread specific variable settings */
-+static sys_var_thd_ulong
-+sys_ndb_autoincrement_prefetch_sz(&vars, "ndb_autoincrement_prefetch_sz",
-+ &SV::ndb_autoincrement_prefetch_sz);
-+static sys_var_thd_bool
-+sys_ndb_force_send(&vars, "ndb_force_send", &SV::ndb_force_send);
-+#ifdef HAVE_NDB_BINLOG
-+static sys_var_long_ptr
-+sys_ndb_report_thresh_binlog_epoch_slip(&vars, "ndb_report_thresh_binlog_epoch_slip",
-+ &ndb_report_thresh_binlog_epoch_slip);
-+static sys_var_long_ptr
-+sys_ndb_report_thresh_binlog_mem_usage(&vars, "ndb_report_thresh_binlog_mem_usage",
-+ &ndb_report_thresh_binlog_mem_usage);
-+#endif
-+static sys_var_thd_bool
-+sys_ndb_use_exact_count(&vars, "ndb_use_exact_count", &SV::ndb_use_exact_count);
-+static sys_var_thd_bool
-+sys_ndb_use_transactions(&vars, "ndb_use_transactions", &SV::ndb_use_transactions);
-+static sys_var_long_ptr
-+sys_ndb_cache_check_time(&vars, "ndb_cache_check_time", &ndb_cache_check_time);
-+static sys_var_const_str
-+sys_ndb_connectstring(&vars, "ndb_connectstring", opt_ndb_constrbuf);
-+static sys_var_thd_bool
-+sys_ndb_index_stat_enable(&vars, "ndb_index_stat_enable",
-+ &SV::ndb_index_stat_enable);
-+static sys_var_thd_ulong
-+sys_ndb_index_stat_cache_entries(&vars, "ndb_index_stat_cache_entries",
-+ &SV::ndb_index_stat_cache_entries);
-+static sys_var_thd_ulong
-+sys_ndb_index_stat_update_freq(&vars, "ndb_index_stat_update_freq",
-+ &SV::ndb_index_stat_update_freq);
-+static sys_var_long_ptr
-+sys_ndb_extra_logging(&vars, "ndb_extra_logging", &ndb_extra_logging);
-+static sys_var_thd_bool
-+sys_ndb_use_copying_alter_table(&vars, "ndb_use_copying_alter_table", &SV::ndb_use_copying_alter_table);
-+#endif //WITH_NDBCLUSTER_STORAGE_ENGINE
-+
-+/* Time/date/datetime formats */
-+
-+static sys_var_thd_date_time_format sys_time_format(&vars, "time_format",
-+ &SV::time_format,
-+ MYSQL_TIMESTAMP_TIME);
-+static sys_var_thd_date_time_format sys_date_format(&vars, "date_format",
-+ &SV::date_format,
-+ MYSQL_TIMESTAMP_DATE);
-+static sys_var_thd_date_time_format sys_datetime_format(&vars, "datetime_format",
-+ &SV::datetime_format,
-+ MYSQL_TIMESTAMP_DATETIME);
-+
-+/* Variables that are bits in THD */
-+
-+sys_var_thd_bit sys_autocommit(&vars, "autocommit", 0,
-+ set_option_autocommit,
-+ OPTION_NOT_AUTOCOMMIT,
-+ 1);
-+static sys_var_thd_bit sys_big_tables(&vars, "big_tables", 0,
-+ set_option_bit,
-+ OPTION_BIG_TABLES);
-+#ifndef TO_BE_DELETED /* Alias for big_tables */
-+static sys_var_thd_bit sys_sql_big_tables(&vars, "sql_big_tables", 0,
-+ set_option_bit,
-+ OPTION_BIG_TABLES);
-+#endif
-+static sys_var_thd_bit sys_big_selects(&vars, "sql_big_selects", 0,
-+ set_option_bit,
-+ OPTION_BIG_SELECTS);
-+static sys_var_thd_bit sys_log_off(&vars, "sql_log_off",
-+ check_log_update,
-+ set_option_bit,
-+ OPTION_LOG_OFF);
-+static sys_var_thd_bit sys_log_update(&vars, "sql_log_update",
-+ check_log_update,
-+ set_log_update,
-+ OPTION_BIN_LOG);
-+static sys_var_thd_bit sys_log_binlog(&vars, "sql_log_bin",
-+ check_log_update,
-+ set_option_log_bin_bit,
-+ OPTION_BIN_LOG);
-+static sys_var_thd_bit sys_sql_warnings(&vars, "sql_warnings", 0,
-+ set_option_bit,
-+ OPTION_WARNINGS);
-+static sys_var_thd_bit sys_sql_notes(&vars, "sql_notes", 0,
-+ set_option_bit,
-+ OPTION_SQL_NOTES);
-+static sys_var_thd_bit sys_auto_is_null(&vars, "sql_auto_is_null", 0,
-+ set_option_bit,
-+ OPTION_AUTO_IS_NULL, 0,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_thd_bit sys_safe_updates(&vars, "sql_safe_updates", 0,
-+ set_option_bit,
-+ OPTION_SAFE_UPDATES);
-+static sys_var_thd_bit sys_buffer_results(&vars, "sql_buffer_result", 0,
-+ set_option_bit,
-+ OPTION_BUFFER_RESULT);
-+static sys_var_thd_bit sys_quote_show_create(&vars, "sql_quote_show_create", 0,
-+ set_option_bit,
-+ OPTION_QUOTE_SHOW_CREATE);
-+static sys_var_thd_bit sys_foreign_key_checks(&vars, "foreign_key_checks", 0,
-+ set_option_bit,
-+ OPTION_NO_FOREIGN_KEY_CHECKS,
-+ 1, sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_thd_bit sys_unique_checks(&vars, "unique_checks", 0,
-+ set_option_bit,
-+ OPTION_RELAXED_UNIQUE_CHECKS,
-+ 1,
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+static sys_var_thd_bit sys_profiling(&vars, "profiling", NULL,
-+ set_option_bit,
-+ ulonglong(OPTION_PROFILING));
-+static sys_var_thd_ulong sys_profiling_history_size(&vars, "profiling_history_size",
-+ &SV::profiling_history_size);
-+#endif
-+
-+/* Local state variables */
-+
-+static sys_var_thd_ha_rows sys_select_limit(&vars, "sql_select_limit",
-+ &SV::select_limit);
-+static sys_var_timestamp sys_timestamp(&vars, "timestamp",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_last_insert_id
-+sys_last_insert_id(&vars, "last_insert_id",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+/*
-+ identity is an alias for last_insert_id(), so that we are compatible
-+ with Sybase
-+*/
-+static sys_var_last_insert_id
-+sys_identity(&vars, "identity", sys_var::SESSION_VARIABLE_IN_BINLOG);
-+
-+static sys_var_thd_lc_time_names
-+sys_lc_time_names(&vars, "lc_time_names", sys_var::SESSION_VARIABLE_IN_BINLOG);
-+
-+/*
-+ insert_id should *not* be marked as written to the binlog (i.e., it
-+ should *not* have binlog_status==SESSION_VARIABLE_IN_BINLOG),
-+ because we want any statement that refers to insert_id explicitly to
-+ be unsafe. (By "explicitly", we mean using @@session.insert_id,
-+ whereas insert_id is used "implicitly" when NULL value is inserted
-+ into an auto_increment column).
-+
-+ We want statements referring explicitly to @@session.insert_id to be
-+ unsafe, because insert_id is modified internally by the slave sql
-+ thread when NULL values are inserted in an AUTO_INCREMENT column.
-+ This modification interfers with the value of the
-+ @@session.insert_id variable if @@session.insert_id is referred
-+ explicitly by an insert statement (as is seen by executing "SET
-+ @@session.insert_id=0; CREATE TABLE t (a INT, b INT KEY
-+ AUTO_INCREMENT); INSERT INTO t(a) VALUES (@@session.insert_id);" in
-+ statement-based logging mode: t will be different on master and
-+ slave).
-+*/
-+static sys_var_insert_id sys_insert_id(&vars, "insert_id");
-+static sys_var_readonly sys_error_count(&vars, "error_count",
-+ OPT_SESSION,
-+ SHOW_LONG,
-+ get_error_count);
-+static sys_var_readonly sys_warning_count(&vars, "warning_count",
-+ OPT_SESSION,
-+ SHOW_LONG,
-+ get_warning_count);
-+
-+static sys_var_rand_seed1 sys_rand_seed1(&vars, "rand_seed1",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+static sys_var_rand_seed2 sys_rand_seed2(&vars, "rand_seed2",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+
-+static sys_var_thd_ulong sys_default_week_format(&vars, "default_week_format",
-+ &SV::default_week_format);
-+
-+sys_var_thd_ulong sys_group_concat_max_len(&vars, "group_concat_max_len",
-+ &SV::group_concat_max_len);
-+
-+sys_var_thd_time_zone sys_time_zone(&vars, "time_zone",
-+ sys_var::SESSION_VARIABLE_IN_BINLOG);
-+
-+/* Global read-only variable containing hostname */
-+static sys_var_const_str sys_hostname(&vars, "hostname", glob_hostname);
-+
-+#ifndef EMBEDDED_LIBRARY
-+static sys_var_const_str_ptr sys_repl_report_host(&vars, "report_host", &report_host);
-+static sys_var_const_str_ptr sys_repl_report_user(&vars, "report_user", &report_user);
-+static sys_var_const_str_ptr sys_repl_report_password(&vars, "report_password", &report_password);
-+
-+static uchar *slave_get_report_port(THD *thd)
-+{
-+ thd->sys_var_tmp.long_value= report_port;
-+ return (uchar*) &thd->sys_var_tmp.long_value;
-+}
-+
-+static sys_var_readonly sys_repl_report_port(&vars, "report_port", OPT_GLOBAL, SHOW_LONG, slave_get_report_port);
-+
-+#endif
-+
-+sys_var_thd_bool sys_keep_files_on_create(&vars, "keep_files_on_create",
-+ &SV::keep_files_on_create);
-+/* Read only variables */
-+
-+static sys_var_have_variable sys_have_compress(&vars, "have_compress", &have_compress);
-+static sys_var_have_variable sys_have_crypt(&vars, "have_crypt", &have_crypt);
-+static sys_var_have_plugin sys_have_csv(&vars, "have_csv", C_STRING_WITH_LEN("csv"), MYSQL_STORAGE_ENGINE_PLUGIN);
-+static sys_var_have_variable sys_have_dlopen(&vars, "have_dynamic_loading", &have_dlopen);
-+static sys_var_have_variable sys_have_geometry(&vars, "have_geometry", &have_geometry);
-+static sys_var_have_plugin sys_have_innodb(&vars, "have_innodb", C_STRING_WITH_LEN("innodb"), MYSQL_STORAGE_ENGINE_PLUGIN);
-+static sys_var_have_plugin sys_have_ndbcluster(&vars, "have_ndbcluster", C_STRING_WITH_LEN("ndbcluster"), MYSQL_STORAGE_ENGINE_PLUGIN);
-+static sys_var_have_variable sys_have_openssl(&vars, "have_openssl", &have_ssl);
-+static sys_var_have_variable sys_have_ssl(&vars, "have_ssl", &have_ssl);
-+static sys_var_have_plugin sys_have_partition_db(&vars, "have_partitioning", C_STRING_WITH_LEN("partition"), MYSQL_STORAGE_ENGINE_PLUGIN);
-+static sys_var_have_variable sys_have_query_cache(&vars, "have_query_cache",
-+ &have_query_cache);
-+static sys_var_have_variable sys_have_community_features(&vars, "have_community_features", &have_community_features);
-+static sys_var_have_variable sys_have_rtree_keys(&vars, "have_rtree_keys", &have_rtree_keys);
-+static sys_var_have_variable sys_have_symlink(&vars, "have_symlink", &have_symlink);
-+/* Global read-only variable describing server license */
-+static sys_var_const_str sys_license(&vars, "license", STRINGIFY_ARG(LICENSE));
-+/* Global variables which enable|disable logging */
-+static sys_var_log_state sys_var_general_log(&vars, "general_log", &opt_log,
-+ QUERY_LOG_GENERAL);
-+/* Synonym of "general_log" for consistency with SHOW VARIABLES output */
-+static sys_var_log_state sys_var_log(&vars, "log", &opt_log,
-+ QUERY_LOG_GENERAL);
-+static sys_var_log_state sys_var_slow_query_log(&vars, "slow_query_log", &opt_slow_log,
-+ QUERY_LOG_SLOW);
-+/* Synonym of "slow_query_log" for consistency with SHOW VARIABLES output */
-+static sys_var_log_state sys_var_log_slow(&vars, "log_slow_queries",
-+ &opt_slow_log, QUERY_LOG_SLOW);
-+sys_var_str sys_var_general_log_path(&vars, "general_log_file", sys_check_log_path,
-+ sys_update_general_log_path,
-+ sys_default_general_log_path,
-+ opt_logname);
-+sys_var_str sys_var_slow_log_path(&vars, "slow_query_log_file", sys_check_log_path,
-+ sys_update_slow_log_path,
-+ sys_default_slow_log_path,
-+ opt_slow_logname);
-+static sys_var_log_output sys_var_log_output_state(&vars, "log_output", &log_output_options,
-+ &log_output_typelib, 0);
-+static sys_var_readonly sys_myisam_mmap_size(&vars, "myisam_mmap_size",
-+ OPT_GLOBAL,
-+ SHOW_LONGLONG,
-+ get_myisam_mmap_size);
-+
-+
-+bool sys_var::check(THD *thd, set_var *var)
-+{
-+ var->save_result.ulonglong_value= var->value->val_int();
-+ return 0;
-+}
-+
-+bool sys_var_str::check(THD *thd, set_var *var)
-+{
-+ int res;
-+ if (!check_func)
-+ return 0;
-+
-+ if ((res=(*check_func)(thd, var)) < 0)
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0),
-+ name, var->value->str_value.ptr());
-+ return res;
-+}
-+
-+/*
-+ Functions to check and update variables
-+*/
-+
-+
-+/*
-+ Update variables 'init_connect, init_slave'.
-+
-+ In case of 'DEFAULT' value
-+ (for example: 'set GLOBAL init_connect=DEFAULT')
-+ 'var' parameter is NULL pointer.
-+*/
-+
-+bool update_sys_var_str(sys_var_str *var_str, rw_lock_t *var_mutex,
-+ set_var *var)
-+{
-+ char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
-+ uint new_length= (var ? var->value->str_value.length() : 0);
-+ if (!old_value)
-+ old_value= (char*) "";
-+ if (!(res= my_strndup(old_value, new_length, MYF(0))))
-+ return 1;
-+ /*
-+ Replace the old value in such a way that the any thread using
-+ the value will work.
-+ */
-+ rw_wrlock(var_mutex);
-+ old_value= var_str->value;
-+ var_str->value= res;
-+ var_str->value_length= new_length;
-+ var_str->is_os_charset= FALSE;
-+ rw_unlock(var_mutex);
-+ my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
-+ return 0;
-+}
-+
-+
-+static bool sys_update_init_connect(THD *thd, set_var *var)
-+{
-+ return update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, var);
-+}
-+
-+
-+static void sys_default_init_connect(THD* thd, enum_var_type type)
-+{
-+ update_sys_var_str(&sys_init_connect, &LOCK_sys_init_connect, 0);
-+}
-+
-+
-+static bool sys_update_init_slave(THD *thd, set_var *var)
-+{
-+ return update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, var);
-+}
-+
-+
-+static void sys_default_init_slave(THD* thd, enum_var_type type)
-+{
-+ update_sys_var_str(&sys_init_slave, &LOCK_sys_init_slave, 0);
-+}
-+
-+static int sys_check_ftb_syntax(THD *thd, set_var *var)
-+{
-+ if (thd->security_ctx->master_access & SUPER_ACL)
-+ return (ft_boolean_check_syntax_string((uchar*)
-+ var->value->str_value.c_ptr()) ?
-+ -1 : 0);
-+ else
-+ {
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-+ return 1;
-+ }
-+}
-+
-+static bool sys_update_ftb_syntax(THD *thd, set_var * var)
-+{
-+ strmake(ft_boolean_syntax, var->value->str_value.c_ptr(),
-+ sizeof(ft_boolean_syntax)-1);
-+
-+#ifdef HAVE_QUERY_CACHE
-+ query_cache.flush();
-+#endif /* HAVE_QUERY_CACHE */
-+
-+ return 0;
-+}
-+
-+static void sys_default_ftb_syntax(THD *thd, enum_var_type type)
-+{
-+ strmake(ft_boolean_syntax, def_ft_boolean_syntax,
-+ sizeof(ft_boolean_syntax)-1);
-+}
-+
-+
-+/**
-+ If one sets the LOW_PRIORIY UPDATES flag, we also must change the
-+ used lock type.
-+*/
-+
-+static void fix_low_priority_updates(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ thr_upgraded_concurrent_insert_lock=
-+ (global_system_variables.low_priority_updates ?
-+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
-+ else
-+ thd->update_lock_default= (thd->variables.low_priority_updates ?
-+ TL_WRITE_LOW_PRIORITY : TL_WRITE);
-+}
-+
-+
-+static void
-+fix_myisam_max_sort_file_size(THD *thd, enum_var_type type)
-+{
-+ myisam_max_temp_length=
-+ (my_off_t) global_system_variables.myisam_max_sort_file_size;
-+}
-+
-+/**
-+ Set the OPTION_BIG_SELECTS flag if max_join_size == HA_POS_ERROR.
-+*/
-+
-+static void fix_max_join_size(THD *thd, enum_var_type type)
-+{
-+ if (type != OPT_GLOBAL)
-+ {
-+ if (thd->variables.max_join_size == HA_POS_ERROR)
-+ thd->options|= OPTION_BIG_SELECTS;
-+ else
-+ thd->options&= ~OPTION_BIG_SELECTS;
-+ }
-+}
-+
-+
-+/**
-+ Can't change the 'next' tx_isolation while we are already in
-+ a transaction
-+*/
-+static int check_tx_isolation(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_DEFAULT && (thd->server_status & SERVER_STATUS_IN_TRANS))
-+ {
-+ my_error(ER_CANT_CHANGE_TX_ISOLATION, MYF(0));
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+/*
-+ If one doesn't use the SESSION modifier, the isolation level
-+ is only active for the next command.
-+*/
-+static void fix_tx_isolation(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_SESSION)
-+ thd->session_tx_isolation= ((enum_tx_isolation)
-+ thd->variables.tx_isolation);
-+}
-+
-+static void fix_completion_type(THD *thd __attribute__((unused)),
-+ enum_var_type type __attribute__((unused))) {}
-+
-+static int check_completion_type(THD *thd, set_var *var)
-+{
-+ longlong val= var->value->val_int();
-+ if (val < 0 || val > 2)
-+ {
-+ char buf[64];
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ If we are changing the thread variable, we have to copy it to NET too
-+*/
-+
-+#ifdef HAVE_REPLICATION
-+static void fix_net_read_timeout(THD *thd, enum_var_type type)
-+{
-+ if (type != OPT_GLOBAL)
-+ my_net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
-+}
-+
-+
-+static void fix_net_write_timeout(THD *thd, enum_var_type type)
-+{
-+ if (type != OPT_GLOBAL)
-+ my_net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
-+}
-+
-+static void fix_net_retry_count(THD *thd, enum_var_type type)
-+{
-+ if (type != OPT_GLOBAL)
-+ thd->net.retry_count=thd->variables.net_retry_count;
-+}
-+#else /* HAVE_REPLICATION */
-+static void fix_net_read_timeout(THD *thd __attribute__((unused)),
-+ enum_var_type type __attribute__((unused)))
-+{}
-+static void fix_net_write_timeout(THD *thd __attribute__((unused)),
-+ enum_var_type type __attribute__((unused)))
-+{}
-+static void fix_net_retry_count(THD *thd __attribute__((unused)),
-+ enum_var_type type __attribute__((unused)))
-+{}
-+#endif /* HAVE_REPLICATION */
-+
-+
-+static void fix_query_cache_size(THD *thd, enum_var_type type)
-+{
-+#ifdef HAVE_QUERY_CACHE
-+ ulong new_cache_size= query_cache.resize(query_cache_size);
-+
-+ /*
-+ Note: query_cache_size is a global variable reflecting the
-+ requested cache size. See also query_cache_size_arg
-+ */
-+
-+ if (query_cache_size != new_cache_size)
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_QC_RESIZE, ER(ER_WARN_QC_RESIZE),
-+ query_cache_size, new_cache_size);
-+
-+ query_cache_size= new_cache_size;
-+#endif
-+}
-+
-+
-+#ifdef HAVE_QUERY_CACHE
-+static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type)
-+{
-+ query_cache_min_res_unit=
-+ query_cache.set_min_res_unit(query_cache_min_res_unit);
-+}
-+#endif
-+
-+
-+extern void fix_delay_key_write(THD *thd, enum_var_type type)
-+{
-+ switch ((enum_delay_key_write) delay_key_write_options) {
-+ case DELAY_KEY_WRITE_NONE:
-+ myisam_delay_key_write=0;
-+ break;
-+ case DELAY_KEY_WRITE_ON:
-+ myisam_delay_key_write=1;
-+ break;
-+ case DELAY_KEY_WRITE_ALL:
-+ myisam_delay_key_write=1;
-+ ha_open_options|= HA_OPEN_DELAY_KEY_WRITE;
-+ break;
-+ }
-+}
-+
-+bool sys_var_set::update(THD *thd, set_var *var)
-+{
-+ *value= var->save_result.ulong_value;
-+ return 0;
-+}
-+
-+uchar *sys_var_set::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ char buff[256];
-+ String tmp(buff, sizeof(buff), &my_charset_latin1);
-+ ulong length;
-+ ulong val= *value;
-+
-+ tmp.length(0);
-+ for (uint i= 0; val; val>>= 1, i++)
-+ {
-+ if (val & 1)
-+ {
-+ tmp.append(enum_names->type_names[i],
-+ enum_names->type_lengths[i]);
-+ tmp.append(',');
-+ }
-+ }
-+
-+ if ((length= tmp.length()))
-+ length--;
-+ return (uchar*) thd->strmake(tmp.ptr(), length);
-+}
-+
-+void sys_var_set_slave_mode::set_default(THD *thd, enum_var_type type)
-+{
-+ slave_exec_mode_options= SLAVE_EXEC_MODE_STRICT;
-+}
-+
-+bool sys_var_set_slave_mode::check(THD *thd, set_var *var)
-+{
-+ bool rc= sys_var_set::check(thd, var);
-+ if (!rc && (var->save_result.ulong_value & SLAVE_EXEC_MODE_STRICT) &&
-+ (var->save_result.ulong_value & SLAVE_EXEC_MODE_IDEMPOTENT))
-+ {
-+ rc= true;
-+ my_error(ER_SLAVE_AMBIGOUS_EXEC_MODE, MYF(0), "");
-+ }
-+ return rc;
-+}
-+
-+bool sys_var_set_slave_mode::update(THD *thd, set_var *var)
-+{
-+ bool rc;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ rc= sys_var_set::update(thd, var);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return rc;
-+}
-+
-+void fix_slave_exec_mode(void)
-+{
-+ DBUG_ENTER("fix_slave_exec_mode");
-+
-+ if ((slave_exec_mode_options & SLAVE_EXEC_MODE_STRICT) &&
-+ (slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
-+ {
-+ sql_print_error("Ambiguous slave modes combination. STRICT will be used");
-+ slave_exec_mode_options&= ~SLAVE_EXEC_MODE_IDEMPOTENT;
-+ }
-+ if (!(slave_exec_mode_options & SLAVE_EXEC_MODE_IDEMPOTENT))
-+ slave_exec_mode_options|= SLAVE_EXEC_MODE_STRICT;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+bool sys_var_thd_binlog_format::check(THD *thd, set_var *var) {
-+ /*
-+ All variables that affect writing to binary log (either format or
-+ turning logging on and off) use the same checking. We call the
-+ superclass ::check function to assign the variable correctly, and
-+ then check the value.
-+ */
-+ bool result= sys_var_thd_enum::check(thd, var);
-+ if (!result)
-+ result= check_log_update(thd, var);
-+ return result;
-+}
-+
-+
-+bool sys_var_thd_binlog_format::is_readonly() const
-+{
-+ /*
-+ Under certain circumstances, the variable is read-only (unchangeable):
-+ */
-+ THD *thd= current_thd;
-+ /*
-+ If RBR and open temporary tables, their CREATE TABLE may not be in the
-+ binlog, so we can't toggle to SBR in this connection.
-+ The test below will also prevent SET GLOBAL, well it was not easy to test
-+ if global or not here.
-+ And this test will also prevent switching from RBR to RBR (a no-op which
-+ should not happen too often).
-+
-+ If we don't have row-based replication compiled in, the variable
-+ is always read-only.
-+ */
-+ if ((thd->variables.binlog_format == BINLOG_FORMAT_ROW) &&
-+ thd->temporary_tables)
-+ {
-+ my_error(ER_TEMP_TABLE_PREVENTS_SWITCH_OUT_OF_RBR, MYF(0));
-+ return 1;
-+ }
-+ /*
-+ if in a stored function/trigger, it's too late to change mode
-+ */
-+ if (thd->in_sub_stmt)
-+ {
-+ my_error(ER_STORED_FUNCTION_PREVENTS_SWITCH_BINLOG_FORMAT, MYF(0));
-+ return 1;
-+ }
-+ return sys_var_thd_enum::is_readonly();
-+}
-+
-+
-+void fix_binlog_format_after_update(THD *thd, enum_var_type type)
-+{
-+ thd->reset_current_stmt_binlog_row_based();
-+}
-+
-+
-+static void fix_max_binlog_size(THD *thd, enum_var_type type)
-+{
-+ DBUG_ENTER("fix_max_binlog_size");
-+ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
-+ max_binlog_size, max_relay_log_size));
-+ mysql_bin_log.set_max_size(max_binlog_size);
-+#ifdef HAVE_REPLICATION
-+ if (!max_relay_log_size)
-+ active_mi->rli.relay_log.set_max_size(max_binlog_size);
-+#endif
-+ DBUG_VOID_RETURN;
-+}
-+
-+static void fix_max_relay_log_size(THD *thd, enum_var_type type)
-+{
-+ DBUG_ENTER("fix_max_relay_log_size");
-+ DBUG_PRINT("info",("max_binlog_size=%lu max_relay_log_size=%lu",
-+ max_binlog_size, max_relay_log_size));
-+#ifdef HAVE_REPLICATION
-+ active_mi->rli.relay_log.set_max_size(max_relay_log_size ?
-+ max_relay_log_size: max_binlog_size);
-+#endif
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+static int check_max_delayed_threads(THD *thd, set_var *var)
-+{
-+ longlong val= var->value->val_int();
-+ if (var->type != OPT_GLOBAL && val != 0 &&
-+ val != (longlong) global_system_variables.max_insert_delayed_threads)
-+ {
-+ char buf[64];
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name, llstr(val, buf));
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static void fix_max_connections(THD *thd, enum_var_type type)
-+{
-+#ifndef EMBEDDED_LIBRARY
-+ resize_thr_alarm(max_connections +
-+ global_system_variables.max_insert_delayed_threads + 10);
-+#endif
-+}
-+
-+
-+static void fix_thd_mem_root(THD *thd, enum_var_type type)
-+{
-+ if (type != OPT_GLOBAL)
-+ reset_root_defaults(thd->mem_root,
-+ thd->variables.query_alloc_block_size,
-+ thd->variables.query_prealloc_size);
-+}
-+
-+
-+static void fix_trans_mem_root(THD *thd, enum_var_type type)
-+{
-+#ifdef USING_TRANSACTIONS
-+ if (type != OPT_GLOBAL)
-+ reset_root_defaults(&thd->transaction.mem_root,
-+ thd->variables.trans_alloc_block_size,
-+ thd->variables.trans_prealloc_size);
-+#endif
-+}
-+
-+
-+static void fix_server_id(THD *thd, enum_var_type type)
-+{
-+ server_id_supplied = 1;
-+ thd->server_id= server_id;
-+}
-+
-+
-+/**
-+ Throw warning (error in STRICT mode) if value for variable needed bounding.
-+ Only call from check(), not update(), because an error in update() would be
-+ bad mojo. Plug-in interface also uses this.
-+
-+ @param thd thread handle
-+ @param fixed did we have to correct the value? (throw warn/err if so)
-+ @param unsignd is value's type unsigned?
-+ @param name variable's name
-+ @param val variable's value
-+
-+ @retval TRUE on error, FALSE otherwise (warning or OK)
-+ */
-+bool throw_bounds_warning(THD *thd, bool fixed, bool unsignd,
-+ const char *name, longlong val)
-+{
-+ if (fixed)
-+ {
-+ char buf[22];
-+
-+ if (unsignd)
-+ ullstr((ulonglong) val, buf);
-+ else
-+ llstr(val, buf);
-+
-+ if (thd->variables.sql_mode & MODE_STRICT_ALL_TABLES)
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buf);
-+ return TRUE;
-+ }
-+
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_TRUNCATED_WRONG_VALUE,
-+ ER(ER_TRUNCATED_WRONG_VALUE), name, buf);
-+ }
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Get unsigned system-variable.
-+ Negative value does not wrap around, but becomes zero.
-+ Check user-supplied value for a systemvariable against bounds.
-+ If we needed to adjust the value, throw a warning or error depending
-+ on SQL-mode.
-+
-+ @param thd thread handle
-+ @param var the system-variable to get
-+ @param user_max a limit given with --maximum-variable-name=... or 0
-+ @param var_type function will bound on systems where necessary.
-+
-+ @retval TRUE on error, FALSE otherwise (warning or OK)
-+ */
-+static bool get_unsigned(THD *thd, set_var *var, ulonglong user_max,
-+ ulong var_type)
-+{
-+ int warnings= 0;
-+ ulonglong unadjusted;
-+ const struct my_option *limits= var->var->option_limits;
-+ struct my_option fallback;
-+
-+ /* get_unsigned() */
-+ if (var->value->unsigned_flag)
-+ var->save_result.ulonglong_value= (ulonglong) var->value->val_int();
-+ else
-+ {
-+ longlong v= var->value->val_int();
-+ var->save_result.ulonglong_value= (ulonglong) ((v < 0) ? 0 : v);
-+ if (v < 0)
-+ {
-+ warnings++;
-+ if (throw_bounds_warning(thd, TRUE, FALSE, var->var->name, v))
-+ return TRUE; /* warning was promoted to error, give up */
-+ }
-+ }
-+
-+ unadjusted= var->save_result.ulonglong_value;
-+
-+ /* max, if any */
-+
-+ if ((user_max > 0) && (unadjusted > user_max))
-+ {
-+ var->save_result.ulonglong_value= user_max;
-+
-+ if ((warnings == 0) && throw_bounds_warning(thd, TRUE, TRUE,
-+ var->var->name,
-+ (longlong) unadjusted))
-+ return TRUE;
-+
-+ warnings++;
-+ }
-+
-+ /*
-+ if the sysvar doesn't have a proper bounds record but the check
-+ function would like bounding to ULONG where its size differs from
-+ that of ULONGLONG, we make up a bogus limits record here and let
-+ the usual suspects handle the actual limiting.
-+ */
-+
-+ if (!limits && var_type != GET_ULL)
-+ {
-+ bzero(&fallback, sizeof(fallback));
-+ fallback.var_type= var_type;
-+ limits= &fallback;
-+ }
-+
-+ /* fix_unsigned() */
-+ if (limits)
-+ {
-+ my_bool fixed;
-+
-+ var->save_result.ulonglong_value= getopt_ull_limit_value(var->save_result.
-+ ulonglong_value,
-+ limits, &fixed);
-+
-+ if ((warnings == 0) && throw_bounds_warning(thd, fixed, TRUE,
-+ var->var->name,
-+ (longlong) unadjusted))
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+
-+sys_var_long_ptr::
-+sys_var_long_ptr(sys_var_chain *chain, const char *name_arg, ulong *value_ptr_arg,
-+ sys_after_update_func after_update_arg)
-+ :sys_var_long_ptr_global(chain, name_arg, value_ptr_arg,
-+ &LOCK_global_system_variables, after_update_arg)
-+{}
-+
-+
-+bool sys_var_long_ptr_global::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, 0, GET_ULONG);
-+}
-+
-+bool sys_var_long_ptr_global::update(THD *thd, set_var *var)
-+{
-+ pthread_mutex_lock(guard);
-+ *value= (ulong) var->save_result.ulonglong_value;
-+ pthread_mutex_unlock(guard);
-+ return 0;
-+}
-+
-+
-+void sys_var_long_ptr_global::set_default(THD *thd, enum_var_type type)
-+{
-+ my_bool not_used;
-+ pthread_mutex_lock(guard);
-+ *value= (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
-+ option_limits, ¬_used);
-+ pthread_mutex_unlock(guard);
-+}
-+
-+
-+bool sys_var_ulonglong_ptr::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, 0, GET_ULL);
-+}
-+
-+
-+bool sys_var_ulonglong_ptr::update(THD *thd, set_var *var)
-+{
-+ ulonglong tmp= var->save_result.ulonglong_value;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ *value= (ulonglong) tmp;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return 0;
-+}
-+
-+
-+void sys_var_ulonglong_ptr::set_default(THD *thd, enum_var_type type)
-+{
-+ my_bool not_used;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ *value= getopt_ull_limit_value((ulonglong) option_limits->def_value,
-+ option_limits, ¬_used);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+}
-+
-+
-+bool sys_var_bool_ptr::update(THD *thd, set_var *var)
-+{
-+ *value= (my_bool) var->save_result.ulong_value;
-+ return 0;
-+}
-+
-+
-+void sys_var_bool_ptr::set_default(THD *thd, enum_var_type type)
-+{
-+ *value= (my_bool) option_limits->def_value;
-+}
-+
-+
-+bool sys_var_enum::update(THD *thd, set_var *var)
-+{
-+ *value= (uint) var->save_result.ulong_value;
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_enum::value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
-+{
-+ return (uchar*) enum_names->type_names[*value];
-+}
-+
-+
-+uchar *sys_var_enum_const::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ return (uchar*) enum_names->type_names[global_system_variables.*offset];
-+}
-+
-+bool sys_var_thd_ulong::check(THD *thd, set_var *var)
-+{
-+ if (get_unsigned(thd, var, max_system_variables.*offset, GET_ULONG))
-+ return TRUE;
-+ DBUG_ASSERT(var->save_result.ulonglong_value <= ULONG_MAX);
-+ return ((check_func && (*check_func)(thd, var)));
-+}
-+
-+bool sys_var_thd_ulong::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ global_system_variables.*offset= (ulong) var->save_result.ulonglong_value;
-+ else
-+ thd->variables.*offset= (ulong) var->save_result.ulonglong_value;
-+
-+ return 0;
-+}
-+
-+
-+void sys_var_thd_ulong::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ {
-+ my_bool not_used;
-+ /* We will not come here if option_limits is not set */
-+ global_system_variables.*offset=
-+ (ulong) getopt_ull_limit_value((ulong) option_limits->def_value,
-+ option_limits, ¬_used);
-+ }
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+uchar *sys_var_thd_ulong::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type == OPT_GLOBAL)
-+ return (uchar*) &(global_system_variables.*offset);
-+ return (uchar*) &(thd->variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_ha_rows::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, max_system_variables.*offset,
-+#ifdef BIG_TABLES
-+ GET_ULL
-+#else
-+ GET_ULONG
-+#endif
-+ );
-+}
-+
-+
-+bool sys_var_thd_ha_rows::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ {
-+ /* Lock is needed to make things safe on 32 bit systems */
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.*offset= (ha_rows)
-+ var->save_result.ulonglong_value;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= (ha_rows) var->save_result.ulonglong_value;
-+ return 0;
-+}
-+
-+
-+void sys_var_thd_ha_rows::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ {
-+ my_bool not_used;
-+ /* We will not come here if option_limits is not set */
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.*offset=
-+ (ha_rows) getopt_ull_limit_value((ha_rows) option_limits->def_value,
-+ option_limits, ¬_used);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+uchar *sys_var_thd_ha_rows::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type == OPT_GLOBAL)
-+ return (uchar*) &(global_system_variables.*offset);
-+ return (uchar*) &(thd->variables.*offset);
-+}
-+
-+bool sys_var_thd_ulonglong::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, max_system_variables.*offset, GET_ULL);
-+}
-+
-+bool sys_var_thd_ulonglong::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ {
-+ /* Lock is needed to make things safe on 32 bit systems */
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.*offset= (ulonglong)
-+ var->save_result.ulonglong_value;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= (ulonglong) var->save_result.ulonglong_value;
-+ return 0;
-+}
-+
-+
-+void sys_var_thd_ulonglong::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ {
-+ my_bool not_used;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.*offset=
-+ getopt_ull_limit_value((ulonglong) option_limits->def_value,
-+ option_limits, ¬_used);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+uchar *sys_var_thd_ulonglong::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type == OPT_GLOBAL)
-+ return (uchar*) &(global_system_variables.*offset);
-+ return (uchar*) &(thd->variables.*offset);
-+}
-+
-+
-+bool sys_var_thd_bool::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ global_system_variables.*offset= (my_bool) var->save_result.ulong_value;
-+ else
-+ thd->variables.*offset= (my_bool) var->save_result.ulong_value;
-+ return 0;
-+}
-+
-+
-+void sys_var_thd_bool::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= (my_bool) option_limits->def_value;
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+uchar *sys_var_thd_bool::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type == OPT_GLOBAL)
-+ return (uchar*) &(global_system_variables.*offset);
-+ return (uchar*) &(thd->variables.*offset);
-+}
-+
-+
-+bool sys_var::check_enum(THD *thd, set_var *var, const TYPELIB *enum_names)
-+{
-+ char buff[STRING_BUFFER_USUAL_SIZE];
-+ const char *value;
-+ String str(buff, sizeof(buff), system_charset_info), *res;
-+
-+ if (var->value->result_type() == STRING_RESULT)
-+ {
-+ if (!(res=var->value->val_str(&str)) ||
-+ ((long) (var->save_result.ulong_value=
-+ (ulong) find_type(enum_names, res->ptr(),
-+ res->length(),1)-1)) < 0)
-+ {
-+ value= res ? res->c_ptr() : "NULL";
-+ goto err;
-+ }
-+ }
-+ else
-+ {
-+ ulonglong tmp=var->value->val_int();
-+ if (tmp >= enum_names->count)
-+ {
-+ llstr(tmp,buff);
-+ value=buff; // Wrong value is here
-+ goto err;
-+ }
-+ var->save_result.ulong_value= (ulong) tmp; // Save for update
-+ }
-+ return 0;
-+
-+err:
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, value);
-+ return 1;
-+}
-+
-+
-+bool sys_var::check_set(THD *thd, set_var *var, TYPELIB *enum_names)
-+{
-+ bool not_used;
-+ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
-+ uint error_len= 0;
-+ String str(buff, sizeof(buff), system_charset_info), *res;
-+
-+ if (var->value->result_type() == STRING_RESULT)
-+ {
-+ if (!(res= var->value->val_str(&str)))
-+ {
-+ strmov(buff, "NULL");
-+ goto err;
-+ }
-+
-+ if (!m_allow_empty_value &&
-+ res->length() == 0)
-+ {
-+ buff[0]= 0;
-+ goto err;
-+ }
-+
-+ var->save_result.ulong_value= ((ulong)
-+ find_set(enum_names, res->c_ptr_safe(),
-+ res->length(),
-+ NULL,
-+ &error, &error_len,
-+ ¬_used));
-+ if (error_len)
-+ {
-+ strmake(buff, error, min(sizeof(buff) - 1, error_len));
-+ goto err;
-+ }
-+ }
-+ else
-+ {
-+ ulonglong tmp= var->value->val_int();
-+
-+ if (!m_allow_empty_value &&
-+ tmp == 0)
-+ {
-+ buff[0]= '0';
-+ buff[1]= 0;
-+ goto err;
-+ }
-+
-+ /*
-+ For when the enum is made to contain 64 elements, as 1ULL<<64 is
-+ undefined, we guard with a "count<64" test.
-+ */
-+ if (unlikely((tmp >= ((ULL(1)) << enum_names->count)) &&
-+ (enum_names->count < 64)))
-+ {
-+ llstr(tmp, buff);
-+ goto err;
-+ }
-+ var->save_result.ulong_value= (ulong) tmp; // Save for update
-+ }
-+ return 0;
-+
-+err:
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
-+ return 1;
-+}
-+
-+
-+CHARSET_INFO *sys_var::charset(THD *thd)
-+{
-+ return is_os_charset ? thd->variables.character_set_filesystem :
-+ system_charset_info;
-+}
-+
-+
-+bool sys_var_thd_enum::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ global_system_variables.*offset= var->save_result.ulong_value;
-+ else
-+ thd->variables.*offset= var->save_result.ulong_value;
-+ return 0;
-+}
-+
-+
-+void sys_var_thd_enum::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= (ulong) option_limits->def_value;
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+uchar *sys_var_thd_enum::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ ulong tmp= ((type == OPT_GLOBAL) ?
-+ global_system_variables.*offset :
-+ thd->variables.*offset);
-+ return (uchar*) enum_names->type_names[tmp];
-+}
-+
-+bool sys_var_thd_bit::check(THD *thd, set_var *var)
-+{
-+ return (check_enum(thd, var, &bool_typelib) ||
-+ (check_func && (*check_func)(thd, var)));
-+}
-+
-+bool sys_var_thd_bit::update(THD *thd, set_var *var)
-+{
-+ int res= (*update_func)(thd, var);
-+ return res;
-+}
-+
-+
-+uchar *sys_var_thd_bit::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ /*
-+ If reverse is 0 (default) return 1 if bit is set.
-+ If reverse is 1, return 0 if bit is set
-+ */
-+ thd->sys_var_tmp.my_bool_value= ((thd->options & bit_flag) ?
-+ !reverse : reverse);
-+ return (uchar*) &thd->sys_var_tmp.my_bool_value;
-+}
-+
-+
-+/** Update a date_time format variable based on given value. */
-+
-+void sys_var_thd_date_time_format::update2(THD *thd, enum_var_type type,
-+ DATE_TIME_FORMAT *new_value)
-+{
-+ DATE_TIME_FORMAT *old;
-+ DBUG_ENTER("sys_var_date_time_format::update2");
-+ DBUG_DUMP("positions", (uchar*) new_value->positions,
-+ sizeof(new_value->positions));
-+
-+ if (type == OPT_GLOBAL)
-+ {
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ old= (global_system_variables.*offset);
-+ (global_system_variables.*offset)= new_value;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ {
-+ old= (thd->variables.*offset);
-+ (thd->variables.*offset)= new_value;
-+ }
-+ my_free((char*) old, MYF(MY_ALLOW_ZERO_PTR));
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+bool sys_var_thd_date_time_format::update(THD *thd, set_var *var)
-+{
-+ DATE_TIME_FORMAT *new_value;
-+ /* We must make a copy of the last value to get it into normal memory */
-+ new_value= date_time_format_copy((THD*) 0,
-+ var->save_result.date_time_format);
-+ if (!new_value)
-+ return 1; // Out of memory
-+ update2(thd, var->type, new_value); // Can't fail
-+ return 0;
-+}
-+
-+
-+bool sys_var_thd_date_time_format::check(THD *thd, set_var *var)
-+{
-+ char buff[STRING_BUFFER_USUAL_SIZE];
-+ String str(buff,sizeof(buff), system_charset_info), *res;
-+ DATE_TIME_FORMAT *format;
-+
-+ if (!(res=var->value->val_str(&str)))
-+ res= &my_empty_string;
-+
-+ if (!(format= date_time_format_make(date_time_type,
-+ res->ptr(), res->length())))
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, res->c_ptr());
-+ return 1;
-+ }
-+
-+ /*
-+ We must copy result to thread space to not get a memory leak if
-+ update is aborted
-+ */
-+ var->save_result.date_time_format= date_time_format_copy(thd, format);
-+ my_free((char*) format, MYF(0));
-+ return var->save_result.date_time_format == 0;
-+}
-+
-+
-+void sys_var_thd_date_time_format::set_default(THD *thd, enum_var_type type)
-+{
-+ DATE_TIME_FORMAT *res= 0;
-+
-+ if (type == OPT_GLOBAL)
-+ {
-+ const char *format;
-+ if ((format= opt_date_time_formats[date_time_type]))
-+ res= date_time_format_make(date_time_type, format, strlen(format));
-+ }
-+ else
-+ {
-+ /* Make copy with malloc */
-+ res= date_time_format_copy((THD *) 0, global_system_variables.*offset);
-+ }
-+
-+ if (res) // Should always be true
-+ update2(thd, type, res);
-+}
-+
-+
-+uchar *sys_var_thd_date_time_format::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type == OPT_GLOBAL)
-+ {
-+ char *res;
-+ /*
-+ We do a copy here just to be sure things will work even if someone
-+ is modifying the original string while the copy is accessed
-+ (Can't happen now in SQL SHOW, but this is a good safety for the future)
-+ */
-+ res= thd->strmake((global_system_variables.*offset)->format.str,
-+ (global_system_variables.*offset)->format.length);
-+ return (uchar*) res;
-+ }
-+ return (uchar*) (thd->variables.*offset)->format.str;
-+}
-+
-+
-+typedef struct old_names_map_st
-+{
-+ const char *old_name;
-+ const char *new_name;
-+} my_old_conv;
-+
-+static my_old_conv old_conv[]=
-+{
-+ { "cp1251_koi8" , "cp1251" },
-+ { "cp1250_latin2" , "cp1250" },
-+ { "kam_latin2" , "keybcs2" },
-+ { "mac_latin2" , "MacRoman" },
-+ { "macce_latin2" , "MacCE" },
-+ { "pc2_latin2" , "pclatin2" },
-+ { "vga_latin2" , "pclatin1" },
-+ { "koi8_cp1251" , "koi8r" },
-+ { "win1251ukr_koi8_ukr" , "win1251ukr" },
-+ { "koi8_ukr_win1251ukr" , "koi8u" },
-+ { NULL , NULL }
-+};
-+
-+CHARSET_INFO *get_old_charset_by_name(const char *name)
-+{
-+ my_old_conv *conv;
-+
-+ for (conv= old_conv; conv->old_name; conv++)
-+ {
-+ if (!my_strcasecmp(&my_charset_latin1, name, conv->old_name))
-+ return get_charset_by_csname(conv->new_name, MY_CS_PRIMARY, MYF(0));
-+ }
-+ return NULL;
-+}
-+
-+
-+bool sys_var_collation::check(THD *thd, set_var *var)
-+{
-+ CHARSET_INFO *tmp;
-+ LINT_INIT(tmp);
-+
-+ if (var->value->result_type() == STRING_RESULT)
-+ {
-+ char buff[STRING_BUFFER_USUAL_SIZE];
-+ String str(buff,sizeof(buff), system_charset_info), *res;
-+ if (!(res=var->value->val_str(&str)))
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
-+ return 1;
-+ }
-+ if (!(tmp=get_charset_by_name(res->c_ptr(),MYF(0))))
-+ {
-+ my_error(ER_UNKNOWN_COLLATION, MYF(0), res->c_ptr());
-+ return 1;
-+ }
-+ }
-+ else // INT_RESULT
-+ {
-+ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
-+ {
-+ char buf[20];
-+ int10_to_str((int) var->value->val_int(), buf, -10);
-+ my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
-+ return 1;
-+ }
-+ }
-+ var->save_result.charset= tmp; // Save for update
-+ return 0;
-+}
-+
-+
-+bool sys_var_character_set::check(THD *thd, set_var *var)
-+{
-+ CHARSET_INFO *tmp;
-+ LINT_INIT(tmp);
-+
-+ if (var->value->result_type() == STRING_RESULT)
-+ {
-+ char buff[STRING_BUFFER_USUAL_SIZE];
-+ String str(buff,sizeof(buff), system_charset_info), *res;
-+ if (!(res=var->value->val_str(&str)))
-+ {
-+ if (!nullable)
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
-+ return 1;
-+ }
-+ tmp= NULL;
-+ }
-+ else if (!(tmp=get_charset_by_csname(res->c_ptr(),MY_CS_PRIMARY,MYF(0))) &&
-+ !(tmp=get_old_charset_by_name(res->c_ptr())))
-+ {
-+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), res->c_ptr());
-+ return 1;
-+ }
-+ }
-+ else // INT_RESULT
-+ {
-+ if (!(tmp=get_charset((int) var->value->val_int(),MYF(0))))
-+ {
-+ char buf[20];
-+ int10_to_str((int) var->value->val_int(), buf, -10);
-+ my_error(ER_UNKNOWN_CHARACTER_SET, MYF(0), buf);
-+ return 1;
-+ }
-+ }
-+ var->save_result.charset= tmp; // Save for update
-+ return 0;
-+}
-+
-+
-+bool sys_var_character_set::update(THD *thd, set_var *var)
-+{
-+ ci_ptr(thd,var->type)[0]= var->save_result.charset;
-+ thd->update_charset();
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_character_set::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ CHARSET_INFO *cs= ci_ptr(thd,type)[0];
-+ return cs ? (uchar*) cs->csname : (uchar*) NULL;
-+}
-+
-+
-+void sys_var_character_set_sv::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= *global_default;
-+ else
-+ {
-+ thd->variables.*offset= global_system_variables.*offset;
-+ thd->update_charset();
-+ }
-+}
-+CHARSET_INFO **sys_var_character_set_sv::ci_ptr(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ return &(global_system_variables.*offset);
-+ else
-+ return &(thd->variables.*offset);
-+}
-+
-+
-+bool sys_var_character_set_client::check(THD *thd, set_var *var)
-+{
-+ if (sys_var_character_set_sv::check(thd, var))
-+ return 1;
-+ /* Currently, UCS-2 cannot be used as a client character set */
-+ if (!is_supported_parser_charset(var->save_result.charset))
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name,
-+ var->save_result.charset->csname);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+CHARSET_INFO ** sys_var_character_set_database::ci_ptr(THD *thd,
-+ enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ return &global_system_variables.collation_database;
-+ else
-+ return &thd->variables.collation_database;
-+}
-+
-+
-+void sys_var_character_set_database::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.collation_database= default_charset_info;
-+ else
-+ {
-+ thd->variables.collation_database= thd->db_charset;
-+ thd->update_charset();
-+ }
-+}
-+
-+
-+bool sys_var_collation_sv::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ global_system_variables.*offset= var->save_result.charset;
-+ else
-+ {
-+ thd->variables.*offset= var->save_result.charset;
-+ thd->update_charset();
-+ }
-+ return 0;
-+}
-+
-+
-+void sys_var_collation_sv::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= *global_default;
-+ else
-+ {
-+ thd->variables.*offset= global_system_variables.*offset;
-+ thd->update_charset();
-+ }
-+}
-+
-+
-+uchar *sys_var_collation_sv::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ CHARSET_INFO *cs= ((type == OPT_GLOBAL) ?
-+ global_system_variables.*offset : thd->variables.*offset);
-+ return cs ? (uchar*) cs->name : (uchar*) "NULL";
-+}
-+
-+
-+LEX_STRING default_key_cache_base= {(char *) "default", 7 };
-+
-+static KEY_CACHE zero_key_cache;
-+
-+KEY_CACHE *get_key_cache(LEX_STRING *cache_name)
-+{
-+ safe_mutex_assert_owner(&LOCK_global_system_variables);
-+ if (!cache_name || ! cache_name->length)
-+ cache_name= &default_key_cache_base;
-+ return ((KEY_CACHE*) find_named(&key_caches,
-+ cache_name->str, cache_name->length, 0));
-+}
-+
-+
-+uchar *sys_var_key_cache_param::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ KEY_CACHE *key_cache= get_key_cache(base);
-+ if (!key_cache)
-+ key_cache= &zero_key_cache;
-+ return (uchar*) key_cache + offset ;
-+}
-+
-+
-+bool sys_var_key_buffer_size::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, 0, GET_ULL);
-+}
-+
-+
-+bool sys_var_key_buffer_size::update(THD *thd, set_var *var)
-+{
-+ ulonglong tmp= var->save_result.ulonglong_value;
-+ LEX_STRING *base_name= &var->base;
-+ KEY_CACHE *key_cache;
-+ bool error= 0;
-+
-+ /* If no basename, assume it's for the key cache named 'default' */
-+ if (!base_name->length)
-+ base_name= &default_key_cache_base;
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ key_cache= get_key_cache(base_name);
-+
-+ if (!key_cache)
-+ {
-+ /* Key cache didn't exist */
-+ if (!tmp) // Tried to delete cache
-+ goto end; // Ok, nothing to do
-+ if (!(key_cache= create_key_cache(base_name->str, base_name->length)))
-+ {
-+ error= 1;
-+ goto end;
-+ }
-+ }
-+
-+ /*
-+ Abort if some other thread is changing the key cache
-+ TODO: This should be changed so that we wait until the previous
-+ assignment is done and then do the new assign
-+ */
-+ if (key_cache->in_init)
-+ goto end;
-+
-+ if (!tmp) // Zero size means delete
-+ {
-+ if (key_cache == dflt_key_cache)
-+ {
-+ error= 1;
-+ my_error(ER_WARN_CANT_DROP_DEFAULT_KEYCACHE, MYF(0));
-+ goto end; // Ignore default key cache
-+ }
-+
-+ if (key_cache->key_cache_inited) // If initied
-+ {
-+ /*
-+ Move tables using this key cache to the default key cache
-+ and clear the old key cache.
-+ */
-+ NAMED_LIST *list;
-+ key_cache= (KEY_CACHE *) find_named(&key_caches, base_name->str,
-+ base_name->length, &list);
-+ key_cache->in_init= 1;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ error= reassign_keycache_tables(thd, key_cache, dflt_key_cache);
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ key_cache->in_init= 0;
-+ }
-+ /*
-+ We don't delete the key cache as some running threads my still be
-+ in the key cache code with a pointer to the deleted (empty) key cache
-+ */
-+ goto end;
-+ }
-+
-+ key_cache->param_buff_size= (ulonglong) tmp;
-+
-+ /* If key cache didn't exist initialize it, else resize it */
-+ key_cache->in_init= 1;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+ if (!key_cache->key_cache_inited)
-+ error= (bool) (ha_init_key_cache("", key_cache));
-+ else
-+ error= (bool)(ha_resize_key_cache(key_cache));
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ key_cache->in_init= 0;
-+
-+end:
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+ var->save_result.ulonglong_value = SIZE_T_MAX;
-+
-+ return error;
-+}
-+
-+
-+bool sys_var_key_cache_long::check(THD *thd, set_var *var)
-+{
-+ return get_unsigned(thd, var, 0, GET_ULONG);
-+}
-+
-+
-+/**
-+ @todo
-+ Abort if some other thread is changing the key cache.
-+ This should be changed so that we wait until the previous
-+ assignment is done and then do the new assign
-+*/
-+bool sys_var_key_cache_long::update(THD *thd, set_var *var)
-+{
-+ LEX_STRING *base_name= &var->base;
-+ bool error= 0;
-+
-+ if (!base_name->length)
-+ base_name= &default_key_cache_base;
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ KEY_CACHE *key_cache= get_key_cache(base_name);
-+
-+ if (!key_cache && !(key_cache= create_key_cache(base_name->str,
-+ base_name->length)))
-+ {
-+ error= 1;
-+ goto end;
-+ }
-+
-+ /*
-+ Abort if some other thread is changing the key cache
-+ TODO: This should be changed so that we wait until the previous
-+ assignment is done and then do the new assign
-+ */
-+ if (key_cache->in_init)
-+ goto end;
-+
-+ *((ulong*) (((char*) key_cache) + offset))= (ulong)
-+ var->save_result.ulonglong_value;
-+
-+ /*
-+ Don't create a new key cache if it didn't exist
-+ (key_caches are created only when the user sets block_size)
-+ */
-+ key_cache->in_init= 1;
-+
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+ error= (bool) (ha_resize_key_cache(key_cache));
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ key_cache->in_init= 0;
-+
-+end:
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return error;
-+}
-+
-+
-+bool sys_var_log_state::update(THD *thd, set_var *var)
-+{
-+ bool res;
-+
-+ if (this == &sys_var_log)
-+ WARN_DEPRECATED(thd, "7.0", "@@log", "'@@general_log'");
-+ else if (this == &sys_var_log_slow)
-+ WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ if (!var->save_result.ulong_value)
-+ {
-+ logger.deactivate_log_handler(thd, log_type);
-+ res= false;
-+ }
-+ else
-+ res= logger.activate_log_handler(thd, log_type);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return res;
-+}
-+
-+void sys_var_log_state::set_default(THD *thd, enum_var_type type)
-+{
-+ if (this == &sys_var_log)
-+ WARN_DEPRECATED(thd, "7.0", "@@log", "'@@general_log'");
-+ else if (this == &sys_var_log_slow)
-+ WARN_DEPRECATED(thd, "7.0", "@@log_slow_queries", "'@@slow_query_log'");
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ logger.deactivate_log_handler(thd, log_type);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+}
-+
-+
-+static int sys_check_log_path(THD *thd, set_var *var)
-+{
-+ char path[FN_REFLEN], buff[FN_REFLEN];
-+ MY_STAT f_stat;
-+ String str(buff, sizeof(buff), system_charset_info), *res;
-+ const char *log_file_str;
-+ size_t path_length;
-+
-+ if (!(res= var->value->val_str(&str)))
-+ goto err;
-+
-+ log_file_str= res->c_ptr();
-+ bzero(&f_stat, sizeof(MY_STAT));
-+
-+ path_length= unpack_filename(path, log_file_str);
-+
-+ if (!path_length)
-+ {
-+ /* File name is empty. */
-+
-+ goto err;
-+ }
-+
-+ if (my_stat(path, &f_stat, MYF(0)))
-+ {
-+ /*
-+ A file system object exists. Check if argument is a file and we have
-+ 'write' permission.
-+ */
-+
-+ if (!MY_S_ISREG(f_stat.st_mode) ||
-+ !(f_stat.st_mode & MY_S_IWRITE))
-+ goto err;
-+
-+ return 0;
-+ }
-+
-+ /* Get dirname of the file path. */
-+ (void) dirname_part(path, log_file_str, &path_length);
-+
-+ /* Dirname is empty if file path is relative. */
-+ if (!path_length)
-+ return 0;
-+
-+ /*
-+ Check if directory exists and we have permission to create file and
-+ write to file.
-+ */
-+ if (my_access(path, (F_OK|W_OK)))
-+ goto err;
-+
-+ return 0;
-+
-+err:
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), var->var->name,
-+ res ? log_file_str : "NULL");
-+ return 1;
-+}
-+
-+
-+bool update_sys_var_str_path(THD *thd, sys_var_str *var_str,
-+ set_var *var, const char *log_ext,
-+ bool log_state, uint log_type)
-+{
-+ MYSQL_QUERY_LOG *file_log;
-+ char buff[FN_REFLEN];
-+ char *res= 0, *old_value=(char *)(var ? var->value->str_value.ptr() : 0);
-+ bool result= 0;
-+ uint str_length= (var ? var->value->str_value.length() : 0);
-+
-+ switch (log_type) {
-+ case QUERY_LOG_SLOW:
-+ file_log= logger.get_slow_log_file_handler();
-+ break;
-+ case QUERY_LOG_GENERAL:
-+ file_log= logger.get_log_file_handler();
-+ break;
-+ default:
-+ MY_ASSERT_UNREACHABLE();
-+ }
-+
-+ if (!old_value)
-+ {
-+ old_value= make_default_log_name(buff, log_ext);
-+ str_length= strlen(old_value);
-+ }
-+ if (!(res= my_strndup(old_value, str_length, MYF(MY_FAE+MY_WME))))
-+ {
-+ result= 1;
-+ goto err;
-+ }
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ logger.lock_exclusive();
-+
-+ if (file_log && log_state)
-+ file_log->close(0);
-+ old_value= var_str->value;
-+ var_str->value= res;
-+ var_str->value_length= str_length;
-+ my_free(old_value, MYF(MY_ALLOW_ZERO_PTR));
-+ if (file_log && log_state)
-+ {
-+ switch (log_type) {
-+ case QUERY_LOG_SLOW:
-+ file_log->open_slow_log(sys_var_slow_log_path.value);
-+ break;
-+ case QUERY_LOG_GENERAL:
-+ file_log->open_query_log(sys_var_general_log_path.value);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ }
-+
-+ logger.unlock();
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+err:
-+ return result;
-+}
-+
-+
-+static bool sys_update_general_log_path(THD *thd, set_var * var)
-+{
-+ return update_sys_var_str_path(thd, &sys_var_general_log_path,
-+ var, ".log", opt_log, QUERY_LOG_GENERAL);
-+}
-+
-+
-+static void sys_default_general_log_path(THD *thd, enum_var_type type)
-+{
-+ (void) update_sys_var_str_path(thd, &sys_var_general_log_path,
-+ 0, ".log", opt_log, QUERY_LOG_GENERAL);
-+}
-+
-+
-+static bool sys_update_slow_log_path(THD *thd, set_var * var)
-+{
-+ return update_sys_var_str_path(thd, &sys_var_slow_log_path,
-+ var, "-slow.log", opt_slow_log,
-+ QUERY_LOG_SLOW);
-+}
-+
-+
-+static void sys_default_slow_log_path(THD *thd, enum_var_type type)
-+{
-+ (void) update_sys_var_str_path(thd, &sys_var_slow_log_path,
-+ 0, "-slow.log", opt_slow_log,
-+ QUERY_LOG_SLOW);
-+}
-+
-+
-+bool sys_var_log_output::update(THD *thd, set_var *var)
-+{
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ logger.lock_exclusive();
-+ logger.init_slow_log(var->save_result.ulong_value);
-+ logger.init_general_log(var->save_result.ulong_value);
-+ *value= var->save_result.ulong_value;
-+ logger.unlock();
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return 0;
-+}
-+
-+
-+void sys_var_log_output::set_default(THD *thd, enum_var_type type)
-+{
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ logger.lock_exclusive();
-+ logger.init_slow_log(LOG_FILE);
-+ logger.init_general_log(LOG_FILE);
-+ *value= LOG_FILE;
-+ logger.unlock();
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+}
-+
-+
-+uchar *sys_var_log_output::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ char buff[256];
-+ String tmp(buff, sizeof(buff), &my_charset_latin1);
-+ ulong length;
-+ ulong val= *value;
-+
-+ tmp.length(0);
-+ for (uint i= 0; val; val>>= 1, i++)
-+ {
-+ if (val & 1)
-+ {
-+ tmp.append(log_output_typelib.type_names[i],
-+ log_output_typelib.type_lengths[i]);
-+ tmp.append(',');
-+ }
-+ }
-+
-+ if ((length= tmp.length()))
-+ length--;
-+ return (uchar*) thd->strmake(tmp.ptr(), length);
-+}
-+
-+
-+/*****************************************************************************
-+ Functions to handle SET NAMES and SET CHARACTER SET
-+*****************************************************************************/
-+
-+int set_var_collation_client::check(THD *thd)
-+{
-+ /* Currently, UCS-2 cannot be used as a client character set */
-+ if (character_set_client->mbminlen > 1)
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
-+ character_set_client->csname);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+int set_var_collation_client::update(THD *thd)
-+{
-+ thd->variables.character_set_client= character_set_client;
-+ thd->variables.character_set_results= character_set_results;
-+ thd->variables.collation_connection= collation_connection;
-+ thd->update_charset();
-+ thd->protocol_text.init(thd);
-+ thd->protocol_binary.init(thd);
-+ return 0;
-+}
-+
-+/****************************************************************************/
-+
-+bool sys_var_timestamp::check(THD *thd, set_var *var)
-+{
-+ longlong val;
-+ var->save_result.ulonglong_value= var->value->val_int();
-+ val= (longlong) var->save_result.ulonglong_value;
-+ if (val != 0 && // this is how you set the default value
-+ (val < TIMESTAMP_MIN_VALUE || val > TIMESTAMP_MAX_VALUE))
-+ {
-+ char buf[64];
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "timestamp", llstr(val, buf));
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+
-+bool sys_var_timestamp::update(THD *thd, set_var *var)
-+{
-+ thd->set_time((time_t) var->save_result.ulonglong_value);
-+ return FALSE;
-+}
-+
-+
-+void sys_var_timestamp::set_default(THD *thd, enum_var_type type)
-+{
-+ thd->user_time=0;
-+}
-+
-+
-+uchar *sys_var_timestamp::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ thd->sys_var_tmp.long_value= (long) thd->start_time;
-+ return (uchar*) &thd->sys_var_tmp.long_value;
-+}
-+
-+
-+bool sys_var_last_insert_id::update(THD *thd, set_var *var)
-+{
-+ thd->first_successful_insert_id_in_prev_stmt=
-+ var->save_result.ulonglong_value;
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_last_insert_id::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ /*
-+ this tmp var makes it robust againt change of type of
-+ read_first_successful_insert_id_in_prev_stmt().
-+ */
-+ thd->sys_var_tmp.ulonglong_value=
-+ thd->read_first_successful_insert_id_in_prev_stmt();
-+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
-+}
-+
-+
-+bool sys_var_insert_id::update(THD *thd, set_var *var)
-+{
-+ thd->force_one_auto_inc_interval(var->save_result.ulonglong_value);
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_insert_id::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ thd->sys_var_tmp.ulonglong_value=
-+ thd->auto_inc_intervals_forced.minimum();
-+ return (uchar*) &thd->sys_var_tmp.ulonglong_value;
-+}
-+
-+
-+bool sys_var_rand_seed1::update(THD *thd, set_var *var)
-+{
-+ thd->rand.seed1= (ulong) var->save_result.ulonglong_value;
-+ return 0;
-+}
-+
-+bool sys_var_rand_seed2::update(THD *thd, set_var *var)
-+{
-+ thd->rand.seed2= (ulong) var->save_result.ulonglong_value;
-+ return 0;
-+}
-+
-+
-+bool sys_var_thd_time_zone::check(THD *thd, set_var *var)
-+{
-+ char buff[MAX_TIME_ZONE_NAME_LENGTH];
-+ String str(buff, sizeof(buff), &my_charset_latin1);
-+ String *res= var->value->val_str(&str);
-+
-+ if (!(var->save_result.time_zone= my_tz_find(thd, res)))
-+ {
-+ my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL");
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+bool sys_var_thd_time_zone::update(THD *thd, set_var *var)
-+{
-+ /* We are using Time_zone object found during check() phase. */
-+ if (var->type == OPT_GLOBAL)
-+ {
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.time_zone= var->save_result.time_zone;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.time_zone= var->save_result.time_zone;
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_thd_time_zone::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ /*
-+ We can use ptr() instead of c_ptr() here because String contaning
-+ time zone name is guaranteed to be zero ended.
-+ */
-+ if (type == OPT_GLOBAL)
-+ return (uchar *)(global_system_variables.time_zone->get_name()->ptr());
-+ else
-+ {
-+ /*
-+ This is an ugly fix for replication: we don't replicate properly queries
-+ invoking system variables' values to update tables; but
-+ CONVERT_TZ(,,@@session.time_zone) is so popular that we make it
-+ replicable (i.e. we tell the binlog code to store the session
-+ timezone). If it's the global value which was used we can't replicate
-+ (binlog code stores session value only).
-+ */
-+ thd->time_zone_used= 1;
-+ return (uchar *)(thd->variables.time_zone->get_name()->ptr());
-+ }
-+}
-+
-+
-+void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type)
-+{
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ if (type == OPT_GLOBAL)
-+ {
-+ if (default_tz_name)
-+ {
-+ String str(default_tz_name, &my_charset_latin1);
-+ /*
-+ We are guaranteed to find this time zone since its existence
-+ is checked during start-up.
-+ */
-+ global_system_variables.time_zone= my_tz_find(thd, &str);
-+ }
-+ else
-+ global_system_variables.time_zone= my_tz_SYSTEM;
-+ }
-+ else
-+ thd->variables.time_zone= global_system_variables.time_zone;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+}
-+
-+
-+bool sys_var_max_user_conn::check(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ return sys_var_thd::check(thd, var);
-+ else
-+ {
-+ /*
-+ Per-session values of max_user_connections can't be set directly.
-+ May be we should have a separate error message for this?
-+ */
-+ my_error(ER_GLOBAL_VARIABLE, MYF(0), name);
-+ return TRUE;
-+ }
-+}
-+
-+bool sys_var_max_user_conn::update(THD *thd, set_var *var)
-+{
-+ DBUG_ASSERT(var->type == OPT_GLOBAL);
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ max_user_connections= (uint)var->save_result.ulonglong_value;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return 0;
-+}
-+
-+
-+void sys_var_max_user_conn::set_default(THD *thd, enum_var_type type)
-+{
-+ DBUG_ASSERT(type == OPT_GLOBAL);
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ max_user_connections= (ulong) option_limits->def_value;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+}
-+
-+
-+uchar *sys_var_max_user_conn::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ if (type != OPT_GLOBAL &&
-+ thd->user_connect && thd->user_connect->user_resources.user_conn)
-+ return (uchar*) &(thd->user_connect->user_resources.user_conn);
-+ return (uchar*) &(max_user_connections);
-+}
-+
-+
-+bool sys_var_thd_ulong_session_readonly::check(THD *thd, set_var *var)
-+{
-+ if (var->type != OPT_GLOBAL)
-+ {
-+ my_error(ER_VARIABLE_IS_READONLY, MYF(0), "SESSION", name, "GLOBAL");
-+ return TRUE;
-+ }
-+
-+ return sys_var_thd_ulong::check(thd, var);
-+}
-+
-+
-+bool sys_var_thd_lc_time_names::check(THD *thd, set_var *var)
-+{
-+ MY_LOCALE *locale_match;
-+
-+ if (var->value->result_type() == INT_RESULT)
-+ {
-+ if (!(locale_match= my_locale_by_number((uint) var->value->val_int())))
-+ {
-+ char buf[20];
-+ int10_to_str((int) var->value->val_int(), buf, -10);
-+ my_printf_error(ER_UNKNOWN_ERROR, "Unknown locale: '%s'", MYF(0), buf);
-+ return 1;
-+ }
-+ }
-+ else // STRING_RESULT
-+ {
-+ char buff[6];
-+ String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+ if (!(res=var->value->val_str(&str)))
-+ {
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, "NULL");
-+ return 1;
-+ }
-+ const char *locale_str= res->c_ptr_safe();
-+ if (!(locale_match= my_locale_by_name(locale_str)))
-+ {
-+ my_printf_error(ER_UNKNOWN_ERROR,
-+ "Unknown locale: '%s'", MYF(0), locale_str);
-+ return 1;
-+ }
-+ }
-+
-+ var->save_result.locale_value= locale_match;
-+ return 0;
-+}
-+
-+
-+bool sys_var_thd_lc_time_names::update(THD *thd, set_var *var)
-+{
-+ if (var->type == OPT_GLOBAL)
-+ global_system_variables.lc_time_names= var->save_result.locale_value;
-+ else
-+ thd->variables.lc_time_names= var->save_result.locale_value;
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_thd_lc_time_names::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ return type == OPT_GLOBAL ?
-+ (uchar *) global_system_variables.lc_time_names->name :
-+ (uchar *) thd->variables.lc_time_names->name;
-+}
-+
-+
-+void sys_var_thd_lc_time_names::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.lc_time_names= my_default_lc_time_names;
-+ else
-+ thd->variables.lc_time_names= global_system_variables.lc_time_names;
-+}
-+
-+/*
-+ Handling of microseoncds given as seconds.part_seconds
-+
-+ NOTES
-+ The argument to long query time is in seconds in decimal
-+ which is converted to ulonglong integer holding microseconds for storage.
-+ This is used for handling long_query_time
-+*/
-+
-+bool sys_var_microseconds::update(THD *thd, set_var *var)
-+{
-+ double num= var->value->val_real();
-+ longlong microseconds;
-+ if (num > (double) option_limits->max_value)
-+ num= (double) option_limits->max_value;
-+ if (num < (double) option_limits->min_value)
-+ num= (double) option_limits->min_value;
-+ microseconds= (longlong) (num * 1000000.0 + 0.5);
-+ if (var->type == OPT_GLOBAL)
-+ {
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ (global_system_variables.*offset)= microseconds;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= microseconds;
-+ return 0;
-+}
-+
-+
-+void sys_var_microseconds::set_default(THD *thd, enum_var_type type)
-+{
-+ longlong microseconds= (longlong) (option_limits->def_value * 1000000.0);
-+ if (type == OPT_GLOBAL)
-+ {
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ global_system_variables.*offset= microseconds;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ }
-+ else
-+ thd->variables.*offset= microseconds;
-+}
-+
-+
-+uchar *sys_var_microseconds::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ thd->tmp_double_value= (double) ((type == OPT_GLOBAL) ?
-+ global_system_variables.*offset :
-+ thd->variables.*offset) / 1000000.0;
-+ return (uchar*) &thd->tmp_double_value;
-+}
-+
-+
-+/*
-+ Functions to update thd->options bits
-+*/
-+
-+static bool set_option_bit(THD *thd, set_var *var)
-+{
-+ sys_var_thd_bit *sys_var= ((sys_var_thd_bit*) var->var);
-+ if ((var->save_result.ulong_value != 0) == sys_var->reverse)
-+ thd->options&= ~sys_var->bit_flag;
-+ else
-+ thd->options|= sys_var->bit_flag;
-+ return 0;
-+}
-+
-+/*
-+ Functions to be only used to update thd->options OPTION_BIN_LOG bit
-+*/
-+static bool set_option_log_bin_bit(THD *thd, set_var *var)
-+{
-+ set_option_bit(thd, var);
-+ if (!thd->in_sub_stmt)
-+ thd->sql_log_bin_toplevel= thd->options & OPTION_BIN_LOG;
-+ return 0;
-+}
-+
-+static bool set_option_autocommit(THD *thd, set_var *var)
-+{
-+ /* The test is negative as the flag we use is NOT autocommit */
-+
-+ ulonglong org_options= thd->options;
-+
-+ if (var->save_result.ulong_value != 0)
-+ thd->options&= ~((sys_var_thd_bit*) var->var)->bit_flag;
-+ else
-+ thd->options|= ((sys_var_thd_bit*) var->var)->bit_flag;
-+
-+ if ((org_options ^ thd->options) & OPTION_NOT_AUTOCOMMIT)
-+ {
-+ if ((org_options & OPTION_NOT_AUTOCOMMIT))
-+ {
-+ /* We changed to auto_commit mode */
-+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+ {
-+ thd->options= org_options;
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ return 1;
-+ }
-+ thd->options&= ~(ulonglong) (OPTION_BEGIN | OPTION_KEEP_LOG);
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
-+ if (ha_commit(thd))
-+ return 1;
-+ }
-+ else
-+ {
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
-+ }
-+ }
-+ return 0;
-+}
-+
-+static int check_log_update(THD *thd, set_var *var)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (!(thd->security_ctx->master_access & SUPER_ACL))
-+ {
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-+ return 1;
-+ }
-+#endif
-+ return 0;
-+}
-+
-+static bool set_log_update(THD *thd, set_var *var)
-+{
-+ /*
-+ The update log is not supported anymore since 5.0.
-+ See sql/mysqld.cc/, comments in function init_server_components() for an
-+ explaination of the different warnings we send below
-+ */
-+
-+ if (opt_sql_bin_update)
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_UPDATE_LOG_DEPRECATED_TRANSLATED,
-+ ER(ER_UPDATE_LOG_DEPRECATED_TRANSLATED));
-+ }
-+ else
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_UPDATE_LOG_DEPRECATED_IGNORED,
-+ ER(ER_UPDATE_LOG_DEPRECATED_IGNORED));
-+ set_option_bit(thd, var);
-+ return 0;
-+}
-+
-+
-+static int check_pseudo_thread_id(THD *thd, set_var *var)
-+{
-+ var->save_result.ulonglong_value= var->value->val_int();
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (thd->security_ctx->master_access & SUPER_ACL)
-+ return 0;
-+ else
-+ {
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-+ return 1;
-+ }
-+#else
-+ return 0;
-+#endif
-+}
-+
-+static uchar *get_warning_count(THD *thd)
-+{
-+ thd->sys_var_tmp.long_value=
-+ (thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_NOTE] +
-+ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR] +
-+ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_WARN]);
-+ return (uchar*) &thd->sys_var_tmp.long_value;
-+}
-+
-+static uchar *get_error_count(THD *thd)
-+{
-+ thd->sys_var_tmp.long_value=
-+ thd->warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_ERROR];
-+ return (uchar*) &thd->sys_var_tmp.long_value;
-+}
-+
-+
-+/**
-+ Get the tmpdir that was specified or chosen by default.
-+
-+ This is necessary because if the user does not specify a temporary
-+ directory via the command line, one is chosen based on the environment
-+ or system defaults. But we can't just always use mysql_tmpdir, because
-+ that is actually a call to my_tmpdir() which cycles among possible
-+ temporary directories.
-+
-+ @param thd thread handle
-+
-+ @retval
-+ ptr pointer to NUL-terminated string
-+*/
-+static uchar *get_tmpdir(THD *thd)
-+{
-+ if (opt_mysql_tmpdir)
-+ return (uchar *)opt_mysql_tmpdir;
-+ return (uchar*)mysql_tmpdir;
-+}
-+
-+static uchar *get_myisam_mmap_size(THD *thd)
-+{
-+ return (uchar *)&myisam_mmap_size;
-+}
-+
-+
-+/****************************************************************************
-+ Main handling of variables:
-+ - Initialisation
-+ - Searching during parsing
-+ - Update loop
-+****************************************************************************/
-+
-+/**
-+ Find variable name in option my_getopt structure used for
-+ command line args.
-+
-+ @param opt option structure array to search in
-+ @param name variable name
-+
-+ @retval
-+ 0 Error
-+ @retval
-+ ptr pointer to option structure
-+*/
-+
-+static struct my_option *find_option(struct my_option *opt, const char *name)
-+{
-+ uint length=strlen(name);
-+ for (; opt->name; opt++)
-+ {
-+ if (!getopt_compare_strings(opt->name, name, length) &&
-+ !opt->name[length])
-+ {
-+ /*
-+ Only accept the option if one can set values through it.
-+ If not, there is no default value or limits in the option.
-+ */
-+ return (opt->value) ? opt : 0;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Return variable name and length for hashing of variables.
-+*/
-+
-+static uchar *get_sys_var_length(const sys_var *var, size_t *length,
-+ my_bool first)
-+{
-+ *length= var->name_length;
-+ return (uchar*) var->name;
-+}
-+
-+
-+/*
-+ Add variables to the dynamic hash of system variables
-+
-+ SYNOPSIS
-+ mysql_add_sys_var_chain()
-+ first Pointer to first system variable to add
-+ long_opt (optional)command line arguments may be tied for limit checks.
-+
-+ RETURN VALUES
-+ 0 SUCCESS
-+ otherwise FAILURE
-+*/
-+
-+
-+int mysql_add_sys_var_chain(sys_var *first, struct my_option *long_options)
-+{
-+ sys_var *var;
-+
-+ /* A write lock should be held on LOCK_system_variables_hash */
-+
-+ for (var= first; var; var= var->next)
-+ {
-+ var->name_length= strlen(var->name);
-+ /* this fails if there is a conflicting variable name. see HASH_UNIQUE */
-+ if (my_hash_insert(&system_variable_hash, (uchar*) var))
-+ goto error;
-+ if (long_options)
-+ var->option_limits= find_option(long_options, var->name);
-+ }
-+ return 0;
-+
-+error:
-+ for (; first != var; first= first->next)
-+ hash_delete(&system_variable_hash, (uchar*) first);
-+ return 1;
-+}
-+
-+
-+/*
-+ Remove variables to the dynamic hash of system variables
-+
-+ SYNOPSIS
-+ mysql_del_sys_var_chain()
-+ first Pointer to first system variable to remove
-+
-+ RETURN VALUES
-+ 0 SUCCESS
-+ otherwise FAILURE
-+*/
-+
-+int mysql_del_sys_var_chain(sys_var *first)
-+{
-+ int result= 0;
-+
-+ /* A write lock should be held on LOCK_system_variables_hash */
-+
-+ for (sys_var *var= first; var; var= var->next)
-+ result|= hash_delete(&system_variable_hash, (uchar*) var);
-+
-+ return result;
-+}
-+
-+
-+static int show_cmp(SHOW_VAR *a, SHOW_VAR *b)
-+{
-+ return strcmp(a->name, b->name);
-+}
-+
-+
-+/*
-+ Constructs an array of system variables for display to the user.
-+
-+ SYNOPSIS
-+ enumerate_sys_vars()
-+ thd current thread
-+ sorted If TRUE, the system variables should be sorted
-+
-+ RETURN VALUES
-+ pointer Array of SHOW_VAR elements for display
-+ NULL FAILURE
-+*/
-+
-+SHOW_VAR* enumerate_sys_vars(THD *thd, bool sorted)
-+{
-+ int count= system_variable_hash.records, i;
-+ int size= sizeof(SHOW_VAR) * (count + 1);
-+ SHOW_VAR *result= (SHOW_VAR*) thd->alloc(size);
-+
-+ if (result)
-+ {
-+ SHOW_VAR *show= result;
-+
-+ for (i= 0; i < count; i++)
-+ {
-+ sys_var *var= (sys_var*) hash_element(&system_variable_hash, i);
-+ show->name= var->name;
-+ show->value= (char*) var;
-+ show->type= SHOW_SYS;
-+ show++;
-+ }
-+
-+ /* sort into order */
-+ if (sorted)
-+ my_qsort(result, count, sizeof(SHOW_VAR),
-+ (qsort_cmp) show_cmp);
-+
-+ /* make last element empty */
-+ bzero(show, sizeof(SHOW_VAR));
-+ }
-+ return result;
-+}
-+
-+
-+/*
-+ Initialize the system variables
-+
-+ SYNOPSIS
-+ set_var_init()
-+
-+ RETURN VALUES
-+ 0 SUCCESS
-+ otherwise FAILURE
-+*/
-+
-+int set_var_init()
-+{
-+ uint count= 0;
-+ DBUG_ENTER("set_var_init");
-+
-+ for (sys_var *var=vars.first; var; var= var->next, count++) ;
-+
-+ if (hash_init(&system_variable_hash, system_charset_info, count, 0,
-+ 0, (hash_get_key) get_sys_var_length, 0, HASH_UNIQUE))
-+ goto error;
-+
-+ vars.last->next= NULL;
-+ if (mysql_add_sys_var_chain(vars.first, my_long_options))
-+ goto error;
-+
-+ /*
-+ Special cases
-+ Needed because MySQL can't find the limits for a variable it it has
-+ a different name than the command line option.
-+ As these variables are deprecated, this code will disappear soon...
-+ */
-+ sys_sql_max_join_size.option_limits= sys_max_join_size.option_limits;
-+
-+ DBUG_RETURN(0);
-+
-+error:
-+ fprintf(stderr, "failed to initialize system variables");
-+ DBUG_RETURN(1);
-+}
-+
-+
-+void set_var_free()
-+{
-+ hash_free(&system_variable_hash);
-+}
-+
-+
-+/**
-+ Find a user set-table variable.
-+
-+ @param str Name of system variable to find
-+ @param length Length of variable. zero means that we should use strlen()
-+ on the variable
-+ @param no_error Refuse to emit an error, even if one occurred.
-+
-+ @retval
-+ pointer pointer to variable definitions
-+ @retval
-+ 0 Unknown variable (error message is given)
-+*/
-+
-+sys_var *intern_find_sys_var(const char *str, uint length, bool no_error)
-+{
-+ sys_var *var;
-+
-+ /*
-+ This function is only called from the sql_plugin.cc.
-+ A lock on LOCK_system_variable_hash should be held
-+ */
-+ var= (sys_var*) hash_search(&system_variable_hash,
-+ (uchar*) str, length ? length : strlen(str));
-+ if (!(var || no_error))
-+ my_error(ER_UNKNOWN_SYSTEM_VARIABLE, MYF(0), (char*) str);
-+
-+ return var;
-+}
-+
-+
-+/**
-+ Execute update of all variables.
-+
-+ First run a check of all variables that all updates will go ok.
-+ If yes, then execute all updates, returning an error if any one failed.
-+
-+ This should ensure that in all normal cases none all or variables are
-+ updated.
-+
-+ @param THD Thread id
-+ @param var_list List of variables to update
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 ERROR, message sent (normally no variables was updated)
-+ @retval
-+ -1 ERROR, message not sent
-+*/
-+
-+int sql_set_variables(THD *thd, List<set_var_base> *var_list)
-+{
-+ int error;
-+ List_iterator_fast<set_var_base> it(*var_list);
-+ DBUG_ENTER("sql_set_variables");
-+
-+ set_var_base *var;
-+ while ((var=it++))
-+ {
-+ if ((error= var->check(thd)))
-+ goto err;
-+ }
-+ if (!(error= test(thd->is_error())))
-+ {
-+ it.rewind();
-+ while ((var= it++))
-+ error|= var->update(thd); // Returns 0, -1 or 1
-+ }
-+
-+err:
-+ free_underlaid_joins(thd, &thd->lex->select_lex);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/**
-+ Say if all variables set by a SET support the ONE_SHOT keyword
-+ (currently, only character set and collation do; later timezones
-+ will).
-+
-+ @param var_list List of variables to update
-+
-+ @note
-+ It has a "not_" because it makes faster tests (no need to "!")
-+
-+ @retval
-+ 0 all variables of the list support ONE_SHOT
-+ @retval
-+ 1 at least one does not support ONE_SHOT
-+*/
-+
-+bool not_all_support_one_shot(List<set_var_base> *var_list)
-+{
-+ List_iterator_fast<set_var_base> it(*var_list);
-+ set_var_base *var;
-+ while ((var= it++))
-+ {
-+ if (var->no_support_one_shot())
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ Functions to handle SET mysql_internal_variable=const_expr
-+*****************************************************************************/
-+
-+int set_var::check(THD *thd)
-+{
-+ if (var->is_readonly())
-+ {
-+ my_error(ER_INCORRECT_GLOBAL_LOCAL_VAR, MYF(0), var->name, "read only");
-+ return -1;
-+ }
-+ if (var->check_type(type))
-+ {
-+ int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
-+ my_error(err, MYF(0), var->name);
-+ return -1;
-+ }
-+ if ((type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL)))
-+ return 1;
-+ /* value is a NULL pointer if we are using SET ... = DEFAULT */
-+ if (!value)
-+ {
-+ if (var->check_default(type))
-+ {
-+ my_error(ER_NO_DEFAULT, MYF(0), var->name);
-+ return -1;
-+ }
-+ return 0;
-+ }
-+
-+ if ((!value->fixed &&
-+ value->fix_fields(thd, &value)) || value->check_cols(1))
-+ return -1;
-+ if (var->check_update_type(value->result_type()))
-+ {
-+ my_error(ER_WRONG_TYPE_FOR_VAR, MYF(0), var->name);
-+ return -1;
-+ }
-+ return var->check(thd, this) ? -1 : 0;
-+}
-+
-+
-+/**
-+ Check variable, but without assigning value (used by PS).
-+
-+ @param thd thread handler
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 ERROR, message sent (normally no variables was updated)
-+ @retval
-+ -1 ERROR, message not sent
-+*/
-+int set_var::light_check(THD *thd)
-+{
-+ if (var->check_type(type))
-+ {
-+ int err= type == OPT_GLOBAL ? ER_LOCAL_VARIABLE : ER_GLOBAL_VARIABLE;
-+ my_error(err, MYF(0), var->name);
-+ return -1;
-+ }
-+ if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
-+ return 1;
-+
-+ if (value && ((!value->fixed && value->fix_fields(thd, &value)) ||
-+ value->check_cols(1)))
-+ return -1;
-+ return 0;
-+}
-+
-+/**
-+ Update variable
-+
-+ @param thd thread handler
-+ @returns 0|1 ok or ERROR
-+
-+ @note ERROR can be only due to abnormal operations involving
-+ the server's execution evironment such as
-+ out of memory, hard disk failure or the computer blows up.
-+ Consider set_var::check() method if there is a need to return
-+ an error due to logics.
-+*/
-+int set_var::update(THD *thd)
-+{
-+ if (!value)
-+ var->set_default(thd, type);
-+ else if (var->update(thd, this))
-+ return -1; // should never happen
-+ if (var->after_update)
-+ (*var->after_update)(thd, type);
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ Functions to handle SET @user_variable=const_expr
-+*****************************************************************************/
-+
-+int set_var_user::check(THD *thd)
-+{
-+ /*
-+ Item_func_set_user_var can't substitute something else on its place =>
-+ 0 can be passed as last argument (reference on item)
-+ */
-+ return (user_var_item->fix_fields(thd, (Item**) 0) ||
-+ user_var_item->check(0)) ? -1 : 0;
-+}
-+
-+
-+/**
-+ Check variable, but without assigning value (used by PS).
-+
-+ @param thd thread handler
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 ERROR, message sent (normally no variables was updated)
-+ @retval
-+ -1 ERROR, message not sent
-+*/
-+int set_var_user::light_check(THD *thd)
-+{
-+ /*
-+ Item_func_set_user_var can't substitute something else on its place =>
-+ 0 can be passed as last argument (reference on item)
-+ */
-+ return (user_var_item->fix_fields(thd, (Item**) 0));
-+}
-+
-+
-+int set_var_user::update(THD *thd)
-+{
-+ if (user_var_item->update())
-+ {
-+ /* Give an error if it's not given already */
-+ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY), MYF(0));
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+
-+/*****************************************************************************
-+ Functions to handle SET PASSWORD
-+*****************************************************************************/
-+
-+int set_var_password::check(THD *thd)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (!user->host.str)
-+ {
-+ DBUG_ASSERT(thd->security_ctx->priv_host);
-+ if (*thd->security_ctx->priv_host != 0)
-+ {
-+ user->host.str= (char *) thd->security_ctx->priv_host;
-+ user->host.length= strlen(thd->security_ctx->priv_host);
-+ }
-+ else
-+ {
-+ user->host.str= (char *)"%";
-+ user->host.length= 1;
-+ }
-+ }
-+ if (!user->user.str)
-+ {
-+ DBUG_ASSERT(thd->security_ctx->priv_user);
-+ user->user.str= (char *) thd->security_ctx->priv_user;
-+ user->user.length= strlen(thd->security_ctx->priv_user);
-+ }
-+ /* Returns 1 as the function sends error to client */
-+ return check_change_password(thd, user->host.str, user->user.str,
-+ password, strlen(password)) ? 1 : 0;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+int set_var_password::update(THD *thd)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ /* Returns 1 as the function sends error to client */
-+ return change_password(thd, user->host.str, user->user.str, password) ?
-+ 1 : 0;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+/****************************************************************************
-+ Functions to handle table_type
-+****************************************************************************/
-+
-+/* Based upon sys_var::check_enum() */
-+
-+bool sys_var_thd_storage_engine::check(THD *thd, set_var *var)
-+{
-+ char buff[STRING_BUFFER_USUAL_SIZE];
-+ const char *value;
-+ String str(buff, sizeof(buff), &my_charset_latin1), *res;
-+
-+ var->save_result.plugin= NULL;
-+ if (var->value->result_type() == STRING_RESULT)
-+ {
-+ LEX_STRING engine_name;
-+ handlerton *hton;
-+ if (!(res=var->value->val_str(&str)) ||
-+ !(engine_name.str= (char *)res->ptr()) ||
-+ !(engine_name.length= res->length()) ||
-+ !(var->save_result.plugin= ha_resolve_by_name(thd, &engine_name)) ||
-+ !(hton= plugin_data(var->save_result.plugin, handlerton *)) ||
-+ ha_checktype(thd, ha_legacy_type(hton), 1, 0) != hton)
-+ {
-+ value= res ? res->c_ptr() : "NULL";
-+ goto err;
-+ }
-+ return 0;
-+ }
-+ value= "unknown";
-+
-+err:
-+ my_error(ER_UNKNOWN_STORAGE_ENGINE, MYF(0), value);
-+ return 1;
-+}
-+
-+
-+uchar *sys_var_thd_storage_engine::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ uchar* result;
-+ handlerton *hton;
-+ LEX_STRING *engine_name;
-+ plugin_ref plugin= thd->variables.*offset;
-+ if (type == OPT_GLOBAL)
-+ plugin= my_plugin_lock(thd, &(global_system_variables.*offset));
-+ hton= plugin_data(plugin, handlerton*);
-+ engine_name= &hton2plugin[hton->slot]->name;
-+ result= (uchar *) thd->strmake(engine_name->str, engine_name->length);
-+ if (type == OPT_GLOBAL)
-+ plugin_unlock(thd, plugin);
-+ return result;
-+}
-+
-+
-+void sys_var_thd_storage_engine::set_default(THD *thd, enum_var_type type)
-+{
-+ plugin_ref old_value, new_value, *value;
-+ if (type == OPT_GLOBAL)
-+ {
-+ value= &(global_system_variables.*offset);
-+ new_value= ha_lock_engine(NULL, myisam_hton);
-+ }
-+ else
-+ {
-+ value= &(thd->variables.*offset);
-+ new_value= my_plugin_lock(NULL, &(global_system_variables.*offset));
-+ }
-+ DBUG_ASSERT(new_value);
-+ old_value= *value;
-+ *value= new_value;
-+ plugin_unlock(NULL, old_value);
-+}
-+
-+
-+bool sys_var_thd_storage_engine::update(THD *thd, set_var *var)
-+{
-+ plugin_ref *value= &(global_system_variables.*offset), old_value;
-+ if (var->type != OPT_GLOBAL)
-+ value= &(thd->variables.*offset);
-+ old_value= *value;
-+ if (old_value != var->save_result.plugin)
-+ {
-+ *value= my_plugin_lock(NULL, &var->save_result.plugin);
-+ plugin_unlock(NULL, old_value);
-+ }
-+ return 0;
-+}
-+
-+void sys_var_thd_table_type::warn_deprecated(THD *thd)
-+{
-+ WARN_DEPRECATED(thd, "6.0", "@@table_type", "'@@storage_engine'");
-+}
-+
-+void sys_var_thd_table_type::set_default(THD *thd, enum_var_type type)
-+{
-+ warn_deprecated(thd);
-+ sys_var_thd_storage_engine::set_default(thd, type);
-+}
-+
-+bool sys_var_thd_table_type::update(THD *thd, set_var *var)
-+{
-+ warn_deprecated(thd);
-+ return sys_var_thd_storage_engine::update(thd, var);
-+}
-+
-+
-+/****************************************************************************
-+ Functions to handle sql_mode
-+****************************************************************************/
-+
-+/**
-+ Make string representation of mode.
-+
-+ @param[in] thd thread handler
-+ @param[in] val sql_mode value
-+ @param[out] len pointer on length of string
-+
-+ @return
-+ pointer to string with sql_mode representation
-+*/
-+
-+bool
-+sys_var_thd_sql_mode::
-+symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-+{
-+ char buff[STRING_BUFFER_USUAL_SIZE*8];
-+ String tmp(buff, sizeof(buff), &my_charset_latin1);
-+
-+ tmp.length(0);
-+
-+ for (uint i= 0; val; val>>= 1, i++)
-+ {
-+ if (val & 1)
-+ {
-+ tmp.append(sql_mode_typelib.type_names[i],
-+ sql_mode_typelib.type_lengths[i]);
-+ tmp.append(',');
-+ }
-+ }
-+
-+ if (tmp.length())
-+ tmp.length(tmp.length() - 1); /* trim the trailing comma */
-+
-+ rep->str= thd->strmake(tmp.ptr(), tmp.length());
-+
-+ rep->length= rep->str ? tmp.length() : 0;
-+
-+ return rep->length != tmp.length();
-+}
-+
-+
-+uchar *sys_var_thd_sql_mode::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ LEX_STRING sql_mode;
-+ ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+ thd->variables.*offset);
-+ (void) symbolic_mode_representation(thd, val, &sql_mode);
-+ return (uchar *) sql_mode.str;
-+}
-+
-+
-+void sys_var_thd_sql_mode::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= 0;
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+
-+void fix_sql_mode_var(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.sql_mode=
-+ fix_sql_mode(global_system_variables.sql_mode);
-+ else
-+ {
-+ thd->variables.sql_mode= fix_sql_mode(thd->variables.sql_mode);
-+ /*
-+ Update thd->server_status
-+ */
-+ if (thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES)
-+ thd->server_status|= SERVER_STATUS_NO_BACKSLASH_ESCAPES;
-+ else
-+ thd->server_status&= ~SERVER_STATUS_NO_BACKSLASH_ESCAPES;
-+ }
-+}
-+
-+/** Map database specific bits to function bits. */
-+
-+ulong fix_sql_mode(ulong sql_mode)
-+{
-+ /*
-+ Note that we dont set
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS
-+ to allow one to get full use of MySQL in this mode.
-+ */
-+
-+ if (sql_mode & MODE_ANSI)
-+ {
-+ sql_mode|= (MODE_REAL_AS_FLOAT | MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE);
-+ /*
-+ MODE_ONLY_FULL_GROUP_BY removed from ANSI mode because it is currently
-+ overly restrictive (see BUG#8510).
-+ */
-+ }
-+ if (sql_mode & MODE_ORACLE)
-+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE |
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
-+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
-+ if (sql_mode & MODE_MSSQL)
-+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE |
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
-+ MODE_NO_FIELD_OPTIONS);
-+ if (sql_mode & MODE_POSTGRESQL)
-+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE |
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
-+ MODE_NO_FIELD_OPTIONS);
-+ if (sql_mode & MODE_DB2)
-+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE |
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
-+ MODE_NO_FIELD_OPTIONS);
-+ if (sql_mode & MODE_MAXDB)
-+ sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES |
-+ MODE_IGNORE_SPACE |
-+ MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS |
-+ MODE_NO_FIELD_OPTIONS | MODE_NO_AUTO_CREATE_USER);
-+ if (sql_mode & MODE_MYSQL40)
-+ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
-+ if (sql_mode & MODE_MYSQL323)
-+ sql_mode|= MODE_HIGH_NOT_PRECEDENCE;
-+ if (sql_mode & MODE_TRADITIONAL)
-+ sql_mode|= (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES |
-+ MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE |
-+ MODE_ERROR_FOR_DIVISION_BY_ZERO | MODE_NO_AUTO_CREATE_USER);
-+ return sql_mode;
-+}
-+
-+
-+bool
-+sys_var_thd_optimizer_switch::
-+symbolic_mode_representation(THD *thd, ulonglong val, LEX_STRING *rep)
-+{
-+ char buff[STRING_BUFFER_USUAL_SIZE*8];
-+ String tmp(buff, sizeof(buff), &my_charset_latin1);
-+ int i;
-+ ulonglong bit;
-+ tmp.length(0);
-+
-+ for (i= 0, bit=1; bit != OPTIMIZER_SWITCH_LAST; i++, bit= bit << 1)
-+ {
-+ tmp.append(optimizer_switch_typelib.type_names[i],
-+ optimizer_switch_typelib.type_lengths[i]);
-+ tmp.append('=');
-+ tmp.append((val & bit)? "on":"off");
-+ tmp.append(',');
-+ }
-+
-+ if (tmp.length())
-+ tmp.length(tmp.length() - 1); /* trim the trailing comma */
-+
-+ rep->str= thd->strmake(tmp.ptr(), tmp.length());
-+
-+ rep->length= rep->str ? tmp.length() : 0;
-+
-+ return rep->length != tmp.length();
-+}
-+
-+
-+uchar *sys_var_thd_optimizer_switch::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ LEX_STRING opts;
-+ ulonglong val= ((type == OPT_GLOBAL) ? global_system_variables.*offset :
-+ thd->variables.*offset);
-+ (void) symbolic_mode_representation(thd, val, &opts);
-+ return (uchar *) opts.str;
-+}
-+
-+
-+/*
-+ Check (and actually parse) string representation of @@optimizer_switch.
-+*/
-+
-+bool sys_var_thd_optimizer_switch::check(THD *thd, set_var *var)
-+{
-+ bool not_used;
-+ char buff[STRING_BUFFER_USUAL_SIZE], *error= 0;
-+ uint error_len= 0;
-+ String str(buff, sizeof(buff), system_charset_info), *res;
-+
-+ if (!(res= var->value->val_str(&str)))
-+ {
-+ strmov(buff, "NULL");
-+ goto err;
-+ }
-+
-+ if (res->length() == 0)
-+ {
-+ buff[0]= 0;
-+ goto err;
-+ }
-+
-+ var->save_result.ulong_value=
-+ (ulong)find_set_from_flags(&optimizer_switch_typelib,
-+ optimizer_switch_typelib.count,
-+ thd->variables.optimizer_switch,
-+ global_system_variables.optimizer_switch,
-+ res->c_ptr_safe(), res->length(), NULL,
-+ &error, &error_len, ¬_used);
-+ if (error_len)
-+ {
-+ strmake(buff, error, min(sizeof(buff) - 1, error_len));
-+ goto err;
-+ }
-+ return FALSE;
-+err:
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), name, buff);
-+ return TRUE;
-+}
-+
-+
-+void sys_var_thd_optimizer_switch::set_default(THD *thd, enum_var_type type)
-+{
-+ if (type == OPT_GLOBAL)
-+ global_system_variables.*offset= OPTIMIZER_SWITCH_DEFAULT;
-+ else
-+ thd->variables.*offset= global_system_variables.*offset;
-+}
-+
-+/****************************************************************************
-+ Named list handling
-+****************************************************************************/
-+
-+uchar* find_named(I_List<NAMED_LIST> *list, const char *name, uint length,
-+ NAMED_LIST **found)
-+{
-+ I_List_iterator<NAMED_LIST> it(*list);
-+ NAMED_LIST *element;
-+ while ((element= it++))
-+ {
-+ if (element->cmp(name, length))
-+ {
-+ if (found)
-+ *found= element;
-+ return element->data;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+void delete_elements(I_List<NAMED_LIST> *list,
-+ void (*free_element)(const char *name, uchar*))
-+{
-+ NAMED_LIST *element;
-+ DBUG_ENTER("delete_elements");
-+ while ((element= list->get()))
-+ {
-+ (*free_element)(element->name, element->data);
-+ delete element;
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/* Key cache functions */
-+
-+static KEY_CACHE *create_key_cache(const char *name, uint length)
-+{
-+ KEY_CACHE *key_cache;
-+ DBUG_ENTER("create_key_cache");
-+ DBUG_PRINT("enter",("name: %.*s", length, name));
-+
-+ if ((key_cache= (KEY_CACHE*) my_malloc(sizeof(KEY_CACHE),
-+ MYF(MY_ZEROFILL | MY_WME))))
-+ {
-+ if (!new NAMED_LIST(&key_caches, name, length, (uchar*) key_cache))
-+ {
-+ my_free((char*) key_cache, MYF(0));
-+ key_cache= 0;
-+ }
-+ else
-+ {
-+ /*
-+ Set default values for a key cache
-+ The values in dflt_key_cache_var is set by my_getopt() at startup
-+
-+ We don't set 'buff_size' as this is used to enable the key cache
-+ */
-+ key_cache->param_block_size= dflt_key_cache_var.param_block_size;
-+ key_cache->param_division_limit= dflt_key_cache_var.param_division_limit;
-+ key_cache->param_age_threshold= dflt_key_cache_var.param_age_threshold;
-+ }
-+ }
-+ DBUG_RETURN(key_cache);
-+}
-+
-+
-+KEY_CACHE *get_or_create_key_cache(const char *name, uint length)
-+{
-+ LEX_STRING key_cache_name;
-+ KEY_CACHE *key_cache;
-+
-+ key_cache_name.str= (char *) name;
-+ key_cache_name.length= length;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ if (!(key_cache= get_key_cache(&key_cache_name)))
-+ key_cache= create_key_cache(name, length);
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ return key_cache;
-+}
-+
-+
-+void free_key_cache(const char *name, KEY_CACHE *key_cache)
-+{
-+ ha_end_key_cache(key_cache);
-+ my_free((char*) key_cache, MYF(0));
-+}
-+
-+
-+bool process_key_caches(process_key_cache_t func)
-+{
-+ I_List_iterator<NAMED_LIST> it(key_caches);
-+ NAMED_LIST *element;
-+
-+ while ((element= it++))
-+ {
-+ KEY_CACHE *key_cache= (KEY_CACHE *) element->data;
-+ func(element->name, key_cache);
-+ }
-+ return 0;
-+}
-+
-+
-+void sys_var_trust_routine_creators::warn_deprecated(THD *thd)
-+{
-+ WARN_DEPRECATED(thd, VER_CELOSIA, "@@log_bin_trust_routine_creators",
-+ "'@@log_bin_trust_function_creators'");
-+}
-+
-+void sys_var_trust_routine_creators::set_default(THD *thd, enum_var_type type)
-+{
-+ warn_deprecated(thd);
-+ sys_var_bool_ptr::set_default(thd, type);
-+}
-+
-+bool sys_var_trust_routine_creators::update(THD *thd, set_var *var)
-+{
-+ warn_deprecated(thd);
-+ return sys_var_bool_ptr::update(thd, var);
-+}
-+
-+bool sys_var_opt_readonly::update(THD *thd, set_var *var)
-+{
-+ bool result;
-+
-+ DBUG_ENTER("sys_var_opt_readonly::update");
-+
-+ /* Prevent self dead-lock */
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
-+ DBUG_RETURN(true);
-+ }
-+
-+ if (thd->global_read_lock)
-+ {
-+ /*
-+ This connection already holds the global read lock.
-+ This can be the case with:
-+ - FLUSH TABLES WITH READ LOCK
-+ - SET GLOBAL READ_ONLY = 1
-+ */
-+ result= sys_var_bool_ptr::update(thd, var);
-+ DBUG_RETURN(result);
-+ }
-+
-+ /*
-+ Perform a 'FLUSH TABLES WITH READ LOCK'.
-+ This is a 3 step process:
-+ - [1] lock_global_read_lock()
-+ - [2] close_cached_tables()
-+ - [3] make_global_read_lock_block_commit()
-+ [1] prevents new connections from obtaining tables locked for write.
-+ [2] waits until all existing connections close their tables.
-+ [3] prevents transactions from being committed.
-+ */
-+
-+ if (lock_global_read_lock(thd))
-+ DBUG_RETURN(true);
-+
-+ /*
-+ This call will be blocked by any connection holding a READ or WRITE lock.
-+ Ideally, we want to wait only for pending WRITE locks, but since:
-+ con 1> LOCK TABLE T FOR READ;
-+ con 2> LOCK TABLE T FOR WRITE; (blocked by con 1)
-+ con 3> SET GLOBAL READ ONLY=1; (blocked by con 2)
-+ can cause to wait on a read lock, it's required for the client application
-+ to unlock everything, and acceptable for the server to wait on all locks.
-+ */
-+ if ((result= close_cached_tables(thd, NULL, FALSE, TRUE, TRUE)))
-+ goto end_with_read_lock;
-+
-+ if ((result= make_global_read_lock_block_commit(thd)))
-+ goto end_with_read_lock;
-+
-+ /* Change the opt_readonly system variable, safe because the lock is held */
-+ result= sys_var_bool_ptr::update(thd, var);
-+
-+end_with_read_lock:
-+ /* Release the lock */
-+ unlock_global_read_lock(thd);
-+ DBUG_RETURN(result);
-+}
-+
-+
-+#ifndef DBUG_OFF
-+/* even session variable here requires SUPER, because of -#o,file */
-+bool sys_var_thd_dbug::check(THD *thd, set_var *var)
-+{
-+ return check_global_access(thd, SUPER_ACL);
-+}
-+
-+bool sys_var_thd_dbug::update(THD *thd, set_var *var)
-+{
-+ char buf[256];
-+ String str(buf, sizeof(buf), system_charset_info), *res;
-+
-+ res= var->value->val_str(&str);
-+
-+ if (var->type == OPT_GLOBAL)
-+ DBUG_SET_INITIAL(res ? res->c_ptr() : "");
-+ else
-+ DBUG_SET(res ? res->c_ptr() : "");
-+
-+ return 0;
-+}
-+
-+
-+uchar *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b)
-+{
-+ char buf[256];
-+ if (type == OPT_GLOBAL)
-+ DBUG_EXPLAIN_INITIAL(buf, sizeof(buf));
-+ else
-+ DBUG_EXPLAIN(buf, sizeof(buf));
-+ return (uchar*) thd->strdup(buf);
-+}
-+#endif /* DBUG_OFF */
-+
-+
-+#ifdef HAVE_EVENT_SCHEDULER
-+bool sys_var_event_scheduler::check(THD *thd, set_var *var)
-+{
-+ return check_enum(thd, var, &Events::var_typelib);
-+}
-+
-+/*
-+ The update method of the global variable event_scheduler.
-+ If event_scheduler is switched from 0 to 1 then the scheduler main
-+ thread is resumed and if from 1 to 0 the scheduler thread is suspended
-+
-+ SYNOPSIS
-+ sys_var_event_scheduler::update()
-+ thd Thread context (unused)
-+ var The new value
-+
-+ Returns
-+ FALSE OK
-+ TRUE Error
-+*/
-+
-+bool
-+sys_var_event_scheduler::update(THD *thd, set_var *var)
-+{
-+ int res;
-+ /* here start the thread if not running. */
-+ DBUG_ENTER("sys_var_event_scheduler::update");
-+ DBUG_PRINT("info", ("new_value: %d", (int) var->save_result.ulong_value));
-+
-+ enum Events::enum_opt_event_scheduler
-+ new_state=
-+ (enum Events::enum_opt_event_scheduler) var->save_result.ulong_value;
-+
-+ res= Events::switch_event_scheduler_state(new_state);
-+
-+ DBUG_RETURN((bool) res);
-+}
-+
-+
-+uchar *sys_var_event_scheduler::value_ptr(THD *thd, enum_var_type type,
-+ LEX_STRING *base)
-+{
-+ return (uchar *) Events::get_opt_event_scheduler_str();
-+}
-+#endif
-+
-+
-+int
-+check_max_allowed_packet(THD *thd, set_var *var)
-+{
-+ longlong val= var->value->val_int();
-+ if (val < (longlong) global_system_variables.net_buffer_length)
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_UNKNOWN_ERROR,
-+ "The value of 'max_allowed_packet' should be no less than "
-+ "the value of 'net_buffer_length'");
-+ }
-+ return 0;
-+}
-+
-+
-+int
-+check_net_buffer_length(THD *thd, set_var *var)
-+{
-+ longlong val= var->value->val_int();
-+ if (val > (longlong) global_system_variables.max_allowed_packet)
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_UNKNOWN_ERROR,
-+ "The value of 'max_allowed_packet' should be no less than "
-+ "the value of 'net_buffer_length'");
-+ }
-+ return 0;
-+}
-+
-+/****************************************************************************
-+ Used templates
-+****************************************************************************/
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class List<set_var_base>;
-+template class List_iterator_fast<set_var_base>;
-+template class I_List_iterator<NAMED_LIST>;
-+#endif
diff -urN mysql-old/sql/slave.cc mysql/sql/slave.cc
--- mysql-old/sql/slave.cc 2011-05-10 17:45:45.626682377 +0000
+++ mysql/sql/slave.cc 2011-05-10 17:56:01.483349044 +0000
@@ -26529,1325 +2180,6 @@ diff -urN mysql-old/sql/sql_connect.cc mysql/sql/sql_connect.cc
HOSTNAME_LENGTH)]= 0;
thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
}
-diff -urN mysql-old/sql/sql_connect.cc.orig mysql/sql/sql_connect.cc.orig
---- mysql-old/sql/sql_connect.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/sql_connect.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,1315 @@
-+/* Copyright (C) 2007 MySQL AB
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+
-+/*
-+ Functions to autenticate and handle reqests for a connection
-+*/
-+
-+#include "mysql_priv.h"
-+
-+#ifdef HAVE_OPENSSL
-+/*
-+ Without SSL the handshake consists of one packet. This packet
-+ has both client capabilites and scrambled password.
-+ With SSL the handshake might consist of two packets. If the first
-+ packet (client capabilities) has CLIENT_SSL flag set, we have to
-+ switch to SSL and read the second packet. The scrambled password
-+ is in the second packet and client_capabilites field will be ignored.
-+ Maybe it is better to accept flags other than CLIENT_SSL from the
-+ second packet?
-+*/
-+#define SSL_HANDSHAKE_SIZE 2
-+#define NORMAL_HANDSHAKE_SIZE 6
-+#define MIN_HANDSHAKE_SIZE 2
-+#else
-+#define MIN_HANDSHAKE_SIZE 6
-+#endif /* HAVE_OPENSSL */
-+
-+#ifdef __WIN__
-+extern void win_install_sigabrt_handler();
-+#endif
-+
-+/*
-+ Get structure for logging connection data for the current user
-+*/
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static HASH hash_user_connections;
-+
-+static int get_or_create_user_conn(THD *thd, const char *user,
-+ const char *host,
-+ USER_RESOURCES *mqh)
-+{
-+ int return_val= 0;
-+ size_t temp_len, user_len;
-+ char temp_user[USER_HOST_BUFF_SIZE];
-+ struct user_conn *uc;
-+
-+ DBUG_ASSERT(user != 0);
-+ DBUG_ASSERT(host != 0);
-+
-+ user_len= strlen(user);
-+ temp_len= (strmov(strmov(temp_user, user)+1, host) - temp_user)+1;
-+ (void) pthread_mutex_lock(&LOCK_user_conn);
-+ if (!(uc = (struct user_conn *) hash_search(&hash_user_connections,
-+ (uchar*) temp_user, temp_len)))
-+ {
-+ /* First connection for user; Create a user connection object */
-+ if (!(uc= ((struct user_conn*)
-+ my_malloc(sizeof(struct user_conn) + temp_len+1,
-+ MYF(MY_WME)))))
-+ {
-+ /* MY_WME ensures an error is set in THD. */
-+ return_val= 1;
-+ goto end;
-+ }
-+ uc->user=(char*) (uc+1);
-+ memcpy(uc->user,temp_user,temp_len+1);
-+ uc->host= uc->user + user_len + 1;
-+ uc->len= temp_len;
-+ uc->connections= uc->questions= uc->updates= uc->conn_per_hour= 0;
-+ uc->user_resources= *mqh;
-+ uc->reset_utime= thd->thr_create_utime;
-+ if (my_hash_insert(&hash_user_connections, (uchar*) uc))
-+ {
-+ /* The only possible error is out of memory, MY_WME sets an error. */
-+ my_free((char*) uc,0);
-+ return_val= 1;
-+ goto end;
-+ }
-+ }
-+ thd->user_connect=uc;
-+ uc->connections++;
-+end:
-+ (void) pthread_mutex_unlock(&LOCK_user_conn);
-+ return return_val;
-+
-+}
-+
-+
-+/*
-+ check if user has already too many connections
-+
-+ SYNOPSIS
-+ check_for_max_user_connections()
-+ thd Thread handle
-+ uc User connect object
-+
-+ NOTES
-+ If check fails, we decrease user connection count, which means one
-+ shouldn't call decrease_user_connections() after this function.
-+
-+ RETURN
-+ 0 ok
-+ 1 error
-+*/
-+
-+static
-+int check_for_max_user_connections(THD *thd, USER_CONN *uc)
-+{
-+ int error=0;
-+ DBUG_ENTER("check_for_max_user_connections");
-+
-+ (void) pthread_mutex_lock(&LOCK_user_conn);
-+ if (max_user_connections && !uc->user_resources.user_conn &&
-+ max_user_connections < (uint) uc->connections)
-+ {
-+ my_error(ER_TOO_MANY_USER_CONNECTIONS, MYF(0), uc->user);
-+ error=1;
-+ goto end;
-+ }
-+ time_out_user_resource_limits(thd, uc);
-+ if (uc->user_resources.user_conn &&
-+ uc->user_resources.user_conn < uc->connections)
-+ {
-+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
-+ "max_user_connections",
-+ (long) uc->user_resources.user_conn);
-+ error= 1;
-+ goto end;
-+ }
-+ if (uc->user_resources.conn_per_hour &&
-+ uc->user_resources.conn_per_hour <= uc->conn_per_hour)
-+ {
-+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user,
-+ "max_connections_per_hour",
-+ (long) uc->user_resources.conn_per_hour);
-+ error=1;
-+ goto end;
-+ }
-+ uc->conn_per_hour++;
-+
-+end:
-+ if (error)
-+ uc->connections--; // no need for decrease_user_connections() here
-+ (void) pthread_mutex_unlock(&LOCK_user_conn);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Decrease user connection count
-+
-+ SYNOPSIS
-+ decrease_user_connections()
-+ uc User connection object
-+
-+ NOTES
-+ If there is a n user connection object for a connection
-+ (which only happens if 'max_user_connections' is defined or
-+ if someone has created a resource grant for a user), then
-+ the connection count is always incremented on connect.
-+
-+ The user connect object is not freed if some users has
-+ 'max connections per hour' defined as we need to be able to hold
-+ count over the lifetime of the connection.
-+*/
-+
-+void decrease_user_connections(USER_CONN *uc)
-+{
-+ DBUG_ENTER("decrease_user_connections");
-+ (void) pthread_mutex_lock(&LOCK_user_conn);
-+ DBUG_ASSERT(uc->connections);
-+ if (!--uc->connections && !mqh_used)
-+ {
-+ /* Last connection for user; Delete it */
-+ (void) hash_delete(&hash_user_connections,(uchar*) uc);
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_user_conn);
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Reset per-hour user resource limits when it has been more than
-+ an hour since they were last checked
-+
-+ SYNOPSIS:
-+ time_out_user_resource_limits()
-+ thd Thread handler
-+ uc User connection details
-+
-+ NOTE:
-+ This assumes that the LOCK_user_conn mutex has been acquired, so it is
-+ safe to test and modify members of the USER_CONN structure.
-+*/
-+
-+void time_out_user_resource_limits(THD *thd, USER_CONN *uc)
-+{
-+ ulonglong check_time= thd->start_utime;
-+ DBUG_ENTER("time_out_user_resource_limits");
-+
-+ /* If more than a hour since last check, reset resource checking */
-+ if (check_time - uc->reset_utime >= LL(3600000000))
-+ {
-+ uc->questions=1;
-+ uc->updates=0;
-+ uc->conn_per_hour=0;
-+ uc->reset_utime= check_time;
-+ }
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+/*
-+ Check if maximum queries per hour limit has been reached
-+ returns 0 if OK.
-+*/
-+
-+bool check_mqh(THD *thd, uint check_command)
-+{
-+ bool error= 0;
-+ USER_CONN *uc=thd->user_connect;
-+ DBUG_ENTER("check_mqh");
-+ DBUG_ASSERT(uc != 0);
-+
-+ (void) pthread_mutex_lock(&LOCK_user_conn);
-+
-+ time_out_user_resource_limits(thd, uc);
-+
-+ /* Check that we have not done too many questions / hour */
-+ if (uc->user_resources.questions &&
-+ uc->questions++ >= uc->user_resources.questions)
-+ {
-+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_questions",
-+ (long) uc->user_resources.questions);
-+ error=1;
-+ goto end;
-+ }
-+ if (check_command < (uint) SQLCOM_END)
-+ {
-+ /* Check that we have not done too many updates / hour */
-+ if (uc->user_resources.updates &&
-+ (sql_command_flags[check_command] & CF_CHANGES_DATA) &&
-+ uc->updates++ >= uc->user_resources.updates)
-+ {
-+ my_error(ER_USER_LIMIT_REACHED, MYF(0), uc->user, "max_updates",
-+ (long) uc->user_resources.updates);
-+ error=1;
-+ goto end;
-+ }
-+ }
-+end:
-+ (void) pthread_mutex_unlock(&LOCK_user_conn);
-+ DBUG_RETURN(error);
-+}
-+
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+
-+
-+/**
-+ Check if user exist and password supplied is correct.
-+
-+ @param thd thread handle, thd->security_ctx->{host,user,ip} are used
-+ @param command originator of the check: now check_user is called
-+ during connect and change user procedures; used for
-+ logging.
-+ @param passwd scrambled password received from client
-+ @param passwd_len length of scrambled password
-+ @param db database name to connect to, may be NULL
-+ @param check_count TRUE if establishing a new connection. In this case
-+ check that we have not exceeded the global
-+ max_connections limist
-+
-+ @note Host, user and passwd may point to communication buffer.
-+ Current implementation does not depend on that, but future changes
-+ should be done with this in mind; 'thd' is INOUT, all other params
-+ are 'IN'.
-+
-+ @retval 0 OK; thd->security_ctx->user/master_access/priv_user/db_access and
-+ thd->db are updated; OK is sent to the client.
-+ @retval 1 error, e.g. access denied or handshake error, not sent to
-+ the client. A message is pushed into the error stack.
-+*/
-+
-+int
-+check_user(THD *thd, enum enum_server_command command,
-+ const char *passwd, uint passwd_len, const char *db,
-+ bool check_count)
-+{
-+ DBUG_ENTER("check_user");
-+ LEX_STRING db_str= { (char *) db, db ? strlen(db) : 0 };
-+
-+ /*
-+ Clear thd->db as it points to something, that will be freed when
-+ connection is closed. We don't want to accidentally free a wrong
-+ pointer if connect failed. Also in case of 'CHANGE USER' failure,
-+ current database will be switched to 'no database selected'.
-+ */
-+ thd->reset_db(NULL, 0);
-+
-+#ifdef NO_EMBEDDED_ACCESS_CHECKS
-+ thd->main_security_ctx.master_access= GLOBAL_ACLS; // Full rights
-+ /* Change database if necessary */
-+ if (db && db[0])
-+ {
-+ if (mysql_change_db(thd, &db_str, FALSE))
-+ DBUG_RETURN(1);
-+ }
-+ my_ok(thd);
-+ DBUG_RETURN(0);
-+#else
-+
-+ my_bool opt_secure_auth_local;
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ opt_secure_auth_local= opt_secure_auth;
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+ /*
-+ If the server is running in secure auth mode, short scrambles are
-+ forbidden.
-+ */
-+ if (opt_secure_auth_local && passwd_len == SCRAMBLE_LENGTH_323)
-+ {
-+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
-+ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-+ DBUG_RETURN(1);
-+ }
-+ if (passwd_len != 0 &&
-+ passwd_len != SCRAMBLE_LENGTH &&
-+ passwd_len != SCRAMBLE_LENGTH_323)
-+ {
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ DBUG_RETURN(1);
-+ }
-+
-+ USER_RESOURCES ur;
-+ int res= acl_getroot(thd, &ur, passwd, passwd_len);
-+#ifndef EMBEDDED_LIBRARY
-+ if (res == -1)
-+ {
-+ /*
-+ This happens when client (new) sends password scrambled with
-+ scramble(), but database holds old value (scrambled with
-+ scramble_323()). Here we please client to send scrambled_password
-+ in old format.
-+ */
-+ NET *net= &thd->net;
-+ if (opt_secure_auth_local)
-+ {
-+ my_error(ER_SERVER_IS_IN_SECURE_AUTH_MODE, MYF(0),
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip);
-+ general_log_print(thd, COM_CONNECT, ER(ER_SERVER_IS_IN_SECURE_AUTH_MODE),
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip);
-+ DBUG_RETURN(1);
-+ }
-+ /* We have to read very specific packet size */
-+ if (send_old_password_request(thd) ||
-+ my_net_read(net) != SCRAMBLE_LENGTH_323 + 1)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ DBUG_RETURN(1);
-+ }
-+ /* Final attempt to check the user based on reply */
-+ /* So as passwd is short, errcode is always >= 0 */
-+ res= acl_getroot(thd, &ur, (char *) net->read_pos, SCRAMBLE_LENGTH_323);
-+ }
-+#endif /*EMBEDDED_LIBRARY*/
-+ /* here res is always >= 0 */
-+ if (res == 0)
-+ {
-+ if (!(thd->main_security_ctx.master_access &
-+ NO_ACCESS)) // authentication is OK
-+ {
-+ DBUG_PRINT("info",
-+ ("Capabilities: %lu packet_length: %ld Host: '%s' "
-+ "Login user: '%s' Priv_user: '%s' Using password: %s "
-+ "Access: %lu db: '%s'",
-+ thd->client_capabilities,
-+ thd->max_client_packet_length,
-+ thd->main_security_ctx.host_or_ip,
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.priv_user,
-+ passwd_len ? "yes": "no",
-+ thd->main_security_ctx.master_access,
-+ (thd->db ? thd->db : "*none*")));
-+
-+ if (check_count)
-+ {
-+ pthread_mutex_lock(&LOCK_connection_count);
-+ bool count_ok= connection_count <= max_connections ||
-+ (thd->main_security_ctx.master_access & SUPER_ACL);
-+ VOID(pthread_mutex_unlock(&LOCK_connection_count));
-+
-+ if (!count_ok)
-+ { // too many connections
-+ my_error(ER_CON_COUNT_ERROR, MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+ }
-+
-+ /*
-+ Log the command before authentication checks, so that the user can
-+ check the log for the tried login tried and also to detect
-+ break-in attempts.
-+ */
-+ general_log_print(thd, command,
-+ (thd->main_security_ctx.priv_user ==
-+ thd->main_security_ctx.user ?
-+ (char*) "%s@%s on %s" :
-+ (char*) "%s@%s as anonymous on %s"),
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip,
-+ db ? db : (char*) "");
-+
-+ /*
-+ This is the default access rights for the current database. It's
-+ set to 0 here because we don't have an active database yet (and we
-+ may not have an active database to set.
-+ */
-+ thd->main_security_ctx.db_access=0;
-+
-+ /* Don't allow user to connect if he has done too many queries */
-+ if ((ur.questions || ur.updates || ur.conn_per_hour || ur.user_conn ||
-+ max_user_connections) &&
-+ get_or_create_user_conn(thd,
-+ (opt_old_style_user_limits ? thd->main_security_ctx.user :
-+ thd->main_security_ctx.priv_user),
-+ (opt_old_style_user_limits ? thd->main_security_ctx.host_or_ip :
-+ thd->main_security_ctx.priv_host),
-+ &ur))
-+ {
-+ /* The error is set by get_or_create_user_conn(). */
-+ DBUG_RETURN(1);
-+ }
-+ if (thd->user_connect &&
-+ (thd->user_connect->user_resources.conn_per_hour ||
-+ thd->user_connect->user_resources.user_conn ||
-+ max_user_connections) &&
-+ check_for_max_user_connections(thd, thd->user_connect))
-+ {
-+ /* The error is set in check_for_max_user_connections(). */
-+ DBUG_RETURN(1);
-+ }
-+
-+ /* Change database if necessary */
-+ if (db && db[0])
-+ {
-+ if (mysql_change_db(thd, &db_str, FALSE))
-+ {
-+ /* mysql_change_db() has pushed the error message. */
-+ if (thd->user_connect)
-+ decrease_user_connections(thd->user_connect);
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ my_ok(thd);
-+ thd->password= test(passwd_len); // remember for error messages
-+#ifndef EMBEDDED_LIBRARY
-+ /*
-+ Allow the network layer to skip big packets. Although a malicious
-+ authenticated session might use this to trick the server to read
-+ big packets indefinitely, this is a previously established behavior
-+ that needs to be preserved as to not break backwards compatibility.
-+ */
-+ thd->net.skip_big_packet= TRUE;
-+#endif
-+ /* Ready to handle queries */
-+ DBUG_RETURN(0);
-+ }
-+ }
-+ else if (res == 2) // client gave short hash, server has long hash
-+ {
-+ my_error(ER_NOT_SUPPORTED_AUTH_MODE, MYF(0));
-+ general_log_print(thd, COM_CONNECT, ER(ER_NOT_SUPPORTED_AUTH_MODE));
-+ DBUG_RETURN(1);
-+ }
-+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip,
-+ passwd_len ? ER(ER_YES) : ER(ER_NO));
-+ general_log_print(thd, COM_CONNECT, ER(ER_ACCESS_DENIED_ERROR),
-+ thd->main_security_ctx.user,
-+ thd->main_security_ctx.host_or_ip,
-+ passwd_len ? ER(ER_YES) : ER(ER_NO));
-+ DBUG_RETURN(1);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+/*
-+ Check for maximum allowable user connections, if the mysqld server is
-+ started with corresponding variable that is greater then 0.
-+*/
-+
-+extern "C" uchar *get_key_conn(user_conn *buff, size_t *length,
-+ my_bool not_used __attribute__((unused)))
-+{
-+ *length= buff->len;
-+ return (uchar*) buff->user;
-+}
-+
-+
-+extern "C" void free_user(struct user_conn *uc)
-+{
-+ my_free((char*) uc,MYF(0));
-+}
-+
-+
-+void init_max_user_conn(void)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ (void) hash_init(&hash_user_connections,system_charset_info,max_connections,
-+ 0,0,
-+ (hash_get_key) get_key_conn, (hash_free_key) free_user,
-+ 0);
-+#endif
-+}
-+
-+
-+void free_max_user_conn(void)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ hash_free(&hash_user_connections);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+void reset_mqh(LEX_USER *lu, bool get_them= 0)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ (void) pthread_mutex_lock(&LOCK_user_conn);
-+ if (lu) // for GRANT
-+ {
-+ USER_CONN *uc;
-+ uint temp_len=lu->user.length+lu->host.length+2;
-+ char temp_user[USER_HOST_BUFF_SIZE];
-+
-+ memcpy(temp_user,lu->user.str,lu->user.length);
-+ memcpy(temp_user+lu->user.length+1,lu->host.str,lu->host.length);
-+ temp_user[lu->user.length]='\0'; temp_user[temp_len-1]=0;
-+ if ((uc = (struct user_conn *) hash_search(&hash_user_connections,
-+ (uchar*) temp_user, temp_len)))
-+ {
-+ uc->questions=0;
-+ get_mqh(temp_user,&temp_user[lu->user.length+1],uc);
-+ uc->updates=0;
-+ uc->conn_per_hour=0;
-+ }
-+ }
-+ else
-+ {
-+ /* for FLUSH PRIVILEGES and FLUSH USER_RESOURCES */
-+ for (uint idx=0;idx < hash_user_connections.records; idx++)
-+ {
-+ USER_CONN *uc=(struct user_conn *) hash_element(&hash_user_connections,
-+ idx);
-+ if (get_them)
-+ get_mqh(uc->user,uc->host,uc);
-+ uc->questions=0;
-+ uc->updates=0;
-+ uc->conn_per_hour=0;
-+ }
-+ }
-+ (void) pthread_mutex_unlock(&LOCK_user_conn);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+}
-+
-+
-+/**
-+ Set thread character set variables from the given ID
-+
-+ @param thd thread handle
-+ @param cs_number character set and collation ID
-+
-+ @retval 0 OK; character_set_client, collation_connection and
-+ character_set_results are set to the new value,
-+ or to the default global values.
-+
-+ @retval 1 error, e.g. the given ID is not supported by parser.
-+ Corresponding SQL error is sent.
-+*/
-+
-+bool thd_init_client_charset(THD *thd, uint cs_number)
-+{
-+ CHARSET_INFO *cs;
-+ /*
-+ Use server character set and collation if
-+ - opt_character_set_client_handshake is not set
-+ - client has not specified a character set
-+ - client character set is the same as the servers
-+ - client character set doesn't exists in server
-+ */
-+ if (!opt_character_set_client_handshake ||
-+ !(cs= get_charset(cs_number, MYF(0))) ||
-+ !my_strcasecmp(&my_charset_latin1,
-+ global_system_variables.character_set_client->name,
-+ cs->name))
-+ {
-+ thd->variables.character_set_client=
-+ global_system_variables.character_set_client;
-+ thd->variables.collation_connection=
-+ global_system_variables.collation_connection;
-+ thd->variables.character_set_results=
-+ global_system_variables.character_set_results;
-+ }
-+ else
-+ {
-+ if (!is_supported_parser_charset(cs))
-+ {
-+ /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
-+ cs->csname);
-+ return true;
-+ }
-+ thd->variables.character_set_results=
-+ thd->variables.collation_connection=
-+ thd->variables.character_set_client= cs;
-+ }
-+ return false;
-+}
-+
-+
-+/*
-+ Initialize connection threads
-+*/
-+
-+bool init_new_connection_handler_thread()
-+{
-+ pthread_detach_this_thread();
-+#if defined(__WIN__)
-+ win_install_sigabrt_handler();
-+#else
-+ /* Win32 calls this in pthread_create */
-+ if (my_thread_init())
-+ return 1;
-+#endif /* __WIN__ */
-+ return 0;
-+}
-+
-+#ifndef EMBEDDED_LIBRARY
-+/**
-+ Get a null character terminated string from a user-supplied buffer.
-+
-+ @param buffer[in, out] Pointer to the buffer to be scanned.
-+ @param max_bytes_available[in, out] Limit the bytes to scan.
-+ @param string_length[out] The number of characters scanned not including
-+ the null character.
-+
-+ @remark The string_length does not include the terminating null character.
-+ However, after the call, the buffer is increased by string_length+1
-+ bytes, beyond the null character if there still available bytes to
-+ scan.
-+
-+ @return pointer to beginning of the string scanned.
-+ @retval NULL The buffer content is malformed
-+*/
-+
-+static
-+char *get_null_terminated_string(char **buffer,
-+ size_t *max_bytes_available,
-+ size_t *string_length)
-+{
-+ char *str= (char *)memchr(*buffer, '\0', *max_bytes_available);
-+
-+ if (str == NULL)
-+ return NULL;
-+
-+ *string_length= (size_t)(str - *buffer);
-+ *max_bytes_available-= *string_length + 1;
-+ str= *buffer;
-+ *buffer += *string_length + 1;
-+
-+ return str;
-+}
-+
-+
-+/**
-+ Get a length encoded string from a user-supplied buffer.
-+
-+ @param buffer[in, out] The buffer to scan; updates position after scan.
-+ @param max_bytes_available[in, out] Limit the number of bytes to scan
-+ @param string_length[out] Number of characters scanned
-+
-+ @remark In case the length is zero, then the total size of the string is
-+ considered to be 1 byte; the size byte.
-+
-+ @return pointer to first byte after the header in buffer.
-+ @retval NULL The buffer content is malformed
-+*/
-+
-+static
-+char *get_length_encoded_string(char **buffer,
-+ size_t *max_bytes_available,
-+ size_t *string_length)
-+{
-+ if (*max_bytes_available == 0)
-+ return NULL;
-+
-+ /* Do double cast to prevent overflow from signed / unsigned conversion */
-+ size_t str_len= (size_t)(unsigned char)**buffer;
-+
-+ /*
-+ If the length encoded string has the length 0
-+ the total size of the string is only one byte long (the size byte)
-+ */
-+ if (str_len == 0)
-+ {
-+ ++*buffer;
-+ *string_length= 0;
-+ /*
-+ Return a pointer to the 0 character so the return value will be
-+ an empty string.
-+ */
-+ return *buffer-1;
-+ }
-+
-+ if (str_len >= *max_bytes_available)
-+ return NULL;
-+
-+ char *str= *buffer+1;
-+ *string_length= str_len;
-+ *max_bytes_available-= *string_length + 1;
-+ *buffer+= *string_length + 1;
-+ return str;
-+}
-+
-+
-+/*
-+ Perform handshake, authorize client and update thd ACL variables.
-+
-+ SYNOPSIS
-+ check_connection()
-+ thd thread handle
-+
-+ RETURN
-+ 0 success, OK is sent to user, thd is updated.
-+ -1 error, which is sent to user
-+ > 0 error code (not sent to user)
-+*/
-+
-+static int check_connection(THD *thd)
-+{
-+ uint connect_errors= 0;
-+ NET *net= &thd->net;
-+ ulong pkt_len= 0;
-+ char *end;
-+
-+ DBUG_PRINT("info",
-+ ("New connection received on %s", vio_description(net->vio)));
-+#ifdef SIGNAL_WITH_VIO_CLOSE
-+ thd->set_active_vio(net->vio);
-+#endif
-+
-+ if (!thd->main_security_ctx.host) // If TCP/IP connection
-+ {
-+ char ip[30];
-+
-+ if (vio_peer_addr(net->vio, ip, &thd->peer_port))
-+ {
-+ my_error(ER_BAD_HOST_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ if (!(thd->main_security_ctx.ip= my_strdup(ip,MYF(MY_WME))))
-+ return 1; /* The error is set by my_strdup(). */
-+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.ip;
-+ vio_in_addr(net->vio,&thd->remote.sin_addr);
-+ if (!(specialflag & SPECIAL_NO_RESOLVE))
-+ {
-+ vio_in_addr(net->vio,&thd->remote.sin_addr);
-+ thd->main_security_ctx.host=
-+ ip_to_hostname(&thd->remote.sin_addr, &connect_errors);
-+ /* Cut very long hostnames to avoid possible overflows */
-+ if (thd->main_security_ctx.host)
-+ {
-+ if (thd->main_security_ctx.host != my_localhost)
-+ thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
-+ HOSTNAME_LENGTH)]= 0;
-+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-+ }
-+ if (connect_errors > max_connect_errors)
-+ {
-+ my_error(ER_HOST_IS_BLOCKED, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ }
-+ DBUG_PRINT("info",("Host: %s ip: %s",
-+ (thd->main_security_ctx.host ?
-+ thd->main_security_ctx.host : "unknown host"),
-+ (thd->main_security_ctx.ip ?
-+ thd->main_security_ctx.ip : "unknown ip")));
-+ if (acl_check_host(thd->main_security_ctx.host, thd->main_security_ctx.ip))
-+ {
-+ my_error(ER_HOST_NOT_PRIVILEGED, MYF(0),
-+ thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ }
-+ else /* Hostname given means that the connection was on a socket */
-+ {
-+ DBUG_PRINT("info",("Host: %s", thd->main_security_ctx.host));
-+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
-+ thd->main_security_ctx.ip= 0;
-+ /* Reset sin_addr */
-+ bzero((char*) &thd->remote, sizeof(thd->remote));
-+ }
-+ vio_keepalive(net->vio, TRUE);
-+
-+ ulong server_capabilites;
-+ {
-+ /* buff[] needs to big enough to hold the server_version variable */
-+ char buff[SERVER_VERSION_LENGTH + 1 + SCRAMBLE_LENGTH + 1 + 64];
-+ server_capabilites= CLIENT_BASIC_FLAGS;
-+
-+ if (opt_using_transactions)
-+ server_capabilites|= CLIENT_TRANSACTIONS;
-+#ifdef HAVE_COMPRESS
-+ server_capabilites|= CLIENT_COMPRESS;
-+#endif /* HAVE_COMPRESS */
-+#ifdef HAVE_OPENSSL
-+ if (ssl_acceptor_fd)
-+ {
-+ server_capabilites |= CLIENT_SSL; /* Wow, SSL is available! */
-+ server_capabilites |= CLIENT_SSL_VERIFY_SERVER_CERT;
-+ }
-+#endif /* HAVE_OPENSSL */
-+
-+ end= strnmov(buff, server_version, SERVER_VERSION_LENGTH) + 1;
-+ int4store((uchar*) end, thd->thread_id);
-+ end+= 4;
-+ /*
-+ So as check_connection is the only entry point to authorization
-+ procedure, scramble is set here. This gives us new scramble for
-+ each handshake.
-+ */
-+ create_random_string(thd->scramble, SCRAMBLE_LENGTH, &thd->rand);
-+ /*
-+ Old clients does not understand long scrambles, but can ignore packet
-+ tail: that's why first part of the scramble is placed here, and second
-+ part at the end of packet.
-+ */
-+ end= strmake(end, thd->scramble, SCRAMBLE_LENGTH_323) + 1;
-+
-+ int2store(end, server_capabilites);
-+ /* write server characteristics: up to 16 bytes allowed */
-+ end[2]=(char) default_charset_info->number;
-+ int2store(end+3, thd->server_status);
-+ bzero(end+5, 13);
-+ end+= 18;
-+ /* write scramble tail */
-+ end= strmake(end, thd->scramble + SCRAMBLE_LENGTH_323,
-+ SCRAMBLE_LENGTH - SCRAMBLE_LENGTH_323) + 1;
-+
-+ /* At this point we write connection message and read reply */
-+ if (net_write_command(net, (uchar) protocol_version, (uchar*) "", 0,
-+ (uchar*) buff, (size_t) (end-buff)) ||
-+ (pkt_len= my_net_read(net)) == packet_error ||
-+ pkt_len < MIN_HANDSHAKE_SIZE)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0),
-+ thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ }
-+#ifdef _CUSTOMCONFIG_
-+#include "_cust_sql_parse.h"
-+#endif
-+ if (connect_errors)
-+ reset_host_errors(&thd->remote.sin_addr);
-+ if (thd->packet.alloc(thd->variables.net_buffer_length))
-+ return 1; /* The error is set by alloc(). */
-+
-+ thd->client_capabilities= uint2korr(net->read_pos);
-+ if (thd->client_capabilities & CLIENT_PROTOCOL_41)
-+ {
-+ thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
-+ thd->max_client_packet_length= uint4korr(net->read_pos+4);
-+ DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
-+ if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
-+ return 1;
-+ thd->update_charset();
-+ end= (char*) net->read_pos+32;
-+ }
-+ else
-+ {
-+ thd->max_client_packet_length= uint3korr(net->read_pos+2);
-+ end= (char*) net->read_pos+5;
-+ }
-+ /*
-+ Disable those bits which are not supported by the server.
-+ This is a precautionary measure, if the client lies. See Bug#27944.
-+ */
-+ thd->client_capabilities&= server_capabilites;
-+
-+ if (thd->client_capabilities & CLIENT_IGNORE_SPACE)
-+ thd->variables.sql_mode|= MODE_IGNORE_SPACE;
-+#ifdef HAVE_OPENSSL
-+ DBUG_PRINT("info", ("client capabilities: %lu", thd->client_capabilities));
-+ if (thd->client_capabilities & CLIENT_SSL)
-+ {
-+ /* Do the SSL layering. */
-+ if (!ssl_acceptor_fd)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ DBUG_PRINT("info", ("IO layer change in progress..."));
-+ if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
-+ {
-+ DBUG_PRINT("error", ("Failed to accept new SSL connection"));
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ DBUG_PRINT("info", ("Reading user information over SSL layer"));
-+ if ((pkt_len= my_net_read(net)) == packet_error ||
-+ pkt_len < NORMAL_HANDSHAKE_SIZE)
-+ {
-+ DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
-+ pkt_len));
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ }
-+#endif /* HAVE_OPENSSL */
-+
-+ if (end > (char *)net->read_pos + pkt_len)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+
-+ if (thd->client_capabilities & CLIENT_INTERACTIVE)
-+ thd->variables.net_wait_timeout= thd->variables.net_interactive_timeout;
-+ if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
-+ opt_using_transactions)
-+ net->return_status= &thd->server_status;
-+
-+ /*
-+ In order to safely scan a head for '\0' string terminators
-+ we must keep track of how many bytes remain in the allocated
-+ buffer or we might read past the end of the buffer.
-+ */
-+ size_t bytes_remaining_in_packet= pkt_len - (end - (char *)net->read_pos);
-+
-+ size_t user_len;
-+ char *user= get_null_terminated_string(&end, &bytes_remaining_in_packet,
-+ &user_len);
-+ if (user == NULL)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+
-+ /*
-+ Old clients send a null-terminated string as password; new clients send
-+ the size (1 byte) + string (not null-terminated). Hence in case of empty
-+ password both send '\0'.
-+ */
-+ size_t passwd_len= 0;
-+ char *passwd= NULL;
-+
-+ if (thd->client_capabilities & CLIENT_SECURE_CONNECTION)
-+ {
-+ /*
-+ 4.1+ password. First byte is password length.
-+ */
-+ passwd= get_length_encoded_string(&end, &bytes_remaining_in_packet,
-+ &passwd_len);
-+ }
-+ else
-+ {
-+ /*
-+ Old passwords are zero terminated strings.
-+ */
-+ passwd= get_null_terminated_string(&end, &bytes_remaining_in_packet,
-+ &passwd_len);
-+ }
-+
-+ if (passwd == NULL)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+
-+ size_t db_len= 0;
-+ char *db= NULL;
-+
-+ if (thd->client_capabilities & CLIENT_CONNECT_WITH_DB)
-+ {
-+ db= get_null_terminated_string(&end, &bytes_remaining_in_packet,
-+ &db_len);
-+ if (db == NULL)
-+ {
-+ inc_host_errors(&thd->remote.sin_addr);
-+ my_error(ER_HANDSHAKE_ERROR, MYF(0), thd->main_security_ctx.host_or_ip);
-+ return 1;
-+ }
-+ }
-+
-+ char db_buff[NAME_LEN + 1]; // buffer to store db in utf8
-+ char user_buff[USERNAME_LENGTH + 1]; // buffer to store user in utf8
-+ uint dummy_errors;
-+
-+ /* Since 4.1 all database names are stored in utf8 */
-+ if (db)
-+ {
-+ db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-+ system_charset_info,
-+ db, db_len,
-+ thd->charset(), &dummy_errors)]= 0;
-+ db= db_buff;
-+ }
-+
-+ user_buff[user_len= copy_and_convert(user_buff, sizeof(user_buff)-1,
-+ system_charset_info, user, user_len,
-+ thd->charset(), &dummy_errors)]= '\0';
-+ user= user_buff;
-+
-+ /* If username starts and ends in "'", chop them off */
-+ if (user_len > 1 && user[0] == '\'' && user[user_len - 1] == '\'')
-+ {
-+ user[user_len-1]= 0;
-+ user++;
-+ user_len-= 2;
-+ }
-+
-+ /*
-+ Clip username to allowed length in characters (not bytes). This is
-+ mostly for backward compatibility.
-+ */
-+ {
-+ CHARSET_INFO *cs= system_charset_info;
-+ int err;
-+
-+ user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len,
-+ USERNAME_CHAR_LENGTH, &err);
-+ user[user_len]= '\0';
-+ }
-+
-+ if (thd->main_security_ctx.user)
-+ x_free(thd->main_security_ctx.user);
-+ if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME))))
-+ return 1; /* The error is set by my_strdup(). */
-+ return check_user(thd, COM_CONNECT, passwd, passwd_len, db, TRUE);
-+}
-+
-+
-+/*
-+ Setup thread to be used with the current thread
-+
-+ SYNOPSIS
-+ bool setup_connection_thread_globals()
-+ thd Thread/connection handler
-+
-+ RETURN
-+ 0 ok
-+ 1 Error (out of memory)
-+ In this case we will close the connection and increment status
-+*/
-+
-+bool setup_connection_thread_globals(THD *thd)
-+{
-+ if (thd->store_globals())
-+ {
-+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+ statistic_increment(aborted_connects,&LOCK_status);
-+ thread_scheduler.end_thread(thd, 0);
-+ return 1; // Error
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ Autenticate user, with error reporting
-+
-+ SYNOPSIS
-+ login_connection()
-+ thd Thread handler
-+
-+ NOTES
-+ Connection is not closed in case of errors
-+
-+ RETURN
-+ 0 ok
-+ 1 error
-+*/
-+
-+
-+static bool login_connection(THD *thd)
-+{
-+ NET *net= &thd->net;
-+ int error;
-+ DBUG_ENTER("login_connection");
-+ DBUG_PRINT("info", ("login_connection called by thread %lu",
-+ thd->thread_id));
-+
-+ /* Use "connect_timeout" value during connection phase */
-+ my_net_set_read_timeout(net, connect_timeout);
-+ my_net_set_write_timeout(net, connect_timeout);
-+
-+ error= check_connection(thd);
-+ net_end_statement(thd);
-+
-+ if (error)
-+ { // Wrong permissions
-+#ifdef __NT__
-+ if (vio_type(net->vio) == VIO_TYPE_NAMEDPIPE)
-+ my_sleep(1000); /* must wait after eof() */
-+#endif
-+ statistic_increment(aborted_connects,&LOCK_status);
-+ DBUG_RETURN(1);
-+ }
-+ /* Connect completed, set read/write timeouts back to default */
-+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
-+ my_net_set_write_timeout(net, thd->variables.net_write_timeout);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Close an established connection
-+
-+ NOTES
-+ This mainly updates status variables
-+*/
-+
-+static void end_connection(THD *thd)
-+{
-+ NET *net= &thd->net;
-+ plugin_thdvar_cleanup(thd);
-+ if (thd->user_connect)
-+ decrease_user_connections(thd->user_connect);
-+
-+ if (thd->killed || (net->error && net->vio != 0))
-+ {
-+ statistic_increment(aborted_threads,&LOCK_status);
-+ }
-+
-+ if (net->error && net->vio != 0)
-+ {
-+ if (!thd->killed && thd->variables.log_warnings > 1)
-+ {
-+ Security_context *sctx= thd->security_ctx;
-+
-+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
-+ sctx->user ? sctx->user : "unauthenticated",
-+ sctx->host_or_ip,
-+ (thd->main_da.is_error() ? thd->main_da.message() :
-+ ER(ER_UNKNOWN_ERROR)));
-+ }
-+ }
-+}
-+
-+
-+/*
-+ Initialize THD to handle queries
-+*/
-+
-+static void prepare_new_connection_state(THD* thd)
-+{
-+ Security_context *sctx= thd->security_ctx;
-+
-+#ifdef __NETWARE__
-+ netware_reg_user(sctx->ip, sctx->user, "MySQL");
-+#endif
-+
-+ if (thd->variables.max_join_size == HA_POS_ERROR)
-+ thd->options |= OPTION_BIG_SELECTS;
-+ if (thd->client_capabilities & CLIENT_COMPRESS)
-+ thd->net.compress=1; // Use compression
-+
-+ /*
-+ Much of this is duplicated in create_embedded_thd() for the
-+ embedded server library.
-+ TODO: refactor this to avoid code duplication there
-+ */
-+ thd->version= refresh_version;
-+ thd->proc_info= 0;
-+ thd->command= COM_SLEEP;
-+ thd->set_time();
-+ thd->init_for_queries();
-+
-+ if (sys_init_connect.value_length && !(sctx->master_access & SUPER_ACL))
-+ {
-+ execute_init_command(thd, &sys_init_connect, &LOCK_sys_init_connect);
-+ if (thd->is_error())
-+ {
-+ thd->killed= THD::KILL_CONNECTION;
-+ sql_print_warning(ER(ER_NEW_ABORTING_CONNECTION),
-+ thd->thread_id,(thd->db ? thd->db : "unconnected"),
-+ sctx->user ? sctx->user : "unauthenticated",
-+ sctx->host_or_ip, "init_connect command failed");
-+ sql_print_warning("%s", thd->main_da.message());
-+ }
-+ thd->proc_info=0;
-+ thd->set_time();
-+ thd->init_for_queries();
-+ }
-+}
-+
-+
-+/*
-+ Thread handler for a connection
-+
-+ SYNOPSIS
-+ handle_one_connection()
-+ arg Connection object (THD)
-+
-+ IMPLEMENTATION
-+ This function (normally) does the following:
-+ - Initialize thread
-+ - Initialize THD to be used with this thread
-+ - Authenticate user
-+ - Execute all queries sent on the connection
-+ - Take connection down
-+ - End thread / Handle next connection using thread from thread cache
-+*/
-+
-+pthread_handler_t handle_one_connection(void *arg)
-+{
-+ THD *thd= (THD*) arg;
-+
-+ thd->thr_create_utime= my_micro_time();
-+
-+ if (thread_scheduler.init_new_connection_thread())
-+ {
-+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+ statistic_increment(aborted_connects,&LOCK_status);
-+ thread_scheduler.end_thread(thd,0);
-+ return 0;
-+ }
-+
-+ /*
-+ If a thread was created to handle this connection:
-+ increment slow_launch_threads counter if it took more than
-+ slow_launch_time seconds to create the thread.
-+ */
-+ if (thd->prior_thr_create_utime)
-+ {
-+ ulong launch_time= (ulong) (thd->thr_create_utime -
-+ thd->prior_thr_create_utime);
-+ if (launch_time >= slow_launch_time*1000000L)
-+ statistic_increment(slow_launch_threads, &LOCK_status);
-+ thd->prior_thr_create_utime= 0;
-+ }
-+
-+ /*
-+ handle_one_connection() is normally the only way a thread would
-+ start and would always be on the very high end of the stack ,
-+ therefore, the thread stack always starts at the address of the
-+ first local variable of handle_one_connection, which is thd. We
-+ need to know the start of the stack so that we could check for
-+ stack overruns.
-+ */
-+ thd->thread_stack= (char*) &thd;
-+ if (setup_connection_thread_globals(thd))
-+ return 0;
-+
-+ for (;;)
-+ {
-+ NET *net= &thd->net;
-+
-+ lex_start(thd);
-+ if (login_connection(thd))
-+ goto end_thread;
-+
-+ prepare_new_connection_state(thd);
-+
-+ while (!net->error && net->vio != 0 &&
-+ !(thd->killed == THD::KILL_CONNECTION))
-+ {
-+ if (do_command(thd))
-+ break;
-+ }
-+ end_connection(thd);
-+
-+end_thread:
-+ close_connection(thd, 0, 1);
-+ if (thread_scheduler.end_thread(thd,1))
-+ return 0; // Probably no-threads
-+
-+ /*
-+ If end_thread() returns, we are either running with
-+ thread-handler=no-threads or this thread has been schedule to
-+ handle the next connection.
-+ */
-+ thd= current_thd;
-+ thd->thread_stack= (char*) &thd;
-+ }
-+}
-+#endif /* EMBEDDED_LIBRARY */
diff -urN mysql-old/sql/sql_load.cc mysql/sql/sql_load.cc
--- mysql-old/sql/sql_load.cc 2011-05-10 17:45:45.626682377 +0000
+++ mysql/sql/sql_load.cc 2011-05-10 17:56:01.503349042 +0000
@@ -27881,8007 +2213,6 @@ diff -urN mysql-old/sql/sql_parse.cc mysql/sql/sql_parse.cc
my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
return 1;
}
-diff -urN mysql-old/sql/sql_parse.cc.orig mysql/sql/sql_parse.cc.orig
---- mysql-old/sql/sql_parse.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/sql_parse.cc.orig 2011-04-12 12:11:38.000000000 +0000
-@@ -0,0 +1,7997 @@
-+/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+#define MYSQL_LEX 1
-+#include "mysql_priv.h"
-+#include "sql_repl.h"
-+#include "rpl_filter.h"
-+#include "repl_failsafe.h"
-+#include <m_ctype.h>
-+#include <myisam.h>
-+#include <my_dir.h>
-+
-+#include "sp_head.h"
-+#include "sp.h"
-+#include "sp_cache.h"
-+#include "events.h"
-+#include "sql_trigger.h"
-+#include "debug_sync.h"
-+
-+/**
-+ @defgroup Runtime_Environment Runtime Environment
-+ @{
-+*/
-+
-+/* Used in error handling only */
-+#define SP_TYPE_STRING(LP) \
-+ ((LP)->sphead->m_type == TYPE_ENUM_FUNCTION ? "FUNCTION" : "PROCEDURE")
-+#define SP_COM_STRING(LP) \
-+ ((LP)->sql_command == SQLCOM_CREATE_SPFUNCTION || \
-+ (LP)->sql_command == SQLCOM_ALTER_FUNCTION || \
-+ (LP)->sql_command == SQLCOM_SHOW_CREATE_FUNC || \
-+ (LP)->sql_command == SQLCOM_DROP_FUNCTION ? \
-+ "FUNCTION" : "PROCEDURE")
-+
-+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables);
-+static bool check_show_create_table_access(THD *thd, TABLE_LIST *table);
-+
-+const char *any_db="*any*"; // Special symbol for check_access
-+
-+const LEX_STRING command_name[]={
-+ { C_STRING_WITH_LEN("Sleep") },
-+ { C_STRING_WITH_LEN("Quit") },
-+ { C_STRING_WITH_LEN("Init DB") },
-+ { C_STRING_WITH_LEN("Query") },
-+ { C_STRING_WITH_LEN("Field List") },
-+ { C_STRING_WITH_LEN("Create DB") },
-+ { C_STRING_WITH_LEN("Drop DB") },
-+ { C_STRING_WITH_LEN("Refresh") },
-+ { C_STRING_WITH_LEN("Shutdown") },
-+ { C_STRING_WITH_LEN("Statistics") },
-+ { C_STRING_WITH_LEN("Processlist") },
-+ { C_STRING_WITH_LEN("Connect") },
-+ { C_STRING_WITH_LEN("Kill") },
-+ { C_STRING_WITH_LEN("Debug") },
-+ { C_STRING_WITH_LEN("Ping") },
-+ { C_STRING_WITH_LEN("Time") },
-+ { C_STRING_WITH_LEN("Delayed insert") },
-+ { C_STRING_WITH_LEN("Change user") },
-+ { C_STRING_WITH_LEN("Binlog Dump") },
-+ { C_STRING_WITH_LEN("Table Dump") },
-+ { C_STRING_WITH_LEN("Connect Out") },
-+ { C_STRING_WITH_LEN("Register Slave") },
-+ { C_STRING_WITH_LEN("Prepare") },
-+ { C_STRING_WITH_LEN("Execute") },
-+ { C_STRING_WITH_LEN("Long Data") },
-+ { C_STRING_WITH_LEN("Close stmt") },
-+ { C_STRING_WITH_LEN("Reset stmt") },
-+ { C_STRING_WITH_LEN("Set option") },
-+ { C_STRING_WITH_LEN("Fetch") },
-+ { C_STRING_WITH_LEN("Daemon") },
-+ { C_STRING_WITH_LEN("Error") } // Last command number
-+};
-+
-+const char *xa_state_names[]={
-+ "NON-EXISTING", "ACTIVE", "IDLE", "PREPARED", "ROLLBACK ONLY"
-+};
-+
-+/**
-+ Mark a XA transaction as rollback-only if the RM unilaterally
-+ rolled back the transaction branch.
-+
-+ @note If a rollback was requested by the RM, this function sets
-+ the appropriate rollback error code and transits the state
-+ to XA_ROLLBACK_ONLY.
-+
-+ @return TRUE if transaction was rolled back or if the transaction
-+ state is XA_ROLLBACK_ONLY. FALSE otherwise.
-+*/
-+static bool xa_trans_rolled_back(XID_STATE *xid_state)
-+{
-+ if (xid_state->rm_error)
-+ {
-+ switch (xid_state->rm_error) {
-+ case ER_LOCK_WAIT_TIMEOUT:
-+ my_error(ER_XA_RBTIMEOUT, MYF(0));
-+ break;
-+ case ER_LOCK_DEADLOCK:
-+ my_error(ER_XA_RBDEADLOCK, MYF(0));
-+ break;
-+ default:
-+ my_error(ER_XA_RBROLLBACK, MYF(0));
-+ }
-+ xid_state->xa_state= XA_ROLLBACK_ONLY;
-+ }
-+
-+ return (xid_state->xa_state == XA_ROLLBACK_ONLY);
-+}
-+
-+/**
-+ Rollback work done on behalf of at ransaction branch.
-+*/
-+static bool xa_trans_rollback(THD *thd)
-+{
-+ /*
-+ Resource Manager error is meaningless at this point, as we perform
-+ explicit rollback request by user. We must reset rm_error before
-+ calling ha_rollback(), so thd->transaction.xid structure gets reset
-+ by ha_rollback()/THD::transaction::cleanup().
-+ */
-+ thd->transaction.xid_state.rm_error= 0;
-+
-+ bool status= test(ha_rollback(thd));
-+
-+ thd->options&= ~(ulong) OPTION_BEGIN;
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+ xid_cache_delete(&thd->transaction.xid_state);
-+ thd->transaction.xid_state.xa_state= XA_NOTR;
-+
-+ return status;
-+}
-+
-+static void unlock_locked_tables(THD *thd)
-+{
-+ if (thd->locked_tables)
-+ {
-+ thd->lock=thd->locked_tables;
-+ thd->locked_tables=0; // Will be automatically closed
-+ close_thread_tables(thd); // Free tables
-+ }
-+}
-+
-+
-+bool end_active_trans(THD *thd)
-+{
-+ int error=0;
-+ DBUG_ENTER("end_active_trans");
-+ if (unlikely(thd->in_sub_stmt))
-+ {
-+ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ DBUG_RETURN(1);
-+ }
-+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
-+ OPTION_TABLE_LOCK))
-+ {
-+ DBUG_PRINT("info",("options: 0x%llx", thd->options));
-+ /* Safety if one did "drop table" on locked tables */
-+ if (!thd->locked_tables)
-+ thd->options&= ~OPTION_TABLE_LOCK;
-+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+ if (ha_commit(thd))
-+ error=1;
-+ }
-+ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ DBUG_RETURN(error);
-+}
-+
-+
-+bool begin_trans(THD *thd)
-+{
-+ int error=0;
-+ if (unlikely(thd->in_sub_stmt))
-+ {
-+ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+ return 1;
-+ }
-+ if (thd->locked_tables)
-+ {
-+ thd->lock=thd->locked_tables;
-+ thd->locked_tables=0; // Will be automatically closed
-+ close_thread_tables(thd); // Free tables
-+ }
-+ if (end_active_trans(thd))
-+ error= -1;
-+ else
-+ {
-+ thd->options|= OPTION_BEGIN;
-+ thd->server_status|= SERVER_STATUS_IN_TRANS;
-+ }
-+ return error;
-+}
-+
-+#ifdef HAVE_REPLICATION
-+/**
-+ Returns true if all tables should be ignored.
-+*/
-+inline bool all_tables_not_ok(THD *thd, TABLE_LIST *tables)
-+{
-+ return rpl_filter->is_on() && tables && !thd->spcont &&
-+ !rpl_filter->tables_ok(thd->db, tables);
-+}
-+#endif
-+
-+
-+static bool some_non_temp_table_to_be_updated(THD *thd, TABLE_LIST *tables)
-+{
-+ for (TABLE_LIST *table= tables; table; table= table->next_global)
-+ {
-+ DBUG_ASSERT(table->db && table->table_name);
-+ if (table->updating &&
-+ !find_temporary_table(thd, table->db, table->table_name))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Mark all commands that somehow changes a table.
-+
-+ This is used to check number of updates / hour.
-+
-+ sql_command is actually set to SQLCOM_END sometimes
-+ so we need the +1 to include it in the array.
-+
-+ See COMMAND_FLAG_xxx for different type of commands
-+ 2 - query that returns meaningful ROW_COUNT() -
-+ a number of modified rows
-+*/
-+
-+uint sql_command_flags[SQLCOM_END+1];
-+
-+void init_update_queries(void)
-+{
-+ bzero((uchar*) &sql_command_flags, sizeof(sql_command_flags));
-+
-+ sql_command_flags[SQLCOM_CREATE_TABLE]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_CREATE_INDEX]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
-+ sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND;
-+ sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_LOAD]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_CREATE_DB]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_DROP_DB]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_BACKUP_TABLE]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_RESTORE_TABLE]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_DROP_VIEW]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_CREATE_EVENT]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_ALTER_EVENT]= CF_CHANGES_DATA;
-+ sql_command_flags[SQLCOM_DROP_EVENT]= CF_CHANGES_DATA;
-+
-+ sql_command_flags[SQLCOM_UPDATE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_UPDATE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_INSERT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_INSERT_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_DELETE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_DELETE_MULTI]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_REPLACE]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_REPLACE_SELECT]= CF_CHANGES_DATA | CF_HAS_ROW_COUNT |
-+ CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SELECT]= CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SET_OPTION]= CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_DO]= CF_REEXECUTION_FRAGILE;
-+
-+ sql_command_flags[SQLCOM_SHOW_STATUS_PROC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_STATUS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_DATABASES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_TRIGGERS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_EVENTS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_OPEN_TABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_PLUGINS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_FIELDS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_KEYS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_VARIABLES]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_CHARSETS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_COLLATIONS]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_NEW_MASTER]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_BINLOGS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_SLAVE_HOSTS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_BINLOG_EVENTS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_COLUMN_TYPES]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_STORAGE_ENGINES]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_AUTHORS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CONTRIBUTORS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_PRIVILEGES]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_WARNS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_ERRORS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_ENGINE_STATUS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_ENGINE_MUTEX]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_ENGINE_LOGS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_PROCESSLIST]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_GRANTS]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE_DB]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_MASTER_STAT]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_SLAVE_STAT]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE_PROC]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE_FUNC]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE_TRIGGER]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_STATUS_FUNC]= CF_STATUS_COMMAND | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_SHOW_PROC_CODE]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_FUNC_CODE]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_CREATE_EVENT]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_PROFILES]= CF_STATUS_COMMAND;
-+ sql_command_flags[SQLCOM_SHOW_PROFILE]= CF_STATUS_COMMAND;
-+
-+ sql_command_flags[SQLCOM_SHOW_TABLES]= (CF_STATUS_COMMAND |
-+ CF_SHOW_TABLE_COMMAND |
-+ CF_REEXECUTION_FRAGILE);
-+ sql_command_flags[SQLCOM_SHOW_TABLE_STATUS]= (CF_STATUS_COMMAND |
-+ CF_SHOW_TABLE_COMMAND |
-+ CF_REEXECUTION_FRAGILE);
-+
-+ /*
-+ The following is used to preserver CF_ROW_COUNT during the
-+ a CALL or EXECUTE statement, so the value generated by the
-+ last called (or executed) statement is preserved.
-+ See mysql_execute_command() for how CF_ROW_COUNT is used.
-+ */
-+ sql_command_flags[SQLCOM_CALL]= CF_HAS_ROW_COUNT | CF_REEXECUTION_FRAGILE;
-+ sql_command_flags[SQLCOM_EXECUTE]= CF_HAS_ROW_COUNT;
-+
-+ /*
-+ The following admin table operations are allowed
-+ on log tables.
-+ */
-+ sql_command_flags[SQLCOM_REPAIR]= CF_WRITE_LOGS_COMMAND;
-+ sql_command_flags[SQLCOM_OPTIMIZE]= CF_WRITE_LOGS_COMMAND;
-+ sql_command_flags[SQLCOM_ANALYZE]= CF_WRITE_LOGS_COMMAND;
-+}
-+
-+
-+bool is_update_query(enum enum_sql_command command)
-+{
-+ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
-+ return (sql_command_flags[command] & CF_CHANGES_DATA) != 0;
-+}
-+
-+/**
-+ Check if a sql command is allowed to write to log tables.
-+ @param command The SQL command
-+ @return true if writing is allowed
-+*/
-+bool is_log_table_write_query(enum enum_sql_command command)
-+{
-+ DBUG_ASSERT(command >= 0 && command <= SQLCOM_END);
-+ return (sql_command_flags[command] & CF_WRITE_LOGS_COMMAND) != 0;
-+}
-+
-+void execute_init_command(THD *thd, sys_var_str *init_command_var,
-+ rw_lock_t *var_mutex)
-+{
-+ Vio* save_vio;
-+ ulong save_client_capabilities;
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.start_new_query();
-+ thd->profiling.set_query_source(init_command_var->value,
-+ init_command_var->value_length);
-+#endif
-+
-+ thd_proc_info(thd, "Execution of init_command");
-+ /*
-+ We need to lock init_command_var because
-+ during execution of init_command_var query
-+ values of init_command_var can't be changed
-+ */
-+ rw_rdlock(var_mutex);
-+ save_client_capabilities= thd->client_capabilities;
-+ thd->client_capabilities|= CLIENT_MULTI_QUERIES;
-+ /*
-+ We don't need return result of execution to client side.
-+ To forbid this we should set thd->net.vio to 0.
-+ */
-+ save_vio= thd->net.vio;
-+ thd->net.vio= 0;
-+ dispatch_command(COM_QUERY, thd,
-+ init_command_var->value,
-+ init_command_var->value_length);
-+ rw_unlock(var_mutex);
-+ thd->client_capabilities= save_client_capabilities;
-+ thd->net.vio= save_vio;
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.finish_current_query();
-+#endif
-+}
-+
-+
-+static void handle_bootstrap_impl(THD *thd)
-+{
-+ FILE *file=bootstrap_file;
-+ char *buff;
-+ const char* found_semicolon= NULL;
-+
-+ DBUG_ENTER("handle_bootstrap");
-+
-+#ifndef EMBEDDED_LIBRARY
-+ pthread_detach_this_thread();
-+ thd->thread_stack= (char*) &thd;
-+#endif /* EMBEDDED_LIBRARY */
-+
-+ if (thd->variables.max_join_size == HA_POS_ERROR)
-+ thd->options |= OPTION_BIG_SELECTS;
-+
-+ thd_proc_info(thd, 0);
-+ thd->version=refresh_version;
-+ thd->security_ctx->priv_user=
-+ thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
-+ thd->security_ctx->priv_host[0]=0;
-+ /*
-+ Make the "client" handle multiple results. This is necessary
-+ to enable stored procedures with SELECTs and Dynamic SQL
-+ in init-file.
-+ */
-+ thd->client_capabilities|= CLIENT_MULTI_RESULTS;
-+
-+ buff= (char*) thd->net.buff;
-+ thd->init_for_queries();
-+ while (fgets(buff, thd->net.max_packet, file))
-+ {
-+ char *query, *res;
-+ /* strlen() can't be deleted because fgets() doesn't return length */
-+ ulong length= (ulong) strlen(buff);
-+ while (buff[length-1] != '\n' && !feof(file))
-+ {
-+ /*
-+ We got only a part of the current string. Will try to increase
-+ net buffer then read the rest of the current string.
-+ */
-+ /* purecov: begin tested */
-+ if (net_realloc(&(thd->net), 2 * thd->net.max_packet))
-+ {
-+ net_end_statement(thd);
-+ bootstrap_error= 1;
-+ break;
-+ }
-+ buff= (char*) thd->net.buff;
-+ res= fgets(buff + length, thd->net.max_packet - length, file);
-+ if (!res && !feof(file))
-+ {
-+ net_end_statement(thd);
-+ bootstrap_error= 1;
-+ break;
-+ }
-+ length+= (ulong) strlen(buff + length);
-+ /* purecov: end */
-+ }
-+ if (bootstrap_error)
-+ break; /* purecov: inspected */
-+
-+ while (length && (my_isspace(thd->charset(), buff[length-1]) ||
-+ buff[length-1] == ';'))
-+ length--;
-+ buff[length]=0;
-+
-+ /* Skip lines starting with delimiter */
-+ if (strncmp(buff, STRING_WITH_LEN("delimiter")) == 0)
-+ continue;
-+
-+ query= (char *) thd->memdup_w_gap(buff, length + 1,
-+ thd->db_length + 1 +
-+ QUERY_CACHE_FLAGS_SIZE);
-+ thd->set_query(query, length);
-+ DBUG_PRINT("query",("%-.4096s", thd->query()));
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.start_new_query();
-+ thd->profiling.set_query_source(thd->query(), length);
-+#endif
-+
-+ /*
-+ We don't need to obtain LOCK_thread_count here because in bootstrap
-+ mode we have only one thread.
-+ */
-+ thd->query_id=next_query_id();
-+ thd->set_time();
-+ mysql_parse(thd, thd->query(), length, & found_semicolon);
-+ close_thread_tables(thd); // Free tables
-+
-+ bootstrap_error= thd->is_error();
-+ net_end_statement(thd);
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.finish_current_query();
-+#endif
-+
-+ if (bootstrap_error)
-+ break;
-+
-+ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
-+#ifdef USING_TRANSACTIONS
-+ free_root(&thd->transaction.mem_root,MYF(MY_KEEP_PREALLOC));
-+#endif
-+ }
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Execute commands from bootstrap_file.
-+
-+ Used when creating the initial grant tables.
-+*/
-+
-+pthread_handler_t handle_bootstrap(void *arg)
-+{
-+ THD *thd=(THD*) arg;
-+
-+ /* The following must be called before DBUG_ENTER */
-+ thd->thread_stack= (char*) &thd;
-+ if (my_thread_init() || thd->store_globals())
-+ {
-+#ifndef EMBEDDED_LIBRARY
-+ close_connection(thd, ER_OUT_OF_RESOURCES, 1);
-+#endif
-+ thd->fatal_error();
-+ goto end;
-+ }
-+
-+ handle_bootstrap_impl(thd);
-+
-+end:
-+ net_end(&thd->net);
-+ thd->cleanup();
-+ delete thd;
-+
-+#ifndef EMBEDDED_LIBRARY
-+ (void) pthread_mutex_lock(&LOCK_thread_count);
-+ thread_count--;
-+ in_bootstrap= FALSE;
-+ (void) pthread_cond_broadcast(&COND_thread_count);
-+ (void) pthread_mutex_unlock(&LOCK_thread_count);
-+ my_thread_end();
-+ pthread_exit(0);
-+#endif
-+
-+ return 0;
-+}
-+
-+
-+/**
-+ @brief Check access privs for a MERGE table and fix children lock types.
-+
-+ @param[in] thd thread handle
-+ @param[in] db database name
-+ @param[in,out] table_list list of child tables (merge_list)
-+ lock_type and optionally db set per table
-+
-+ @return status
-+ @retval 0 OK
-+ @retval != 0 Error
-+
-+ @detail
-+ This function is used for write access to MERGE tables only
-+ (CREATE TABLE, ALTER TABLE ... UNION=(...)). Set TL_WRITE for
-+ every child. Set 'db' for every child if not present.
-+*/
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static bool check_merge_table_access(THD *thd, char *db,
-+ TABLE_LIST *table_list)
-+{
-+ int error= 0;
-+
-+ if (table_list)
-+ {
-+ /* Check that all tables use the current database */
-+ TABLE_LIST *tlist;
-+
-+ for (tlist= table_list; tlist; tlist= tlist->next_local)
-+ {
-+ if (!tlist->db || !tlist->db[0])
-+ tlist->db= db; /* purecov: inspected */
-+ }
-+ error= check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
-+ table_list, UINT_MAX, FALSE);
-+ }
-+ return error;
-+}
-+#endif
-+
-+/* This works because items are allocated with sql_alloc() */
-+
-+void free_items(Item *item)
-+{
-+ Item *next;
-+ DBUG_ENTER("free_items");
-+ for (; item ; item=next)
-+ {
-+ next=item->next;
-+ item->delete_self();
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+/**
-+ This works because items are allocated with sql_alloc().
-+ @note The function also handles null pointers (empty list).
-+*/
-+void cleanup_items(Item *item)
-+{
-+ DBUG_ENTER("cleanup_items");
-+ for (; item ; item=item->next)
-+ item->cleanup();
-+ DBUG_VOID_RETURN;
-+}
-+
-+/**
-+ Handle COM_TABLE_DUMP command.
-+
-+ @param thd thread handle
-+ @param db database name or an empty string. If empty,
-+ the current database of the connection is used
-+ @param tbl_name name of the table to dump
-+
-+ @note
-+ This function is written to handle one specific command only.
-+
-+ @retval
-+ 0 success
-+ @retval
-+ 1 error, the error message is set in THD
-+*/
-+
-+static
-+int mysql_table_dump(THD *thd, LEX_STRING *db, LEX_STRING *table_name)
-+{
-+ TABLE* table;
-+ TABLE_LIST* table_list;
-+ int error = 0;
-+ DBUG_ENTER("mysql_table_dump");
-+ if (db->length == 0)
-+ {
-+ db->str= thd->db; /* purecov: inspected */
-+ db->length= thd->db_length; /* purecov: inspected */
-+ }
-+ if (!(table_list = (TABLE_LIST*) thd->calloc(sizeof(TABLE_LIST))))
-+ DBUG_RETURN(1); // out of memory
-+ table_list->db= db->str;
-+ table_list->table_name= table_list->alias= table_name->str;
-+ table_list->lock_type= TL_READ_NO_INSERT;
-+ table_list->prev_global= &table_list; // can be removed after merge with 4.1
-+
-+ if (check_db_name(db))
-+ {
-+ /* purecov: begin inspected */
-+ my_error(ER_WRONG_DB_NAME ,MYF(0), db->str ? db->str : "NULL");
-+ goto err;
-+ /* purecov: end */
-+ }
-+ if (!table_name->length ||
-+ check_table_name(table_name->str, table_name->length, TRUE))
-+ {
-+ my_error(ER_WRONG_TABLE_NAME, MYF(0),
-+ table_name->str ? table_name->str : "NULL");
-+ error= 1;
-+ goto err;
-+ }
-+ if (lower_case_table_names)
-+ my_casedn_str(files_charset_info, table_name->str);
-+
-+ if (!(table=open_ltable(thd, table_list, TL_READ_NO_INSERT, 0)))
-+ DBUG_RETURN(1);
-+
-+ if (check_one_table_access(thd, SELECT_ACL, table_list))
-+ goto err;
-+ thd->free_list = 0;
-+ thd->set_query(table_name->str, table_name->length);
-+ if ((error = mysqld_dump_create_info(thd, table_list, -1)))
-+ {
-+ my_error(ER_GET_ERRNO, MYF(0), my_errno);
-+ goto err;
-+ }
-+ net_flush(&thd->net);
-+ if ((error= table->file->dump(thd,-1)))
-+ my_error(ER_GET_ERRNO, MYF(0), error);
-+
-+err:
-+ DBUG_RETURN(error);
-+}
-+
-+/**
-+ Ends the current transaction and (maybe) begin the next.
-+
-+ @param thd Current thread
-+ @param completion Completion type
-+
-+ @retval
-+ 0 OK
-+*/
-+
-+int end_trans(THD *thd, enum enum_mysql_completiontype completion)
-+{
-+ bool do_release= 0;
-+ int res= 0;
-+ DBUG_ENTER("end_trans");
-+
-+ if (unlikely(thd->in_sub_stmt))
-+ {
-+ my_error(ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG, MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ DBUG_RETURN(1);
-+ }
-+ switch (completion) {
-+ case COMMIT:
-+ /*
-+ We don't use end_active_trans() here to ensure that this works
-+ even if there is a problem with the OPTION_AUTO_COMMIT flag
-+ (Which of course should never happen...)
-+ */
-+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+ res= ha_commit(thd);
-+ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ break;
-+ case COMMIT_RELEASE:
-+ do_release= 1; /* fall through */
-+ case COMMIT_AND_CHAIN:
-+ res= end_active_trans(thd);
-+ if (!res && completion == COMMIT_AND_CHAIN)
-+ res= begin_trans(thd);
-+ break;
-+ case ROLLBACK_RELEASE:
-+ do_release= 1; /* fall through */
-+ case ROLLBACK:
-+ case ROLLBACK_AND_CHAIN:
-+ {
-+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+ if (ha_rollback(thd))
-+ res= -1;
-+ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ if (!res && (completion == ROLLBACK_AND_CHAIN))
-+ res= begin_trans(thd);
-+ break;
-+ }
-+ default:
-+ res= -1;
-+ my_error(ER_UNKNOWN_COM_ERROR, MYF(0));
-+ DBUG_RETURN(-1);
-+ }
-+
-+ if (res < 0)
-+ my_error(thd->killed_errno(), MYF(0));
-+ else if ((res == 0) && do_release)
-+ thd->killed= THD::KILL_CONNECTION;
-+
-+ DBUG_RETURN(res);
-+}
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+/**
-+ Read one command from connection and execute it (query or simple command).
-+ This function is called in loop from thread function.
-+
-+ For profiling to work, it must never be called recursively.
-+
-+ @retval
-+ 0 success
-+ @retval
-+ 1 request of thread shutdown (see dispatch_command() description)
-+*/
-+
-+bool do_command(THD *thd)
-+{
-+ bool return_value;
-+ char *packet= 0;
-+ ulong packet_length;
-+ NET *net= &thd->net;
-+ enum enum_server_command command;
-+ DBUG_ENTER("do_command");
-+
-+ /*
-+ indicator of uninitialized lex => normal flow of errors handling
-+ (see my_message_sql)
-+ */
-+ thd->lex->current_select= 0;
-+
-+ /*
-+ This thread will do a blocking read from the client which
-+ will be interrupted when the next command is received from
-+ the client, the connection is closed or "net_wait_timeout"
-+ number of seconds has passed
-+ */
-+ my_net_set_read_timeout(net, thd->variables.net_wait_timeout);
-+
-+ /*
-+ XXX: this code is here only to clear possible errors of init_connect.
-+ Consider moving to init_connect() instead.
-+ */
-+ thd->clear_error(); // Clear error message
-+ thd->main_da.reset_diagnostics_area();
-+
-+ net_new_transaction(net);
-+
-+ packet_length= my_net_read(net);
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.start_new_query();
-+#endif
-+ if (packet_length == packet_error)
-+ {
-+ DBUG_PRINT("info",("Got error %d reading command from socket %s",
-+ net->error,
-+ vio_description(net->vio)));
-+
-+ /* Check if we can continue without closing the connection */
-+
-+ /* The error must be set. */
-+ DBUG_ASSERT(thd->is_error());
-+ net_end_statement(thd);
-+
-+ if (net->error != 3)
-+ {
-+ return_value= TRUE; // We have to close it.
-+ goto out;
-+ }
-+
-+ net->error= 0;
-+ return_value= FALSE;
-+ goto out;
-+ }
-+
-+ packet= (char*) net->read_pos;
-+ /*
-+ 'packet_length' contains length of data, as it was stored in packet
-+ header. In case of malformed header, my_net_read returns zero.
-+ If packet_length is not zero, my_net_read ensures that the returned
-+ number of bytes was actually read from network.
-+ There is also an extra safety measure in my_net_read:
-+ it sets packet[packet_length]= 0, but only for non-zero packets.
-+ */
-+ if (packet_length == 0) /* safety */
-+ {
-+ /* Initialize with COM_SLEEP packet */
-+ packet[0]= (uchar) COM_SLEEP;
-+ packet_length= 1;
-+ }
-+ /* Do not rely on my_net_read, extra safety against programming errors. */
-+ packet[packet_length]= '\0'; /* safety */
-+
-+ command= (enum enum_server_command) (uchar) packet[0];
-+
-+ if (command >= COM_END)
-+ command= COM_END; // Wrong command
-+
-+ DBUG_PRINT("info",("Command on %s = %d (%s)",
-+ vio_description(net->vio), command,
-+ command_name[command].str));
-+
-+ /* Restore read timeout value */
-+ my_net_set_read_timeout(net, thd->variables.net_read_timeout);
-+
-+ DBUG_ASSERT(packet_length);
-+ return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length-1));
-+
-+out:
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.finish_current_query();
-+#endif
-+ DBUG_RETURN(return_value);
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+/**
-+ @brief Determine if an attempt to update a non-temporary table while the
-+ read-only option was enabled has been made.
-+
-+ This is a helper function to mysql_execute_command.
-+
-+ @note SQLCOM_MULTI_UPDATE is an exception and delt with elsewhere.
-+
-+ @see mysql_execute_command
-+ @returns Status code
-+ @retval TRUE The statement should be denied.
-+ @retval FALSE The statement isn't updating any relevant tables.
-+*/
-+
-+static my_bool deny_updates_if_read_only_option(THD *thd,
-+ TABLE_LIST *all_tables)
-+{
-+ DBUG_ENTER("deny_updates_if_read_only_option");
-+
-+ if (!opt_readonly)
-+ DBUG_RETURN(FALSE);
-+
-+ LEX *lex= thd->lex;
-+
-+ const my_bool user_is_super=
-+ ((ulong)(thd->security_ctx->master_access & SUPER_ACL) ==
-+ (ulong)SUPER_ACL);
-+
-+ if (user_is_super)
-+ DBUG_RETURN(FALSE);
-+
-+ if (!(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA))
-+ DBUG_RETURN(FALSE);
-+
-+ /* Multi update is an exception and is dealt with later. */
-+ if (lex->sql_command == SQLCOM_UPDATE_MULTI)
-+ DBUG_RETURN(FALSE);
-+
-+ const my_bool create_temp_tables=
-+ (lex->sql_command == SQLCOM_CREATE_TABLE) &&
-+ (lex->create_info.options & HA_LEX_CREATE_TMP_TABLE);
-+
-+ const my_bool drop_temp_tables=
-+ (lex->sql_command == SQLCOM_DROP_TABLE) &&
-+ lex->drop_temporary;
-+
-+ const my_bool update_real_tables=
-+ some_non_temp_table_to_be_updated(thd, all_tables) &&
-+ !(create_temp_tables || drop_temp_tables);
-+
-+
-+ const my_bool create_or_drop_databases=
-+ (lex->sql_command == SQLCOM_CREATE_DB) ||
-+ (lex->sql_command == SQLCOM_DROP_DB);
-+
-+ if (update_real_tables || create_or_drop_databases)
-+ {
-+ /*
-+ An attempt was made to modify one or more non-temporary tables.
-+ */
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+
-+ /* Assuming that only temporary tables are modified. */
-+ DBUG_RETURN(FALSE);
-+}
-+
-+/**
-+ Perform one connection-level (COM_XXXX) command.
-+
-+ @param command type of command to perform
-+ @param thd connection handle
-+ @param packet data for the command, packet is always null-terminated
-+ @param packet_length length of packet + 1 (to show that data is
-+ null-terminated) except for COM_SLEEP, where it
-+ can be zero.
-+
-+ @todo
-+ set thd->lex->sql_command to SQLCOM_END here.
-+ @todo
-+ The following has to be changed to an 8 byte integer
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 request of thread shutdown, i. e. if command is
-+ COM_QUIT/COM_SHUTDOWN
-+*/
-+bool dispatch_command(enum enum_server_command command, THD *thd,
-+ char* packet, uint packet_length)
-+{
-+ NET *net= &thd->net;
-+ bool error= 0;
-+ DBUG_ENTER("dispatch_command");
-+ DBUG_PRINT("info",("packet: '%*.s'; command: %d", packet_length, packet, command));
-+
-+ thd->command=command;
-+ /*
-+ Commands which always take a long time are logged into
-+ the slow log only if opt_log_slow_admin_statements is set.
-+ */
-+ thd->enable_slow_log= TRUE;
-+ thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */
-+ thd->set_time();
-+ if (!thd->is_valid_time())
-+ {
-+ /*
-+ If the time has got past 2038 we need to shut this server down
-+ We do this by making sure every command is a shutdown and we
-+ have enough privileges to shut the server down
-+
-+ TODO: remove this when we have full 64 bit my_time_t support
-+ */
-+ thd->security_ctx->master_access|= SHUTDOWN_ACL;
-+ command= COM_SHUTDOWN;
-+ }
-+
-+ VOID(pthread_mutex_lock(&LOCK_thread_count));
-+ thd->query_id= global_query_id;
-+
-+ switch( command ) {
-+ /* Ignore these statements. */
-+ case COM_STATISTICS:
-+ case COM_PING:
-+ break;
-+ /* Only increase id on these statements but don't count them. */
-+ case COM_STMT_PREPARE:
-+ case COM_STMT_CLOSE:
-+ case COM_STMT_RESET:
-+ next_query_id();
-+ break;
-+ /* Increase id and count all other statements. */
-+ default:
-+ statistic_increment(thd->status_var.questions, &LOCK_status);
-+ next_query_id();
-+ }
-+
-+ thread_running++;
-+ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+
-+ /**
-+ Clear the set of flags that are expected to be cleared at the
-+ beginning of each command.
-+ */
-+ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
-+ switch (command) {
-+ case COM_INIT_DB:
-+ {
-+ LEX_STRING tmp;
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_CHANGE_DB]);
-+ thd->convert_string(&tmp, system_charset_info,
-+ packet, packet_length, thd->charset());
-+ if (!mysql_change_db(thd, &tmp, FALSE))
-+ {
-+ general_log_write(thd, command, thd->db, thd->db_length);
-+ my_ok(thd);
-+ }
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ case COM_REGISTER_SLAVE:
-+ {
-+ if (!register_slave(thd, (uchar*)packet, packet_length))
-+ my_ok(thd);
-+ break;
-+ }
-+#endif
-+ case COM_TABLE_DUMP:
-+ {
-+ LEX_STRING db, table;
-+ /* Safe because there is always a trailing \0 at the end of the packet */
-+ uint db_len= *(uchar*) packet;
-+ if (db_len + 1 > packet_length || db_len > NAME_LEN)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+ /* Safe because there is always a trailing \0 at the end of the packet */
-+ uint tbl_len= *(uchar*) (packet + db_len + 1);
-+ if (db_len + tbl_len + 2 > packet_length || tbl_len > NAME_LEN)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+
-+ status_var_increment(thd->status_var.com_other);
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ db.str= (char*) thd->alloc(db_len + tbl_len + 2);
-+ if (!db.str)
-+ {
-+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
-+ break;
-+ }
-+ db.length= db_len;
-+ table.length= tbl_len;
-+ table.str= strmake(db.str, packet + 1, db_len) + 1;
-+ strmake(table.str, packet + db_len + 2, tbl_len);
-+ if (mysql_table_dump(thd, &db, &table) == 0)
-+ thd->main_da.disable_status();
-+ break;
-+ }
-+ case COM_CHANGE_USER:
-+ {
-+ status_var_increment(thd->status_var.com_other);
-+ char *user= (char*) packet, *packet_end= packet + packet_length;
-+ /* Safe because there is always a trailing \0 at the end of the packet */
-+ char *passwd= strend(user)+1;
-+
-+ thd->change_user();
-+ thd->clear_error(); // if errors from rollback
-+
-+ /*
-+ Old clients send null-terminated string ('\0' for empty string) for
-+ password. New clients send the size (1 byte) + string (not null
-+ terminated, so also '\0' for empty string).
-+
-+ Cast *passwd to an unsigned char, so that it doesn't extend the sign
-+ for *passwd > 127 and become 2**32-127 after casting to uint.
-+ */
-+ char db_buff[NAME_LEN+1]; // buffer to store db in utf8
-+ char *db= passwd;
-+ char *save_db;
-+ /*
-+ If there is no password supplied, the packet must contain '\0',
-+ in any type of handshake (4.1 or pre-4.1).
-+ */
-+ if (passwd >= packet_end)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+ uint passwd_len= (thd->client_capabilities & CLIENT_SECURE_CONNECTION ?
-+ (uchar)(*passwd++) : strlen(passwd));
-+ uint dummy_errors, save_db_length, db_length;
-+ int res;
-+ Security_context save_security_ctx= *thd->security_ctx;
-+ USER_CONN *save_user_connect;
-+
-+ db+= passwd_len + 1;
-+ /*
-+ Database name is always NUL-terminated, so in case of empty database
-+ the packet must contain at least the trailing '\0'.
-+ */
-+ if (db >= packet_end)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+ db_length= strlen(db);
-+
-+ char *ptr= db + db_length + 1;
-+ uint cs_number= 0;
-+
-+ if (ptr < packet_end)
-+ {
-+ CHARSET_INFO *cs;
-+ if (ptr + 2 > packet_end)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+
-+ if ((cs_number= uint2korr(ptr)) &&
-+ (cs= get_charset(cs_number, MYF(0))) &&
-+ !is_supported_parser_charset(cs))
-+ {
-+ /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */
-+ my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client",
-+ cs->csname);
-+ break;
-+ }
-+ }
-+
-+ /* Convert database name to utf8 */
-+ db_buff[copy_and_convert(db_buff, sizeof(db_buff)-1,
-+ system_charset_info, db, db_length,
-+ thd->charset(), &dummy_errors)]= 0;
-+ db= db_buff;
-+
-+ /* Save user and privileges */
-+ save_db_length= thd->db_length;
-+ save_db= thd->db;
-+ save_user_connect= thd->user_connect;
-+
-+ if (!(thd->security_ctx->user= my_strdup(user, MYF(0))))
-+ {
-+ thd->security_ctx->user= save_security_ctx.user;
-+ my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0));
-+ break;
-+ }
-+
-+ /* Clear variables that are allocated */
-+ thd->user_connect= 0;
-+ thd->security_ctx->priv_user= thd->security_ctx->user;
-+ res= check_user(thd, COM_CHANGE_USER, passwd, passwd_len, db, FALSE);
-+
-+ if (res)
-+ {
-+ x_free(thd->security_ctx->user);
-+ *thd->security_ctx= save_security_ctx;
-+ thd->user_connect= save_user_connect;
-+ thd->db= save_db;
-+ thd->db_length= save_db_length;
-+ }
-+ else
-+ {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ /* we've authenticated new user */
-+ if (save_user_connect)
-+ decrease_user_connections(save_user_connect);
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+ x_free(save_db);
-+ x_free(save_security_ctx.user);
-+
-+ if (cs_number)
-+ {
-+ /*
-+ We have checked charset earlier,
-+ so thd_init_client_charset cannot fail.
-+ */
-+ if (thd_init_client_charset(thd, cs_number))
-+ DBUG_ASSERT(0);
-+ thd->update_charset();
-+ }
-+ }
-+ break;
-+ }
-+ case COM_STMT_EXECUTE:
-+ {
-+ mysqld_stmt_execute(thd, packet, packet_length);
-+ break;
-+ }
-+ case COM_STMT_FETCH:
-+ {
-+ mysqld_stmt_fetch(thd, packet, packet_length);
-+ break;
-+ }
-+ case COM_STMT_SEND_LONG_DATA:
-+ {
-+ mysql_stmt_get_longdata(thd, packet, packet_length);
-+ break;
-+ }
-+ case COM_STMT_PREPARE:
-+ {
-+ mysqld_stmt_prepare(thd, packet, packet_length);
-+ break;
-+ }
-+ case COM_STMT_CLOSE:
-+ {
-+ mysqld_stmt_close(thd, packet);
-+ break;
-+ }
-+ case COM_STMT_RESET:
-+ {
-+ mysqld_stmt_reset(thd, packet);
-+ break;
-+ }
-+ case COM_QUERY:
-+ {
-+ if (alloc_query(thd, packet, packet_length))
-+ break; // fatal error is set
-+ char *packet_end= thd->query() + thd->query_length();
-+ /* 'b' stands for 'buffer' parameter', special for 'my_snprintf' */
-+ const char* end_of_stmt= NULL;
-+
-+ general_log_write(thd, command, thd->query(), thd->query_length());
-+ DBUG_PRINT("query",("%-.4096s",thd->query()));
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.set_query_source(thd->query(), thd->query_length());
-+#endif
-+
-+ if (!(specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_setprio(pthread_self(),QUERY_PRIOR);
-+
-+ mysql_parse(thd, thd->query(), thd->query_length(), &end_of_stmt);
-+
-+ while (!thd->killed && (end_of_stmt != NULL) && ! thd->is_error())
-+ {
-+ char *beginning_of_next_stmt= (char*) end_of_stmt;
-+
-+ net_end_statement(thd);
-+ query_cache_end_of_result(thd);
-+ /*
-+ Multiple queries exits, execute them individually
-+ */
-+ close_thread_tables(thd);
-+ ulong length= (ulong)(packet_end - beginning_of_next_stmt);
-+
-+ log_slow_statement(thd);
-+
-+ /* Remove garbage at start of query */
-+ while (length > 0 && my_isspace(thd->charset(), *beginning_of_next_stmt))
-+ {
-+ beginning_of_next_stmt++;
-+ length--;
-+ }
-+
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.finish_current_query();
-+ thd->profiling.start_new_query("continuing");
-+ thd->profiling.set_query_source(beginning_of_next_stmt, length);
-+#endif
-+
-+ thd->set_query(beginning_of_next_stmt, length);
-+ VOID(pthread_mutex_lock(&LOCK_thread_count));
-+ /*
-+ Count each statement from the client.
-+ */
-+ statistic_increment(thd->status_var.questions, &LOCK_status);
-+ thd->query_id= next_query_id();
-+ thd->set_time(); /* Reset the query start time. */
-+ /* TODO: set thd->lex->sql_command to SQLCOM_END here */
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt);
-+ }
-+
-+ if (!(specialflag & SPECIAL_NO_PRIOR))
-+ my_pthread_setprio(pthread_self(),WAIT_PRIOR);
-+ DBUG_PRINT("info",("query ready"));
-+ break;
-+ }
-+ case COM_FIELD_LIST: // This isn't actually needed
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+ MYF(0)); /* purecov: inspected */
-+ break;
-+#else
-+ {
-+ char *fields, *packet_end= packet + packet_length, *arg_end;
-+ /* Locked closure of all tables */
-+ TABLE_LIST table_list;
-+ LEX_STRING conv_name;
-+
-+ /* used as fields initializator */
-+ lex_start(thd);
-+
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_FIELDS]);
-+ bzero((char*) &table_list,sizeof(table_list));
-+ if (thd->copy_db_to(&table_list.db, &table_list.db_length))
-+ break;
-+ /*
-+ We have name + wildcard in packet, separated by endzero
-+ */
-+ arg_end= strend(packet);
-+ uint arg_length= arg_end - packet;
-+
-+ /* Check given table name length. */
-+ if (arg_length >= packet_length || arg_length > NAME_LEN)
-+ {
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+ thd->convert_string(&conv_name, system_charset_info,
-+ packet, arg_length, thd->charset());
-+ if (check_table_name(conv_name.str, conv_name.length, FALSE))
-+ {
-+ /* this is OK due to convert_string() null-terminating the string */
-+ my_error(ER_WRONG_TABLE_NAME, MYF(0), conv_name.str);
-+ break;
-+ }
-+
-+ table_list.alias= table_list.table_name= conv_name.str;
-+ packet= arg_end + 1;
-+
-+ if (is_schema_db(table_list.db, table_list.db_length))
-+ {
-+ ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, table_list.alias);
-+ if (schema_table)
-+ table_list.schema_table= schema_table;
-+ }
-+
-+ uint query_length= (uint) (packet_end - packet); // Don't count end \0
-+ if (!(fields= (char *) thd->memdup(packet, query_length + 1)))
-+ break;
-+ thd->set_query(fields, query_length);
-+ general_log_print(thd, command, "%s %s", table_list.table_name, fields);
-+ if (lower_case_table_names)
-+ my_casedn_str(files_charset_info, table_list.table_name);
-+
-+ if (check_access(thd,SELECT_ACL,table_list.db,&table_list.grant.privilege,
-+ 0, 0, test(table_list.schema_table)))
-+ break;
-+ if (check_grant(thd, SELECT_ACL, &table_list, 2, UINT_MAX, 0))
-+ break;
-+ /* init structures for VIEW processing */
-+ table_list.select_lex= &(thd->lex->select_lex);
-+
-+ lex_start(thd);
-+ mysql_reset_thd_for_next_command(thd);
-+
-+ thd->lex->
-+ select_lex.table_list.link_in_list(&table_list,
-+ &table_list.next_local);
-+ thd->lex->add_to_query_tables(&table_list);
-+
-+ /* switch on VIEW optimisation: do not fill temporary tables */
-+ thd->lex->sql_command= SQLCOM_SHOW_FIELDS;
-+ mysqld_list_fields(thd,&table_list,fields);
-+ thd->lex->unit.cleanup();
-+ thd->cleanup_after_query();
-+ break;
-+ }
-+#endif
-+ case COM_QUIT:
-+ /* We don't calculate statistics for this command */
-+ general_log_print(thd, command, NullS);
-+ net->error=0; // Don't give 'abort' message
-+ thd->main_da.disable_status(); // Don't send anything back
-+ error=TRUE; // End server
-+ break;
-+
-+#ifdef REMOVED
-+ case COM_CREATE_DB: // QQ: To be removed
-+ {
-+ LEX_STRING db, alias;
-+ HA_CREATE_INFO create_info;
-+
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_CREATE_DB]);
-+ if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
-+ thd->make_lex_string(&alias, db.str, db.length, FALSE) ||
-+ check_db_name(&db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
-+ break;
-+ }
-+ if (check_access(thd, CREATE_ACL, db.str , 0, 1, 0,
-+ is_schema_db(db.str, db.length)))
-+ break;
-+ general_log_print(thd, command, "%.*s", db.length, db.str);
-+ bzero(&create_info, sizeof(create_info));
-+ mysql_create_db(thd, (lower_case_table_names == 2 ? alias.str : db.str),
-+ &create_info, 0);
-+ break;
-+ }
-+ case COM_DROP_DB: // QQ: To be removed
-+ {
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_DROP_DB]);
-+ LEX_STRING db;
-+
-+ if (thd->make_lex_string(&db, packet, packet_length, FALSE) ||
-+ check_db_name(&db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str ? db.str : "NULL");
-+ break;
-+ }
-+ if (check_access(thd, DROP_ACL, db.str, 0, 1, 0,
-+ is_schema_db(db.str, db.length)))
-+ break;
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ break;
-+ }
-+ general_log_write(thd, command, "%.*s", db.length, db.str);
-+ mysql_rm_db(thd, db.str, 0, 0);
-+ break;
-+ }
-+#endif
-+#ifndef EMBEDDED_LIBRARY
-+ case COM_BINLOG_DUMP:
-+ {
-+ ulong pos;
-+ ushort flags;
-+ uint32 slave_server_id;
-+
-+ status_var_increment(thd->status_var.com_other);
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ if (check_global_access(thd, REPL_SLAVE_ACL))
-+ break;
-+
-+ /* TODO: The following has to be changed to an 8 byte integer */
-+ pos = uint4korr(packet);
-+ flags = uint2korr(packet + 4);
-+ thd->server_id=0; /* avoid suicide */
-+ if ((slave_server_id= uint4korr(packet+6))) // mysqlbinlog.server_id==0
-+ kill_zombie_dump_threads(slave_server_id);
-+ thd->server_id = slave_server_id;
-+
-+ general_log_print(thd, command, "Log: '%s' Pos: %ld", packet+10,
-+ (long) pos);
-+ mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, flags);
-+ unregister_slave(thd,1,1);
-+ /* fake COM_QUIT -- if we get here, the thread needs to terminate */
-+ error = TRUE;
-+ break;
-+ }
-+#endif
-+ case COM_REFRESH:
-+ {
-+ int not_used;
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_FLUSH]);
-+ ulong options= (ulong) (uchar) packet[0];
-+ if (check_global_access(thd,RELOAD_ACL))
-+ break;
-+ general_log_print(thd, command, NullS);
-+#ifndef DBUG_OFF
-+ bool debug_simulate= FALSE;
-+ DBUG_EXECUTE_IF("simulate_detached_thread_refresh", debug_simulate= TRUE;);
-+ if (debug_simulate)
-+ {
-+ /*
-+ Simulate a reload without a attached thread session.
-+ Provides a environment similar to that of when the
-+ server receives a SIGHUP signal and reloads caches
-+ and flushes tables.
-+ */
-+ bool res;
-+ my_pthread_setspecific_ptr(THR_THD, NULL);
-+ res= reload_acl_and_cache(NULL, options | REFRESH_FAST,
-+ NULL, ¬_used);
-+ my_pthread_setspecific_ptr(THR_THD, thd);
-+ if (!res)
-+ my_ok(thd);
-+ break;
-+ }
-+#endif
-+ if (!reload_acl_and_cache(thd, options, NULL, ¬_used))
-+ my_ok(thd);
-+ break;
-+ }
-+#ifndef EMBEDDED_LIBRARY
-+ case COM_SHUTDOWN:
-+ {
-+ status_var_increment(thd->status_var.com_other);
-+ if (check_global_access(thd,SHUTDOWN_ACL))
-+ break; /* purecov: inspected */
-+ /*
-+ If the client is < 4.1.3, it is going to send us no argument; then
-+ packet_length is 0, packet[0] is the end 0 of the packet. Note that
-+ SHUTDOWN_DEFAULT is 0. If client is >= 4.1.3, the shutdown level is in
-+ packet[0].
-+ */
-+ enum mysql_enum_shutdown_level level;
-+ if (!thd->is_valid_time())
-+ level= SHUTDOWN_DEFAULT;
-+ else
-+ level= (enum mysql_enum_shutdown_level) (uchar) packet[0];
-+ if (level == SHUTDOWN_DEFAULT)
-+ level= SHUTDOWN_WAIT_ALL_BUFFERS; // soon default will be configurable
-+ else if (level != SHUTDOWN_WAIT_ALL_BUFFERS)
-+ {
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "this shutdown level");
-+ break;
-+ }
-+ DBUG_PRINT("quit",("Got shutdown command for level %u", level));
-+ general_log_print(thd, command, NullS);
-+ my_eof(thd);
-+ close_thread_tables(thd); // Free before kill
-+ kill_mysql();
-+ error=TRUE;
-+ break;
-+ }
-+#endif
-+ case COM_STATISTICS:
-+ {
-+ STATUS_VAR current_global_status_var;
-+ ulong uptime;
-+ uint length __attribute__((unused));
-+ ulonglong queries_per_second1000;
-+ char buff[250];
-+ uint buff_len= sizeof(buff);
-+
-+ general_log_print(thd, command, NullS);
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_STATUS]);
-+ calc_sum_of_all_status(¤t_global_status_var);
-+ if (!(uptime= (ulong) (thd->start_time - server_start_time)))
-+ queries_per_second1000= 0;
-+ else
-+ queries_per_second1000= thd->query_id * LL(1000) / uptime;
-+
-+ length= my_snprintf(buff, buff_len - 1,
-+ "Uptime: %lu Threads: %d Questions: %lu "
-+ "Slow queries: %lu Opens: %lu Flush tables: %lu "
-+ "Open tables: %u Queries per second avg: %u.%u",
-+ uptime,
-+ (int) thread_count, (ulong) thd->query_id,
-+ current_global_status_var.long_query_count,
-+ current_global_status_var.opened_tables,
-+ refresh_version,
-+ cached_open_tables(),
-+ (uint) (queries_per_second1000 / 1000),
-+ (uint) (queries_per_second1000 % 1000));
-+#ifdef SAFEMALLOC
-+ if (sf_malloc_cur_memory) // Using SAFEMALLOC
-+ {
-+ char *end= buff + length;
-+ length+= my_snprintf(end, buff_len - length - 1,
-+ end," Memory in use: %ldK Max memory used: %ldK",
-+ (sf_malloc_cur_memory+1023L)/1024L,
-+ (sf_malloc_max_memory+1023L)/1024L);
-+ }
-+#endif
-+#ifndef EMBEDDED_LIBRARY
-+ VOID(my_net_write(net, (uchar*) buff, length));
-+ VOID(net_flush(net));
-+ thd->main_da.disable_status();
-+#else
-+ /* Store the buffer in permanent memory */
-+ my_ok(thd, 0, 0, buff);
-+#endif
-+ break;
-+ }
-+ case COM_PING:
-+ status_var_increment(thd->status_var.com_other);
-+ my_ok(thd); // Tell client we are alive
-+ break;
-+ case COM_PROCESS_INFO:
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_SHOW_PROCESSLIST]);
-+ if (!thd->security_ctx->priv_user[0] &&
-+ check_global_access(thd, PROCESS_ACL))
-+ break;
-+ general_log_print(thd, command, NullS);
-+ mysqld_list_processes(thd,
-+ thd->security_ctx->master_access & PROCESS_ACL ?
-+ NullS : thd->security_ctx->priv_user, 0);
-+ break;
-+ case COM_PROCESS_KILL:
-+ {
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_KILL]);
-+ ulong id=(ulong) uint4korr(packet);
-+ sql_kill(thd,id,false);
-+ break;
-+ }
-+ case COM_SET_OPTION:
-+ {
-+ status_var_increment(thd->status_var.com_stat[SQLCOM_SET_OPTION]);
-+ uint opt_command= uint2korr(packet);
-+
-+ switch (opt_command) {
-+ case (int) MYSQL_OPTION_MULTI_STATEMENTS_ON:
-+ thd->client_capabilities|= CLIENT_MULTI_STATEMENTS;
-+ my_eof(thd);
-+ break;
-+ case (int) MYSQL_OPTION_MULTI_STATEMENTS_OFF:
-+ thd->client_capabilities&= ~CLIENT_MULTI_STATEMENTS;
-+ my_eof(thd);
-+ break;
-+ default:
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+ break;
-+ }
-+ case COM_DEBUG:
-+ status_var_increment(thd->status_var.com_other);
-+ if (check_global_access(thd, SUPER_ACL))
-+ break; /* purecov: inspected */
-+ mysql_print_status();
-+ general_log_print(thd, command, NullS);
-+ my_eof(thd);
-+ break;
-+ case COM_SLEEP:
-+ case COM_CONNECT: // Impossible here
-+ case COM_TIME: // Impossible from client
-+ case COM_DELAYED_INSERT:
-+ case COM_END:
-+ default:
-+ my_message(ER_UNKNOWN_COM_ERROR, ER(ER_UNKNOWN_COM_ERROR), MYF(0));
-+ break;
-+ }
-+
-+ /* report error issued during command execution */
-+ if (thd->killed_errno())
-+ {
-+ if (! thd->main_da.is_set())
-+ thd->send_kill_message();
-+ }
-+ if (thd->killed == THD::KILL_QUERY || thd->killed == THD::KILL_BAD_DATA)
-+ {
-+ thd->killed= THD::NOT_KILLED;
-+ thd->mysys_var->abort= 0;
-+ }
-+
-+ /* If commit fails, we should be able to reset the OK status. */
-+ thd->main_da.can_overwrite_status= TRUE;
-+ ha_autocommit_or_rollback(thd, thd->is_error());
-+ thd->main_da.can_overwrite_status= FALSE;
-+
-+ thd->transaction.stmt.reset();
-+
-+ net_end_statement(thd);
-+ query_cache_end_of_result(thd);
-+
-+ thd->proc_info= "closing tables";
-+ /* Free tables */
-+ close_thread_tables(thd);
-+
-+ log_slow_statement(thd);
-+
-+ thd_proc_info(thd, "cleaning up");
-+ thd->set_query(NULL, 0);
-+ thd->command=COM_SLEEP;
-+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
-+ thread_running--;
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ thd_proc_info(thd, 0);
-+ thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory
-+ free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
-+ DBUG_RETURN(error);
-+}
-+
-+
-+void log_slow_statement(THD *thd)
-+{
-+ DBUG_ENTER("log_slow_statement");
-+
-+ /*
-+ The following should never be true with our current code base,
-+ but better to keep this here so we don't accidently try to log a
-+ statement in a trigger or stored function
-+ */
-+ if (unlikely(thd->in_sub_stmt))
-+ DBUG_VOID_RETURN; // Don't set time for sub stmt
-+
-+ /*
-+ Do not log administrative statements unless the appropriate option is
-+ set.
-+ */
-+ if (thd->enable_slow_log)
-+ {
-+ ulonglong end_utime_of_query= thd->current_utime();
-+ thd_proc_info(thd, "logging slow query");
-+
-+ if (((end_utime_of_query - thd->utime_after_lock) >
-+ thd->variables.long_query_time ||
-+ ((thd->server_status &
-+ (SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED)) &&
-+ opt_log_queries_not_using_indexes &&
-+ !(sql_command_flags[thd->lex->sql_command] & CF_STATUS_COMMAND))) &&
-+ thd->examined_row_count >= thd->variables.min_examined_row_limit)
-+ {
-+ thd_proc_info(thd, "logging slow query");
-+ thd->status_var.long_query_count++;
-+ slow_log_print(thd, thd->query(), thd->query_length(),
-+ end_utime_of_query);
-+ }
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Create a TABLE_LIST object for an INFORMATION_SCHEMA table.
-+
-+ This function is used in the parser to convert a SHOW or DESCRIBE
-+ table_name command to a SELECT from INFORMATION_SCHEMA.
-+ It prepares a SELECT_LEX and a TABLE_LIST object to represent the
-+ given command as a SELECT parse tree.
-+
-+ @param thd thread handle
-+ @param lex current lex
-+ @param table_ident table alias if it's used
-+ @param schema_table_idx the type of the INFORMATION_SCHEMA table to be
-+ created
-+
-+ @note
-+ Due to the way this function works with memory and LEX it cannot
-+ be used outside the parser (parse tree transformations outside
-+ the parser break PS and SP).
-+
-+ @retval
-+ 0 success
-+ @retval
-+ 1 out of memory or SHOW commands are not allowed
-+ in this version of the server.
-+*/
-+
-+int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
-+ enum enum_schema_tables schema_table_idx)
-+{
-+ SELECT_LEX *schema_select_lex= NULL;
-+ DBUG_ENTER("prepare_schema_table");
-+
-+ switch (schema_table_idx) {
-+ case SCH_SCHEMATA:
-+#if defined(DONT_ALLOW_SHOW_COMMANDS)
-+ my_message(ER_NOT_ALLOWED_COMMAND,
-+ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(1);
-+#else
-+ break;
-+#endif
-+
-+ case SCH_TABLE_NAMES:
-+ case SCH_TABLES:
-+ case SCH_VIEWS:
-+ case SCH_TRIGGERS:
-+ case SCH_EVENTS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND,
-+ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(1);
-+#else
-+ {
-+ LEX_STRING db;
-+ size_t dummy;
-+ if (lex->select_lex.db == NULL &&
-+ lex->copy_db_to(&lex->select_lex.db, &dummy))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ schema_select_lex= new SELECT_LEX();
-+ db.str= schema_select_lex->db= lex->select_lex.db;
-+ schema_select_lex->table_list.first= NULL;
-+ db.length= strlen(db.str);
-+
-+ if (check_db_name(&db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), db.str);
-+ DBUG_RETURN(1);
-+ }
-+ break;
-+ }
-+#endif
-+ case SCH_COLUMNS:
-+ case SCH_STATISTICS:
-+ {
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND,
-+ ER(ER_NOT_ALLOWED_COMMAND), MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(1);
-+#else
-+ DBUG_ASSERT(table_ident);
-+ TABLE_LIST **query_tables_last= lex->query_tables_last;
-+ schema_select_lex= new SELECT_LEX();
-+ /* 'parent_lex' is used in init_query() so it must be before it. */
-+ schema_select_lex->parent_lex= lex;
-+ schema_select_lex->init_query();
-+ if (!schema_select_lex->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
-+ DBUG_RETURN(1);
-+ lex->query_tables_last= query_tables_last;
-+ break;
-+ }
-+#endif
-+ case SCH_PROFILES:
-+ /*
-+ Mark this current profiling record to be discarded. We don't
-+ wish to have SHOW commands show up in profiling.
-+ */
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.discard_current_query();
-+#endif
-+ break;
-+ case SCH_OPEN_TABLES:
-+ case SCH_VARIABLES:
-+ case SCH_STATUS:
-+ case SCH_PROCEDURES:
-+ case SCH_CHARSETS:
-+ case SCH_ENGINES:
-+ case SCH_COLLATIONS:
-+ case SCH_COLLATION_CHARACTER_SET_APPLICABILITY:
-+ case SCH_USER_PRIVILEGES:
-+ case SCH_SCHEMA_PRIVILEGES:
-+ case SCH_TABLE_PRIVILEGES:
-+ case SCH_COLUMN_PRIVILEGES:
-+ case SCH_TABLE_CONSTRAINTS:
-+ case SCH_KEY_COLUMN_USAGE:
-+ default:
-+ break;
-+ }
-+
-+ SELECT_LEX *select_lex= lex->current_select;
-+ if (make_schema_select(thd, select_lex, schema_table_idx))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ TABLE_LIST *table_list= select_lex->table_list.first;
-+ table_list->schema_select_lex= schema_select_lex;
-+ table_list->schema_table_reformed= 1;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ Read query from packet and store in thd->query.
-+ Used in COM_QUERY and COM_STMT_PREPARE.
-+
-+ Sets the following THD variables:
-+ - query
-+ - query_length
-+
-+ @retval
-+ FALSE ok
-+ @retval
-+ TRUE error; In this case thd->fatal_error is set
-+*/
-+
-+bool alloc_query(THD *thd, const char *packet, uint packet_length)
-+{
-+ char *query;
-+ /* Remove garbage at start and end of query */
-+ while (packet_length > 0 && my_isspace(thd->charset(), packet[0]))
-+ {
-+ packet++;
-+ packet_length--;
-+ }
-+ const char *pos= packet + packet_length; // Point at end null
-+ while (packet_length > 0 &&
-+ (pos[-1] == ';' || my_isspace(thd->charset() ,pos[-1])))
-+ {
-+ pos--;
-+ packet_length--;
-+ }
-+ /* We must allocate some extra memory for query cache */
-+ if (! (query= (char*) thd->memdup_w_gap(packet,
-+ packet_length,
-+ 1 + thd->db_length +
-+ QUERY_CACHE_FLAGS_SIZE)))
-+ return TRUE;
-+ query[packet_length]= '\0';
-+ thd->set_query(query, packet_length);
-+
-+ /* Reclaim some memory */
-+ thd->packet.shrink(thd->variables.net_buffer_length);
-+ thd->convert_buffer.shrink(thd->variables.net_buffer_length);
-+
-+ return FALSE;
-+}
-+
-+static void reset_one_shot_variables(THD *thd)
-+{
-+ thd->variables.character_set_client=
-+ global_system_variables.character_set_client;
-+ thd->variables.collation_connection=
-+ global_system_variables.collation_connection;
-+ thd->variables.collation_database=
-+ global_system_variables.collation_database;
-+ thd->variables.collation_server=
-+ global_system_variables.collation_server;
-+ thd->update_charset();
-+ thd->variables.time_zone=
-+ global_system_variables.time_zone;
-+ thd->variables.lc_time_names= &my_locale_en_US;
-+ thd->one_shot_set= 0;
-+}
-+
-+
-+static
-+bool sp_process_definer(THD *thd)
-+{
-+ DBUG_ENTER("sp_process_definer");
-+
-+ LEX *lex= thd->lex;
-+
-+ /*
-+ If the definer is not specified, this means that CREATE-statement missed
-+ DEFINER-clause. DEFINER-clause can be missed in two cases:
-+
-+ - The user submitted a statement w/o the clause. This is a normal
-+ case, we should assign CURRENT_USER as definer.
-+
-+ - Our slave received an updated from the master, that does not
-+ replicate definer for stored rountines. We should also assign
-+ CURRENT_USER as definer here, but also we should mark this routine
-+ as NON-SUID. This is essential for the sake of backward
-+ compatibility.
-+
-+ The problem is the slave thread is running under "special" user (@),
-+ that actually does not exist. In the older versions we do not fail
-+ execution of a stored routine if its definer does not exist and
-+ continue the execution under the authorization of the invoker
-+ (BUG#13198). And now if we try to switch to slave-current-user (@),
-+ we will fail.
-+
-+ Actually, this leads to the inconsistent state of master and
-+ slave (different definers, different SUID behaviour), but it seems,
-+ this is the best we can do.
-+ */
-+
-+ if (!lex->definer)
-+ {
-+ Query_arena original_arena;
-+ Query_arena *ps_arena= thd->activate_stmt_arena_if_needed(&original_arena);
-+
-+ lex->definer= create_default_definer(thd);
-+
-+ if (ps_arena)
-+ thd->restore_active_arena(ps_arena, &original_arena);
-+
-+ /* Error has been already reported. */
-+ if (lex->definer == NULL)
-+ DBUG_RETURN(TRUE);
-+
-+ if (thd->slave_thread && lex->sphead)
-+ lex->sphead->m_chistics->suid= SP_IS_NOT_SUID;
-+ }
-+ else
-+ {
-+ /*
-+ If the specified definer differs from the current user, we
-+ should check that the current user has SUPER privilege (in order
-+ to create a stored routine under another user one must have
-+ SUPER privilege).
-+ */
-+ if ((strcmp(lex->definer->user.str, thd->security_ctx->priv_user) ||
-+ my_strcasecmp(system_charset_info, lex->definer->host.str,
-+ thd->security_ctx->priv_host)) &&
-+ check_global_access(thd, SUPER_ACL))
-+ {
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "SUPER");
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+
-+ /* Check that the specified definer exists. Emit a warning if not. */
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (!is_acl_user(lex->definer->host.str, lex->definer->user.str))
-+ {
-+ push_warning_printf(thd,
-+ MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_NO_SUCH_USER,
-+ ER(ER_NO_SUCH_USER),
-+ lex->definer->user.str,
-+ lex->definer->host.str);
-+ }
-+#endif /* NO_EMBEDDED_ACCESS_CHECKS */
-+
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Execute command saved in thd and lex->sql_command.
-+
-+ Before every operation that can request a write lock for a table
-+ wait if a global read lock exists. However do not wait if this
-+ thread has locked tables already. No new locks can be requested
-+ until the other locks are released. The thread that requests the
-+ global read lock waits for write locked tables to become unlocked.
-+
-+ Note that wait_if_global_read_lock() sets a protection against a new
-+ global read lock when it succeeds. This needs to be released by
-+ start_waiting_global_read_lock() after the operation.
-+
-+ @param thd Thread handle
-+
-+ @todo
-+ - Invalidate the table in the query cache if something changed
-+ after unlocking when changes become visible.
-+ TODO: this is workaround. right way will be move invalidating in
-+ the unlock procedure.
-+ - TODO: use check_change_password()
-+ - JOIN is not supported yet. TODO
-+ - SUSPEND and FOR MIGRATE are not supported yet. TODO
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE Error
-+*/
-+
-+int
-+mysql_execute_command(THD *thd)
-+{
-+ int res= FALSE;
-+ bool need_start_waiting= FALSE; // have protection against global read lock
-+ int up_result= 0;
-+ LEX *lex= thd->lex;
-+ /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */
-+ SELECT_LEX *select_lex= &lex->select_lex;
-+ /* first table of first SELECT_LEX */
-+ TABLE_LIST *first_table= select_lex->table_list.first;
-+ /* list of all tables in query */
-+ TABLE_LIST *all_tables;
-+ /* most outer SELECT_LEX_UNIT of query */
-+ SELECT_LEX_UNIT *unit= &lex->unit;
-+#ifdef HAVE_REPLICATION
-+ /* have table map for update for multi-update statement (BUG#37051) */
-+ bool have_table_map_for_update= FALSE;
-+#endif
-+ /* Saved variable value */
-+ DBUG_ENTER("mysql_execute_command");
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ thd->work_part_info= 0;
-+#endif
-+
-+ /*
-+ In many cases first table of main SELECT_LEX have special meaning =>
-+ check that it is first table in global list and relink it first in
-+ queries_tables list if it is necessary (we need such relinking only
-+ for queries with subqueries in select list, in this case tables of
-+ subqueries will go to global list first)
-+
-+ all_tables will differ from first_table only if most upper SELECT_LEX
-+ do not contain tables.
-+
-+ Because of above in place where should be at least one table in most
-+ outer SELECT_LEX we have following check:
-+ DBUG_ASSERT(first_table == all_tables);
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ */
-+ lex->first_lists_tables_same();
-+ /* should be assigned after making first tables same */
-+ all_tables= lex->query_tables;
-+ /* set context for commands which do not use setup_tables */
-+ select_lex->
-+ context.resolve_in_table_list_only(select_lex->
-+ table_list.first);
-+
-+ /*
-+ Reset warning count for each query that uses tables
-+ A better approach would be to reset this for any commands
-+ that is not a SHOW command or a select that only access local
-+ variables, but for now this is probably good enough.
-+ Don't reset warnings when executing a stored routine.
-+ */
-+ if ((all_tables || !lex->is_single_level_stmt()) && !thd->spcont)
-+ mysql_reset_errors(thd, 0);
-+
-+#ifdef HAVE_REPLICATION
-+ if (unlikely(thd->slave_thread))
-+ {
-+ if (lex->sql_command == SQLCOM_DROP_TRIGGER)
-+ {
-+ /*
-+ When dropping a trigger, we need to load its table name
-+ before checking slave filter rules.
-+ */
-+ add_table_for_trigger(thd, thd->lex->spname, 1, &all_tables);
-+
-+ if (!all_tables)
-+ {
-+ /*
-+ If table name cannot be loaded,
-+ it means the trigger does not exists possibly because
-+ CREATE TRIGGER was previously skipped for this trigger
-+ according to slave filtering rules.
-+ Returning success without producing any errors in this case.
-+ */
-+ DBUG_RETURN(0);
-+ }
-+
-+ // force searching in slave.cc:tables_ok()
-+ all_tables->updating= 1;
-+ }
-+
-+ /*
-+ For fix of BUG#37051, the master stores the table map for update
-+ in the Query_log_event, and the value is assigned to
-+ thd->variables.table_map_for_update before executing the update
-+ query.
-+
-+ If thd->variables.table_map_for_update is set, then we are
-+ replicating from a new master, we can use this value to apply
-+ filter rules without opening all the tables. However If
-+ thd->variables.table_map_for_update is not set, then we are
-+ replicating from an old master, so we just skip this and
-+ continue with the old method. And of course, the bug would still
-+ exist for old masters.
-+ */
-+ if (lex->sql_command == SQLCOM_UPDATE_MULTI &&
-+ thd->table_map_for_update)
-+ {
-+ have_table_map_for_update= TRUE;
-+ table_map table_map_for_update= thd->table_map_for_update;
-+ uint nr= 0;
-+ TABLE_LIST *table;
-+ for (table=all_tables; table; table=table->next_global, nr++)
-+ {
-+ if (table_map_for_update & ((table_map)1 << nr))
-+ table->updating= TRUE;
-+ else
-+ table->updating= FALSE;
-+ }
-+
-+ if (all_tables_not_ok(thd, all_tables))
-+ {
-+ /* we warn the slave SQL thread */
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ if (thd->one_shot_set)
-+ reset_one_shot_variables(thd);
-+ DBUG_RETURN(0);
-+ }
-+
-+ for (table=all_tables; table; table=table->next_global)
-+ table->updating= TRUE;
-+ }
-+
-+ /*
-+ Check if statment should be skipped because of slave filtering
-+ rules
-+
-+ Exceptions are:
-+ - UPDATE MULTI: For this statement, we want to check the filtering
-+ rules later in the code
-+ - SET: we always execute it (Not that many SET commands exists in
-+ the binary log anyway -- only 4.1 masters write SET statements,
-+ in 5.0 there are no SET statements in the binary log)
-+ - DROP TEMPORARY TABLE IF EXISTS: we always execute it (otherwise we
-+ have stale files on slave caused by exclusion of one tmp table).
-+ */
-+ if (!(lex->sql_command == SQLCOM_UPDATE_MULTI) &&
-+ !(lex->sql_command == SQLCOM_SET_OPTION) &&
-+ !(lex->sql_command == SQLCOM_DROP_TABLE &&
-+ lex->drop_temporary && lex->drop_if_exists) &&
-+ all_tables_not_ok(thd, all_tables))
-+ {
-+ /* we warn the slave SQL thread */
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ if (thd->one_shot_set)
-+ {
-+ /*
-+ It's ok to check thd->one_shot_set here:
-+
-+ The charsets in a MySQL 5.0 slave can change by both a binlogged
-+ SET ONE_SHOT statement and the event-internal charset setting,
-+ and these two ways to change charsets do not seems to work
-+ together.
-+
-+ At least there seems to be problems in the rli cache for
-+ charsets if we are using ONE_SHOT. Note that this is normally no
-+ problem because either the >= 5.0 slave reads a 4.1 binlog (with
-+ ONE_SHOT) *or* or 5.0 binlog (without ONE_SHOT) but never both."
-+ */
-+ reset_one_shot_variables(thd);
-+ }
-+ DBUG_RETURN(0);
-+ }
-+ }
-+ else
-+ {
-+#endif /* HAVE_REPLICATION */
-+ /*
-+ When option readonly is set deny operations which change non-temporary
-+ tables. Except for the replication thread and the 'super' users.
-+ */
-+ if (deny_updates_if_read_only_option(thd, all_tables))
-+ {
-+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-+ DBUG_RETURN(-1);
-+ }
-+#ifdef HAVE_REPLICATION
-+ } /* endif unlikely slave */
-+#endif
-+ status_var_increment(thd->status_var.com_stat[lex->sql_command]);
-+
-+ DBUG_ASSERT(thd->transaction.stmt.modified_non_trans_table == FALSE);
-+
-+ switch (lex->sql_command) {
-+
-+ case SQLCOM_SHOW_EVENTS:
-+#ifndef HAVE_EVENT_SCHEDULER
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "embedded server");
-+ break;
-+#endif
-+ case SQLCOM_SHOW_STATUS_PROC:
-+ case SQLCOM_SHOW_STATUS_FUNC:
-+ if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
-+ res= execute_sqlcom_select(thd, all_tables);
-+ break;
-+ case SQLCOM_SHOW_STATUS:
-+ {
-+ system_status_var old_status_var= thd->status_var;
-+ thd->initial_status_var= &old_status_var;
-+ if (!(res= check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE)))
-+ res= execute_sqlcom_select(thd, all_tables);
-+ /* Don't log SHOW STATUS commands to slow query log */
-+ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED |
-+ SERVER_QUERY_NO_GOOD_INDEX_USED);
-+ /*
-+ restore status variables, as we don't want 'show status' to cause
-+ changes
-+ */
-+ pthread_mutex_lock(&LOCK_status);
-+ add_diff_to_status(&global_status_var, &thd->status_var,
-+ &old_status_var);
-+ thd->status_var= old_status_var;
-+ pthread_mutex_unlock(&LOCK_status);
-+ break;
-+ }
-+ case SQLCOM_SHOW_DATABASES:
-+ case SQLCOM_SHOW_TABLES:
-+ case SQLCOM_SHOW_TRIGGERS:
-+ case SQLCOM_SHOW_TABLE_STATUS:
-+ case SQLCOM_SHOW_OPEN_TABLES:
-+ case SQLCOM_SHOW_PLUGINS:
-+ case SQLCOM_SHOW_FIELDS:
-+ case SQLCOM_SHOW_KEYS:
-+ case SQLCOM_SHOW_VARIABLES:
-+ case SQLCOM_SHOW_CHARSETS:
-+ case SQLCOM_SHOW_COLLATIONS:
-+ case SQLCOM_SHOW_STORAGE_ENGINES:
-+ case SQLCOM_SHOW_PROFILE:
-+ case SQLCOM_SELECT:
-+ thd->status_var.last_query_cost= 0.0;
-+ if (all_tables)
-+ {
-+ res= check_table_access(thd,
-+ lex->exchange ? SELECT_ACL | FILE_ACL :
-+ SELECT_ACL,
-+ all_tables, UINT_MAX, FALSE);
-+ }
-+ else
-+ res= check_access(thd,
-+ lex->exchange ? SELECT_ACL | FILE_ACL : SELECT_ACL,
-+ any_db, 0, 0, 0, 0);
-+
-+ if (res)
-+ break;
-+
-+ if (!thd->locked_tables && lex->protect_against_global_read_lock &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ break;
-+
-+ res= execute_sqlcom_select(thd, all_tables);
-+ break;
-+ case SQLCOM_PREPARE:
-+ {
-+ mysql_sql_stmt_prepare(thd);
-+ break;
-+ }
-+ case SQLCOM_EXECUTE:
-+ {
-+ mysql_sql_stmt_execute(thd);
-+ break;
-+ }
-+ case SQLCOM_DEALLOCATE_PREPARE:
-+ {
-+ mysql_sql_stmt_close(thd);
-+ break;
-+ }
-+ case SQLCOM_DO:
-+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
-+ open_and_lock_tables(thd, all_tables))
-+ goto error;
-+
-+ res= mysql_do(thd, *lex->insert_list);
-+ break;
-+
-+ case SQLCOM_EMPTY_QUERY:
-+ my_ok(thd);
-+ break;
-+
-+ case SQLCOM_HELP:
-+ res= mysqld_help(thd,lex->help_arg);
-+ break;
-+
-+#ifndef EMBEDDED_LIBRARY
-+ case SQLCOM_PURGE:
-+ {
-+ if (check_global_access(thd, SUPER_ACL))
-+ goto error;
-+ /* PURGE MASTER LOGS TO 'file' */
-+ res = purge_master_logs(thd, lex->to_log);
-+ break;
-+ }
-+ case SQLCOM_PURGE_BEFORE:
-+ {
-+ Item *it;
-+
-+ if (check_global_access(thd, SUPER_ACL))
-+ goto error;
-+ /* PURGE MASTER LOGS BEFORE 'data' */
-+ it= (Item *)lex->value_list.head();
-+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
-+ it->check_cols(1))
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
-+ goto error;
-+ }
-+ it= new Item_func_unix_timestamp(it);
-+ /*
-+ it is OK only emulate fix_fieds, because we need only
-+ value of constant
-+ */
-+ it->quick_fix_field();
-+ res = purge_master_logs_before_date(thd, (ulong)it->val_int());
-+ break;
-+ }
-+#endif
-+ case SQLCOM_SHOW_WARNS:
-+ {
-+ res= mysqld_show_warnings(thd, (ulong)
-+ ((1L << (uint) MYSQL_ERROR::WARN_LEVEL_NOTE) |
-+ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_WARN) |
-+ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR)
-+ ));
-+ break;
-+ }
-+ case SQLCOM_SHOW_ERRORS:
-+ {
-+ res= mysqld_show_warnings(thd, (ulong)
-+ (1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
-+ break;
-+ }
-+ case SQLCOM_SHOW_PROFILES:
-+ {
-+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
-+ thd->profiling.discard_current_query();
-+ res= thd->profiling.show_profiles();
-+ if (res)
-+ goto error;
-+#else
-+ my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
-+ goto error;
-+#endif
-+ break;
-+ }
-+ case SQLCOM_SHOW_NEW_MASTER:
-+ {
-+ if (check_global_access(thd, REPL_SLAVE_ACL))
-+ goto error;
-+ /* This query don't work now. See comment in repl_failsafe.cc */
-+#ifndef WORKING_NEW_MASTER
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "SHOW NEW MASTER");
-+ goto error;
-+#else
-+ res = show_new_master(thd);
-+ break;
-+#endif
-+ }
-+
-+#ifdef HAVE_REPLICATION
-+ case SQLCOM_SHOW_SLAVE_HOSTS:
-+ {
-+ if (check_global_access(thd, REPL_SLAVE_ACL))
-+ goto error;
-+ res = show_slave_hosts(thd);
-+ break;
-+ }
-+ case SQLCOM_SHOW_BINLOG_EVENTS:
-+ {
-+ if (check_global_access(thd, REPL_SLAVE_ACL))
-+ goto error;
-+ res = mysql_show_binlog_events(thd);
-+ break;
-+ }
-+#endif
-+
-+ case SQLCOM_BACKUP_TABLE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
-+ check_global_access(thd, FILE_ACL))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res = mysql_backup_table(thd, first_table);
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+ case SQLCOM_RESTORE_TABLE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, INSERT_ACL, all_tables, UINT_MAX, FALSE) ||
-+ check_global_access(thd, FILE_ACL))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res = mysql_restore_table(thd, first_table);
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+ case SQLCOM_ASSIGN_TO_KEYCACHE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_access(thd, INDEX_ACL, first_table->db,
-+ &first_table->grant.privilege, 0, 0,
-+ test(first_table->schema_table)))
-+ goto error;
-+ res= mysql_assign_to_keycache(thd, first_table, &lex->ident);
-+ break;
-+ }
-+ case SQLCOM_PRELOAD_KEYS:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_access(thd, INDEX_ACL, first_table->db,
-+ &first_table->grant.privilege, 0, 0,
-+ test(first_table->schema_table)))
-+ goto error;
-+ res = mysql_preload_keys(thd, first_table);
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ case SQLCOM_CHANGE_MASTER:
-+ {
-+ if (check_global_access(thd, SUPER_ACL))
-+ goto error;
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ res = change_master(thd,active_mi);
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ break;
-+ }
-+ case SQLCOM_SHOW_SLAVE_STAT:
-+ {
-+ /* Accept one of two privileges */
-+ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
-+ goto error;
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ if (active_mi != NULL)
-+ {
-+ res = show_master_info(thd, active_mi);
-+ }
-+ else
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ WARN_NO_MASTER_INFO, ER(WARN_NO_MASTER_INFO));
-+ my_ok(thd);
-+ }
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ break;
-+ }
-+ case SQLCOM_SHOW_MASTER_STAT:
-+ {
-+ /* Accept one of two privileges */
-+ if (check_global_access(thd, SUPER_ACL | REPL_CLIENT_ACL))
-+ goto error;
-+ res = show_binlog_info(thd);
-+ break;
-+ }
-+
-+ case SQLCOM_LOAD_MASTER_DATA: // sync with master
-+ if (check_global_access(thd, SUPER_ACL))
-+ goto error;
-+ if (end_active_trans(thd))
-+ goto error;
-+ res = load_master_data(thd);
-+ break;
-+#endif /* HAVE_REPLICATION */
-+ case SQLCOM_SHOW_ENGINE_STATUS:
-+ {
-+ if (check_global_access(thd, PROCESS_ACL))
-+ goto error;
-+ res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_STATUS);
-+ break;
-+ }
-+ case SQLCOM_SHOW_ENGINE_MUTEX:
-+ {
-+ if (check_global_access(thd, PROCESS_ACL))
-+ goto error;
-+ res = ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_MUTEX);
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ case SQLCOM_LOAD_MASTER_TABLE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ DBUG_ASSERT(first_table->db); /* Must be set in the parser */
-+
-+ if (check_access(thd, CREATE_ACL, first_table->db,
-+ &first_table->grant.privilege, 0, 0,
-+ test(first_table->schema_table)))
-+ goto error; /* purecov: inspected */
-+ /* Check that the first table has CREATE privilege */
-+ if (check_grant(thd, CREATE_ACL, all_tables, 0, 1, 0))
-+ goto error;
-+
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ /*
-+ fetch_master_table will send the error to the client on failure.
-+ Give error if the table already exists.
-+ */
-+ if (!fetch_master_table(thd, first_table->db, first_table->table_name,
-+ active_mi, 0, 0))
-+ {
-+ my_ok(thd);
-+ }
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ break;
-+ }
-+#endif /* HAVE_REPLICATION */
-+
-+ case SQLCOM_CREATE_TABLE:
-+ {
-+ /* If CREATE TABLE of non-temporary table, do implicit commit */
-+ if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ if (end_active_trans(thd))
-+ {
-+ res= -1;
-+ break;
-+ }
-+ }
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ bool link_to_local;
-+ // Skip first table, which is the table we are creating
-+ TABLE_LIST *create_table= lex->unlink_first_table(&link_to_local);
-+ TABLE_LIST *select_tables= lex->query_tables;
-+ /*
-+ Code below (especially in mysql_create_table() and select_create
-+ methods) may modify HA_CREATE_INFO structure in LEX, so we have to
-+ use a copy of this structure to make execution prepared statement-
-+ safe. A shallow copy is enough as this code won't modify any memory
-+ referenced from this structure.
-+ */
-+ HA_CREATE_INFO create_info(lex->create_info);
-+ /*
-+ We need to copy alter_info for the same reasons of re-execution
-+ safety, only in case of Alter_info we have to do (almost) a deep
-+ copy.
-+ */
-+ Alter_info alter_info(lex->alter_info, thd->mem_root);
-+
-+ if (thd->is_fatal_error)
-+ {
-+ /* If out of memory when creating a copy of alter_info. */
-+ res= 1;
-+ goto end_with_restore_list;
-+ }
-+
-+ if ((res= create_table_precheck(thd, select_tables, create_table)))
-+ goto end_with_restore_list;
-+
-+ /* Might have been updated in create_table_precheck */
-+ create_info.alias= create_table->alias;
-+
-+#ifdef HAVE_READLINK
-+ /* Fix names if symlinked tables */
-+ if (append_file_to_dir(thd, &create_info.data_file_name,
-+ create_table->table_name) ||
-+ append_file_to_dir(thd, &create_info.index_file_name,
-+ create_table->table_name))
-+ goto end_with_restore_list;
-+#endif
-+ /*
-+ If we are using SET CHARSET without DEFAULT, add an implicit
-+ DEFAULT to not confuse old users. (This may change).
-+ */
-+ if ((create_info.used_fields &
-+ (HA_CREATE_USED_DEFAULT_CHARSET | HA_CREATE_USED_CHARSET)) ==
-+ HA_CREATE_USED_CHARSET)
-+ {
-+ create_info.used_fields&= ~HA_CREATE_USED_CHARSET;
-+ create_info.used_fields|= HA_CREATE_USED_DEFAULT_CHARSET;
-+ create_info.default_table_charset= create_info.table_charset;
-+ create_info.table_charset= 0;
-+ }
-+ /*
-+ The create-select command will open and read-lock the select table
-+ and then create, open and write-lock the new table. If a global
-+ read lock steps in, we get a deadlock. The write lock waits for
-+ the global read lock, while the global read lock waits for the
-+ select table to be closed. So we wait until the global readlock is
-+ gone before starting both steps. Note that
-+ wait_if_global_read_lock() sets a protection against a new global
-+ read lock when it succeeds. This needs to be released by
-+ start_waiting_global_read_lock(). We protect the normal CREATE
-+ TABLE in the same way. That way we avoid that a new table is
-+ created during a gobal read lock.
-+ */
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ goto end_with_restore_list;
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ {
-+ partition_info *part_info= thd->lex->part_info;
-+ if (part_info && !(part_info= thd->lex->part_info->get_clone()))
-+ {
-+ res= -1;
-+ goto end_with_restore_list;
-+ }
-+ thd->work_part_info= part_info;
-+ }
-+#endif
-+ if (select_lex->item_list.elements) // With select
-+ {
-+ select_result *result;
-+
-+ /*
-+ If:
-+ a) we inside an SP and there was NAME_CONST substitution,
-+ b) binlogging is on (STMT mode),
-+ c) we log the SP as separate statements
-+ raise a warning, as it may cause problems
-+ (see 'NAME_CONST issues' in 'Binary Logging of Stored Programs')
-+ */
-+ if (thd->query_name_consts &&
-+ mysql_bin_log.is_open() &&
-+ thd->variables.binlog_format == BINLOG_FORMAT_STMT &&
-+ !mysql_bin_log.is_query_in_union(thd, thd->query_id))
-+ {
-+ List_iterator_fast<Item> it(select_lex->item_list);
-+ Item *item;
-+ uint splocal_refs= 0;
-+ /* Count SP local vars in the top-level SELECT list */
-+ while ((item= it++))
-+ {
-+ if (item->is_splocal())
-+ splocal_refs++;
-+ }
-+ /*
-+ If it differs from number of NAME_CONST substitution applied,
-+ we may have a SOME_FUNC(NAME_CONST()) in the SELECT list,
-+ that may cause a problem with binary log (see BUG#35383),
-+ raise a warning.
-+ */
-+ if (splocal_refs != thd->query_name_consts)
-+ push_warning(thd,
-+ MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_UNKNOWN_ERROR,
-+"Invoked routine ran a statement that may cause problems with "
-+"binary log, see 'NAME_CONST issues' in 'Binary Logging of Stored Programs' "
-+"section of the manual.");
-+ }
-+
-+ select_lex->options|= SELECT_NO_UNLOCK;
-+ unit->set_limit(select_lex);
-+
-+ /*
-+ Disable non-empty MERGE tables with CREATE...SELECT. Too
-+ complicated. See Bug #26379. Empty MERGE tables are read-only
-+ and don't allow CREATE...SELECT anyway.
-+ */
-+ if (create_info.used_fields & HA_CREATE_USED_UNION)
-+ {
-+ my_error(ER_WRONG_OBJECT, MYF(0), create_table->db,
-+ create_table->table_name, "BASE TABLE");
-+ res= 1;
-+ goto end_with_restore_list;
-+ }
-+
-+ if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ lex->link_first_table_back(create_table, link_to_local);
-+ create_table->create= TRUE;
-+ /* Base table and temporary table are not in the same name space. */
-+ create_table->skip_temporary= 1;
-+ }
-+
-+ if (!(res= open_and_lock_tables(thd, lex->query_tables)))
-+ {
-+ /*
-+ Is table which we are changing used somewhere in other parts
-+ of query
-+ */
-+ if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ TABLE_LIST *duplicate;
-+ create_table= lex->unlink_first_table(&link_to_local);
-+
-+ if (create_table->view)
-+ {
-+ if (create_info.options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ {
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_TABLE_EXISTS_ERROR,
-+ ER(ER_TABLE_EXISTS_ERROR),
-+ create_info.alias);
-+ my_ok(thd);
-+ }
-+ else
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), create_info.alias);
-+ res= 1;
-+ }
-+ goto end_with_restore_list;
-+ }
-+
-+ if ((duplicate= unique_table(thd, create_table, select_tables, 0)))
-+ {
-+ update_non_unique_table_error(create_table, "CREATE", duplicate);
-+ res= 1;
-+ goto end_with_restore_list;
-+ }
-+ }
-+ /* If we create merge table, we have to test tables in merge, too */
-+ if (create_info.used_fields & HA_CREATE_USED_UNION)
-+ {
-+ TABLE_LIST *tab;
-+ for (tab= create_info.merge_list.first;
-+ tab;
-+ tab= tab->next_local)
-+ {
-+ TABLE_LIST *duplicate;
-+ if ((duplicate= unique_table(thd, tab, select_tables, 0)))
-+ {
-+ update_non_unique_table_error(tab, "CREATE", duplicate);
-+ res= 1;
-+ goto end_with_restore_list;
-+ }
-+ }
-+ }
-+
-+ /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
-+ if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
-+ thd->options|= OPTION_KEEP_LOG;
-+
-+ /*
-+ select_create is currently not re-execution friendly and
-+ needs to be created for every execution of a PS/SP.
-+ */
-+ if ((result= new select_create(create_table,
-+ &create_info,
-+ &alter_info,
-+ select_lex->item_list,
-+ lex->duplicates,
-+ lex->ignore,
-+ select_tables)))
-+ {
-+ /*
-+ CREATE from SELECT give its SELECT_LEX for SELECT,
-+ and item_list belong to SELECT
-+ */
-+ res= handle_select(thd, lex, result, 0);
-+ delete result;
-+ }
-+ }
-+ else if (!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
-+ create_table= lex->unlink_first_table(&link_to_local);
-+
-+ }
-+ else
-+ {
-+ /* So that CREATE TEMPORARY TABLE gets to binlog at commit/rollback */
-+ if (create_info.options & HA_LEX_CREATE_TMP_TABLE)
-+ thd->options|= OPTION_KEEP_LOG;
-+ /* regular create */
-+ if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
-+ res= mysql_create_like_table(thd, create_table, select_tables,
-+ &create_info);
-+ else
-+ {
-+ res= mysql_create_table(thd, create_table->db,
-+ create_table->table_name, &create_info,
-+ &alter_info, 0, 0);
-+ }
-+ if (!res)
-+ my_ok(thd);
-+ }
-+
-+ /* put tables back for PS rexecuting */
-+end_with_restore_list:
-+ lex->link_first_table_back(create_table, link_to_local);
-+ break;
-+ }
-+ case SQLCOM_CREATE_INDEX:
-+ /* Fall through */
-+ case SQLCOM_DROP_INDEX:
-+ /*
-+ CREATE INDEX and DROP INDEX are implemented by calling ALTER
-+ TABLE with proper arguments.
-+
-+ In the future ALTER TABLE will notice that the request is to
-+ only add indexes and create these one by one for the existing
-+ table without having to do a full rebuild.
-+ */
-+ {
-+ /* Prepare stack copies to be re-execution safe */
-+ HA_CREATE_INFO create_info;
-+ Alter_info alter_info(lex->alter_info, thd->mem_root);
-+
-+ if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
-+ goto error;
-+
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_one_table_access(thd, INDEX_ACL, all_tables))
-+ goto error; /* purecov: inspected */
-+ if (end_active_trans(thd))
-+ goto error;
-+ /*
-+ Currently CREATE INDEX or DROP INDEX cause a full table rebuild
-+ and thus classify as slow administrative statements just like
-+ ALTER TABLE.
-+ */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+
-+ bzero((char*) &create_info, sizeof(create_info));
-+ create_info.db_type= 0;
-+ create_info.row_type= ROW_TYPE_NOT_USED;
-+ create_info.default_table_charset= thd->variables.collation_database;
-+
-+ res= mysql_alter_table(thd, first_table->db, first_table->table_name,
-+ &create_info, first_table, &alter_info,
-+ 0, (ORDER*) 0, 0);
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ case SQLCOM_SLAVE_START:
-+ {
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ start_slave(thd,active_mi,1 /* net report*/);
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ break;
-+ }
-+ case SQLCOM_SLAVE_STOP:
-+ /*
-+ If the client thread has locked tables, a deadlock is possible.
-+ Assume that
-+ - the client thread does LOCK TABLE t READ.
-+ - then the master updates t.
-+ - then the SQL slave thread wants to update t,
-+ so it waits for the client thread because t is locked by it.
-+ - then the client thread does SLAVE STOP.
-+ SLAVE STOP waits for the SQL slave thread to terminate its
-+ update t, which waits for the client thread because t is locked by it.
-+ To prevent that, refuse SLAVE STOP if the
-+ client thread has locked tables
-+ */
-+ if (thd->locked_tables || thd->active_transaction() || thd->global_read_lock)
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ goto error;
-+ }
-+ {
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ stop_slave(thd,active_mi,1/* net report*/);
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ break;
-+ }
-+#endif /* HAVE_REPLICATION */
-+
-+ case SQLCOM_ALTER_TABLE:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ {
-+ ulong priv=0;
-+ ulong priv_needed= ALTER_ACL;
-+ /*
-+ Code in mysql_alter_table() may modify its HA_CREATE_INFO argument,
-+ so we have to use a copy of this structure to make execution
-+ prepared statement- safe. A shallow copy is enough as no memory
-+ referenced from this structure will be modified.
-+ */
-+ HA_CREATE_INFO create_info(lex->create_info);
-+ Alter_info alter_info(lex->alter_info, thd->mem_root);
-+
-+ if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */
-+ goto error;
-+ /*
-+ We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well
-+ as for RENAME TO, as being done by SQLCOM_RENAME_TABLE
-+ */
-+ if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
-+ priv_needed|= DROP_ACL;
-+
-+ /* Must be set in the parser */
-+ DBUG_ASSERT(select_lex->db);
-+ if (check_access(thd, priv_needed, first_table->db,
-+ &first_table->grant.privilege, 0, 0,
-+ test(first_table->schema_table)) ||
-+ check_access(thd,INSERT_ACL | CREATE_ACL,select_lex->db,&priv,0,0,
-+ is_schema_db(select_lex->db))||
-+ check_merge_table_access(thd, first_table->db,
-+ create_info.merge_list.first))
-+ goto error; /* purecov: inspected */
-+ if (check_grant(thd, priv_needed, all_tables, 0, UINT_MAX, 0))
-+ goto error;
-+ if (lex->name.str && !test_all_bits(priv,INSERT_ACL | CREATE_ACL))
-+ { // Rename of table
-+ TABLE_LIST tmp_table;
-+ bzero((char*) &tmp_table,sizeof(tmp_table));
-+ tmp_table.table_name= lex->name.str;
-+ tmp_table.db=select_lex->db;
-+ tmp_table.grant.privilege=priv;
-+ if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, 0,
-+ UINT_MAX, 0))
-+ goto error;
-+ }
-+
-+ /* Don't yet allow changing of symlinks with ALTER TABLE */
-+ if (create_info.data_file_name)
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
-+ "DATA DIRECTORY");
-+ if (create_info.index_file_name)
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
-+ "INDEX DIRECTORY");
-+ create_info.data_file_name= create_info.index_file_name= NULL;
-+ /* ALTER TABLE ends previous transaction */
-+ if (end_active_trans(thd))
-+ goto error;
-+
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res= mysql_alter_table(thd, select_lex->db, lex->name.str,
-+ &create_info,
-+ first_table,
-+ &alter_info,
-+ select_lex->order_list.elements,
-+ (ORDER *) select_lex->order_list.first,
-+ lex->ignore);
-+ break;
-+ }
-+ case SQLCOM_RENAME_TABLE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ TABLE_LIST *table;
-+ for (table= first_table; table; table= table->next_local->next_local)
-+ {
-+ if (check_access(thd, ALTER_ACL | DROP_ACL, table->db,
-+ &table->grant.privilege,0,0, test(table->schema_table)) ||
-+ check_access(thd, INSERT_ACL | CREATE_ACL, table->next_local->db,
-+ &table->next_local->grant.privilege, 0, 0,
-+ test(table->next_local->schema_table)))
-+ goto error;
-+ TABLE_LIST old_list, new_list;
-+ /*
-+ we do not need initialize old_list and new_list because we will
-+ come table[0] and table->next[0] there
-+ */
-+ old_list= table[0];
-+ new_list= table->next_local[0];
-+ if (check_grant(thd, ALTER_ACL | DROP_ACL, &old_list, 0, 1, 0) ||
-+ (!test_all_bits(table->next_local->grant.privilege,
-+ INSERT_ACL | CREATE_ACL) &&
-+ check_grant(thd, INSERT_ACL | CREATE_ACL, &new_list, 0, 1, 0)))
-+ goto error;
-+ }
-+
-+ if (end_active_trans(thd) || mysql_rename_tables(thd, first_table, 0))
-+ goto error;
-+ break;
-+ }
-+#ifndef EMBEDDED_LIBRARY
-+ case SQLCOM_SHOW_BINLOGS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+ MYF(0)); /* purecov: inspected */
-+ goto error;
-+#else
-+ {
-+ if (check_global_access(thd, SUPER_ACL))
-+ goto error;
-+ res = show_binlogs(thd);
-+ break;
-+ }
-+#endif
-+#endif /* EMBEDDED_LIBRARY */
-+ case SQLCOM_SHOW_CREATE:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+ MYF(0)); /* purecov: inspected */
-+ goto error;
-+#else
-+ {
-+ /* Ignore temporary tables if this is "SHOW CREATE VIEW" */
-+ if (lex->only_view)
-+ first_table->skip_temporary= 1;
-+ if (check_show_create_table_access(thd, first_table))
-+ goto error;
-+ res= mysqld_show_create(thd, first_table);
-+ break;
-+ }
-+#endif
-+ case SQLCOM_CHECKSUM:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL, all_tables,
-+ UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ res = mysql_checksum_table(thd, first_table, &lex->check_opt);
-+ break;
-+ }
-+ case SQLCOM_REPAIR:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
-+ UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res= mysql_repair_table(thd, first_table, &lex->check_opt);
-+ /* ! we write after unlocking the table */
-+ if (!res && !lex->no_write_to_binlog)
-+ {
-+ /*
-+ Presumably, REPAIR and binlog writing doesn't require synchronization
-+ */
-+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ }
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+ case SQLCOM_CHECK:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL | EXTRA_ACL , all_tables,
-+ UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res = mysql_check_table(thd, first_table, &lex->check_opt);
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+ case SQLCOM_ANALYZE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
-+ UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res= mysql_analyze_table(thd, first_table, &lex->check_opt);
-+ /* ! we write after unlocking the table */
-+ if (!res && !lex->no_write_to_binlog)
-+ {
-+ /*
-+ Presumably, ANALYZE and binlog writing doesn't require synchronization
-+ */
-+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ }
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+
-+ case SQLCOM_OPTIMIZE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL | INSERT_ACL, all_tables,
-+ UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ thd->enable_slow_log= opt_log_slow_admin_statements;
-+ res= (specialflag & (SPECIAL_SAFE_MODE | SPECIAL_NO_NEW_FUNC)) ?
-+ mysql_recreate_table(thd, first_table) :
-+ mysql_optimize_table(thd, first_table, &lex->check_opt);
-+ /* ! we write after unlocking the table */
-+ if (!res && !lex->no_write_to_binlog)
-+ {
-+ /*
-+ Presumably, OPTIMIZE and binlog writing doesn't require synchronization
-+ */
-+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ }
-+ select_lex->table_list.first= first_table;
-+ lex->query_tables=all_tables;
-+ break;
-+ }
-+ case SQLCOM_UPDATE:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (update_precheck(thd, all_tables))
-+ break;
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ goto error;
-+ DBUG_ASSERT(select_lex->offset_limit == 0);
-+ unit->set_limit(select_lex);
-+ res= (up_result= mysql_update(thd, all_tables,
-+ select_lex->item_list,
-+ lex->value_list,
-+ select_lex->where,
-+ select_lex->order_list.elements,
-+ select_lex->order_list.first,
-+ unit->select_limit_cnt,
-+ lex->duplicates, lex->ignore));
-+ /* mysql_update return 2 if we need to switch to multi-update */
-+ if (up_result != 2)
-+ break;
-+ /* Fall through */
-+ case SQLCOM_UPDATE_MULTI:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ /* if we switched from normal update, rights are checked */
-+ if (up_result != 2)
-+ {
-+ if ((res= multi_update_precheck(thd, all_tables)))
-+ break;
-+ }
-+ else
-+ res= 0;
-+
-+ /*
-+ Protection might have already been risen if its a fall through
-+ from the SQLCOM_UPDATE case above.
-+ */
-+ if (!thd->locked_tables &&
-+ lex->sql_command == SQLCOM_UPDATE_MULTI &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ goto error;
-+
-+ res= mysql_multi_update_prepare(thd);
-+
-+#ifdef HAVE_REPLICATION
-+ /* Check slave filtering rules */
-+ if (unlikely(thd->slave_thread && !have_table_map_for_update))
-+ {
-+ if (all_tables_not_ok(thd, all_tables))
-+ {
-+ if (res!= 0)
-+ {
-+ res= 0; /* don't care of prev failure */
-+ thd->clear_error(); /* filters are of highest prior */
-+ }
-+ /* we warn the slave SQL thread */
-+ my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
-+ break;
-+ }
-+ if (res)
-+ break;
-+ }
-+ else
-+ {
-+#endif /* HAVE_REPLICATION */
-+ if (res)
-+ break;
-+ if (opt_readonly &&
-+ !(thd->security_ctx->master_access & SUPER_ACL) &&
-+ some_non_temp_table_to_be_updated(thd, all_tables))
-+ {
-+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "--read-only");
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ } /* unlikely */
-+#endif
-+
-+ res= mysql_multi_update(thd, all_tables,
-+ &select_lex->item_list,
-+ &lex->value_list,
-+ select_lex->where,
-+ select_lex->options,
-+ lex->duplicates, lex->ignore, unit, select_lex);
-+ break;
-+ }
-+ case SQLCOM_REPLACE:
-+#ifndef DBUG_OFF
-+ if (mysql_bin_log.is_open())
-+ {
-+ /*
-+ Generate an incident log event before writing the real event
-+ to the binary log. We put this event is before the statement
-+ since that makes it simpler to check that the statement was
-+ not executed on the slave (since incidents usually stop the
-+ slave).
-+
-+ Observe that any row events that are generated will be
-+ generated before.
-+
-+ This is only for testing purposes and will not be present in a
-+ release build.
-+ */
-+
-+ Incident incident= INCIDENT_NONE;
-+ DBUG_PRINT("debug", ("Just before generate_incident()"));
-+ DBUG_EXECUTE_IF("incident_database_resync_on_replace",
-+ incident= INCIDENT_LOST_EVENTS;);
-+ if (incident)
-+ {
-+ Incident_log_event ev(thd, incident);
-+ (void) mysql_bin_log.write(&ev); /* error is ignored */
-+ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
-+ {
-+ res= 1;
-+ break;
-+ }
-+ }
-+ DBUG_PRINT("debug", ("Just after generate_incident()"));
-+ }
-+#endif
-+ case SQLCOM_INSERT:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if ((res= insert_precheck(thd, all_tables)))
-+ break;
-+
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+
-+ res= mysql_insert(thd, all_tables, lex->field_list, lex->many_values,
-+ lex->update_list, lex->value_list,
-+ lex->duplicates, lex->ignore);
-+
-+ /*
-+ If we have inserted into a VIEW, and the base table has
-+ AUTO_INCREMENT column, but this column is not accessible through
-+ a view, then we should restore LAST_INSERT_ID to the value it
-+ had before the statement.
-+ */
-+ if (first_table->view && !first_table->contain_auto_increment)
-+ thd->first_successful_insert_id_in_cur_stmt=
-+ thd->first_successful_insert_id_in_prev_stmt;
-+
-+ DBUG_EXECUTE_IF("after_mysql_insert",
-+ {
-+ const char act[]=
-+ "now "
-+ "wait_for signal.continue";
-+ DBUG_ASSERT(opt_debug_sync_timeout > 0);
-+ DBUG_ASSERT(!debug_sync_set_action(current_thd,
-+ STRING_WITH_LEN(act)));
-+ };);
-+ break;
-+ }
-+ case SQLCOM_REPLACE_SELECT:
-+ case SQLCOM_INSERT_SELECT:
-+ {
-+ select_result *sel_result;
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if ((res= insert_precheck(thd, all_tables)))
-+ break;
-+
-+ /* Fix lock for first table */
-+ if (first_table->lock_type == TL_WRITE_DELAYED)
-+ first_table->lock_type= TL_WRITE;
-+
-+ /* Don't unlock tables until command is written to binary log */
-+ select_lex->options|= SELECT_NO_UNLOCK;
-+
-+ unit->set_limit(select_lex);
-+
-+ if (! thd->locked_tables &&
-+ ! (need_start_waiting= ! wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+
-+ if (!(res= open_and_lock_tables(thd, all_tables)))
-+ {
-+ /* Skip first table, which is the table we are inserting in */
-+ TABLE_LIST *second_table= first_table->next_local;
-+ select_lex->table_list.first= second_table;
-+ select_lex->context.table_list=
-+ select_lex->context.first_name_resolution_table= second_table;
-+ res= mysql_insert_select_prepare(thd);
-+ if (!res && (sel_result= new select_insert(first_table,
-+ first_table->table,
-+ &lex->field_list,
-+ &lex->update_list,
-+ &lex->value_list,
-+ lex->duplicates,
-+ lex->ignore)))
-+ {
-+ res= handle_select(thd, lex, sel_result, OPTION_SETUP_TABLES_DONE);
-+ /*
-+ Invalidate the table in the query cache if something changed
-+ after unlocking when changes become visible.
-+ TODO: this is workaround. right way will be move invalidating in
-+ the unlock procedure.
-+ */
-+ if (!res && first_table->lock_type == TL_WRITE_CONCURRENT_INSERT &&
-+ thd->lock)
-+ {
-+ /* INSERT ... SELECT should invalidate only the very first table */
-+ TABLE_LIST *save_table= first_table->next_local;
-+ first_table->next_local= 0;
-+ query_cache_invalidate3(thd, first_table, 1);
-+ first_table->next_local= save_table;
-+ }
-+ delete sel_result;
-+ }
-+ /* revert changes for SP */
-+ select_lex->table_list.first= first_table;
-+ }
-+
-+ /*
-+ If we have inserted into a VIEW, and the base table has
-+ AUTO_INCREMENT column, but this column is not accessible through
-+ a view, then we should restore LAST_INSERT_ID to the value it
-+ had before the statement.
-+ */
-+ if (first_table->view && !first_table->contain_auto_increment)
-+ thd->first_successful_insert_id_in_cur_stmt=
-+ thd->first_successful_insert_id_in_prev_stmt;
-+
-+ break;
-+ }
-+ case SQLCOM_TRUNCATE:
-+ if (end_active_trans(thd))
-+ {
-+ res= -1;
-+ break;
-+ }
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_one_table_access(thd, DROP_ACL, all_tables))
-+ goto error;
-+ /*
-+ Don't allow this within a transaction because we want to use
-+ re-generate table
-+ */
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ goto error;
-+ }
-+ if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ goto error;
-+ res= mysql_truncate(thd, first_table, 0);
-+ break;
-+ case SQLCOM_DELETE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if ((res= delete_precheck(thd, all_tables)))
-+ break;
-+ DBUG_ASSERT(select_lex->offset_limit == 0);
-+ unit->set_limit(select_lex);
-+
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+
-+ res = mysql_delete(thd, all_tables, select_lex->where,
-+ &select_lex->order_list,
-+ unit->select_limit_cnt, select_lex->options,
-+ FALSE);
-+ break;
-+ }
-+ case SQLCOM_DELETE_MULTI:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
-+ multi_delete *del_result;
-+
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+
-+ if ((res= multi_delete_precheck(thd, all_tables)))
-+ break;
-+
-+ /* condition will be TRUE on SP re-excuting */
-+ if (select_lex->item_list.elements != 0)
-+ select_lex->item_list.empty();
-+ if (add_item_to_list(thd, new Item_null()))
-+ goto error;
-+
-+ thd_proc_info(thd, "init");
-+ if ((res= open_and_lock_tables(thd, all_tables)))
-+ break;
-+
-+ if ((res= mysql_multi_delete_prepare(thd)))
-+ goto error;
-+
-+ if (!thd->is_fatal_error &&
-+ (del_result= new multi_delete(aux_tables, lex->table_count)))
-+ {
-+ res= mysql_select(thd, &select_lex->ref_pointer_array,
-+ select_lex->get_table_list(),
-+ select_lex->with_wild,
-+ select_lex->item_list,
-+ select_lex->where,
-+ 0, (ORDER *)NULL, (ORDER *)NULL, (Item *)NULL,
-+ (ORDER *)NULL,
-+ (select_lex->options | thd->options |
-+ SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
-+ OPTION_SETUP_TABLES_DONE) & ~OPTION_BUFFER_RESULT,
-+ del_result, unit, select_lex);
-+ res|= thd->is_error();
-+ if (res)
-+ del_result->abort();
-+ delete del_result;
-+ }
-+ else
-+ res= TRUE; // Error
-+ break;
-+ }
-+ case SQLCOM_DROP_TABLE:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (!lex->drop_temporary)
-+ {
-+ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE))
-+ goto error; /* purecov: inspected */
-+ if (end_active_trans(thd))
-+ goto error;
-+ }
-+ else
-+ {
-+ /* So that DROP TEMPORARY TABLE gets to binlog at commit/rollback */
-+ thd->options|= OPTION_KEEP_LOG;
-+ }
-+ /* DDL and binlog write order protected by LOCK_open */
-+ res= mysql_rm_table(thd, first_table, lex->drop_if_exists,
-+ lex->drop_temporary);
-+ }
-+ break;
-+ case SQLCOM_SHOW_PROCESSLIST:
-+ if (!thd->security_ctx->priv_user[0] &&
-+ check_global_access(thd,PROCESS_ACL))
-+ break;
-+ mysqld_list_processes(thd,
-+ (thd->security_ctx->master_access & PROCESS_ACL ?
-+ NullS :
-+ thd->security_ctx->priv_user),
-+ lex->verbose);
-+ break;
-+ case SQLCOM_SHOW_AUTHORS:
-+ res= mysqld_show_authors(thd);
-+ break;
-+ case SQLCOM_SHOW_CONTRIBUTORS:
-+ res= mysqld_show_contributors(thd);
-+ break;
-+ case SQLCOM_SHOW_PRIVILEGES:
-+ res= mysqld_show_privileges(thd);
-+ break;
-+ case SQLCOM_SHOW_COLUMN_TYPES:
-+ res= mysqld_show_column_types(thd);
-+ break;
-+ case SQLCOM_SHOW_ENGINE_LOGS:
-+#ifdef DONT_ALLOW_SHOW_COMMANDS
-+ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND),
-+ MYF(0)); /* purecov: inspected */
-+ goto error;
-+#else
-+ {
-+ if (check_access(thd, FILE_ACL, any_db,0,0,0,0))
-+ goto error;
-+ res= ha_show_status(thd, lex->create_info.db_type, HA_ENGINE_LOGS);
-+ break;
-+ }
-+#endif
-+ case SQLCOM_CHANGE_DB:
-+ {
-+ LEX_STRING db_str= { (char *) select_lex->db, strlen(select_lex->db) };
-+
-+ if (!mysql_change_db(thd, &db_str, FALSE))
-+ my_ok(thd);
-+
-+ break;
-+ }
-+
-+ case SQLCOM_LOAD:
-+ {
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ uint privilege= (lex->duplicates == DUP_REPLACE ?
-+ INSERT_ACL | DELETE_ACL : INSERT_ACL) |
-+ (lex->local_file ? 0 : FILE_ACL);
-+
-+ if (lex->local_file)
-+ {
-+ if (!(thd->client_capabilities & CLIENT_LOCAL_FILES) ||
-+ !opt_local_infile)
-+ {
-+ my_message(ER_NOT_ALLOWED_COMMAND, ER(ER_NOT_ALLOWED_COMMAND), MYF(0));
-+ goto error;
-+ }
-+ }
-+
-+ if (check_one_table_access(thd, privilege, all_tables))
-+ goto error;
-+
-+ if (!thd->locked_tables &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ goto error;
-+
-+ res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
-+ lex->update_list, lex->value_list, lex->duplicates,
-+ lex->ignore, (bool) lex->local_file);
-+ break;
-+ }
-+
-+ case SQLCOM_SET_OPTION:
-+ {
-+ List<set_var_base> *lex_var_list= &lex->var_list;
-+
-+ if (lex->autocommit && end_active_trans(thd))
-+ goto error;
-+
-+ if ((check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
-+ open_and_lock_tables(thd, all_tables)))
-+ goto error;
-+ if (lex->one_shot_set && not_all_support_one_shot(lex_var_list))
-+ {
-+ my_error(ER_RESERVED_SYNTAX, MYF(0), "SET ONE_SHOT");
-+ goto error;
-+ }
-+ if (!(res= sql_set_variables(thd, lex_var_list)))
-+ {
-+ /*
-+ If the previous command was a SET ONE_SHOT, we don't want to forget
-+ about the ONE_SHOT property of that SET. So we use a |= instead of = .
-+ */
-+ thd->one_shot_set|= lex->one_shot_set;
-+ my_ok(thd);
-+ }
-+ else
-+ {
-+ /*
-+ We encountered some sort of error, but no message was sent.
-+ Send something semi-generic here since we don't know which
-+ assignment in the list caused the error.
-+ */
-+ if (!thd->is_error())
-+ my_error(ER_WRONG_ARGUMENTS,MYF(0),"SET");
-+ goto error;
-+ }
-+
-+ break;
-+ }
-+
-+ case SQLCOM_UNLOCK_TABLES:
-+ /*
-+ It is critical for mysqldump --single-transaction --master-data that
-+ UNLOCK TABLES does not implicitely commit a connection which has only
-+ done FLUSH TABLES WITH READ LOCK + BEGIN. If this assumption becomes
-+ false, mysqldump will not work.
-+ */
-+ unlock_locked_tables(thd);
-+ if (thd->options & OPTION_TABLE_LOCK)
-+ {
-+ end_active_trans(thd);
-+ thd->options&= ~(OPTION_TABLE_LOCK);
-+ }
-+ if (thd->global_read_lock)
-+ unlock_global_read_lock(thd);
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_LOCK_TABLES:
-+ unlock_locked_tables(thd);
-+ /* we must end the trasaction first, regardless of anything */
-+ if (end_active_trans(thd))
-+ goto error;
-+ if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables,
-+ UINT_MAX, FALSE))
-+ goto error;
-+ if (lex->protect_against_global_read_lock &&
-+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
-+ goto error;
-+ thd->in_lock_tables=1;
-+ thd->options|= OPTION_TABLE_LOCK;
-+
-+ if (!(res= simple_open_n_lock_tables(thd, all_tables)))
-+ {
-+#ifdef HAVE_QUERY_CACHE
-+ if (thd->variables.query_cache_wlock_invalidate)
-+ query_cache.invalidate_locked_for_write(first_table);
-+#endif /*HAVE_QUERY_CACHE*/
-+ thd->locked_tables=thd->lock;
-+ thd->lock=0;
-+ my_ok(thd);
-+ }
-+ else
-+ {
-+ /*
-+ Need to end the current transaction, so the storage engine (InnoDB)
-+ can free its locks if LOCK TABLES locked some tables before finding
-+ that it can't lock a table in its list
-+ */
-+ ha_autocommit_or_rollback(thd, 1);
-+ end_active_trans(thd);
-+ thd->options&= ~(OPTION_TABLE_LOCK);
-+ }
-+ thd->in_lock_tables=0;
-+ break;
-+ case SQLCOM_CREATE_DB:
-+ {
-+ /*
-+ As mysql_create_db() may modify HA_CREATE_INFO structure passed to
-+ it, we need to use a copy of LEX::create_info to make execution
-+ prepared statement- safe.
-+ */
-+ HA_CREATE_INFO create_info(lex->create_info);
-+ if (end_active_trans(thd))
-+ {
-+ res= -1;
-+ break;
-+ }
-+ char *alias;
-+ if (!(alias=thd->strmake(lex->name.str, lex->name.length)) ||
-+ check_db_name(&lex->name))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
-+ break;
-+ }
-+ /*
-+ If in a slave thread :
-+ CREATE DATABASE DB was certainly not preceded by USE DB.
-+ For that reason, db_ok() in sql/slave.cc did not check the
-+ do_db/ignore_db. And as this query involves no tables, tables_ok()
-+ above was not called. So we have to check rules again here.
-+ */
-+#ifdef HAVE_REPLICATION
-+ if (thd->slave_thread &&
-+ (!rpl_filter->db_ok(lex->name.str) ||
-+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
-+ {
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ break;
-+ }
-+#endif
-+ if (check_access(thd,CREATE_ACL,lex->name.str, 0, 1, 0,
-+ is_schema_db(lex->name.str, lex->name.length)))
-+ break;
-+ res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
-+ lex->name.str), &create_info, 0);
-+ break;
-+ }
-+ case SQLCOM_DROP_DB:
-+ {
-+ if (end_active_trans(thd))
-+ {
-+ res= -1;
-+ break;
-+ }
-+ if (check_db_name(&lex->name))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
-+ break;
-+ }
-+ /*
-+ If in a slave thread :
-+ DROP DATABASE DB may not be preceded by USE DB.
-+ For that reason, maybe db_ok() in sql/slave.cc did not check the
-+ do_db/ignore_db. And as this query involves no tables, tables_ok()
-+ above was not called. So we have to check rules again here.
-+ */
-+#ifdef HAVE_REPLICATION
-+ if (thd->slave_thread &&
-+ (!rpl_filter->db_ok(lex->name.str) ||
-+ !rpl_filter->db_ok_with_wild_table(lex->name.str)))
-+ {
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ break;
-+ }
-+#endif
-+ if (check_access(thd,DROP_ACL,lex->name.str,0,1,0,
-+ is_schema_db(lex->name.str, lex->name.length)))
-+ break;
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ goto error;
-+ }
-+ res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
-+ break;
-+ }
-+ case SQLCOM_ALTER_DB_UPGRADE:
-+ {
-+ LEX_STRING *db= & lex->name;
-+ if (end_active_trans(thd))
-+ {
-+ res= 1;
-+ break;
-+ }
-+#ifdef HAVE_REPLICATION
-+ if (thd->slave_thread &&
-+ (!rpl_filter->db_ok(db->str) ||
-+ !rpl_filter->db_ok_with_wild_table(db->str)))
-+ {
-+ res= 1;
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ break;
-+ }
-+#endif
-+ if (check_db_name(db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
-+ break;
-+ }
-+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
-+ is_schema_db(db->str, db->length)) ||
-+ check_access(thd, DROP_ACL, db->str, 0, 1, 0,
-+ is_schema_db(db->str, db->length)) ||
-+ check_access(thd, CREATE_ACL, db->str, 0, 1, 0,
-+ is_schema_db(db->str, db->length)))
-+ {
-+ res= 1;
-+ break;
-+ }
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ res= 1;
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ goto error;
-+ }
-+
-+ res= mysql_upgrade_db(thd, db);
-+ if (!res)
-+ my_ok(thd);
-+ break;
-+ }
-+ case SQLCOM_ALTER_DB:
-+ {
-+ LEX_STRING *db= &lex->name;
-+ HA_CREATE_INFO create_info(lex->create_info);
-+ if (check_db_name(db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), db->str);
-+ break;
-+ }
-+ /*
-+ If in a slave thread :
-+ ALTER DATABASE DB may not be preceded by USE DB.
-+ For that reason, maybe db_ok() in sql/slave.cc did not check the
-+ do_db/ignore_db. And as this query involves no tables, tables_ok()
-+ above was not called. So we have to check rules again here.
-+ */
-+#ifdef HAVE_REPLICATION
-+ if (thd->slave_thread &&
-+ (!rpl_filter->db_ok(db->str) ||
-+ !rpl_filter->db_ok_with_wild_table(db->str)))
-+ {
-+ my_message(ER_SLAVE_IGNORED_TABLE, ER(ER_SLAVE_IGNORED_TABLE), MYF(0));
-+ break;
-+ }
-+#endif
-+ if (check_access(thd, ALTER_ACL, db->str, 0, 1, 0,
-+ is_schema_db(db->str, db->length)))
-+ break;
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ goto error;
-+ }
-+ res= mysql_alter_db(thd, db->str, &create_info);
-+ break;
-+ }
-+ case SQLCOM_SHOW_CREATE_DB:
-+ {
-+ DBUG_EXECUTE_IF("4x_server_emul",
-+ my_error(ER_UNKNOWN_ERROR, MYF(0)); goto error;);
-+ if (check_db_name(&lex->name))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->name.str);
-+ break;
-+ }
-+ res= mysqld_show_create_db(thd, lex->name.str, &lex->create_info);
-+ break;
-+ }
-+ case SQLCOM_CREATE_EVENT:
-+ case SQLCOM_ALTER_EVENT:
-+ #ifdef HAVE_EVENT_SCHEDULER
-+ do
-+ {
-+ DBUG_ASSERT(lex->event_parse_data);
-+ if (lex->table_or_sp_used())
-+ {
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
-+ "function calls as part of this statement");
-+ break;
-+ }
-+
-+ res= sp_process_definer(thd);
-+ if (res)
-+ break;
-+
-+ switch (lex->sql_command) {
-+ case SQLCOM_CREATE_EVENT:
-+ {
-+ bool if_not_exists= (lex->create_info.options &
-+ HA_LEX_CREATE_IF_NOT_EXISTS);
-+ res= Events::create_event(thd, lex->event_parse_data, if_not_exists);
-+ break;
-+ }
-+ case SQLCOM_ALTER_EVENT:
-+ res= Events::update_event(thd, lex->event_parse_data,
-+ lex->spname ? &lex->spname->m_db : NULL,
-+ lex->spname ? &lex->spname->m_name : NULL);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ DBUG_PRINT("info",("DDL error code=%d", res));
-+ if (!res)
-+ my_ok(thd);
-+
-+ } while (0);
-+ /* Don't do it, if we are inside a SP */
-+ if (!thd->spcont)
-+ {
-+ delete lex->sphead;
-+ lex->sphead= NULL;
-+ }
-+ /* lex->unit.cleanup() is called outside, no need to call it here */
-+ break;
-+ case SQLCOM_SHOW_CREATE_EVENT:
-+ res= Events::show_create_event(thd, lex->spname->m_db,
-+ lex->spname->m_name);
-+ break;
-+ case SQLCOM_DROP_EVENT:
-+ if (!(res= Events::drop_event(thd,
-+ lex->spname->m_db, lex->spname->m_name,
-+ lex->drop_if_exists)))
-+ my_ok(thd);
-+ break;
-+#else
-+ my_error(ER_NOT_SUPPORTED_YET,MYF(0),"embedded server");
-+ break;
-+#endif
-+ case SQLCOM_CREATE_FUNCTION: // UDF function
-+ {
-+ if (check_access(thd,INSERT_ACL,"mysql",0,1,0,0))
-+ break;
-+#ifdef HAVE_DLOPEN
-+ if (!(res = mysql_create_function(thd, &lex->udf)))
-+ my_ok(thd);
-+#else
-+ my_error(ER_CANT_OPEN_LIBRARY, MYF(0), lex->udf.dl, 0, "feature disabled");
-+ res= TRUE;
-+#endif
-+ break;
-+ }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ case SQLCOM_CREATE_USER:
-+ {
-+ if (check_access(thd, INSERT_ACL, "mysql", 0, 1, 1, 0) &&
-+ check_global_access(thd,CREATE_USER_ACL))
-+ break;
-+ if (end_active_trans(thd))
-+ goto error;
-+ /* Conditionally writes to binlog */
-+ if (!(res= mysql_create_user(thd, lex->users_list)))
-+ my_ok(thd);
-+ break;
-+ }
-+ case SQLCOM_DROP_USER:
-+ {
-+ if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 1, 0) &&
-+ check_global_access(thd,CREATE_USER_ACL))
-+ break;
-+ if (end_active_trans(thd))
-+ goto error;
-+ /* Conditionally writes to binlog */
-+ if (!(res= mysql_drop_user(thd, lex->users_list)))
-+ my_ok(thd);
-+ break;
-+ }
-+ case SQLCOM_RENAME_USER:
-+ {
-+ if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
-+ check_global_access(thd,CREATE_USER_ACL))
-+ break;
-+ if (end_active_trans(thd))
-+ goto error;
-+ /* Conditionally writes to binlog */
-+ if (!(res= mysql_rename_user(thd, lex->users_list)))
-+ my_ok(thd);
-+ break;
-+ }
-+ case SQLCOM_REVOKE_ALL:
-+ {
-+ if (end_active_trans(thd))
-+ goto error;
-+ if (check_access(thd, UPDATE_ACL, "mysql", 0, 1, 1, 0) &&
-+ check_global_access(thd,CREATE_USER_ACL))
-+ break;
-+
-+ /* Replicate current user as grantor */
-+ thd->binlog_invoker();
-+
-+ /* Conditionally writes to binlog */
-+ if (!(res = mysql_revoke_all(thd, lex->users_list)))
-+ my_ok(thd);
-+ break;
-+ }
-+ case SQLCOM_REVOKE:
-+ case SQLCOM_GRANT:
-+ {
-+ if (end_active_trans(thd))
-+ goto error;
-+
-+ if (check_access(thd, lex->grant | lex->grant_tot_col | GRANT_ACL,
-+ first_table ? first_table->db : select_lex->db,
-+ first_table ? &first_table->grant.privilege : 0,
-+ first_table ? 0 : 1, 0,
-+ first_table ? (bool) first_table->schema_table :
-+ select_lex->db ?
-+ is_schema_db(select_lex->db) : 0))
-+ goto error;
-+
-+ /* Replicate current user as grantor */
-+ thd->binlog_invoker();
-+
-+ if (thd->security_ctx->user) // If not replication
-+ {
-+ LEX_USER *user, *tmp_user;
-+
-+ List_iterator <LEX_USER> user_list(lex->users_list);
-+ while ((tmp_user= user_list++))
-+ {
-+ if (!(user= get_current_user(thd, tmp_user)))
-+ goto error;
-+ if (specialflag & SPECIAL_NO_RESOLVE &&
-+ hostname_requires_resolving(user->host.str))
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARN_HOSTNAME_WONT_WORK,
-+ ER(ER_WARN_HOSTNAME_WONT_WORK),
-+ user->host.str);
-+ // Are we trying to change a password of another user
-+ DBUG_ASSERT(user->host.str != 0);
-+ if (strcmp(thd->security_ctx->user, user->user.str) ||
-+ my_strcasecmp(system_charset_info,
-+ user->host.str, thd->security_ctx->host_or_ip))
-+ {
-+ // TODO: use check_change_password()
-+ if (is_acl_user(user->host.str, user->user.str) &&
-+ user->password.str &&
-+ check_access(thd, UPDATE_ACL,"mysql",0,1,1,0))
-+ {
-+ my_message(ER_PASSWORD_NOT_ALLOWED,
-+ ER(ER_PASSWORD_NOT_ALLOWED), MYF(0));
-+ goto error;
-+ }
-+ }
-+ }
-+ }
-+ if (first_table)
-+ {
-+ if (lex->type == TYPE_ENUM_PROCEDURE ||
-+ lex->type == TYPE_ENUM_FUNCTION)
-+ {
-+ uint grants= lex->all_privileges
-+ ? (PROC_ACLS & ~GRANT_ACL) | (lex->grant & GRANT_ACL)
-+ : lex->grant;
-+ if (check_grant_routine(thd, grants | GRANT_ACL, all_tables,
-+ lex->type == TYPE_ENUM_PROCEDURE, 0))
-+ goto error;
-+ /* Conditionally writes to binlog */
-+ res= mysql_routine_grant(thd, all_tables,
-+ lex->type == TYPE_ENUM_PROCEDURE,
-+ lex->users_list, grants,
-+ lex->sql_command == SQLCOM_REVOKE, TRUE);
-+ if (!res)
-+ my_ok(thd);
-+ }
-+ else
-+ {
-+ if (check_grant(thd,(lex->grant | lex->grant_tot_col | GRANT_ACL),
-+ all_tables, 0, UINT_MAX, 0))
-+ goto error;
-+ /* Conditionally writes to binlog */
-+ res= mysql_table_grant(thd, all_tables, lex->users_list,
-+ lex->columns, lex->grant,
-+ lex->sql_command == SQLCOM_REVOKE);
-+ }
-+ }
-+ else
-+ {
-+ if (lex->columns.elements || lex->type)
-+ {
-+ my_message(ER_ILLEGAL_GRANT_FOR_TABLE, ER(ER_ILLEGAL_GRANT_FOR_TABLE),
-+ MYF(0));
-+ goto error;
-+ }
-+ else
-+ /* Conditionally writes to binlog */
-+ res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
-+ lex->sql_command == SQLCOM_REVOKE);
-+ if (!res)
-+ {
-+ if (lex->sql_command == SQLCOM_GRANT)
-+ {
-+ List_iterator <LEX_USER> str_list(lex->users_list);
-+ LEX_USER *user, *tmp_user;
-+ while ((tmp_user=str_list++))
-+ {
-+ if (!(user= get_current_user(thd, tmp_user)))
-+ goto error;
-+ reset_mqh(user, 0);
-+ }
-+ }
-+ }
-+ }
-+ break;
-+ }
-+#endif /*!NO_EMBEDDED_ACCESS_CHECKS*/
-+ case SQLCOM_RESET:
-+ /*
-+ RESET commands are never written to the binary log, so we have to
-+ initialize this variable because RESET shares the same code as FLUSH
-+ */
-+ lex->no_write_to_binlog= 1;
-+ case SQLCOM_FLUSH:
-+ {
-+ int write_to_binlog;
-+ if (check_global_access(thd,RELOAD_ACL))
-+ goto error;
-+
-+ /*
-+ reload_acl_and_cache() will tell us if we are allowed to write to the
-+ binlog or not.
-+ */
-+ if (!reload_acl_and_cache(thd, lex->type, first_table, &write_to_binlog))
-+ {
-+ /*
-+ We WANT to write and we CAN write.
-+ ! we write after unlocking the table.
-+ */
-+ /*
-+ Presumably, RESET and binlog writing doesn't require synchronization
-+ */
-+
-+ if (write_to_binlog > 0) // we should write
-+ {
-+ if (!lex->no_write_to_binlog)
-+ res= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
-+ } else if (write_to_binlog < 0)
-+ {
-+ /*
-+ We should not write, but rather report error because
-+ reload_acl_and_cache binlog interactions failed
-+ */
-+ res= 1;
-+ }
-+
-+ if (!res)
-+ my_ok(thd);
-+ }
-+
-+ break;
-+ }
-+ case SQLCOM_KILL:
-+ {
-+ Item *it= (Item *)lex->value_list.head();
-+
-+ if (lex->table_or_sp_used())
-+ {
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "Usage of subqueries or stored "
-+ "function calls as part of this statement");
-+ break;
-+ }
-+
-+ if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
-+ {
-+ my_message(ER_SET_CONSTANTS_ONLY, ER(ER_SET_CONSTANTS_ONLY),
-+ MYF(0));
-+ goto error;
-+ }
-+ sql_kill(thd, (ulong)it->val_int(), lex->type & ONLY_KILL_QUERY);
-+ break;
-+ }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ case SQLCOM_SHOW_GRANTS:
-+ {
-+ LEX_USER *grant_user= get_current_user(thd, lex->grant_user);
-+ if (!grant_user)
-+ goto error;
-+ if ((thd->security_ctx->priv_user &&
-+ !strcmp(thd->security_ctx->priv_user, grant_user->user.str)) ||
-+ !check_access(thd, SELECT_ACL, "mysql",0,1,0,0))
-+ {
-+ res = mysql_show_grants(thd, grant_user);
-+ }
-+ break;
-+ }
-+#endif
-+ case SQLCOM_HA_OPEN:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE))
-+ goto error;
-+ res= mysql_ha_open(thd, first_table, 0);
-+ break;
-+ case SQLCOM_HA_CLOSE:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ res= mysql_ha_close(thd, first_table);
-+ break;
-+ case SQLCOM_HA_READ:
-+ DBUG_ASSERT(first_table == all_tables && first_table != 0);
-+ /*
-+ There is no need to check for table permissions here, because
-+ if a user has no permissions to read a table, he won't be
-+ able to open it (with SQLCOM_HA_OPEN) in the first place.
-+ */
-+ unit->set_limit(select_lex);
-+ res= mysql_ha_read(thd, first_table, lex->ha_read_mode, lex->ident.str,
-+ lex->insert_list, lex->ha_rkey_mode, select_lex->where,
-+ unit->select_limit_cnt, unit->offset_limit_cnt);
-+ break;
-+
-+ case SQLCOM_BEGIN:
-+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ if (begin_trans(thd))
-+ goto error;
-+ if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
-+ {
-+ if (ha_start_consistent_snapshot(thd))
-+ goto error;
-+ }
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_COMMIT:
-+ if (end_trans(thd, lex->tx_release ? COMMIT_RELEASE :
-+ lex->tx_chain ? COMMIT_AND_CHAIN : COMMIT))
-+ goto error;
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_ROLLBACK:
-+ if (end_trans(thd, lex->tx_release ? ROLLBACK_RELEASE :
-+ lex->tx_chain ? ROLLBACK_AND_CHAIN : ROLLBACK))
-+ goto error;
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_RELEASE_SAVEPOINT:
-+ {
-+ SAVEPOINT *sv;
-+ for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
-+ {
-+ if (my_strnncoll(system_charset_info,
-+ (uchar *)lex->ident.str, lex->ident.length,
-+ (uchar *)sv->name, sv->length) == 0)
-+ break;
-+ }
-+ if (sv)
-+ {
-+ if (ha_release_savepoint(thd, sv))
-+ res= TRUE; // cannot happen
-+ else
-+ my_ok(thd);
-+ thd->transaction.savepoints=sv->prev;
-+ }
-+ else
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
-+ break;
-+ }
-+ case SQLCOM_ROLLBACK_TO_SAVEPOINT:
-+ {
-+ SAVEPOINT *sv;
-+ for (sv=thd->transaction.savepoints; sv; sv=sv->prev)
-+ {
-+ if (my_strnncoll(system_charset_info,
-+ (uchar *)lex->ident.str, lex->ident.length,
-+ (uchar *)sv->name, sv->length) == 0)
-+ break;
-+ }
-+ if (sv)
-+ {
-+ if (ha_rollback_to_savepoint(thd, sv))
-+ res= TRUE; // cannot happen
-+ else
-+ {
-+ if (((thd->options & OPTION_KEEP_LOG) ||
-+ thd->transaction.all.modified_non_trans_table) &&
-+ !thd->slave_thread)
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_WARNING_NOT_COMPLETE_ROLLBACK,
-+ ER(ER_WARNING_NOT_COMPLETE_ROLLBACK));
-+ my_ok(thd);
-+ }
-+ thd->transaction.savepoints=sv;
-+ }
-+ else
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "SAVEPOINT", lex->ident.str);
-+ break;
-+ }
-+ case SQLCOM_SAVEPOINT:
-+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
-+ thd->in_sub_stmt) || !opt_using_transactions)
-+ my_ok(thd);
-+ else
-+ {
-+ SAVEPOINT **sv, *newsv;
-+ for (sv=&thd->transaction.savepoints; *sv; sv=&(*sv)->prev)
-+ {
-+ if (my_strnncoll(system_charset_info,
-+ (uchar *)lex->ident.str, lex->ident.length,
-+ (uchar *)(*sv)->name, (*sv)->length) == 0)
-+ break;
-+ }
-+ if (*sv) /* old savepoint of the same name exists */
-+ {
-+ newsv=*sv;
-+ ha_release_savepoint(thd, *sv); // it cannot fail
-+ *sv=(*sv)->prev;
-+ }
-+ else if ((newsv=(SAVEPOINT *) alloc_root(&thd->transaction.mem_root,
-+ savepoint_alloc_size)) == 0)
-+ {
-+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
-+ break;
-+ }
-+ newsv->name=strmake_root(&thd->transaction.mem_root,
-+ lex->ident.str, lex->ident.length);
-+ newsv->length=lex->ident.length;
-+ /*
-+ if we'll get an error here, don't add new savepoint to the list.
-+ we'll lose a little bit of memory in transaction mem_root, but it'll
-+ be free'd when transaction ends anyway
-+ */
-+ if (ha_savepoint(thd, newsv))
-+ res= TRUE;
-+ else
-+ {
-+ newsv->prev=thd->transaction.savepoints;
-+ thd->transaction.savepoints=newsv;
-+ my_ok(thd);
-+ }
-+ }
-+ break;
-+ case SQLCOM_CREATE_PROCEDURE:
-+ case SQLCOM_CREATE_SPFUNCTION:
-+ {
-+ uint namelen;
-+ char *name;
-+ int sp_result= SP_INTERNAL_ERROR;
-+
-+ DBUG_ASSERT(lex->sphead != 0);
-+ DBUG_ASSERT(lex->sphead->m_db.str); /* Must be initialized in the parser */
-+ /*
-+ Verify that the database name is allowed, optionally
-+ lowercase it.
-+ */
-+ if (check_db_name(&lex->sphead->m_db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), lex->sphead->m_db.str);
-+ goto create_sp_error;
-+ }
-+
-+ /*
-+ Check that a database directory with this name
-+ exists. Design note: This won't work on virtual databases
-+ like information_schema.
-+ */
-+ if (check_db_dir_existence(lex->sphead->m_db.str))
-+ {
-+ my_error(ER_BAD_DB_ERROR, MYF(0), lex->sphead->m_db.str);
-+ goto create_sp_error;
-+ }
-+
-+ if (check_access(thd, CREATE_PROC_ACL, lex->sphead->m_db.str, 0, 0, 0,
-+ is_schema_db(lex->sphead->m_db.str,
-+ lex->sphead->m_db.length)))
-+ goto create_sp_error;
-+
-+ if (end_active_trans(thd))
-+ goto create_sp_error;
-+
-+ name= lex->sphead->name(&namelen);
-+#ifdef HAVE_DLOPEN
-+ if (lex->sphead->m_type == TYPE_ENUM_FUNCTION)
-+ {
-+ udf_func *udf = find_udf(name, namelen);
-+
-+ if (udf)
-+ {
-+ my_error(ER_UDF_EXISTS, MYF(0), name);
-+ goto create_sp_error;
-+ }
-+ }
-+#endif
-+
-+ if (sp_process_definer(thd))
-+ goto create_sp_error;
-+
-+ res= (sp_result= lex->sphead->create(thd));
-+ switch (sp_result) {
-+ case SP_OK: {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ /* only add privileges if really neccessary */
-+
-+ Security_context security_context;
-+ bool restore_backup_context= false;
-+ Security_context *backup= NULL;
-+ LEX_USER *definer= thd->lex->definer;
-+ /*
-+ Check if the definer exists on slave,
-+ then use definer privilege to insert routine privileges to mysql.procs_priv.
-+
-+ For current user of SQL thread has GLOBAL_ACL privilege,
-+ which doesn't any check routine privileges,
-+ so no routine privilege record will insert into mysql.procs_priv.
-+ */
-+ if (thd->slave_thread && is_acl_user(definer->host.str, definer->user.str))
-+ {
-+ security_context.change_security_context(thd,
-+ &thd->lex->definer->user,
-+ &thd->lex->definer->host,
-+ &thd->lex->sphead->m_db,
-+ &backup);
-+ restore_backup_context= true;
-+ }
-+
-+ if (sp_automatic_privileges && !opt_noacl &&
-+ check_routine_access(thd, DEFAULT_CREATE_PROC_ACLS,
-+ lex->sphead->m_db.str, name,
-+ lex->sql_command == SQLCOM_CREATE_PROCEDURE, 1))
-+ {
-+ if (sp_grant_privileges(thd, lex->sphead->m_db.str, name,
-+ lex->sql_command == SQLCOM_CREATE_PROCEDURE))
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_PROC_AUTO_GRANT_FAIL,
-+ ER(ER_PROC_AUTO_GRANT_FAIL));
-+ }
-+
-+ /*
-+ Restore current user with GLOBAL_ACL privilege of SQL thread
-+ */
-+ if (restore_backup_context)
-+ {
-+ DBUG_ASSERT(thd->slave_thread == 1);
-+ thd->security_ctx->restore_security_context(thd, backup);
-+ }
-+
-+#endif
-+ break;
-+ }
-+ case SP_WRITE_ROW_FAILED:
-+ my_error(ER_SP_ALREADY_EXISTS, MYF(0), SP_TYPE_STRING(lex), name);
-+ break;
-+ case SP_BAD_IDENTIFIER:
-+ my_error(ER_TOO_LONG_IDENT, MYF(0), name);
-+ break;
-+ case SP_BODY_TOO_LONG:
-+ my_error(ER_TOO_LONG_BODY, MYF(0), name);
-+ break;
-+ case SP_FLD_STORE_FAILED:
-+ my_error(ER_CANT_CREATE_SROUTINE, MYF(0), name);
-+ break;
-+ default:
-+ my_error(ER_SP_STORE_FAILED, MYF(0), SP_TYPE_STRING(lex), name);
-+ break;
-+ } /* end switch */
-+
-+ /*
-+ Capture all errors within this CASE and
-+ clean up the environment.
-+ */
-+create_sp_error:
-+ if (sp_result != SP_OK )
-+ goto error;
-+ my_ok(thd);
-+ break; /* break super switch */
-+ } /* end case group bracket */
-+ case SQLCOM_CALL:
-+ {
-+ sp_head *sp;
-+
-+ /*
-+ This will cache all SP and SF and open and lock all tables
-+ required for execution.
-+ */
-+ if (check_table_access(thd, SELECT_ACL, all_tables, UINT_MAX, FALSE) ||
-+ open_and_lock_tables(thd, all_tables))
-+ goto error;
-+
-+ /*
-+ By this moment all needed SPs should be in cache so no need to look
-+ into DB.
-+ */
-+ if (!(sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+ &thd->sp_proc_cache, TRUE)))
-+ {
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "PROCEDURE",
-+ lex->spname->m_qname.str);
-+ goto error;
-+ }
-+ else
-+ {
-+ ha_rows select_limit;
-+ /* bits that should be cleared in thd->server_status */
-+ uint bits_to_be_cleared= 0;
-+ /*
-+ Check that the stored procedure doesn't contain Dynamic SQL
-+ and doesn't return result sets: such stored procedures can't
-+ be called from a function or trigger.
-+ */
-+ if (thd->in_sub_stmt)
-+ {
-+ const char *where= (thd->in_sub_stmt & SUB_STMT_TRIGGER ?
-+ "trigger" : "function");
-+ if (sp->is_not_allowed_in_function(where))
-+ goto error;
-+ }
-+
-+ if (sp->m_flags & sp_head::MULTI_RESULTS)
-+ {
-+ if (! (thd->client_capabilities & CLIENT_MULTI_RESULTS))
-+ {
-+ /*
-+ The client does not support multiple result sets being sent
-+ back
-+ */
-+ my_error(ER_SP_BADSELECT, MYF(0), sp->m_qname.str);
-+ goto error;
-+ }
-+ /*
-+ If SERVER_MORE_RESULTS_EXISTS is not set,
-+ then remember that it should be cleared
-+ */
-+ bits_to_be_cleared= (~thd->server_status &
-+ SERVER_MORE_RESULTS_EXISTS);
-+ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
-+ }
-+
-+ if (check_routine_access(thd, EXECUTE_ACL,
-+ sp->m_db.str, sp->m_name.str, TRUE, FALSE))
-+ {
-+ goto error;
-+ }
-+ select_limit= thd->variables.select_limit;
-+ thd->variables.select_limit= HA_POS_ERROR;
-+
-+ /*
-+ We never write CALL statements into binlog:
-+ - If the mode is non-prelocked, each statement will be logged
-+ separately.
-+ - If the mode is prelocked, the invoking statement will care
-+ about writing into binlog.
-+ So just execute the statement.
-+ */
-+ res= sp->execute_procedure(thd, &lex->value_list);
-+ /*
-+ If warnings have been cleared, we have to clear total_warn_count
-+ too, otherwise the clients get confused.
-+ */
-+ if (thd->warn_list.is_empty())
-+ thd->total_warn_count= 0;
-+
-+ thd->variables.select_limit= select_limit;
-+
-+ thd->server_status&= ~bits_to_be_cleared;
-+
-+ if (!res)
-+ my_ok(thd, (ulong) (thd->row_count_func < 0 ? 0 :
-+ thd->row_count_func));
-+ else
-+ {
-+ DBUG_ASSERT(thd->is_error() || thd->killed);
-+ goto error; // Substatement should already have sent error
-+ }
-+ }
-+ break;
-+ }
-+ case SQLCOM_ALTER_PROCEDURE:
-+ case SQLCOM_ALTER_FUNCTION:
-+ {
-+ int sp_result;
-+ sp_head *sp;
-+ st_sp_chistics chistics;
-+
-+ memcpy(&chistics, &lex->sp_chistics, sizeof(chistics));
-+ if (lex->sql_command == SQLCOM_ALTER_PROCEDURE)
-+ sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+ &thd->sp_proc_cache, FALSE);
-+ else
-+ sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-+ &thd->sp_func_cache, FALSE);
-+ mysql_reset_errors(thd, 0);
-+ if (! sp)
-+ {
-+ if (lex->spname->m_db.str)
-+ sp_result= SP_KEY_NOT_FOUND;
-+ else
-+ {
-+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
-+ goto error;
-+ }
-+ }
-+ else
-+ {
-+ if (check_routine_access(thd, ALTER_PROC_ACL, sp->m_db.str,
-+ sp->m_name.str,
-+ lex->sql_command == SQLCOM_ALTER_PROCEDURE, 0))
-+ goto error;
-+
-+ if (end_active_trans(thd))
-+ goto error;
-+ memcpy(&lex->sp_chistics, &chistics, sizeof(lex->sp_chistics));
-+ if ((sp->m_type == TYPE_ENUM_FUNCTION) &&
-+ !trust_function_creators && mysql_bin_log.is_open() &&
-+ !sp->m_chistics->detistic &&
-+ (chistics.daccess == SP_CONTAINS_SQL ||
-+ chistics.daccess == SP_MODIFIES_SQL_DATA))
-+ {
-+ my_message(ER_BINLOG_UNSAFE_ROUTINE,
-+ ER(ER_BINLOG_UNSAFE_ROUTINE), MYF(0));
-+ sp_result= SP_INTERNAL_ERROR;
-+ }
-+ else
-+ {
-+ /*
-+ Note that if you implement the capability of ALTER FUNCTION to
-+ alter the body of the function, this command should be made to
-+ follow the restrictions that log-bin-trust-function-creators=0
-+ already puts on CREATE FUNCTION.
-+ */
-+ /* Conditionally writes to binlog */
-+
-+ int type= lex->sql_command == SQLCOM_ALTER_PROCEDURE ?
-+ TYPE_ENUM_PROCEDURE :
-+ TYPE_ENUM_FUNCTION;
-+
-+ sp_result= sp_update_routine(thd,
-+ type,
-+ lex->spname,
-+ &lex->sp_chistics);
-+ }
-+ }
-+ switch (sp_result)
-+ {
-+ case SP_OK:
-+ my_ok(thd);
-+ break;
-+ case SP_KEY_NOT_FOUND:
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_qname.str);
-+ goto error;
-+ default:
-+ my_error(ER_SP_CANT_ALTER, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_qname.str);
-+ goto error;
-+ }
-+ break;
-+ }
-+ case SQLCOM_DROP_PROCEDURE:
-+ case SQLCOM_DROP_FUNCTION:
-+ {
-+ int sp_result;
-+ int type= (lex->sql_command == SQLCOM_DROP_PROCEDURE ?
-+ TYPE_ENUM_PROCEDURE : TYPE_ENUM_FUNCTION);
-+
-+ sp_result= sp_routine_exists_in_table(thd, type, lex->spname);
-+ mysql_reset_errors(thd, 0);
-+ if (sp_result == SP_OK)
-+ {
-+ char *db= lex->spname->m_db.str;
-+ char *name= lex->spname->m_name.str;
-+
-+ if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
-+ lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
-+ goto error;
-+
-+ if (end_active_trans(thd))
-+ goto error;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (sp_automatic_privileges && !opt_noacl &&
-+ sp_revoke_privileges(thd, db, name,
-+ lex->sql_command == SQLCOM_DROP_PROCEDURE))
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_PROC_AUTO_REVOKE_FAIL,
-+ ER(ER_PROC_AUTO_REVOKE_FAIL));
-+ }
-+#endif
-+ /* Conditionally writes to binlog */
-+
-+ int type= lex->sql_command == SQLCOM_DROP_PROCEDURE ?
-+ TYPE_ENUM_PROCEDURE :
-+ TYPE_ENUM_FUNCTION;
-+
-+ sp_result= sp_drop_routine(thd, type, lex->spname);
-+ }
-+ else
-+ {
-+#ifdef HAVE_DLOPEN
-+ if (lex->sql_command == SQLCOM_DROP_FUNCTION)
-+ {
-+ udf_func *udf = find_udf(lex->spname->m_name.str,
-+ lex->spname->m_name.length);
-+ if (udf)
-+ {
-+ if (check_access(thd, DELETE_ACL, "mysql", 0, 1, 0, 0))
-+ goto error;
-+
-+ if (!(res = mysql_drop_function(thd, &lex->spname->m_name)))
-+ {
-+ my_ok(thd);
-+ break;
-+ }
-+ }
-+ }
-+#endif
-+ if (lex->spname->m_db.str)
-+ sp_result= SP_KEY_NOT_FOUND;
-+ else
-+ {
-+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR), MYF(0));
-+ goto error;
-+ }
-+ }
-+ res= sp_result;
-+ switch (sp_result) {
-+ case SP_OK:
-+ my_ok(thd);
-+ break;
-+ case SP_KEY_NOT_FOUND:
-+ if (lex->drop_if_exists)
-+ {
-+ res= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
-+ SP_COM_STRING(lex), lex->spname->m_name.str);
-+ if (!res)
-+ my_ok(thd);
-+ break;
-+ }
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_qname.str);
-+ goto error;
-+ default:
-+ my_error(ER_SP_DROP_FAILED, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_qname.str);
-+ goto error;
-+ }
-+ break;
-+ }
-+ case SQLCOM_SHOW_CREATE_PROC:
-+ {
-+ if (sp_show_create_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname))
-+ {
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_name.str);
-+ goto error;
-+ }
-+ break;
-+ }
-+ case SQLCOM_SHOW_CREATE_FUNC:
-+ {
-+ if (sp_show_create_routine(thd, TYPE_ENUM_FUNCTION, lex->spname))
-+ {
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_name.str);
-+ goto error;
-+ }
-+ break;
-+ }
-+#ifndef DBUG_OFF
-+ case SQLCOM_SHOW_PROC_CODE:
-+ case SQLCOM_SHOW_FUNC_CODE:
-+ {
-+ sp_head *sp;
-+
-+ if (lex->sql_command == SQLCOM_SHOW_PROC_CODE)
-+ sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, lex->spname,
-+ &thd->sp_proc_cache, FALSE);
-+ else
-+ sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, lex->spname,
-+ &thd->sp_func_cache, FALSE);
-+ if (!sp || sp->show_routine_code(thd))
-+ {
-+ /* We don't distinguish between errors for now */
-+ my_error(ER_SP_DOES_NOT_EXIST, MYF(0),
-+ SP_COM_STRING(lex), lex->spname->m_name.str);
-+ goto error;
-+ }
-+ break;
-+ }
-+#endif // ifndef DBUG_OFF
-+ case SQLCOM_SHOW_CREATE_TRIGGER:
-+ {
-+ if (lex->spname->m_name.length > NAME_LEN)
-+ {
-+ my_error(ER_TOO_LONG_IDENT, MYF(0), lex->spname->m_name.str);
-+ goto error;
-+ }
-+
-+ if (show_create_trigger(thd, lex->spname))
-+ goto error; /* Error has been already logged. */
-+
-+ break;
-+ }
-+ case SQLCOM_CREATE_VIEW:
-+ {
-+ /*
-+ Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
-+ as specified through the thd->lex->create_view_mode flag.
-+ */
-+ if (end_active_trans(thd))
-+ goto error;
-+
-+ res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
-+ break;
-+ }
-+ case SQLCOM_DROP_VIEW:
-+ {
-+ if (check_table_access(thd, DROP_ACL, all_tables, UINT_MAX, FALSE) ||
-+ end_active_trans(thd))
-+ goto error;
-+ /* Conditionally writes to binlog. */
-+ res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
-+ break;
-+ }
-+ case SQLCOM_CREATE_TRIGGER:
-+ {
-+ if (end_active_trans(thd))
-+ goto error;
-+
-+ /* Conditionally writes to binlog. */
-+ res= mysql_create_or_drop_trigger(thd, all_tables, 1);
-+
-+ break;
-+ }
-+ case SQLCOM_DROP_TRIGGER:
-+ {
-+ if (end_active_trans(thd))
-+ goto error;
-+
-+ /* Conditionally writes to binlog. */
-+ res= mysql_create_or_drop_trigger(thd, all_tables, 0);
-+ break;
-+ }
-+ case SQLCOM_XA_START:
-+ if (thd->transaction.xid_state.xa_state == XA_IDLE &&
-+ thd->lex->xa_opt == XA_RESUME)
-+ {
-+ if (! thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+ {
-+ my_error(ER_XAER_NOTA, MYF(0));
-+ break;
-+ }
-+ thd->transaction.xid_state.xa_state= XA_ACTIVE;
-+ my_ok(thd);
-+ break;
-+ }
-+ if (thd->lex->xa_opt != XA_NONE)
-+ { // JOIN is not supported yet. TODO
-+ my_error(ER_XAER_INVAL, MYF(0));
-+ break;
-+ }
-+ if (thd->transaction.xid_state.xa_state != XA_NOTR)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ if (thd->active_transaction() || thd->locked_tables)
-+ {
-+ my_error(ER_XAER_OUTSIDE, MYF(0));
-+ break;
-+ }
-+ DBUG_ASSERT(thd->transaction.xid_state.xid.is_null());
-+ thd->transaction.xid_state.xa_state= XA_ACTIVE;
-+ thd->transaction.xid_state.rm_error= 0;
-+ thd->transaction.xid_state.xid.set(thd->lex->xid);
-+ if (xid_cache_insert(&thd->transaction.xid_state))
-+ {
-+ thd->transaction.xid_state.xa_state= XA_NOTR;
-+ thd->transaction.xid_state.xid.null();
-+ break;
-+ }
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ thd->options= ((thd->options & ~(OPTION_KEEP_LOG)) | OPTION_BEGIN);
-+ thd->server_status|= SERVER_STATUS_IN_TRANS;
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_XA_END:
-+ /* fake it */
-+ if (thd->lex->xa_opt != XA_NONE)
-+ { // SUSPEND and FOR MIGRATE are not supported yet. TODO
-+ my_error(ER_XAER_INVAL, MYF(0));
-+ break;
-+ }
-+ if (thd->transaction.xid_state.xa_state != XA_ACTIVE)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+ {
-+ my_error(ER_XAER_NOTA, MYF(0));
-+ break;
-+ }
-+ if (xa_trans_rolled_back(&thd->transaction.xid_state))
-+ break;
-+ thd->transaction.xid_state.xa_state=XA_IDLE;
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_XA_PREPARE:
-+ if (thd->transaction.xid_state.xa_state != XA_IDLE)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+ {
-+ my_error(ER_XAER_NOTA, MYF(0));
-+ break;
-+ }
-+ if (ha_prepare(thd))
-+ {
-+ my_error(ER_XA_RBROLLBACK, MYF(0));
-+ xid_cache_delete(&thd->transaction.xid_state);
-+ thd->transaction.xid_state.xa_state=XA_NOTR;
-+ break;
-+ }
-+ thd->transaction.xid_state.xa_state=XA_PREPARED;
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_XA_COMMIT:
-+ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+ {
-+ /*
-+ xid_state.in_thd is always true beside of xa recovery
-+ procedure. Note, that there is no race condition here
-+ between xid_cache_search and xid_cache_delete, since we're always
-+ deleting our own XID (thd->lex->xid == thd->transaction.xid_state.xid).
-+ The only case when thd->lex->xid != thd->transaction.xid_state.xid
-+ and xid_state->in_thd == 0 is in ha_recover() functionality,
-+ which is called before starting client connections, and thus is
-+ always single-threaded.
-+ */
-+ XID_STATE *xs=xid_cache_search(thd->lex->xid);
-+ if (!xs || xs->in_thd)
-+ my_error(ER_XAER_NOTA, MYF(0));
-+ else if (xa_trans_rolled_back(xs))
-+ {
-+ ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
-+ xid_cache_delete(xs);
-+ break;
-+ }
-+ else
-+ {
-+ ha_commit_or_rollback_by_xid(thd->lex->xid, 1);
-+ xid_cache_delete(xs);
-+ my_ok(thd);
-+ }
-+ break;
-+ }
-+ if (xa_trans_rolled_back(&thd->transaction.xid_state))
-+ {
-+ xa_trans_rollback(thd);
-+ break;
-+ }
-+ if (thd->transaction.xid_state.xa_state == XA_IDLE &&
-+ thd->lex->xa_opt == XA_ONE_PHASE)
-+ {
-+ int r;
-+ if ((r= ha_commit(thd)))
-+ my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
-+ else
-+ my_ok(thd);
-+ }
-+ else if (thd->transaction.xid_state.xa_state == XA_PREPARED &&
-+ thd->lex->xa_opt == XA_NONE)
-+ {
-+ if (wait_if_global_read_lock(thd, 0, 0))
-+ {
-+ ha_rollback(thd);
-+ my_error(ER_XAER_RMERR, MYF(0));
-+ }
-+ else
-+ {
-+ if (ha_commit_one_phase(thd, 1))
-+ my_error(ER_XAER_RMERR, MYF(0));
-+ else
-+ my_ok(thd);
-+ start_waiting_global_read_lock(thd);
-+ }
-+ }
-+ else
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ thd->options&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ thd->server_status&= ~SERVER_STATUS_IN_TRANS;
-+ xid_cache_delete(&thd->transaction.xid_state);
-+ thd->transaction.xid_state.xa_state=XA_NOTR;
-+ break;
-+ case SQLCOM_XA_ROLLBACK:
-+ if (!thd->transaction.xid_state.xid.eq(thd->lex->xid))
-+ {
-+ XID_STATE *xs=xid_cache_search(thd->lex->xid);
-+ if (!xs || xs->in_thd)
-+ my_error(ER_XAER_NOTA, MYF(0));
-+ else
-+ {
-+ bool ok= !xa_trans_rolled_back(xs);
-+ ha_commit_or_rollback_by_xid(thd->lex->xid, 0);
-+ xid_cache_delete(xs);
-+ if (ok)
-+ my_ok(thd);
-+ }
-+ break;
-+ }
-+ if (thd->transaction.xid_state.xa_state != XA_IDLE &&
-+ thd->transaction.xid_state.xa_state != XA_PREPARED &&
-+ thd->transaction.xid_state.xa_state != XA_ROLLBACK_ONLY)
-+ {
-+ my_error(ER_XAER_RMFAIL, MYF(0),
-+ xa_state_names[thd->transaction.xid_state.xa_state]);
-+ break;
-+ }
-+ if (xa_trans_rollback(thd))
-+ my_error(ER_XAER_RMERR, MYF(0));
-+ else
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_XA_RECOVER:
-+ res= mysql_xa_recover(thd);
-+ break;
-+ case SQLCOM_ALTER_TABLESPACE:
-+ if (check_access(thd, ALTER_ACL, thd->db, 0, 1, 0,
-+ thd->db ? is_schema_db(thd->db, thd->db_length) : 0))
-+ break;
-+ if (!(res= mysql_alter_tablespace(thd, lex->alter_tablespace_info)))
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_INSTALL_PLUGIN:
-+ if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
-+ &thd->lex->ident)))
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_UNINSTALL_PLUGIN:
-+ if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment)))
-+ my_ok(thd);
-+ break;
-+ case SQLCOM_BINLOG_BASE64_EVENT:
-+ {
-+#ifndef EMBEDDED_LIBRARY
-+ mysql_client_binlog_statement(thd);
-+#else /* EMBEDDED_LIBRARY */
-+ my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), "embedded");
-+#endif /* EMBEDDED_LIBRARY */
-+ break;
-+ }
-+ case SQLCOM_CREATE_SERVER:
-+ {
-+ int error;
-+ LEX *lex= thd->lex;
-+ DBUG_PRINT("info", ("case SQLCOM_CREATE_SERVER"));
-+
-+ if (check_global_access(thd, SUPER_ACL))
-+ break;
-+
-+ if ((error= create_server(thd, &lex->server_options)))
-+ {
-+ DBUG_PRINT("info", ("problem creating server <%s>",
-+ lex->server_options.server_name));
-+ my_error(error, MYF(0), lex->server_options.server_name);
-+ break;
-+ }
-+ my_ok(thd, 1);
-+ break;
-+ }
-+ case SQLCOM_ALTER_SERVER:
-+ {
-+ int error;
-+ LEX *lex= thd->lex;
-+ DBUG_PRINT("info", ("case SQLCOM_ALTER_SERVER"));
-+
-+ if (check_global_access(thd, SUPER_ACL))
-+ break;
-+
-+ if ((error= alter_server(thd, &lex->server_options)))
-+ {
-+ DBUG_PRINT("info", ("problem altering server <%s>",
-+ lex->server_options.server_name));
-+ my_error(error, MYF(0), lex->server_options.server_name);
-+ break;
-+ }
-+ my_ok(thd, 1);
-+ break;
-+ }
-+ case SQLCOM_DROP_SERVER:
-+ {
-+ int err_code;
-+ LEX *lex= thd->lex;
-+ DBUG_PRINT("info", ("case SQLCOM_DROP_SERVER"));
-+
-+ if (check_global_access(thd, SUPER_ACL))
-+ break;
-+
-+ if ((err_code= drop_server(thd, &lex->server_options)))
-+ {
-+ if (! lex->drop_if_exists && err_code == ER_FOREIGN_SERVER_DOESNT_EXIST)
-+ {
-+ DBUG_PRINT("info", ("problem dropping server %s",
-+ lex->server_options.server_name));
-+ my_error(err_code, MYF(0), lex->server_options.server_name);
-+ }
-+ else
-+ {
-+ my_ok(thd, 0);
-+ }
-+ break;
-+ }
-+ my_ok(thd, 1);
-+ break;
-+ }
-+ default:
-+#ifndef EMBEDDED_LIBRARY
-+ DBUG_ASSERT(0); /* Impossible */
-+#endif
-+ my_ok(thd);
-+ break;
-+ }
-+ thd_proc_info(thd, "query end");
-+
-+ /*
-+ Binlog-related cleanup:
-+ Reset system variables temporarily modified by SET ONE SHOT.
-+
-+ Exception: If this is a SET, do nothing. This is to allow
-+ mysqlbinlog to print many SET commands (in this case we want the
-+ charset temp setting to live until the real query). This is also
-+ needed so that SET CHARACTER_SET_CLIENT... does not cancel itself
-+ immediately.
-+ */
-+ if (thd->one_shot_set && lex->sql_command != SQLCOM_SET_OPTION)
-+ reset_one_shot_variables(thd);
-+
-+ /*
-+ The return value for ROW_COUNT() is "implementation dependent" if the
-+ statement is not DELETE, INSERT or UPDATE, but -1 is what JDBC and ODBC
-+ wants. We also keep the last value in case of SQLCOM_CALL or
-+ SQLCOM_EXECUTE.
-+ */
-+ if (!(sql_command_flags[lex->sql_command] & CF_HAS_ROW_COUNT))
-+ thd->row_count_func= -1;
-+
-+ goto finish;
-+
-+error:
-+ res= TRUE;
-+
-+finish:
-+ if (need_start_waiting)
-+ {
-+ /*
-+ Release the protection against the global read lock and wake
-+ everyone, who might want to set a global read lock.
-+ */
-+ start_waiting_global_read_lock(thd);
-+ }
-+ DBUG_RETURN(res || thd->is_error());
-+}
-+
-+
-+static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables)
-+{
-+ LEX *lex= thd->lex;
-+ select_result *result=lex->result;
-+ bool res;
-+ /* assign global limit variable if limit is not given */
-+ {
-+ SELECT_LEX *param= lex->unit.global_parameters;
-+ if (!param->explicit_limit)
-+ param->select_limit=
-+ new Item_int((ulonglong) thd->variables.select_limit);
-+ }
-+ if (!(res= open_and_lock_tables(thd, all_tables)))
-+ {
-+ if (lex->describe)
-+ {
-+ /*
-+ We always use select_send for EXPLAIN, even if it's an EXPLAIN
-+ for SELECT ... INTO OUTFILE: a user application should be able
-+ to prepend EXPLAIN to any query and receive output for it,
-+ even if the query itself redirects the output.
-+ */
-+ if (!(result= new select_send()))
-+ return 1; /* purecov: inspected */
-+ thd->send_explain_fields(result);
-+ res= mysql_explain_union(thd, &thd->lex->unit, result);
-+ if (lex->describe & DESCRIBE_EXTENDED)
-+ {
-+ char buff[1024];
-+ String str(buff,(uint32) sizeof(buff), system_charset_info);
-+ str.length(0);
-+ thd->lex->unit.print(&str, QT_ORDINARY);
-+ str.append('\0');
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_YES, str.ptr());
-+ }
-+ if (res)
-+ result->abort();
-+ else
-+ result->send_eof();
-+ delete result;
-+ }
-+ else
-+ {
-+ if (!result && !(result= new select_send()))
-+ return 1; /* purecov: inspected */
-+ query_cache_store_query(thd, all_tables);
-+ res= handle_select(thd, lex, result, 0);
-+ if (result != lex->result)
-+ delete result;
-+ }
-+ }
-+ return res;
-+}
-+
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+/**
-+ Check grants for commands which work only with one table.
-+
-+ @param thd Thread handler
-+ @param privilege requested privilege
-+ @param all_tables global table list of query
-+ @param no_errors FALSE/TRUE - report/don't report error to
-+ the client (using my_error() call).
-+
-+ @retval
-+ 0 OK
-+ @retval
-+ 1 access denied, error is sent to client
-+*/
-+
-+bool check_single_table_access(THD *thd, ulong privilege,
-+ TABLE_LIST *all_tables, bool no_errors)
-+{
-+ Security_context * backup_ctx= thd->security_ctx;
-+
-+ /* we need to switch to the saved context (if any) */
-+ if (all_tables->security_ctx)
-+ thd->security_ctx= all_tables->security_ctx;
-+
-+ const char *db_name;
-+ if ((all_tables->view || all_tables->field_translation) &&
-+ !all_tables->schema_table)
-+ db_name= all_tables->view_db.str;
-+ else
-+ db_name= all_tables->db;
-+
-+ if (check_access(thd, privilege, db_name,
-+ &all_tables->grant.privilege, 0, no_errors,
-+ test(all_tables->schema_table)))
-+ goto deny;
-+
-+ /* Show only 1 table for check_grant */
-+ if (!(all_tables->belong_to_view &&
-+ (thd->lex->sql_command == SQLCOM_SHOW_FIELDS)) &&
-+ check_grant(thd, privilege, all_tables, 0, 1, no_errors))
-+ goto deny;
-+
-+ thd->security_ctx= backup_ctx;
-+ return 0;
-+
-+deny:
-+ thd->security_ctx= backup_ctx;
-+ return 1;
-+}
-+
-+/**
-+ Check grants for commands which work only with one table and all other
-+ tables belonging to subselects or implicitly opened tables.
-+
-+ @param thd Thread handler
-+ @param privilege requested privilege
-+ @param all_tables global table list of query
-+
-+ @retval
-+ 0 OK
-+ @retval
-+ 1 access denied, error is sent to client
-+*/
-+
-+bool check_one_table_access(THD *thd, ulong privilege, TABLE_LIST *all_tables)
-+{
-+ if (check_single_table_access (thd,privilege,all_tables, FALSE))
-+ return 1;
-+
-+ /* Check rights on tables of subselects and implictly opened tables */
-+ TABLE_LIST *subselects_tables, *view= all_tables->view ? all_tables : 0;
-+ if ((subselects_tables= all_tables->next_global))
-+ {
-+ /*
-+ Access rights asked for the first table of a view should be the same
-+ as for the view
-+ */
-+ if (view && subselects_tables->belong_to_view == view)
-+ {
-+ if (check_single_table_access (thd, privilege, subselects_tables, FALSE))
-+ return 1;
-+ subselects_tables= subselects_tables->next_global;
-+ }
-+ if (subselects_tables &&
-+ (check_table_access(thd, SELECT_ACL, subselects_tables, UINT_MAX, FALSE)))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Get the user (global) and database privileges for all used tables.
-+
-+ @param save_priv In this we store global and db level grants for the
-+ table. Note that we don't store db level grants if the
-+ global grants is enough to satisfy the request and the
-+ global grants contains a SELECT grant.
-+
-+ @note
-+ The idea of EXTRA_ACL is that one will be granted access to the table if
-+ one has the asked privilege on any column combination of the table; For
-+ example to be able to check a table one needs to have SELECT privilege on
-+ any column of the table.
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 If we can't get the privileges and we don't use table/column
-+ grants.
-+*/
-+bool
-+check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
-+ bool dont_check_global_grants, bool no_errors, bool schema_db)
-+{
-+ Security_context *sctx= thd->security_ctx;
-+ ulong db_access;
-+ /*
-+ GRANT command:
-+ In case of database level grant the database name may be a pattern,
-+ in case of table|column level grant the database name can not be a pattern.
-+ We use 'dont_check_global_grants' as a flag to determine
-+ if it's database level grant command
-+ (see SQLCOM_GRANT case, mysql_execute_command() function) and
-+ set db_is_pattern according to 'dont_check_global_grants' value.
-+ */
-+ bool db_is_pattern= (test(want_access & GRANT_ACL) &&
-+ dont_check_global_grants);
-+ ulong dummy;
-+ DBUG_ENTER("check_access");
-+ DBUG_PRINT("enter",("db: %s want_access: %lu master_access: %lu",
-+ db ? db : "", want_access, sctx->master_access));
-+ if (save_priv)
-+ *save_priv=0;
-+ else
-+ save_priv= &dummy;
-+
-+ thd_proc_info(thd, "checking permissions");
-+ if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
-+ {
-+ DBUG_PRINT("error",("No database"));
-+ if (!no_errors)
-+ my_message(ER_NO_DB_ERROR, ER(ER_NO_DB_ERROR),
-+ MYF(0)); /* purecov: tested */
-+ DBUG_RETURN(TRUE); /* purecov: tested */
-+ }
-+
-+ if (schema_db)
-+ {
-+ if ((!(sctx->master_access & FILE_ACL) && (want_access & FILE_ACL)) ||
-+ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
-+ {
-+ if (!no_errors)
-+ {
-+ const char *db_name= db ? db : thd->db;
-+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+ sctx->priv_user, sctx->priv_host, db_name);
-+ }
-+ DBUG_RETURN(TRUE);
-+ }
-+ else
-+ {
-+ *save_priv= SELECT_ACL;
-+ DBUG_RETURN(FALSE);
-+ }
-+ }
-+
-+ if ((sctx->master_access & want_access) == want_access)
-+ {
-+ /*
-+ If we don't have a global SELECT privilege, we have to get the database
-+ specific access rights to be able to handle queries of type
-+ UPDATE t1 SET a=1 WHERE b > 0
-+ */
-+ db_access= sctx->db_access;
-+ if (!(sctx->master_access & SELECT_ACL) &&
-+ (db && (!thd->db || db_is_pattern || strcmp(db,thd->db))))
-+ db_access=acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
-+ db_is_pattern);
-+ *save_priv=sctx->master_access | db_access;
-+ DBUG_RETURN(FALSE);
-+ }
-+ if (((want_access & ~sctx->master_access) & ~(DB_ACLS | EXTRA_ACL)) ||
-+ (! db && dont_check_global_grants))
-+ { // We can never grant this
-+ DBUG_PRINT("error",("No possible access"));
-+ if (!no_errors)
-+ my_error(ER_ACCESS_DENIED_ERROR, MYF(0),
-+ sctx->priv_user,
-+ sctx->priv_host,
-+ (thd->password ?
-+ ER(ER_YES) :
-+ ER(ER_NO))); /* purecov: tested */
-+ DBUG_RETURN(TRUE); /* purecov: tested */
-+ }
-+
-+ if (db == any_db)
-+ DBUG_RETURN(FALSE); // Allow select on anything
-+
-+ if (db && (!thd->db || db_is_pattern || strcmp(db,thd->db)))
-+ db_access= acl_get(sctx->host, sctx->ip, sctx->priv_user, db,
-+ db_is_pattern);
-+ else
-+ db_access= sctx->db_access;
-+ DBUG_PRINT("info",("db_access: %lu", db_access));
-+ /* Remove SHOW attribute and access rights we already have */
-+ want_access &= ~(sctx->master_access | EXTRA_ACL);
-+ DBUG_PRINT("info",("db_access: %lu want_access: %lu",
-+ db_access, want_access));
-+ db_access= ((*save_priv=(db_access | sctx->master_access)) & want_access);
-+
-+ if (db_access == want_access ||
-+ (!dont_check_global_grants &&
-+ !(want_access & ~(db_access | TABLE_ACLS | PROC_ACLS))))
-+ DBUG_RETURN(FALSE); /* Ok */
-+
-+ DBUG_PRINT("error",("Access denied"));
-+ if (!no_errors)
-+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+ sctx->priv_user, sctx->priv_host,
-+ (db ? db : (thd->db ?
-+ thd->db :
-+ "unknown"))); /* purecov: tested */
-+ DBUG_RETURN(TRUE); /* purecov: tested */
-+}
-+
-+
-+static bool check_show_access(THD *thd, TABLE_LIST *table)
-+{
-+ switch (get_schema_table_idx(table->schema_table)) {
-+ case SCH_SCHEMATA:
-+ return (specialflag & SPECIAL_SKIP_SHOW_DB) &&
-+ check_global_access(thd, SHOW_DB_ACL);
-+
-+ case SCH_TABLE_NAMES:
-+ case SCH_TABLES:
-+ case SCH_VIEWS:
-+ case SCH_TRIGGERS:
-+ case SCH_EVENTS:
-+ {
-+ const char *dst_db_name= table->schema_select_lex->db;
-+
-+ DBUG_ASSERT(dst_db_name);
-+
-+ if (check_access(thd, SELECT_ACL, dst_db_name,
-+ &thd->col_access, FALSE, FALSE,
-+ is_schema_db(dst_db_name)))
-+ return TRUE;
-+
-+ if (!thd->col_access && check_grant_db(thd, dst_db_name))
-+ {
-+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+ thd->security_ctx->priv_user,
-+ thd->security_ctx->priv_host,
-+ dst_db_name);
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+ }
-+
-+ case SCH_COLUMNS:
-+ case SCH_STATISTICS:
-+ {
-+ TABLE_LIST *dst_table;
-+ dst_table= table->schema_select_lex->table_list.first;
-+
-+ DBUG_ASSERT(dst_table);
-+
-+ if (check_access(thd, SELECT_ACL | EXTRA_ACL,
-+ dst_table->db,
-+ &dst_table->grant.privilege,
-+ FALSE, FALSE,
-+ test(dst_table->schema_table)))
-+ return FALSE;
-+
-+ return (check_grant(thd, SELECT_ACL, dst_table, 2, UINT_MAX, FALSE));
-+ }
-+ default:
-+ break;
-+ }
-+
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Check the privilege for all used tables.
-+
-+ @param thd Thread context
-+ @param want_access Privileges requested
-+ @param tables List of tables to be checked
-+ @param number Check at most this number of tables.
-+ @param no_errors FALSE/TRUE - report/don't report error to
-+ the client (using my_error() call).
-+
-+ @note
-+ Table privileges are cached in the table list for GRANT checking.
-+ This functions assumes that table list used and
-+ thd->lex->query_tables_own_last value correspond to each other
-+ (the latter should be either 0 or point to next_global member
-+ of one of elements of this table list).
-+
-+ @retval FALSE OK
-+ @retval TRUE Access denied
-+*/
-+
-+bool
-+check_table_access(THD *thd, ulong want_access,TABLE_LIST *tables,
-+ uint number, bool no_errors)
-+{
-+ TABLE_LIST *org_tables= tables;
-+ TABLE_LIST *first_not_own_table= thd->lex->first_not_own_table();
-+ uint i= 0;
-+ Security_context *sctx= thd->security_ctx, *backup_ctx= thd->security_ctx;
-+ /*
-+ The check that first_not_own_table is not reached is for the case when
-+ the given table list refers to the list for prelocking (contains tables
-+ of other queries). For simple queries first_not_own_table is 0.
-+ */
-+ for (; i < number && tables != first_not_own_table;
-+ tables= tables->next_global, i++)
-+ {
-+ if (tables->security_ctx)
-+ sctx= tables->security_ctx;
-+ else
-+ sctx= backup_ctx;
-+
-+ if (tables->schema_table &&
-+ (want_access & ~(SELECT_ACL | EXTRA_ACL | FILE_ACL)))
-+ {
-+ if (!no_errors)
-+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+ sctx->priv_user, sctx->priv_host,
-+ INFORMATION_SCHEMA_NAME.str);
-+ return TRUE;
-+ }
-+ /*
-+ Register access for view underlying table.
-+ Remove SHOW_VIEW_ACL, because it will be checked during making view
-+ */
-+ tables->grant.orig_want_privilege= (want_access & ~SHOW_VIEW_ACL);
-+
-+ if (tables->schema_table_reformed)
-+ {
-+ if (check_show_access(thd, tables))
-+ goto deny;
-+
-+ continue;
-+ }
-+
-+ if (tables->is_anonymous_derived_table() ||
-+ (tables->table && (int)tables->table->s->tmp_table))
-+ continue;
-+ thd->security_ctx= sctx;
-+ if ((sctx->master_access & want_access) ==
-+ (want_access & ~EXTRA_ACL) &&
-+ thd->db)
-+ tables->grant.privilege= want_access;
-+ else if (tables->db && thd->db && strcmp(tables->db, thd->db) == 0)
-+ {
-+ if (check_access(thd, want_access, tables->get_db_name(),
-+ &tables->grant.privilege, 0, no_errors,
-+ test(tables->schema_table)))
-+ goto deny; // Access denied
-+ }
-+ else if (check_access(thd, want_access, tables->get_db_name(),
-+ &tables->grant.privilege, 0, no_errors,
-+ test(tables->schema_table)))
-+ goto deny;
-+ }
-+ thd->security_ctx= backup_ctx;
-+ return check_grant(thd,want_access & ~EXTRA_ACL,org_tables,
-+ test(want_access & EXTRA_ACL), number, no_errors);
-+deny:
-+ thd->security_ctx= backup_ctx;
-+ return TRUE;
-+}
-+
-+
-+bool
-+check_routine_access(THD *thd, ulong want_access,char *db, char *name,
-+ bool is_proc, bool no_errors)
-+{
-+ TABLE_LIST tables[1];
-+
-+ bzero((char *)tables, sizeof(TABLE_LIST));
-+ tables->db= db;
-+ tables->table_name= tables->alias= name;
-+
-+ /*
-+ The following test is just a shortcut for check_access() (to avoid
-+ calculating db_access) under the assumption that it's common to
-+ give persons global right to execute all stored SP (but not
-+ necessary to create them).
-+ */
-+ if ((thd->security_ctx->master_access & want_access) == want_access)
-+ tables->grant.privilege= want_access;
-+ else if (check_access(thd,want_access,db,&tables->grant.privilege,
-+ 0, no_errors, 0))
-+ return TRUE;
-+
-+ return check_grant_routine(thd, want_access, tables, is_proc, no_errors);
-+}
-+
-+
-+/**
-+ Check if the routine has any of the routine privileges.
-+
-+ @param thd Thread handler
-+ @param db Database name
-+ @param name Routine name
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error
-+*/
-+
-+bool check_some_routine_access(THD *thd, const char *db, const char *name,
-+ bool is_proc)
-+{
-+ ulong save_priv;
-+ if (thd->security_ctx->master_access & SHOW_PROC_ACLS)
-+ return FALSE;
-+ /*
-+ There are no routines in information_schema db. So we can safely
-+ pass zero to last paramter of check_access function
-+ */
-+ if (!check_access(thd, SHOW_PROC_ACLS, db, &save_priv, 0, 1, 0) ||
-+ (save_priv & SHOW_PROC_ACLS))
-+ return FALSE;
-+ return check_routine_level_acl(thd, db, name, is_proc);
-+}
-+
-+
-+/*
-+ Check if the given table has any of the asked privileges
-+
-+ @param thd Thread handler
-+ @param want_access Bitmap of possible privileges to check for
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error
-+*/
-+
-+bool check_some_access(THD *thd, ulong want_access, TABLE_LIST *table)
-+{
-+ ulong access;
-+ DBUG_ENTER("check_some_access");
-+
-+ /* This loop will work as long as we have less than 32 privileges */
-+ for (access= 1; access < want_access ; access<<= 1)
-+ {
-+ if (access & want_access)
-+ {
-+ if (!check_access(thd, access, table->db,
-+ &table->grant.privilege, 0, 1,
-+ test(table->schema_table)) &&
-+ !check_grant(thd, access, table, 0, 1, 1))
-+ DBUG_RETURN(0);
-+ }
-+ }
-+ DBUG_PRINT("exit",("no matching access rights"));
-+ DBUG_RETURN(1);
-+}
-+
-+#endif /*NO_EMBEDDED_ACCESS_CHECKS*/
-+
-+
-+/**
-+ check for global access and give descriptive error message if it fails.
-+
-+ @param thd Thread handler
-+ @param want_access Use should have any of these global rights
-+
-+ @warning
-+ One gets access right if one has ANY of the rights in want_access.
-+ This is useful as one in most cases only need one global right,
-+ but in some case we want to check if the user has SUPER or
-+ REPL_CLIENT_ACL rights.
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 Access denied. In this case an error is sent to the client
-+*/
-+
-+bool check_global_access(THD *thd, ulong want_access)
-+{
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ char command[128];
-+ if ((thd->security_ctx->master_access & want_access))
-+ return 0;
-+ get_privilege_desc(command, sizeof(command), want_access);
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), command);
-+ return 1;
-+#else
-+ return 0;
-+#endif
-+}
-+
-+/****************************************************************************
-+ Check stack size; Send error if there isn't enough stack to continue
-+****************************************************************************/
-+
-+#ifndef EMBEDDED_LIBRARY
-+
-+#if STACK_DIRECTION < 0
-+#define used_stack(A,B) (long) (A - B)
-+#else
-+#define used_stack(A,B) (long) (B - A)
-+#endif
-+
-+#ifndef DBUG_OFF
-+long max_stack_used;
-+#endif
-+
-+/**
-+ @note
-+ Note: The 'buf' parameter is necessary, even if it is unused here.
-+ - fix_fields functions has a "dummy" buffer large enough for the
-+ corresponding exec. (Thus we only have to check in fix_fields.)
-+ - Passing to check_stack_overrun() prevents the compiler from removing it.
-+*/
-+bool check_stack_overrun(THD *thd, long margin,
-+ uchar *buf __attribute__((unused)))
-+{
-+ long stack_used;
-+ DBUG_ASSERT(thd == current_thd);
-+ if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
-+ (long) (my_thread_stack_size - margin))
-+ {
-+ char ebuff[MYSQL_ERRMSG_SIZE];
-+ my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
-+ stack_used, my_thread_stack_size, margin);
-+ my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
-+ thd->fatal_error();
-+ return 1;
-+ }
-+#ifndef DBUG_OFF
-+ max_stack_used= max(max_stack_used, stack_used);
-+#endif
-+ return 0;
-+}
-+#endif /* EMBEDDED_LIBRARY */
-+
-+#define MY_YACC_INIT 1000 // Start with big alloc
-+#define MY_YACC_MAX 32000 // Because of 'short'
-+
-+bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, ulong *yystacksize)
-+{
-+ Yacc_state *state= & current_thd->m_parser_state->m_yacc;
-+ ulong old_info=0;
-+ DBUG_ASSERT(state);
-+ if ((uint) *yystacksize >= MY_YACC_MAX)
-+ return 1;
-+ if (!state->yacc_yyvs)
-+ old_info= *yystacksize;
-+ *yystacksize= set_zone((*yystacksize)*2,MY_YACC_INIT,MY_YACC_MAX);
-+ if (!(state->yacc_yyvs= (uchar*)
-+ my_realloc(state->yacc_yyvs,
-+ *yystacksize*sizeof(**yyvs),
-+ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))) ||
-+ !(state->yacc_yyss= (uchar*)
-+ my_realloc(state->yacc_yyss,
-+ *yystacksize*sizeof(**yyss),
-+ MYF(MY_ALLOW_ZERO_PTR | MY_FREE_ON_ERROR))))
-+ return 1;
-+ if (old_info)
-+ {
-+ /*
-+ Only copy the old stack on the first call to my_yyoverflow(),
-+ when replacing a static stack (YYINITDEPTH) by a dynamic stack.
-+ For subsequent calls, my_realloc already did preserve the old stack.
-+ */
-+ memcpy(state->yacc_yyss, *yyss, old_info*sizeof(**yyss));
-+ memcpy(state->yacc_yyvs, *yyvs, old_info*sizeof(**yyvs));
-+ }
-+ *yyss= (short*) state->yacc_yyss;
-+ *yyvs= (YYSTYPE*) state->yacc_yyvs;
-+ return 0;
-+}
-+
-+
-+/**
-+ Reset THD part responsible for command processing state.
-+
-+ This needs to be called before execution of every statement
-+ (prepared or conventional).
-+ It is not called by substatements of routines.
-+
-+ @todo
-+ Make it a method of THD and align its name with the rest of
-+ reset/end/start/init methods.
-+ @todo
-+ Call it after we use THD for queries, not before.
-+*/
-+
-+void mysql_reset_thd_for_next_command(THD *thd)
-+{
-+ DBUG_ENTER("mysql_reset_thd_for_next_command");
-+ DBUG_ASSERT(!thd->spcont); /* not for substatements of routines */
-+ DBUG_ASSERT(! thd->in_sub_stmt);
-+ thd->free_list= 0;
-+ thd->select_number= 1;
-+ /*
-+ Those two lines below are theoretically unneeded as
-+ THD::cleanup_after_query() should take care of this already.
-+ */
-+ thd->auto_inc_intervals_in_cur_stmt_for_binlog.empty();
-+ thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
-+
-+ thd->query_start_used= 0;
-+ thd->is_fatal_error= thd->time_zone_used= 0;
-+ /*
-+ Clear the status flag that are expected to be cleared at the
-+ beginning of each SQL statement.
-+ */
-+ thd->server_status&= ~SERVER_STATUS_CLEAR_SET;
-+ /*
-+ If in autocommit mode and not in a transaction, reset
-+ OPTION_STATUS_NO_TRANS_UPDATE | OPTION_KEEP_LOG to not get warnings
-+ in ha_rollback_trans() about some tables couldn't be rolled back.
-+ */
-+ if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
-+ {
-+ thd->options&= ~OPTION_KEEP_LOG;
-+ thd->transaction.all.modified_non_trans_table= FALSE;
-+ }
-+ DBUG_ASSERT(thd->security_ctx== &thd->main_security_ctx);
-+ thd->thread_specific_used= FALSE;
-+
-+ if (opt_bin_log)
-+ {
-+ reset_dynamic(&thd->user_var_events);
-+ thd->user_var_events_alloc= thd->mem_root;
-+ }
-+ thd->clear_error();
-+ thd->main_da.reset_diagnostics_area();
-+ thd->total_warn_count=0; // Warnings for this query
-+ thd->rand_used= 0;
-+ thd->sent_row_count= thd->examined_row_count= 0;
-+
-+ /*
-+ Because we come here only for start of top-statements, binlog format is
-+ constant inside a complex statement (using stored functions) etc.
-+ */
-+ thd->reset_current_stmt_binlog_row_based();
-+
-+ DBUG_PRINT("debug",
-+ ("current_stmt_binlog_row_based: %d",
-+ thd->current_stmt_binlog_row_based));
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Resets the lex->current_select object.
-+ @note It is assumed that lex->current_select != NULL
-+
-+ This function is a wrapper around select_lex->init_select() with an added
-+ check for the special situation when using INTO OUTFILE and LOAD DATA.
-+*/
-+
-+void
-+mysql_init_select(LEX *lex)
-+{
-+ SELECT_LEX *select_lex= lex->current_select;
-+ select_lex->init_select();
-+ lex->wild= 0;
-+ if (select_lex == &lex->select_lex)
-+ {
-+ DBUG_ASSERT(lex->result == 0);
-+ lex->exchange= 0;
-+ }
-+}
-+
-+
-+/**
-+ Used to allocate a new SELECT_LEX object on the current thd mem_root and
-+ link it into the relevant lists.
-+
-+ This function is always followed by mysql_init_select.
-+
-+ @see mysql_init_select
-+
-+ @retval TRUE An error occurred
-+ @retval FALSE The new SELECT_LEX was successfully allocated.
-+*/
-+
-+bool
-+mysql_new_select(LEX *lex, bool move_down)
-+{
-+ SELECT_LEX *select_lex;
-+ THD *thd= lex->thd;
-+ DBUG_ENTER("mysql_new_select");
-+
-+ if (!(select_lex= new (thd->mem_root) SELECT_LEX()))
-+ DBUG_RETURN(1);
-+ select_lex->select_number= ++thd->select_number;
-+ select_lex->parent_lex= lex; /* Used in init_query. */
-+ select_lex->init_query();
-+ select_lex->init_select();
-+ lex->nest_level++;
-+ if (lex->nest_level > (int) MAX_SELECT_NESTING)
-+ {
-+ my_error(ER_TOO_HIGH_LEVEL_OF_NESTING_FOR_SELECT,MYF(0),MAX_SELECT_NESTING);
-+ DBUG_RETURN(1);
-+ }
-+ select_lex->nest_level= lex->nest_level;
-+ if (move_down)
-+ {
-+ SELECT_LEX_UNIT *unit;
-+ lex->subqueries= TRUE;
-+ /* first select_lex of subselect or derived table */
-+ if (!(unit= new (thd->mem_root) SELECT_LEX_UNIT()))
-+ DBUG_RETURN(1);
-+
-+ unit->init_query();
-+ unit->init_select();
-+ unit->thd= thd;
-+ unit->include_down(lex->current_select);
-+ unit->link_next= 0;
-+ unit->link_prev= 0;
-+ unit->return_to= lex->current_select;
-+ select_lex->include_down(unit);
-+ /*
-+ By default we assume that it is usual subselect and we have outer name
-+ resolution context, if no we will assign it to 0 later
-+ */
-+ select_lex->context.outer_context= &select_lex->outer_select()->context;
-+ }
-+ else
-+ {
-+ if (lex->current_select->order_list.first && !lex->current_select->braces)
-+ {
-+ my_error(ER_WRONG_USAGE, MYF(0), "UNION", "ORDER BY");
-+ DBUG_RETURN(1);
-+ }
-+ select_lex->include_neighbour(lex->current_select);
-+ SELECT_LEX_UNIT *unit= select_lex->master_unit();
-+ if (!unit->fake_select_lex && unit->add_fake_select_lex(lex->thd))
-+ DBUG_RETURN(1);
-+ select_lex->context.outer_context=
-+ unit->first_select()->context.outer_context;
-+ }
-+
-+ select_lex->master_unit()->global_parameters= select_lex;
-+ select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
-+ lex->current_select= select_lex;
-+ /*
-+ in subquery is SELECT query and we allow resolution of names in SELECT
-+ list
-+ */
-+ select_lex->context.resolve_in_select_list= TRUE;
-+ DBUG_RETURN(0);
-+}
-+
-+/**
-+ Create a select to return the same output as 'SELECT @@var_name'.
-+
-+ Used for SHOW COUNT(*) [ WARNINGS | ERROR].
-+
-+ This will crash with a core dump if the variable doesn't exists.
-+
-+ @param var_name Variable name
-+*/
-+
-+void create_select_for_variable(const char *var_name)
-+{
-+ THD *thd;
-+ LEX *lex;
-+ LEX_STRING tmp, null_lex_string;
-+ Item *var;
-+ char buff[MAX_SYS_VAR_LENGTH*2+4+8], *end;
-+ DBUG_ENTER("create_select_for_variable");
-+
-+ thd= current_thd;
-+ lex= thd->lex;
-+ mysql_init_select(lex);
-+ lex->sql_command= SQLCOM_SELECT;
-+ tmp.str= (char*) var_name;
-+ tmp.length=strlen(var_name);
-+ bzero((char*) &null_lex_string.str, sizeof(null_lex_string));
-+ /*
-+ We set the name of Item to @@session.var_name because that then is used
-+ as the column name in the output.
-+ */
-+ if ((var= get_system_var(thd, OPT_SESSION, tmp, null_lex_string)))
-+ {
-+ end= strxmov(buff, "@@session.", var_name, NullS);
-+ var->set_name(buff, end-buff, system_charset_info);
-+ add_item_to_list(thd, var);
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+void mysql_init_multi_delete(LEX *lex)
-+{
-+ lex->sql_command= SQLCOM_DELETE_MULTI;
-+ mysql_init_select(lex);
-+ lex->select_lex.select_limit= 0;
-+ lex->unit.select_limit_cnt= HA_POS_ERROR;
-+ lex->select_lex.table_list.save_and_clear(&lex->auxiliary_table_list);
-+ lex->lock_option= TL_READ_DEFAULT;
-+ lex->query_tables= 0;
-+ lex->query_tables_last= &lex->query_tables;
-+}
-+
-+
-+/*
-+ When you modify mysql_parse(), you may need to mofify
-+ mysql_test_parse_for_slave() in this same file.
-+*/
-+
-+/**
-+ Parse a query.
-+
-+ @param thd Current thread
-+ @param rawbuf Begining of the query text
-+ @param length Length of the query text
-+ @param[out] found_semicolon For multi queries, position of the character of
-+ the next query in the query text.
-+*/
-+
-+void mysql_parse(THD *thd, char *rawbuf, uint length,
-+ const char ** found_semicolon)
-+{
-+ DBUG_ENTER("mysql_parse");
-+
-+ DBUG_EXECUTE_IF("parser_debug", turn_parser_debug_on(););
-+
-+ /*
-+ Warning.
-+ The purpose of query_cache_send_result_to_client() is to lookup the
-+ query in the query cache first, to avoid parsing and executing it.
-+ So, the natural implementation would be to:
-+ - first, call query_cache_send_result_to_client,
-+ - second, if caching failed, initialise the lexical and syntactic parser.
-+ The problem is that the query cache depends on a clean initialization
-+ of (among others) lex->safe_to_cache_query and thd->server_status,
-+ which are reset respectively in
-+ - lex_start()
-+ - mysql_reset_thd_for_next_command()
-+ So, initializing the lexical analyser *before* using the query cache
-+ is required for the cache to work properly.
-+ FIXME: cleanup the dependencies in the code to simplify this.
-+ */
-+ lex_start(thd);
-+ mysql_reset_thd_for_next_command(thd);
-+
-+ if (query_cache_send_result_to_client(thd, rawbuf, length) <= 0)
-+ {
-+ LEX *lex= thd->lex;
-+
-+ sp_cache_flush_obsolete(&thd->sp_proc_cache);
-+ sp_cache_flush_obsolete(&thd->sp_func_cache);
-+
-+ Parser_state parser_state;
-+ bool err;
-+ if (!(err= parser_state.init(thd, rawbuf, length)))
-+ {
-+ err= parse_sql(thd, & parser_state, NULL);
-+ *found_semicolon= parser_state.m_lip.found_semicolon;
-+ }
-+ else
-+ *found_semicolon= NULL;
-+
-+ if (!err)
-+ {
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (mqh_used && thd->user_connect &&
-+ check_mqh(thd, lex->sql_command))
-+ {
-+ thd->net.error = 0;
-+ }
-+ else
-+#endif
-+ {
-+ if (! thd->is_error())
-+ {
-+ /*
-+ Binlog logs a string starting from thd->query and having length
-+ thd->query_length; so we set thd->query_length correctly (to not
-+ log several statements in one event, when we executed only first).
-+ We set it to not see the ';' (otherwise it would get into binlog
-+ and Query_log_event::print() would give ';;' output).
-+ This also helps display only the current query in SHOW
-+ PROCESSLIST.
-+ Note that we don't need LOCK_thread_count to modify query_length.
-+ */
-+ if (*found_semicolon && (ulong) (*found_semicolon - thd->query()))
-+ thd->set_query_inner(thd->query(),
-+ (uint32) (*found_semicolon -
-+ thd->query() - 1));
-+ /* Actually execute the query */
-+ if (*found_semicolon)
-+ {
-+ lex->safe_to_cache_query= 0;
-+ thd->server_status|= SERVER_MORE_RESULTS_EXISTS;
-+ }
-+ lex->set_trg_event_type_for_tables();
-+ mysql_execute_command(thd);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ DBUG_ASSERT(thd->is_error());
-+ DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
-+ thd->is_fatal_error));
-+
-+ query_cache_abort(&thd->net);
-+ }
-+ if (thd->lex->sphead)
-+ {
-+ delete thd->lex->sphead;
-+ thd->lex->sphead= 0;
-+ }
-+ lex->unit.cleanup();
-+ thd_proc_info(thd, "freeing items");
-+ thd->end_statement();
-+ thd->cleanup_after_query();
-+ DBUG_ASSERT(thd->change_list.is_empty());
-+ }
-+ else
-+ {
-+ /* There are no multi queries in the cache. */
-+ *found_semicolon= NULL;
-+ }
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+#ifdef HAVE_REPLICATION
-+/*
-+ Usable by the replication SQL thread only: just parse a query to know if it
-+ can be ignored because of replicate-*-table rules.
-+
-+ @retval
-+ 0 cannot be ignored
-+ @retval
-+ 1 can be ignored
-+*/
-+
-+bool mysql_test_parse_for_slave(THD *thd, char *rawbuf, uint length)
-+{
-+ LEX *lex= thd->lex;
-+ bool error= 0;
-+ DBUG_ENTER("mysql_test_parse_for_slave");
-+
-+ Parser_state parser_state;
-+ if (!(error= parser_state.init(thd, rawbuf, length)))
-+ {
-+ lex_start(thd);
-+ mysql_reset_thd_for_next_command(thd);
-+
-+ if (!parse_sql(thd, & parser_state, NULL) &&
-+ all_tables_not_ok(thd, lex->select_lex.table_list.first))
-+ error= 1; /* Ignore question */
-+ thd->end_statement();
-+ }
-+ thd->cleanup_after_query();
-+ DBUG_RETURN(error);
-+}
-+#endif
-+
-+
-+
-+/**
-+ Store field definition for create.
-+
-+ @return
-+ Return 0 if ok
-+*/
-+
-+bool add_field_to_list(THD *thd, LEX_STRING *field_name, enum_field_types type,
-+ char *length, char *decimals,
-+ uint type_modifier,
-+ Item *default_value, Item *on_update_value,
-+ LEX_STRING *comment,
-+ char *change,
-+ List<String> *interval_list, CHARSET_INFO *cs,
-+ uint uint_geom_type)
-+{
-+ register Create_field *new_field;
-+ LEX *lex= thd->lex;
-+ DBUG_ENTER("add_field_to_list");
-+
-+ if (check_string_char_length(field_name, "", NAME_CHAR_LEN,
-+ system_charset_info, 1))
-+ {
-+ my_error(ER_TOO_LONG_IDENT, MYF(0), field_name->str); /* purecov: inspected */
-+ DBUG_RETURN(1); /* purecov: inspected */
-+ }
-+ if (type_modifier & PRI_KEY_FLAG)
-+ {
-+ Key *key;
-+ lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
-+ key= new Key(Key::PRIMARY, NullS,
-+ &default_key_create_info,
-+ 0, lex->col_list);
-+ lex->alter_info.key_list.push_back(key);
-+ lex->col_list.empty();
-+ }
-+ if (type_modifier & (UNIQUE_FLAG | UNIQUE_KEY_FLAG))
-+ {
-+ Key *key;
-+ lex->col_list.push_back(new Key_part_spec(field_name->str, 0));
-+ key= new Key(Key::UNIQUE, NullS,
-+ &default_key_create_info, 0,
-+ lex->col_list);
-+ lex->alter_info.key_list.push_back(key);
-+ lex->col_list.empty();
-+ }
-+
-+ if (default_value)
-+ {
-+ /*
-+ Default value should be literal => basic constants =>
-+ no need fix_fields()
-+
-+ We allow only one function as part of default value -
-+ NOW() as default for TIMESTAMP type.
-+ */
-+ if (default_value->type() == Item::FUNC_ITEM &&
-+ !(((Item_func*)default_value)->functype() == Item_func::NOW_FUNC &&
-+ type == MYSQL_TYPE_TIMESTAMP))
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
-+ DBUG_RETURN(1);
-+ }
-+ else if (default_value->type() == Item::NULL_ITEM)
-+ {
-+ default_value= 0;
-+ if ((type_modifier & (NOT_NULL_FLAG | AUTO_INCREMENT_FLAG)) ==
-+ NOT_NULL_FLAG)
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ else if (type_modifier & AUTO_INCREMENT_FLAG)
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), field_name->str);
-+ DBUG_RETURN(1);
-+ }
-+ }
-+
-+ if (on_update_value && type != MYSQL_TYPE_TIMESTAMP)
-+ {
-+ my_error(ER_INVALID_ON_UPDATE, MYF(0), field_name->str);
-+ DBUG_RETURN(1);
-+ }
-+
-+ if (type == MYSQL_TYPE_TIMESTAMP && length)
-+ {
-+ /* Display widths are no longer supported for TIMSTAMP as of MySQL 4.1.
-+ In other words, for declarations such as TIMESTAMP(2), TIMESTAMP(4),
-+ and so on, the display width is ignored.
-+ */
-+ char buf[32];
-+ my_snprintf(buf, sizeof(buf), "TIMESTAMP(%s)", length);
-+ WARN_DEPRECATED(thd, "6.0", buf, "'TIMESTAMP'");
-+ }
-+
-+ if (!(new_field= new Create_field()) ||
-+ new_field->init(thd, field_name->str, type, length, decimals, type_modifier,
-+ default_value, on_update_value, comment, change,
-+ interval_list, cs, uint_geom_type))
-+ DBUG_RETURN(1);
-+
-+ lex->alter_info.create_list.push_back(new_field);
-+ lex->last_field=new_field;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/** Store position for column in ALTER TABLE .. ADD column. */
-+
-+void store_position_for_column(const char *name)
-+{
-+ current_thd->lex->last_field->after=my_const_cast(char*) (name);
-+}
-+
-+bool
-+add_proc_to_list(THD* thd, Item *item)
-+{
-+ ORDER *order;
-+ Item **item_ptr;
-+
-+ if (!(order = (ORDER *) thd->alloc(sizeof(ORDER)+sizeof(Item*))))
-+ return 1;
-+ item_ptr = (Item**) (order+1);
-+ *item_ptr= item;
-+ order->item=item_ptr;
-+ order->free_me=0;
-+ thd->lex->proc_list.link_in_list(order, &order->next);
-+ return 0;
-+}
-+
-+
-+/**
-+ save order by and tables in own lists.
-+*/
-+
-+bool add_to_list(THD *thd, SQL_I_List<ORDER> &list, Item *item,bool asc)
-+{
-+ ORDER *order;
-+ DBUG_ENTER("add_to_list");
-+ if (!(order = (ORDER *) thd->alloc(sizeof(ORDER))))
-+ DBUG_RETURN(1);
-+ order->item_ptr= item;
-+ order->item= &order->item_ptr;
-+ order->asc = asc;
-+ order->free_me=0;
-+ order->used=0;
-+ order->counter_used= 0;
-+ list.link_in_list(order, &order->next);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ Add a table to list of used tables.
-+
-+ @param table Table to add
-+ @param alias alias for table (or null if no alias)
-+ @param table_options A set of the following bits:
-+ - TL_OPTION_UPDATING : Table will be updated
-+ - TL_OPTION_FORCE_INDEX : Force usage of index
-+ - TL_OPTION_ALIAS : an alias in multi table DELETE
-+ @param lock_type How table should be locked
-+ @param use_index List of indexed used in USE INDEX
-+ @param ignore_index List of indexed used in IGNORE INDEX
-+
-+ @retval
-+ 0 Error
-+ @retval
-+ \# Pointer to TABLE_LIST element added to the total table list
-+*/
-+
-+TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
-+ Table_ident *table,
-+ LEX_STRING *alias,
-+ ulong table_options,
-+ thr_lock_type lock_type,
-+ List<Index_hint> *index_hints_arg,
-+ LEX_STRING *option)
-+{
-+ register TABLE_LIST *ptr;
-+ TABLE_LIST *previous_table_ref; /* The table preceding the current one. */
-+ char *alias_str;
-+ LEX *lex= thd->lex;
-+ DBUG_ENTER("add_table_to_list");
-+ LINT_INIT(previous_table_ref);
-+
-+ if (!table)
-+ DBUG_RETURN(0); // End of memory
-+ alias_str= alias ? alias->str : table->table.str;
-+ if (!test(table_options & TL_OPTION_ALIAS) &&
-+ check_table_name(table->table.str, table->table.length, FALSE))
-+ {
-+ my_error(ER_WRONG_TABLE_NAME, MYF(0), table->table.str);
-+ DBUG_RETURN(0);
-+ }
-+
-+ if (table->is_derived_table() == FALSE && table->db.str &&
-+ check_db_name(&table->db))
-+ {
-+ my_error(ER_WRONG_DB_NAME, MYF(0), table->db.str);
-+ DBUG_RETURN(0);
-+ }
-+
-+ if (!alias) /* Alias is case sensitive */
-+ {
-+ if (table->sel)
-+ {
-+ my_message(ER_DERIVED_MUST_HAVE_ALIAS,
-+ ER(ER_DERIVED_MUST_HAVE_ALIAS), MYF(0));
-+ DBUG_RETURN(0);
-+ }
-+ if (!(alias_str= (char*) thd->memdup(alias_str,table->table.length+1)))
-+ DBUG_RETURN(0);
-+ }
-+ if (!(ptr = (TABLE_LIST *) thd->calloc(sizeof(TABLE_LIST))))
-+ DBUG_RETURN(0); /* purecov: inspected */
-+ if (table->db.str)
-+ {
-+ ptr->db= table->db.str;
-+ ptr->db_length= table->db.length;
-+ }
-+ else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
-+ DBUG_RETURN(0);
-+
-+ ptr->alias= alias_str;
-+ if (lower_case_table_names && table->table.length)
-+ table->table.length= my_casedn_str(files_charset_info, table->table.str);
-+ ptr->table_name=table->table.str;
-+ ptr->table_name_length=table->table.length;
-+ ptr->lock_type= lock_type;
-+ ptr->updating= test(table_options & TL_OPTION_UPDATING);
-+ /* TODO: remove TL_OPTION_FORCE_INDEX as it looks like it's not used */
-+ ptr->force_index= test(table_options & TL_OPTION_FORCE_INDEX);
-+ ptr->ignore_leaves= test(table_options & TL_OPTION_IGNORE_LEAVES);
-+ ptr->derived= table->sel;
-+ if (!ptr->derived && is_schema_db(ptr->db, ptr->db_length))
-+ {
-+ ST_SCHEMA_TABLE *schema_table= find_schema_table(thd, ptr->table_name);
-+ if (!schema_table ||
-+ (schema_table->hidden &&
-+ ((sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0 ||
-+ /*
-+ this check is used for show columns|keys from I_S hidden table
-+ */
-+ lex->sql_command == SQLCOM_SHOW_FIELDS ||
-+ lex->sql_command == SQLCOM_SHOW_KEYS)))
-+ {
-+ my_error(ER_UNKNOWN_TABLE, MYF(0),
-+ ptr->table_name, INFORMATION_SCHEMA_NAME.str);
-+ DBUG_RETURN(0);
-+ }
-+ ptr->schema_table_name= ptr->table_name;
-+ ptr->schema_table= schema_table;
-+ }
-+ ptr->select_lex= lex->current_select;
-+ ptr->cacheable_table= 1;
-+ ptr->index_hints= index_hints_arg;
-+ ptr->option= option ? option->str : 0;
-+ /* check that used name is unique */
-+ if (lock_type != TL_IGNORE)
-+ {
-+ TABLE_LIST *first_table= table_list.first;
-+ if (lex->sql_command == SQLCOM_CREATE_VIEW)
-+ first_table= first_table ? first_table->next_local : NULL;
-+ for (TABLE_LIST *tables= first_table ;
-+ tables ;
-+ tables=tables->next_local)
-+ {
-+ if (!my_strcasecmp(table_alias_charset, alias_str, tables->alias) &&
-+ !strcmp(ptr->db, tables->db))
-+ {
-+ my_error(ER_NONUNIQ_TABLE, MYF(0), alias_str); /* purecov: tested */
-+ DBUG_RETURN(0); /* purecov: tested */
-+ }
-+ }
-+ }
-+ /* Store the table reference preceding the current one. */
-+ if (table_list.elements > 0)
-+ {
-+ /*
-+ table_list.next points to the last inserted TABLE_LIST->next_local'
-+ element
-+ We don't use the offsetof() macro here to avoid warnings from gcc
-+ */
-+ previous_table_ref= (TABLE_LIST*) ((char*) table_list.next -
-+ ((char*) &(ptr->next_local) -
-+ (char*) ptr));
-+ /*
-+ Set next_name_resolution_table of the previous table reference to point
-+ to the current table reference. In effect the list
-+ TABLE_LIST::next_name_resolution_table coincides with
-+ TABLE_LIST::next_local. Later this may be changed in
-+ store_top_level_join_columns() for NATURAL/USING joins.
-+ */
-+ previous_table_ref->next_name_resolution_table= ptr;
-+ }
-+
-+ /*
-+ Link the current table reference in a local list (list for current select).
-+ Notice that as a side effect here we set the next_local field of the
-+ previous table reference to 'ptr'. Here we also add one element to the
-+ list 'table_list'.
-+ */
-+ table_list.link_in_list(ptr, &ptr->next_local);
-+ ptr->next_name_resolution_table= NULL;
-+ /* Link table in global list (all used tables) */
-+ lex->add_to_query_tables(ptr);
-+ DBUG_RETURN(ptr);
-+}
-+
-+
-+/**
-+ Initialize a new table list for a nested join.
-+
-+ The function initializes a structure of the TABLE_LIST type
-+ for a nested join. It sets up its nested join list as empty.
-+ The created structure is added to the front of the current
-+ join list in the st_select_lex object. Then the function
-+ changes the current nest level for joins to refer to the newly
-+ created empty list after having saved the info on the old level
-+ in the initialized structure.
-+
-+ @param thd current thread
-+
-+ @retval
-+ 0 if success
-+ @retval
-+ 1 otherwise
-+*/
-+
-+bool st_select_lex::init_nested_join(THD *thd)
-+{
-+ TABLE_LIST *ptr;
-+ NESTED_JOIN *nested_join;
-+ DBUG_ENTER("init_nested_join");
-+
-+ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
-+ sizeof(NESTED_JOIN))))
-+ DBUG_RETURN(1);
-+ nested_join= ptr->nested_join=
-+ ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
-+
-+ join_list->push_front(ptr);
-+ ptr->embedding= embedding;
-+ ptr->join_list= join_list;
-+ ptr->alias= (char*) "(nested_join)";
-+ embedding= ptr;
-+ join_list= &nested_join->join_list;
-+ join_list->empty();
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ End a nested join table list.
-+
-+ The function returns to the previous join nest level.
-+ If the current level contains only one member, the function
-+ moves it one level up, eliminating the nest.
-+
-+ @param thd current thread
-+
-+ @return
-+ - Pointer to TABLE_LIST element added to the total table list, if success
-+ - 0, otherwise
-+*/
-+
-+TABLE_LIST *st_select_lex::end_nested_join(THD *thd)
-+{
-+ TABLE_LIST *ptr;
-+ NESTED_JOIN *nested_join;
-+ DBUG_ENTER("end_nested_join");
-+
-+ DBUG_ASSERT(embedding);
-+ ptr= embedding;
-+ join_list= ptr->join_list;
-+ embedding= ptr->embedding;
-+ nested_join= ptr->nested_join;
-+ if (nested_join->join_list.elements == 1)
-+ {
-+ TABLE_LIST *embedded= nested_join->join_list.head();
-+ join_list->pop();
-+ embedded->join_list= join_list;
-+ embedded->embedding= embedding;
-+ join_list->push_front(embedded);
-+ ptr= embedded;
-+ }
-+ else if (nested_join->join_list.elements == 0)
-+ {
-+ join_list->pop();
-+ ptr= 0; // return value
-+ }
-+ DBUG_RETURN(ptr);
-+}
-+
-+
-+/**
-+ Nest last join operation.
-+
-+ The function nest last join operation as if it was enclosed in braces.
-+
-+ @param thd current thread
-+
-+ @retval
-+ 0 Error
-+ @retval
-+ \# Pointer to TABLE_LIST element created for the new nested join
-+*/
-+
-+TABLE_LIST *st_select_lex::nest_last_join(THD *thd)
-+{
-+ TABLE_LIST *ptr;
-+ NESTED_JOIN *nested_join;
-+ List<TABLE_LIST> *embedded_list;
-+ DBUG_ENTER("nest_last_join");
-+
-+ if (!(ptr= (TABLE_LIST*) thd->calloc(ALIGN_SIZE(sizeof(TABLE_LIST))+
-+ sizeof(NESTED_JOIN))))
-+ DBUG_RETURN(0);
-+ nested_join= ptr->nested_join=
-+ ((NESTED_JOIN*) ((uchar*) ptr + ALIGN_SIZE(sizeof(TABLE_LIST))));
-+
-+ ptr->embedding= embedding;
-+ ptr->join_list= join_list;
-+ ptr->alias= (char*) "(nest_last_join)";
-+ embedded_list= &nested_join->join_list;
-+ embedded_list->empty();
-+
-+ for (uint i=0; i < 2; i++)
-+ {
-+ TABLE_LIST *table= join_list->pop();
-+ table->join_list= embedded_list;
-+ table->embedding= ptr;
-+ embedded_list->push_back(table);
-+ if (table->natural_join)
-+ {
-+ ptr->is_natural_join= TRUE;
-+ /*
-+ If this is a JOIN ... USING, move the list of joined fields to the
-+ table reference that describes the join.
-+ */
-+ if (prev_join_using)
-+ ptr->join_using_fields= prev_join_using;
-+ }
-+ }
-+ join_list->push_front(ptr);
-+ nested_join->used_tables= nested_join->not_null_tables= (table_map) 0;
-+ DBUG_RETURN(ptr);
-+}
-+
-+
-+/**
-+ Add a table to the current join list.
-+
-+ The function puts a table in front of the current join list
-+ of st_select_lex object.
-+ Thus, joined tables are put into this list in the reverse order
-+ (the most outer join operation follows first).
-+
-+ @param table the table to add
-+
-+ @return
-+ None
-+*/
-+
-+void st_select_lex::add_joined_table(TABLE_LIST *table)
-+{
-+ DBUG_ENTER("add_joined_table");
-+ join_list->push_front(table);
-+ table->join_list= join_list;
-+ table->embedding= embedding;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Convert a right join into equivalent left join.
-+
-+ The function takes the current join list t[0],t[1] ... and
-+ effectively converts it into the list t[1],t[0] ...
-+ Although the outer_join flag for the new nested table contains
-+ JOIN_TYPE_RIGHT, it will be handled as the inner table of a left join
-+ operation.
-+
-+ EXAMPLES
-+ @verbatim
-+ SELECT * FROM t1 RIGHT JOIN t2 ON on_expr =>
-+ SELECT * FROM t2 LEFT JOIN t1 ON on_expr
-+
-+ SELECT * FROM t1,t2 RIGHT JOIN t3 ON on_expr =>
-+ SELECT * FROM t1,t3 LEFT JOIN t2 ON on_expr
-+
-+ SELECT * FROM t1,t2 RIGHT JOIN (t3,t4) ON on_expr =>
-+ SELECT * FROM t1,(t3,t4) LEFT JOIN t2 ON on_expr
-+
-+ SELECT * FROM t1 LEFT JOIN t2 ON on_expr1 RIGHT JOIN t3 ON on_expr2 =>
-+ SELECT * FROM t3 LEFT JOIN (t1 LEFT JOIN t2 ON on_expr2) ON on_expr1
-+ @endverbatim
-+
-+ @param thd current thread
-+
-+ @return
-+ - Pointer to the table representing the inner table, if success
-+ - 0, otherwise
-+*/
-+
-+TABLE_LIST *st_select_lex::convert_right_join()
-+{
-+ TABLE_LIST *tab2= join_list->pop();
-+ TABLE_LIST *tab1= join_list->pop();
-+ DBUG_ENTER("convert_right_join");
-+
-+ join_list->push_front(tab2);
-+ join_list->push_front(tab1);
-+ tab1->outer_join|= JOIN_TYPE_RIGHT;
-+
-+ DBUG_RETURN(tab1);
-+}
-+
-+/**
-+ Set lock for all tables in current select level.
-+
-+ @param lock_type Lock to set for tables
-+
-+ @note
-+ If lock is a write lock, then tables->updating is set 1
-+ This is to get tables_ok to know that the table is updated by the
-+ query
-+*/
-+
-+void st_select_lex::set_lock_for_tables(thr_lock_type lock_type)
-+{
-+ bool for_update= lock_type >= TL_READ_NO_INSERT;
-+ DBUG_ENTER("set_lock_for_tables");
-+ DBUG_PRINT("enter", ("lock_type: %d for_update: %d", lock_type,
-+ for_update));
-+ for (TABLE_LIST *tables= table_list.first;
-+ tables;
-+ tables= tables->next_local)
-+ {
-+ tables->lock_type= lock_type;
-+ tables->updating= for_update;
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Create a fake SELECT_LEX for a unit.
-+
-+ The method create a fake SELECT_LEX object for a unit.
-+ This object is created for any union construct containing a union
-+ operation and also for any single select union construct of the form
-+ @verbatim
-+ (SELECT ... ORDER BY order_list [LIMIT n]) ORDER BY ...
-+ @endvarbatim
-+ or of the form
-+ @varbatim
-+ (SELECT ... ORDER BY LIMIT n) ORDER BY ...
-+ @endvarbatim
-+
-+ @param thd_arg thread handle
-+
-+ @note
-+ The object is used to retrieve rows from the temporary table
-+ where the result on the union is obtained.
-+
-+ @retval
-+ 1 on failure to create the object
-+ @retval
-+ 0 on success
-+*/
-+
-+bool st_select_lex_unit::add_fake_select_lex(THD *thd_arg)
-+{
-+ SELECT_LEX *first_sl= first_select();
-+ DBUG_ENTER("add_fake_select_lex");
-+ DBUG_ASSERT(!fake_select_lex);
-+
-+ if (!(fake_select_lex= new (thd_arg->mem_root) SELECT_LEX()))
-+ DBUG_RETURN(1);
-+ fake_select_lex->include_standalone(this,
-+ (SELECT_LEX_NODE**)&fake_select_lex);
-+ fake_select_lex->select_number= INT_MAX;
-+ fake_select_lex->parent_lex= thd_arg->lex; /* Used in init_query. */
-+ fake_select_lex->make_empty_select();
-+ fake_select_lex->linkage= GLOBAL_OPTIONS_TYPE;
-+ fake_select_lex->select_limit= 0;
-+
-+ fake_select_lex->context.outer_context=first_sl->context.outer_context;
-+ /* allow item list resolving in fake select for ORDER BY */
-+ fake_select_lex->context.resolve_in_select_list= TRUE;
-+ fake_select_lex->context.select_lex= fake_select_lex;
-+
-+ if (!is_union())
-+ {
-+ /*
-+ This works only for
-+ (SELECT ... ORDER BY list [LIMIT n]) ORDER BY order_list [LIMIT m],
-+ (SELECT ... LIMIT n) ORDER BY order_list [LIMIT m]
-+ just before the parser starts processing order_list
-+ */
-+ global_parameters= fake_select_lex;
-+ fake_select_lex->no_table_names_allowed= 1;
-+ thd_arg->lex->current_select= fake_select_lex;
-+ }
-+ thd_arg->lex->pop_context();
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ Push a new name resolution context for a JOIN ... ON clause to the
-+ context stack of a query block.
-+
-+ Create a new name resolution context for a JOIN ... ON clause,
-+ set the first and last leaves of the list of table references
-+ to be used for name resolution, and push the newly created
-+ context to the stack of contexts of the query.
-+
-+ @param thd pointer to current thread
-+ @param left_op left operand of the JOIN
-+ @param right_op rigth operand of the JOIN
-+
-+ @retval
-+ FALSE if all is OK
-+ @retval
-+ TRUE if a memory allocation error occured
-+*/
-+
-+bool
-+push_new_name_resolution_context(THD *thd,
-+ TABLE_LIST *left_op, TABLE_LIST *right_op)
-+{
-+ Name_resolution_context *on_context;
-+ if (!(on_context= new (thd->mem_root) Name_resolution_context))
-+ return TRUE;
-+ on_context->init();
-+ on_context->first_name_resolution_table=
-+ left_op->first_leaf_for_name_resolution();
-+ on_context->last_name_resolution_table=
-+ right_op->last_leaf_for_name_resolution();
-+ return thd->lex->push_context(on_context);
-+}
-+
-+
-+/**
-+ Add an ON condition to the second operand of a JOIN ... ON.
-+
-+ Add an ON condition to the right operand of a JOIN ... ON clause.
-+
-+ @param b the second operand of a JOIN ... ON
-+ @param expr the condition to be added to the ON clause
-+
-+ @retval
-+ FALSE if there was some error
-+ @retval
-+ TRUE if all is OK
-+*/
-+
-+void add_join_on(TABLE_LIST *b, Item *expr)
-+{
-+ if (expr)
-+ {
-+ if (!b->on_expr)
-+ b->on_expr= expr;
-+ else
-+ {
-+ /*
-+ If called from the parser, this happens if you have both a
-+ right and left join. If called later, it happens if we add more
-+ than one condition to the ON clause.
-+ */
-+ b->on_expr= new Item_cond_and(b->on_expr,expr);
-+ }
-+ b->on_expr->top_level_item();
-+ }
-+}
-+
-+
-+/**
-+ Mark that there is a NATURAL JOIN or JOIN ... USING between two
-+ tables.
-+
-+ This function marks that table b should be joined with a either via
-+ a NATURAL JOIN or via JOIN ... USING. Both join types are special
-+ cases of each other, so we treat them together. The function
-+ setup_conds() creates a list of equal condition between all fields
-+ of the same name for NATURAL JOIN or the fields in 'using_fields'
-+ for JOIN ... USING. The list of equality conditions is stored
-+ either in b->on_expr, or in JOIN::conds, depending on whether there
-+ was an outer join.
-+
-+ EXAMPLE
-+ @verbatim
-+ SELECT * FROM t1 NATURAL LEFT JOIN t2
-+ <=>
-+ SELECT * FROM t1 LEFT JOIN t2 ON (t1.i=t2.i and t1.j=t2.j ... )
-+
-+ SELECT * FROM t1 NATURAL JOIN t2 WHERE <some_cond>
-+ <=>
-+ SELECT * FROM t1, t2 WHERE (t1.i=t2.i and t1.j=t2.j and <some_cond>)
-+
-+ SELECT * FROM t1 JOIN t2 USING(j) WHERE <some_cond>
-+ <=>
-+ SELECT * FROM t1, t2 WHERE (t1.j=t2.j and <some_cond>)
-+ @endverbatim
-+
-+ @param a Left join argument
-+ @param b Right join argument
-+ @param using_fields Field names from USING clause
-+*/
-+
-+void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List<String> *using_fields,
-+ SELECT_LEX *lex)
-+{
-+ b->natural_join= a;
-+ lex->prev_join_using= using_fields;
-+}
-+
-+
-+/**
-+ Reload/resets privileges and the different caches.
-+
-+ @param thd Thread handler (can be NULL!)
-+ @param options What should be reset/reloaded (tables, privileges, slave...)
-+ @param tables Tables to flush (if any)
-+ @param write_to_binlog < 0 if there was an error while interacting with the binary log inside
-+ reload_acl_and_cache,
-+ 0 if we should not write to the binary log,
-+ > 0 if we can write to the binlog.
-+
-+ @note Depending on 'options', it may be very bad to write the
-+ query to the binlog (e.g. FLUSH SLAVE); this is a
-+ pointer where reload_acl_and_cache() will put 0 if
-+ it thinks we really should not write to the binlog.
-+ Otherwise it will put 1.
-+
-+ @return Error status code
-+ @retval 0 Ok
-+ @retval !=0 Error; thd->killed is set or thd->is_error() is true
-+*/
-+
-+bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables,
-+ int *write_to_binlog)
-+{
-+ bool result=0;
-+ select_errors=0; /* Write if more errors */
-+ int tmp_write_to_binlog= *write_to_binlog= 1;
-+
-+ DBUG_ASSERT(!thd || !thd->in_sub_stmt);
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (options & REFRESH_GRANT)
-+ {
-+ THD *tmp_thd= 0;
-+ /*
-+ If reload_acl_and_cache() is called from SIGHUP handler we have to
-+ allocate temporary THD for execution of acl_reload()/grant_reload().
-+ */
-+ if (!thd && (thd= (tmp_thd= new THD)))
-+ {
-+ thd->thread_stack= (char*) &tmp_thd;
-+ thd->store_globals();
-+ lex_start(thd);
-+ }
-+
-+ if (thd)
-+ {
-+ bool reload_acl_failed= acl_reload(thd);
-+ bool reload_grants_failed= grant_reload(thd);
-+ bool reload_servers_failed= servers_reload(thd);
-+
-+ if (reload_acl_failed || reload_grants_failed || reload_servers_failed)
-+ {
-+ result= 1;
-+ /*
-+ When an error is returned, my_message may have not been called and
-+ the client will hang waiting for a response.
-+ */
-+ my_error(ER_UNKNOWN_ERROR, MYF(0), "FLUSH PRIVILEGES failed");
-+ }
-+ }
-+
-+ if (tmp_thd)
-+ {
-+ delete tmp_thd;
-+ /* Remember that we don't have a THD */
-+ my_pthread_setspecific_ptr(THR_THD, 0);
-+ thd= 0;
-+ }
-+ reset_mqh((LEX_USER *)NULL, TRUE);
-+ }
-+#endif
-+ if (options & REFRESH_LOG)
-+ {
-+ /*
-+ Flush the normal query log, the update log, the binary log,
-+ the slow query log, the relay log (if it exists) and the log
-+ tables.
-+ */
-+
-+ /*
-+ Writing this command to the binlog may result in infinite loops
-+ when doing mysqlbinlog|mysql, and anyway it does not really make
-+ sense to log it automatically (would cause more trouble to users
-+ than it would help them)
-+ */
-+ tmp_write_to_binlog= 0;
-+ if( mysql_bin_log.is_open() )
-+ {
-+ if (mysql_bin_log.rotate_and_purge(RP_FORCE_ROTATE))
-+ *write_to_binlog= -1;
-+ }
-+#ifdef HAVE_REPLICATION
-+ int rotate_error= 0;
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ rotate_error= rotate_relay_log(active_mi);
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ if (rotate_error)
-+ *write_to_binlog= -1;
-+#endif
-+
-+ /* flush slow and general logs */
-+ logger.flush_logs(thd);
-+
-+ if (ha_flush_logs(NULL))
-+ result=1;
-+ if (flush_error_log())
-+ result=1;
-+ }
-+#ifdef HAVE_QUERY_CACHE
-+ if (options & REFRESH_QUERY_CACHE_FREE)
-+ {
-+ query_cache.pack(); // FLUSH QUERY CACHE
-+ options &= ~REFRESH_QUERY_CACHE; // Don't flush cache, just free memory
-+ }
-+ if (options & (REFRESH_TABLES | REFRESH_QUERY_CACHE))
-+ {
-+ query_cache.flush(); // RESET QUERY CACHE
-+ }
-+#endif /*HAVE_QUERY_CACHE*/
-+ /*
-+ Note that if REFRESH_READ_LOCK bit is set then REFRESH_TABLES is set too
-+ (see sql_yacc.yy)
-+ */
-+ if (options & (REFRESH_TABLES | REFRESH_READ_LOCK))
-+ {
-+ if ((options & REFRESH_READ_LOCK) && thd)
-+ {
-+ /*
-+ We must not try to aspire a global read lock if we have a write
-+ locked table. This would lead to a deadlock when trying to
-+ reopen (and re-lock) the table after the flush.
-+ */
-+ if (thd->locked_tables)
-+ {
-+ THR_LOCK_DATA **lock_p= thd->locked_tables->locks;
-+ THR_LOCK_DATA **end_p= lock_p + thd->locked_tables->lock_count;
-+
-+ for (; lock_p < end_p; lock_p++)
-+ {
-+ if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE)
-+ {
-+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
-+ return 1;
-+ }
-+ }
-+ }
-+ /*
-+ Writing to the binlog could cause deadlocks, as we don't log
-+ UNLOCK TABLES
-+ */
-+ tmp_write_to_binlog= 0;
-+ if (lock_global_read_lock(thd))
-+ return 1; // Killed
-+ if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
-+ FALSE : TRUE, TRUE))
-+ result= 1;
-+
-+ if (make_global_read_lock_block_commit(thd)) // Killed
-+ {
-+ /* Don't leave things in a half-locked state */
-+ unlock_global_read_lock(thd);
-+ return 1;
-+ }
-+ }
-+ else
-+ {
-+ if (close_cached_tables(thd, tables, FALSE, (options & REFRESH_FAST) ?
-+ FALSE : TRUE, FALSE))
-+ result= 1;
-+ }
-+ my_dbopt_cleanup();
-+ }
-+ if (options & REFRESH_HOSTS)
-+ hostname_cache_refresh();
-+ if (thd && (options & REFRESH_STATUS))
-+ refresh_status(thd);
-+ if (options & REFRESH_THREADS)
-+ flush_thread_cache();
-+#ifdef HAVE_REPLICATION
-+ if (options & REFRESH_MASTER)
-+ {
-+ DBUG_ASSERT(thd);
-+ tmp_write_to_binlog= 0;
-+ if (reset_master(thd))
-+ {
-+ result=1;
-+ }
-+ }
-+#endif
-+#ifdef OPENSSL
-+ if (options & REFRESH_DES_KEY_FILE)
-+ {
-+ if (des_key_file && load_des_key_file(des_key_file))
-+ result= 1;
-+ }
-+#endif
-+#ifdef HAVE_REPLICATION
-+ if (options & REFRESH_SLAVE)
-+ {
-+ tmp_write_to_binlog= 0;
-+ pthread_mutex_lock(&LOCK_active_mi);
-+ if (reset_slave(thd, active_mi))
-+ result=1;
-+ pthread_mutex_unlock(&LOCK_active_mi);
-+ }
-+#endif
-+ if (options & REFRESH_USER_RESOURCES)
-+ reset_mqh((LEX_USER *) NULL, 0); /* purecov: inspected */
-+ if (*write_to_binlog != -1)
-+ *write_to_binlog= tmp_write_to_binlog;
-+ /*
-+ If the query was killed then this function must fail.
-+ */
-+ return result || (thd ? thd->killed : 0);
-+}
-+
-+
-+/**
-+ kill on thread.
-+
-+ @param thd Thread class
-+ @param id Thread id
-+ @param only_kill_query Should it kill the query or the connection
-+
-+ @note
-+ This is written such that we have a short lock on LOCK_thread_count
-+*/
-+
-+uint kill_one_thread(THD *thd, ulong id, bool only_kill_query)
-+{
-+ THD *tmp;
-+ uint error=ER_NO_SUCH_THREAD;
-+ DBUG_ENTER("kill_one_thread");
-+ DBUG_PRINT("enter", ("id=%lu only_kill=%d", id, only_kill_query));
-+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+ I_List_iterator<THD> it(threads);
-+ while ((tmp=it++))
-+ {
-+ if (tmp->command == COM_DAEMON)
-+ continue;
-+ if (tmp->thread_id == id)
-+ {
-+ pthread_mutex_lock(&tmp->LOCK_thd_data); // Lock from delete
-+ break;
-+ }
-+ }
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ if (tmp)
-+ {
-+
-+ /*
-+ If we're SUPER, we can KILL anything, including system-threads.
-+ No further checks.
-+
-+ KILLer: thd->security_ctx->user could in theory be NULL while
-+ we're still in "unauthenticated" state. This is a theoretical
-+ case (the code suggests this could happen, so we play it safe).
-+
-+ KILLee: tmp->security_ctx->user will be NULL for system threads.
-+ We need to check so Jane Random User doesn't crash the server
-+ when trying to kill a) system threads or b) unauthenticated users'
-+ threads (Bug#43748).
-+
-+ If user of both killer and killee are non-NULL, proceed with
-+ slayage if both are string-equal.
-+ */
-+
-+ if ((thd->security_ctx->master_access & SUPER_ACL) ||
-+ thd->security_ctx->user_matches(tmp->security_ctx))
-+ {
-+ tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION);
-+ error=0;
-+ }
-+ else
-+ error=ER_KILL_DENIED_ERROR;
-+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
-+ }
-+ DBUG_PRINT("exit", ("%d", error));
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ kills a thread and sends response
-+
-+ SYNOPSIS
-+ sql_kill()
-+ thd Thread class
-+ id Thread id
-+ only_kill_query Should it kill the query or the connection
-+*/
-+
-+void sql_kill(THD *thd, ulong id, bool only_kill_query)
-+{
-+ uint error;
-+ if (!(error= kill_one_thread(thd, id, only_kill_query)))
-+ my_ok(thd);
-+ else
-+ my_error(error, MYF(0), id);
-+}
-+
-+
-+/** If pointer is not a null pointer, append filename to it. */
-+
-+bool append_file_to_dir(THD *thd, const char **filename_ptr,
-+ const char *table_name)
-+{
-+ char buff[FN_REFLEN],*ptr, *end;
-+ if (!*filename_ptr)
-+ return 0; // nothing to do
-+
-+ /* Check that the filename is not too long and it's a hard path */
-+ if (strlen(*filename_ptr)+strlen(table_name) >= FN_REFLEN-1 ||
-+ !test_if_hard_path(*filename_ptr))
-+ {
-+ my_error(ER_WRONG_TABLE_NAME, MYF(0), *filename_ptr);
-+ return 1;
-+ }
-+ /* Fix is using unix filename format on dos */
-+ strmov(buff,*filename_ptr);
-+ end=convert_dirname(buff, *filename_ptr, NullS);
-+ if (!(ptr= (char*) thd->alloc((size_t) (end-buff) + strlen(table_name)+1)))
-+ return 1; // End of memory
-+ *filename_ptr=ptr;
-+ strxmov(ptr,buff,table_name,NullS);
-+ return 0;
-+}
-+
-+
-+/**
-+ Check if the select is a simple select (not an union).
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error ; In this case the error messege is sent to the client
-+*/
-+
-+bool check_simple_select()
-+{
-+ THD *thd= current_thd;
-+ LEX *lex= thd->lex;
-+ if (lex->current_select != &lex->select_lex)
-+ {
-+ char command[80];
-+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
-+ strmake(command, lip->yylval->symbol.str,
-+ min(lip->yylval->symbol.length, sizeof(command)-1));
-+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+Comp_creator *comp_eq_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)&ne_creator:(Comp_creator *)&eq_creator;
-+}
-+
-+
-+Comp_creator *comp_ge_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)<_creator:(Comp_creator *)&ge_creator;
-+}
-+
-+
-+Comp_creator *comp_gt_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)&le_creator:(Comp_creator *)>_creator;
-+}
-+
-+
-+Comp_creator *comp_le_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)>_creator:(Comp_creator *)&le_creator;
-+}
-+
-+
-+Comp_creator *comp_lt_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)&ge_creator:(Comp_creator *)<_creator;
-+}
-+
-+
-+Comp_creator *comp_ne_creator(bool invert)
-+{
-+ return invert?(Comp_creator *)&eq_creator:(Comp_creator *)&ne_creator;
-+}
-+
-+
-+/**
-+ Construct ALL/ANY/SOME subquery Item.
-+
-+ @param left_expr pointer to left expression
-+ @param cmp compare function creator
-+ @param all true if we create ALL subquery
-+ @param select_lex pointer on parsed subquery structure
-+
-+ @return
-+ constructed Item (or 0 if out of memory)
-+*/
-+Item * all_any_subquery_creator(Item *left_expr,
-+ chooser_compare_func_creator cmp,
-+ bool all,
-+ SELECT_LEX *select_lex)
-+{
-+ if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN
-+ return new Item_in_subselect(left_expr, select_lex);
-+
-+ if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN
-+ return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
-+
-+ Item_allany_subselect *it=
-+ new Item_allany_subselect(left_expr, cmp, select_lex, all);
-+ if (all)
-+ return it->upper_item= new Item_func_not_all(it); /* ALL */
-+
-+ return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */
-+}
-+
-+
-+/**
-+ Multi update query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global/local table list (have to be the same)
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE Error
-+*/
-+
-+bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+ const char *msg= 0;
-+ TABLE_LIST *table;
-+ LEX *lex= thd->lex;
-+ SELECT_LEX *select_lex= &lex->select_lex;
-+ DBUG_ENTER("multi_update_precheck");
-+
-+ if (select_lex->item_list.elements != lex->value_list.elements)
-+ {
-+ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ /*
-+ Ensure that we have UPDATE or SELECT privilege for each table
-+ The exact privilege is checked in mysql_multi_update()
-+ */
-+ for (table= tables; table; table= table->next_local)
-+ {
-+ if (table->derived)
-+ table->grant.privilege= SELECT_ACL;
-+ else if ((check_access(thd, UPDATE_ACL, table->db,
-+ &table->grant.privilege, 0, 1,
-+ test(table->schema_table)) ||
-+ check_grant(thd, UPDATE_ACL, table, 0, 1, 1)) &&
-+ (check_access(thd, SELECT_ACL, table->db,
-+ &table->grant.privilege, 0, 0,
-+ test(table->schema_table)) ||
-+ check_grant(thd, SELECT_ACL, table, 0, 1, 0)))
-+ DBUG_RETURN(TRUE);
-+
-+ table->table_in_first_from_clause= 1;
-+ }
-+ /*
-+ Is there tables of subqueries?
-+ */
-+ if (&lex->select_lex != lex->all_selects_list)
-+ {
-+ DBUG_PRINT("info",("Checking sub query list"));
-+ for (table= tables; table; table= table->next_global)
-+ {
-+ if (!table->table_in_first_from_clause)
-+ {
-+ if (check_access(thd, SELECT_ACL, table->db,
-+ &table->grant.privilege, 0, 0,
-+ test(table->schema_table)) ||
-+ check_grant(thd, SELECT_ACL, table, 0, 1, 0))
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+
-+ if (select_lex->order_list.elements)
-+ msg= "ORDER BY";
-+ else if (select_lex->select_limit)
-+ msg= "LIMIT";
-+ if (msg)
-+ {
-+ my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+/**
-+ Multi delete query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global/local table list
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE error
-+*/
-+
-+bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+ SELECT_LEX *select_lex= &thd->lex->select_lex;
-+ TABLE_LIST *aux_tables= thd->lex->auxiliary_table_list.first;
-+ TABLE_LIST **save_query_tables_own_last= thd->lex->query_tables_own_last;
-+ DBUG_ENTER("multi_delete_precheck");
-+
-+ /* sql_yacc guarantees that tables and aux_tables are not zero */
-+ DBUG_ASSERT(aux_tables != 0);
-+ if (check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
-+ DBUG_RETURN(TRUE);
-+
-+ /*
-+ Since aux_tables list is not part of LEX::query_tables list we
-+ have to juggle with LEX::query_tables_own_last value to be able
-+ call check_table_access() safely.
-+ */
-+ thd->lex->query_tables_own_last= 0;
-+ if (check_table_access(thd, DELETE_ACL, aux_tables, UINT_MAX, FALSE))
-+ {
-+ thd->lex->query_tables_own_last= save_query_tables_own_last;
-+ DBUG_RETURN(TRUE);
-+ }
-+ thd->lex->query_tables_own_last= save_query_tables_own_last;
-+
-+ if ((thd->options & OPTION_SAFE_UPDATES) && !select_lex->where)
-+ {
-+ my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
-+ ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Link tables in auxilary table list of multi-delete with corresponding
-+ elements in main table list, and set proper locks for them.
-+
-+ @param lex pointer to LEX representing multi-delete
-+
-+ @retval
-+ FALSE success
-+ @retval
-+ TRUE error
-+*/
-+
-+bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
-+{
-+ TABLE_LIST *tables= lex->select_lex.table_list.first;
-+ TABLE_LIST *target_tbl;
-+ DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
-+
-+ lex->table_count= 0;
-+
-+ for (target_tbl= lex->auxiliary_table_list.first;
-+ target_tbl; target_tbl= target_tbl->next_local)
-+ {
-+ lex->table_count++;
-+ /* All tables in aux_tables must be found in FROM PART */
-+ TABLE_LIST *walk;
-+ for (walk= tables; walk; walk= walk->next_local)
-+ {
-+ if (!my_strcasecmp(table_alias_charset,
-+ target_tbl->alias, walk->alias) &&
-+ !strcmp(walk->db, target_tbl->db))
-+ break;
-+ }
-+ if (!walk)
-+ {
-+ my_error(ER_UNKNOWN_TABLE, MYF(0),
-+ target_tbl->table_name, "MULTI DELETE");
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (!walk->derived)
-+ {
-+ target_tbl->table_name= walk->table_name;
-+ target_tbl->table_name_length= walk->table_name_length;
-+ }
-+ walk->updating= target_tbl->updating;
-+ walk->lock_type= target_tbl->lock_type;
-+ target_tbl->correspondent_table= walk; // Remember corresponding table
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ simple UPDATE query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global table list
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE Error
-+*/
-+
-+bool update_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+ DBUG_ENTER("update_precheck");
-+ if (thd->lex->select_lex.item_list.elements != thd->lex->value_list.elements)
-+ {
-+ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(check_one_table_access(thd, UPDATE_ACL, tables));
-+}
-+
-+
-+/**
-+ simple DELETE query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global table list
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE error
-+*/
-+
-+bool delete_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+ DBUG_ENTER("delete_precheck");
-+ if (check_one_table_access(thd, DELETE_ACL, tables))
-+ DBUG_RETURN(TRUE);
-+ /* Set privilege for the WHERE clause */
-+ tables->grant.want_privilege=(SELECT_ACL & ~tables->grant.privilege);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ simple INSERT query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global table list
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE error
-+*/
-+
-+bool insert_precheck(THD *thd, TABLE_LIST *tables)
-+{
-+ LEX *lex= thd->lex;
-+ DBUG_ENTER("insert_precheck");
-+
-+ /*
-+ Check that we have modify privileges for the first table and
-+ select privileges for the rest
-+ */
-+ ulong privilege= (INSERT_ACL |
-+ (lex->duplicates == DUP_REPLACE ? DELETE_ACL : 0) |
-+ (lex->value_list.elements ? UPDATE_ACL : 0));
-+
-+ if (check_one_table_access(thd, privilege, tables))
-+ DBUG_RETURN(TRUE);
-+
-+ if (lex->update_list.elements != lex->value_list.elements)
-+ {
-+ my_message(ER_WRONG_VALUE_COUNT, ER(ER_WRONG_VALUE_COUNT), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ @brief Check privileges for SHOW CREATE TABLE statement.
-+
-+ @param thd Thread context
-+ @param table Target table
-+
-+ @retval TRUE Failure
-+ @retval FALSE Success
-+*/
-+
-+static bool check_show_create_table_access(THD *thd, TABLE_LIST *table)
-+{
-+ return check_access(thd, SELECT_ACL | EXTRA_ACL, table->db,
-+ &table->grant.privilege, 0, 0,
-+ test(table->schema_table)) ||
-+ check_grant(thd, SELECT_ACL, table, 2, UINT_MAX, 0);
-+}
-+
-+
-+/**
-+ CREATE TABLE query pre-check.
-+
-+ @param thd Thread handler
-+ @param tables Global table list
-+ @param create_table Table which will be created
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE Error
-+*/
-+
-+bool create_table_precheck(THD *thd, TABLE_LIST *tables,
-+ TABLE_LIST *create_table)
-+{
-+ LEX *lex= thd->lex;
-+ SELECT_LEX *select_lex= &lex->select_lex;
-+ ulong want_priv;
-+ bool error= TRUE; // Error message is given
-+ DBUG_ENTER("create_table_precheck");
-+
-+ /*
-+ Require CREATE [TEMPORARY] privilege on new table; for
-+ CREATE TABLE ... SELECT, also require INSERT.
-+ */
-+
-+ want_priv= ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) ?
-+ CREATE_TMP_ACL : CREATE_ACL) |
-+ (select_lex->item_list.elements ? INSERT_ACL : 0);
-+
-+ if (check_access(thd, want_priv, create_table->db,
-+ &create_table->grant.privilege, 0, 0,
-+ test(create_table->schema_table)) ||
-+ check_merge_table_access(thd, create_table->db,
-+ lex->create_info.merge_list.first))
-+ goto err;
-+ if (want_priv != CREATE_TMP_ACL &&
-+ check_grant(thd, want_priv, create_table, 0, 1, 0))
-+ goto err;
-+
-+ if (select_lex->item_list.elements)
-+ {
-+ /* Check permissions for used tables in CREATE TABLE ... SELECT */
-+
-+#ifdef NOT_NECESSARY_TO_CHECK_CREATE_TABLE_EXIST_WHEN_PREPARING_STATEMENT
-+ /* This code throws an ill error for CREATE TABLE t1 SELECT * FROM t1 */
-+ /*
-+ Only do the check for PS, because we on execute we have to check that
-+ 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->stmt_arena->is_stmt_prepare_or_first_sp_execute())
-+ {
-+ /*
-+ For temporary tables we don't have to check if the created table exists
-+ */
-+ if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
-+ find_table_in_global_list(tables, create_table->db,
-+ create_table->table_name))
-+ {
-+ error= FALSE;
-+ goto err;
-+ }
-+ }
-+#endif
-+ if (tables && check_table_access(thd, SELECT_ACL, tables, UINT_MAX, FALSE))
-+ goto err;
-+ }
-+ else if (lex->create_info.options & HA_LEX_CREATE_TABLE_LIKE)
-+ {
-+ if (check_show_create_table_access(thd, tables))
-+ goto err;
-+ }
-+ error= FALSE;
-+
-+err:
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/**
-+ negate given expression.
-+
-+ @param thd thread handler
-+ @param expr expression for negation
-+
-+ @return
-+ negated expression
-+*/
-+
-+Item *negate_expression(THD *thd, Item *expr)
-+{
-+ Item *negated;
-+ if (expr->type() == Item::FUNC_ITEM &&
-+ ((Item_func *) expr)->functype() == Item_func::NOT_FUNC)
-+ {
-+ /* it is NOT(NOT( ... )) */
-+ Item *arg= ((Item_func *) expr)->arguments()[0];
-+ enum_parsing_place place= thd->lex->current_select->parsing_place;
-+ if (arg->is_bool_func() || place == IN_WHERE || place == IN_HAVING)
-+ return arg;
-+ /*
-+ if it is not boolean function then we have to emulate value of
-+ not(not(a)), it will be a != 0
-+ */
-+ return new Item_func_ne(arg, new Item_int((char*) "0", 0, 1));
-+ }
-+
-+ if ((negated= expr->neg_transformer(thd)) != 0)
-+ return negated;
-+ return new Item_func_not(expr);
-+}
-+
-+/**
-+ Set the specified definer to the default value, which is the
-+ current user in the thread.
-+
-+ @param[in] thd thread handler
-+ @param[out] definer definer
-+*/
-+
-+void get_default_definer(THD *thd, LEX_USER *definer)
-+{
-+ const Security_context *sctx= thd->security_ctx;
-+
-+ definer->user.str= (char *) sctx->priv_user;
-+ definer->user.length= strlen(definer->user.str);
-+
-+ definer->host.str= (char *) sctx->priv_host;
-+ definer->host.length= strlen(definer->host.str);
-+
-+ definer->password.str= NULL;
-+ definer->password.length= 0;
-+}
-+
-+
-+/**
-+ Create default definer for the specified THD.
-+
-+ @param[in] thd thread handler
-+
-+ @return
-+ - On success, return a valid pointer to the created and initialized
-+ LEX_USER, which contains definer information.
-+ - On error, return 0.
-+*/
-+
-+LEX_USER *create_default_definer(THD *thd)
-+{
-+ LEX_USER *definer;
-+
-+ if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
-+ return 0;
-+
-+ thd->get_definer(definer);
-+
-+ return definer;
-+}
-+
-+
-+/**
-+ Create definer with the given user and host names.
-+
-+ @param[in] thd thread handler
-+ @param[in] user_name user name
-+ @param[in] host_name host name
-+
-+ @return
-+ - On success, return a valid pointer to the created and initialized
-+ LEX_USER, which contains definer information.
-+ - On error, return 0.
-+*/
-+
-+LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
-+{
-+ LEX_USER *definer;
-+
-+ /* Create and initialize. */
-+
-+ if (! (definer= (LEX_USER*) thd->alloc(sizeof(LEX_USER))))
-+ return 0;
-+
-+ definer->user= *user_name;
-+ definer->host= *host_name;
-+ definer->password.str= NULL;
-+ definer->password.length= 0;
-+
-+ return definer;
-+}
-+
-+
-+/**
-+ Retuns information about user or current user.
-+
-+ @param[in] thd thread handler
-+ @param[in] user user
-+
-+ @return
-+ - On success, return a valid pointer to initialized
-+ LEX_USER, which contains user information.
-+ - On error, return 0.
-+*/
-+
-+LEX_USER *get_current_user(THD *thd, LEX_USER *user)
-+{
-+ if (!user->user.str) // current_user
-+ return create_default_definer(thd);
-+
-+ return user;
-+}
-+
-+
-+/**
-+ Check that byte length of a string does not exceed some limit.
-+
-+ @param str string to be checked
-+ @param err_msg error message to be displayed if the string is too long
-+ @param max_length max length
-+
-+ @retval
-+ FALSE the passed string is not longer than max_length
-+ @retval
-+ TRUE the passed string is longer than max_length
-+
-+ NOTE
-+ The function is not used in existing code but can be useful later?
-+*/
-+
-+bool check_string_byte_length(LEX_STRING *str, const char *err_msg,
-+ uint max_byte_length)
-+{
-+ if (str->length <= max_byte_length)
-+ return FALSE;
-+
-+ my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_byte_length);
-+
-+ return TRUE;
-+}
-+
-+
-+/*
-+ Check that char length of a string does not exceed some limit.
-+
-+ SYNOPSIS
-+ check_string_char_length()
-+ str string to be checked
-+ err_msg error message to be displayed if the string is too long
-+ max_char_length max length in symbols
-+ cs string charset
-+
-+ RETURN
-+ FALSE the passed string is not longer than max_char_length
-+ TRUE the passed string is longer than max_char_length
-+*/
-+
-+
-+bool check_string_char_length(LEX_STRING *str, const char *err_msg,
-+ uint max_char_length, CHARSET_INFO *cs,
-+ bool no_error)
-+{
-+ int well_formed_error;
-+ uint res= cs->cset->well_formed_len(cs, str->str, str->str + str->length,
-+ max_char_length, &well_formed_error);
-+
-+ if (!well_formed_error && str->length == res)
-+ return FALSE;
-+
-+ if (!no_error)
-+ my_error(ER_WRONG_STRING_LENGTH, MYF(0), str->str, err_msg, max_char_length);
-+ return TRUE;
-+}
-+
-+
-+/*
-+ Check if path does not contain mysql data home directory
-+ SYNOPSIS
-+ test_if_data_home_dir()
-+ dir directory
-+ conv_home_dir converted data home directory
-+ home_dir_len converted data home directory length
-+
-+ RETURN VALUES
-+ 0 ok
-+ 1 error
-+*/
-+C_MODE_START
-+
-+int test_if_data_home_dir(const char *dir)
-+{
-+ char path[FN_REFLEN];
-+ int dir_len;
-+ DBUG_ENTER("test_if_data_home_dir");
-+
-+ if (!dir)
-+ DBUG_RETURN(0);
-+
-+ (void) fn_format(path, dir, "", "",
-+ (MY_RETURN_REAL_PATH|MY_RESOLVE_SYMLINKS));
-+ dir_len= strlen(path);
-+ if (mysql_unpacked_real_data_home_len<= dir_len)
-+ {
-+ if (dir_len > mysql_unpacked_real_data_home_len &&
-+ path[mysql_unpacked_real_data_home_len] != FN_LIBCHAR)
-+ DBUG_RETURN(0);
-+
-+ if (lower_case_file_system)
-+ {
-+ if (!my_strnncoll(default_charset_info, (const uchar*) path,
-+ mysql_unpacked_real_data_home_len,
-+ (const uchar*) mysql_unpacked_real_data_home,
-+ mysql_unpacked_real_data_home_len))
-+ DBUG_RETURN(1);
-+ }
-+ else if (!memcmp(path, mysql_unpacked_real_data_home,
-+ mysql_unpacked_real_data_home_len))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+C_MODE_END
-+
-+
-+/**
-+ Check that host name string is valid.
-+
-+ @param[in] str string to be checked
-+
-+ @return Operation status
-+ @retval FALSE host name is ok
-+ @retval TRUE host name string is longer than max_length or
-+ has invalid symbols
-+*/
-+
-+bool check_host_name(LEX_STRING *str)
-+{
-+ const char *name= str->str;
-+ const char *end= str->str + str->length;
-+ if (check_string_byte_length(str, ER(ER_HOSTNAME), HOSTNAME_LENGTH))
-+ return TRUE;
-+
-+ while (name != end)
-+ {
-+ if (*name == '@')
-+ {
-+ my_printf_error(ER_UNKNOWN_ERROR,
-+ "Malformed hostname (illegal symbol: '%c')", MYF(0),
-+ *name);
-+ return TRUE;
-+ }
-+ name++;
-+ }
-+ return FALSE;
-+}
-+
-+
-+extern int MYSQLparse(void *thd); // from sql_yacc.cc
-+
-+
-+/**
-+ This is a wrapper of MYSQLparse(). All the code should call parse_sql()
-+ instead of MYSQLparse().
-+
-+ @param thd Thread context.
-+ @param parser_state Parser state.
-+ @param creation_ctx Object creation context.
-+
-+ @return Error status.
-+ @retval FALSE on success.
-+ @retval TRUE on parsing error.
-+*/
-+
-+bool parse_sql(THD *thd,
-+ Parser_state *parser_state,
-+ Object_creation_ctx *creation_ctx)
-+{
-+ DBUG_ASSERT(thd->m_parser_state == NULL);
-+
-+ /* Backup creation context. */
-+
-+ Object_creation_ctx *backup_ctx= NULL;
-+
-+ if (creation_ctx)
-+ backup_ctx= creation_ctx->set_n_backup(thd);
-+
-+ /* Set parser state. */
-+
-+ thd->m_parser_state= parser_state;
-+
-+ /* Parse the query. */
-+
-+ bool mysql_parse_status= MYSQLparse(thd) != 0;
-+
-+ /* Check that if MYSQLparse() failed, thd->is_error() is set. */
-+
-+ DBUG_ASSERT(!mysql_parse_status ||
-+ (mysql_parse_status && thd->is_error()));
-+
-+ /* Reset parser state. */
-+
-+ thd->m_parser_state= NULL;
-+
-+ /* Restore creation context. */
-+
-+ if (creation_ctx)
-+ creation_ctx->restore_env(thd, backup_ctx);
-+
-+ /* That's it. */
-+
-+ return mysql_parse_status || thd->is_fatal_error;
-+}
-+
-+/**
-+ @} (end of group Runtime_Environment)
-+*/
diff -urN mysql-old/sql/sql_partition.cc mysql/sql/sql_partition.cc
--- mysql-old/sql/sql_partition.cc 2011-05-10 17:45:45.636682376 +0000
+++ mysql/sql/sql_partition.cc 2011-05-10 17:56:01.513349044 +0000
@@ -36104,17362 +2435,6 @@ diff -urN mysql-old/sql/sql_select.cc mysql/sql/sql_select.cc
if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
cache->end=cache->buff+size;
-diff -urN mysql-old/sql/sql_select.cc.orig mysql/sql/sql_select.cc.orig
---- mysql-old/sql/sql_select.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/sql_select.cc.orig 2011-04-12 12:11:38.000000000 +0000
-@@ -0,0 +1,17352 @@
-+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-+
-+/**
-+ @file
-+
-+ @brief
-+ mysql_select and join optimization
-+
-+
-+ @defgroup Query_Optimizer Query Optimizer
-+ @{
-+*/
-+
-+#ifdef USE_PRAGMA_IMPLEMENTATION
-+#pragma implementation // gcc: Class implementation
-+#endif
-+
-+#include "mysql_priv.h"
-+#include "sql_select.h"
-+#include "sql_cursor.h"
-+
-+#include <m_ctype.h>
-+#include <my_bit.h>
-+#include <hash.h>
-+#include <ft_global.h>
-+
-+const char *join_type_str[]={ "UNKNOWN","system","const","eq_ref","ref",
-+ "MAYBE_REF","ALL","range","index","fulltext",
-+ "ref_or_null","unique_subquery","index_subquery",
-+ "index_merge"
-+};
-+
-+struct st_sargable_param;
-+
-+static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array);
-+static bool make_join_statistics(JOIN *join, TABLE_LIST *leaves, COND *conds,
-+ DYNAMIC_ARRAY *keyuse);
-+static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,
-+ JOIN_TAB *join_tab,
-+ uint tables, COND *conds,
-+ COND_EQUAL *cond_equal,
-+ table_map table_map, SELECT_LEX *select_lex,
-+ st_sargable_param **sargables);
-+static int sort_keyuse(KEYUSE *a,KEYUSE *b);
-+static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key);
-+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
-+ table_map used_tables);
-+static bool choose_plan(JOIN *join,table_map join_tables);
-+
-+static void best_access_path(JOIN *join, JOIN_TAB *s, THD *thd,
-+ table_map remaining_tables, uint idx,
-+ double record_count, double read_time);
-+static void optimize_straight_join(JOIN *join, table_map join_tables);
-+static bool greedy_search(JOIN *join, table_map remaining_tables,
-+ uint depth, uint prune_level);
-+static bool best_extension_by_limited_search(JOIN *join,
-+ table_map remaining_tables,
-+ uint idx, double record_count,
-+ double read_time, uint depth,
-+ uint prune_level);
-+static uint determine_search_depth(JOIN* join);
-+static int join_tab_cmp(const void* ptr1, const void* ptr2);
-+static int join_tab_cmp_straight(const void* ptr1, const void* ptr2);
-+/*
-+ TODO: 'find_best' is here only temporarily until 'greedy_search' is
-+ tested and approved.
-+*/
-+static bool find_best(JOIN *join,table_map rest_tables,uint index,
-+ double record_count,double read_time);
-+static uint cache_record_length(JOIN *join,uint index);
-+static double prev_record_reads(JOIN *join, uint idx, table_map found_ref);
-+static bool get_best_combination(JOIN *join);
-+static store_key *get_store_key(THD *thd,
-+ KEYUSE *keyuse, table_map used_tables,
-+ KEY_PART_INFO *key_part, uchar *key_buff,
-+ uint maybe_null);
-+static void make_outerjoin_info(JOIN *join);
-+static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
-+static void make_join_readinfo(JOIN *join, ulonglong options);
-+static bool only_eq_ref_tables(JOIN *join, ORDER *order, table_map tables);
-+static void update_depend_map(JOIN *join);
-+static void update_depend_map(JOIN *join, ORDER *order);
-+static ORDER *remove_const(JOIN *join,ORDER *first_order,COND *cond,
-+ bool change_list, bool *simple_order);
-+static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
-+ List<Item> &fields, bool send_row,
-+ ulonglong select_options, const char *info,
-+ Item *having);
-+static COND *build_equal_items(THD *thd, COND *cond,
-+ COND_EQUAL *inherited,
-+ List<TABLE_LIST> *join_list,
-+ COND_EQUAL **cond_equal_ref);
-+static COND* substitute_for_best_equal_field(COND *cond,
-+ COND_EQUAL *cond_equal,
-+ void *table_join_idx);
-+static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
-+ COND *conds, bool top);
-+static bool check_interleaving_with_nj(JOIN_TAB *next);
-+static void restore_prev_nj_state(JOIN_TAB *last);
-+static void reset_nj_counters(List<TABLE_LIST> *join_list);
-+static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
-+ uint first_unused);
-+
-+static COND *optimize_cond(JOIN *join, COND *conds,
-+ List<TABLE_LIST> *join_list,
-+ Item::cond_result *cond_value);
-+static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
-+static bool open_tmp_table(TABLE *table);
-+static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
-+ ulonglong options);
-+static int do_select(JOIN *join,List<Item> *fields,TABLE *tmp_table,
-+ Procedure *proc);
-+
-+static enum_nested_loop_state
-+evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
-+ int error);
-+static enum_nested_loop_state
-+evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab);
-+static enum_nested_loop_state
-+flush_cached_records(JOIN *join, JOIN_TAB *join_tab, bool skip_last);
-+static enum_nested_loop_state
-+end_send(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+static enum_nested_loop_state
-+end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+static enum_nested_loop_state
-+end_write(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+static enum_nested_loop_state
-+end_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+static enum_nested_loop_state
-+end_unique_update(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+static enum_nested_loop_state
-+end_write_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records);
-+
-+static int test_if_group_changed(List<Cached_item> &list);
-+static int join_read_const_table(JOIN_TAB *tab, POSITION *pos);
-+static int join_read_system(JOIN_TAB *tab);
-+static int join_read_const(JOIN_TAB *tab);
-+static int join_read_key(JOIN_TAB *tab);
-+static void join_read_key_unlock_row(st_join_table *tab);
-+static int join_read_always_key(JOIN_TAB *tab);
-+static int join_read_last_key(JOIN_TAB *tab);
-+static int join_no_more_records(READ_RECORD *info);
-+static int join_read_next(READ_RECORD *info);
-+static int join_init_quick_read_record(JOIN_TAB *tab);
-+static int test_if_quick_select(JOIN_TAB *tab);
-+static int join_init_read_record(JOIN_TAB *tab);
-+static int join_read_first(JOIN_TAB *tab);
-+static int join_read_next(READ_RECORD *info);
-+static int join_read_next_same(READ_RECORD *info);
-+static int join_read_last(JOIN_TAB *tab);
-+static int join_read_prev_same(READ_RECORD *info);
-+static int join_read_prev(READ_RECORD *info);
-+static int join_ft_read_first(JOIN_TAB *tab);
-+static int join_ft_read_next(READ_RECORD *info);
-+int join_read_always_key_or_null(JOIN_TAB *tab);
-+int join_read_next_same_or_null(READ_RECORD *info);
-+static COND *make_cond_for_table(COND *cond,table_map table,
-+ table_map used_table);
-+static Item* part_of_refkey(TABLE *form,Field *field);
-+uint find_shortest_key(TABLE *table, const key_map *usable_keys);
-+static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,
-+ ha_rows select_limit, bool no_changes,
-+ key_map *map);
-+static bool list_contains_unique_index(TABLE *table,
-+ bool (*find_func) (Field *, void *), void *data);
-+static bool find_field_in_item_list (Field *field, void *data);
-+static bool find_field_in_order_list (Field *field, void *data);
-+static int create_sort_index(THD *thd, JOIN *join, ORDER *order,
-+ ha_rows filesort_limit, ha_rows select_limit,
-+ bool is_order_by);
-+static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields,
-+ Item *having);
-+static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field,
-+ ulong offset,Item *having);
-+static int remove_dup_with_hash_index(THD *thd,TABLE *table,
-+ uint field_count, Field **first_field,
-+
-+ ulong key_length,Item *having);
-+static int join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count);
-+static ulong used_blob_length(CACHE_FIELD **ptr);
-+static bool store_record_in_cache(JOIN_CACHE *cache);
-+static void reset_cache_read(JOIN_CACHE *cache);
-+static void reset_cache_write(JOIN_CACHE *cache);
-+static void read_cached_record(JOIN_TAB *tab);
-+static bool cmp_buffer_with_ref(JOIN_TAB *tab);
-+static bool setup_new_fields(THD *thd, List<Item> &fields,
-+ List<Item> &all_fields, ORDER *new_order);
-+static ORDER *create_distinct_group(THD *thd, Item **ref_pointer_array,
-+ ORDER *order, List<Item> &fields,
-+ List<Item> &all_fields,
-+ bool *all_order_by_fields_used);
-+static bool test_if_subpart(ORDER *a,ORDER *b);
-+static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables);
-+static void calc_group_buffer(JOIN *join,ORDER *group);
-+static bool make_group_fields(JOIN *main_join, JOIN *curr_join);
-+static bool alloc_group_fields(JOIN *join,ORDER *group);
-+// Create list for using with tempory table
-+static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
-+ List<Item> &new_list1,
-+ List<Item> &new_list2,
-+ uint elements, List<Item> &items);
-+// Create list for using with tempory table
-+static bool change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
-+ List<Item> &new_list1,
-+ List<Item> &new_list2,
-+ uint elements, List<Item> &items);
-+static void init_tmptable_sum_functions(Item_sum **func);
-+static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table);
-+static void copy_sum_funcs(Item_sum **func_ptr, Item_sum **end);
-+static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
-+static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
-+static bool init_sum_functions(Item_sum **func, Item_sum **end);
-+static bool update_sum_func(Item_sum **func);
-+static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
-+ bool distinct, const char *message=NullS);
-+static Item *remove_additional_cond(Item* conds);
-+static void add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab);
-+static bool test_if_ref(Item_field *left_item,Item *right_item);
-+
-+
-+/**
-+ This handles SELECT with and without UNION.
-+*/
-+
-+bool handle_select(THD *thd, LEX *lex, select_result *result,
-+ ulong setup_tables_done_option)
-+{
-+ bool res;
-+ register SELECT_LEX *select_lex = &lex->select_lex;
-+ DBUG_ENTER("handle_select");
-+
-+ if (select_lex->master_unit()->is_union() ||
-+ select_lex->master_unit()->fake_select_lex)
-+ res= mysql_union(thd, lex, result, &lex->unit, setup_tables_done_option);
-+ else
-+ {
-+ SELECT_LEX_UNIT *unit= &lex->unit;
-+ unit->set_limit(unit->global_parameters);
-+ /*
-+ 'options' of mysql_select will be set in JOIN, as far as JOIN for
-+ every PS/SP execution new, we will not need reset this flag if
-+ setup_tables_done_option changed for next rexecution
-+ */
-+ res= mysql_select(thd, &select_lex->ref_pointer_array,
-+ select_lex->table_list.first,
-+ select_lex->with_wild, select_lex->item_list,
-+ select_lex->where,
-+ select_lex->order_list.elements +
-+ select_lex->group_list.elements,
-+ select_lex->order_list.first,
-+ select_lex->group_list.first,
-+ select_lex->having,
-+ lex->proc_list.first,
-+ select_lex->options | thd->options |
-+ setup_tables_done_option,
-+ result, unit, select_lex);
-+ }
-+ DBUG_PRINT("info",("res: %d report_error: %d", res,
-+ thd->is_error()));
-+ res|= thd->is_error();
-+ if (unlikely(res))
-+ result->abort();
-+
-+ DBUG_RETURN(res);
-+}
-+
-+
-+/**
-+ Fix fields referenced from inner selects.
-+
-+ @param thd Thread handle
-+ @param all_fields List of all fields used in select
-+ @param select Current select
-+ @param ref_pointer_array Array of references to Items used in current select
-+ @param group_list GROUP BY list (is NULL by default)
-+
-+ @details
-+ The function serves 3 purposes
-+
-+ - adds fields referenced from inner query blocks to the current select list
-+
-+ - Decides which class to use to reference the items (Item_ref or
-+ Item_direct_ref)
-+
-+ - fixes references (Item_ref objects) to these fields.
-+
-+ If a field isn't already on the select list and the ref_pointer_array
-+ is provided then it is added to the all_fields list and the pointer to
-+ it is saved in the ref_pointer_array.
-+
-+ The class to access the outer field is determined by the following rules:
-+
-+ -#. If the outer field isn't used under an aggregate function then the
-+ Item_ref class should be used.
-+
-+ -#. If the outer field is used under an aggregate function and this
-+ function is, in turn, aggregated in the query block where the outer
-+ field was resolved or some query nested therein, then the
-+ Item_direct_ref class should be used. Also it should be used if we are
-+ grouping by a subquery containing the outer field.
-+
-+ The resolution is done here and not at the fix_fields() stage as
-+ it can be done only after aggregate functions are fixed and pulled up to
-+ selects where they are to be aggregated.
-+
-+ When the class is chosen it substitutes the original field in the
-+ Item_outer_ref object.
-+
-+ After this we proceed with fixing references (Item_outer_ref objects) to
-+ this field from inner subqueries.
-+
-+ @return Status
-+ @retval true An error occured.
-+ @retval false OK.
-+ */
-+
-+bool
-+fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
-+ Item **ref_pointer_array, ORDER *group_list)
-+{
-+ Item_outer_ref *ref;
-+
-+ List_iterator<Item_outer_ref> ref_it(select->inner_refs_list);
-+ while ((ref= ref_it++))
-+ {
-+ bool direct_ref= false;
-+ Item *item= ref->outer_ref;
-+ Item **item_ref= ref->ref;
-+ Item_ref *new_ref;
-+ /*
-+ TODO: this field item already might be present in the select list.
-+ In this case instead of adding new field item we could use an
-+ existing one. The change will lead to less operations for copying fields,
-+ smaller temporary tables and less data passed through filesort.
-+ */
-+ if (ref_pointer_array && !ref->found_in_select_list)
-+ {
-+ int el= all_fields.elements;
-+ ref_pointer_array[el]= item;
-+ /* Add the field item to the select list of the current select. */
-+ all_fields.push_front(item);
-+ /*
-+ If it's needed reset each Item_ref item that refers this field with
-+ a new reference taken from ref_pointer_array.
-+ */
-+ item_ref= ref_pointer_array + el;
-+ }
-+
-+ if (ref->in_sum_func)
-+ {
-+ Item_sum *sum_func;
-+ if (ref->in_sum_func->nest_level > select->nest_level)
-+ direct_ref= TRUE;
-+ else
-+ {
-+ for (sum_func= ref->in_sum_func; sum_func &&
-+ sum_func->aggr_level >= select->nest_level;
-+ sum_func= sum_func->in_sum_func)
-+ {
-+ if (sum_func->aggr_level == select->nest_level)
-+ {
-+ direct_ref= TRUE;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ Check if GROUP BY item trees contain the outer ref:
-+ in this case we have to use Item_direct_ref instead of Item_ref.
-+ */
-+ for (ORDER *group= group_list; group; group= group->next)
-+ {
-+ if ((*group->item)->walk(&Item::find_item_processor, TRUE,
-+ (uchar *) ref))
-+ {
-+ direct_ref= TRUE;
-+ break;
-+ }
-+ }
-+ }
-+ new_ref= direct_ref ?
-+ new Item_direct_ref(ref->context, item_ref, ref->table_name,
-+ ref->field_name, ref->alias_name_used) :
-+ new Item_ref(ref->context, item_ref, ref->table_name,
-+ ref->field_name, ref->alias_name_used);
-+ if (!new_ref)
-+ return TRUE;
-+ ref->outer_ref= new_ref;
-+ ref->ref= &ref->outer_ref;
-+
-+ if (!ref->fixed && ref->fix_fields(thd, 0))
-+ return TRUE;
-+ thd->used_tables|= item->used_tables();
-+ }
-+ return false;
-+}
-+
-+/**
-+ Function to setup clauses without sum functions.
-+*/
-+inline int setup_without_group(THD *thd, Item **ref_pointer_array,
-+ TABLE_LIST *tables,
-+ TABLE_LIST *leaves,
-+ List<Item> &fields,
-+ List<Item> &all_fields,
-+ COND **conds,
-+ ORDER *order,
-+ ORDER *group, bool *hidden_group_fields)
-+{
-+ int res;
-+ nesting_map save_allow_sum_func=thd->lex->allow_sum_func ;
-+ /*
-+ Need to save the value, so we can turn off only the new NON_AGG_FIELD
-+ additions coming from the WHERE
-+ */
-+ uint8 saved_flag= thd->lex->current_select->full_group_by_flag;
-+ DBUG_ENTER("setup_without_group");
-+
-+ thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
-+ res= setup_conds(thd, tables, leaves, conds);
-+
-+ /* it's not wrong to have non-aggregated columns in a WHERE */
-+ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
-+ thd->lex->current_select->full_group_by_flag= saved_flag |
-+ (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED);
-+
-+ thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level;
-+ res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields,
-+ order);
-+ thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level);
-+ res= res || setup_group(thd, ref_pointer_array, tables, fields, all_fields,
-+ group, hidden_group_fields);
-+ thd->lex->allow_sum_func= save_allow_sum_func;
-+ DBUG_RETURN(res);
-+}
-+
-+/*****************************************************************************
-+ Check fields, find best join, do the select and output fields.
-+ mysql_select assumes that all tables are already opened
-+*****************************************************************************/
-+
-+/**
-+ Prepare of whole select (including sub queries in future).
-+
-+ @todo
-+ Add check of calculation of GROUP functions and fields:
-+ SELECT COUNT(*)+table.col1 from table1;
-+
-+ @retval
-+ -1 on error
-+ @retval
-+ 0 on success
-+*/
-+int
-+JOIN::prepare(Item ***rref_pointer_array,
-+ TABLE_LIST *tables_init,
-+ uint wild_num, COND *conds_init, uint og_num,
-+ ORDER *order_init, ORDER *group_init,
-+ Item *having_init,
-+ ORDER *proc_param_init, SELECT_LEX *select_lex_arg,
-+ SELECT_LEX_UNIT *unit_arg)
-+{
-+ DBUG_ENTER("JOIN::prepare");
-+
-+ // to prevent double initialization on EXPLAIN
-+ if (optimized)
-+ DBUG_RETURN(0);
-+
-+ conds= conds_init;
-+ order= order_init;
-+ group_list= group_init;
-+ having= having_init;
-+ proc_param= proc_param_init;
-+ tables_list= tables_init;
-+ select_lex= select_lex_arg;
-+ select_lex->join= this;
-+ join_list= &select_lex->top_join_list;
-+ union_part= unit_arg->is_union();
-+
-+ thd->lex->current_select->is_item_list_lookup= 1;
-+ /*
-+ If we have already executed SELECT, then it have not sense to prevent
-+ its table from update (see unique_table())
-+ */
-+ if (thd->derived_tables_processing)
-+ select_lex->exclude_from_table_unique_test= TRUE;
-+
-+ /* Check that all tables, fields, conds and order are ok */
-+
-+ if (!(select_options & OPTION_SETUP_TABLES_DONE) &&
-+ setup_tables_and_check_access(thd, &select_lex->context, join_list,
-+ tables_list, &select_lex->leaf_tables,
-+ FALSE, SELECT_ACL, SELECT_ACL))
-+ DBUG_RETURN(-1);
-+
-+ TABLE_LIST *table_ptr;
-+ for (table_ptr= select_lex->leaf_tables;
-+ table_ptr;
-+ table_ptr= table_ptr->next_leaf)
-+ tables++;
-+
-+ if (setup_wild(thd, tables_list, fields_list, &all_fields, wild_num) ||
-+ select_lex->setup_ref_array(thd, og_num) ||
-+ setup_fields(thd, (*rref_pointer_array), fields_list, MARK_COLUMNS_READ,
-+ &all_fields, 1) ||
-+ setup_without_group(thd, (*rref_pointer_array), tables_list,
-+ select_lex->leaf_tables, fields_list,
-+ all_fields, &conds, order, group_list,
-+ &hidden_group_fields))
-+ DBUG_RETURN(-1); /* purecov: inspected */
-+
-+ ref_pointer_array= *rref_pointer_array;
-+
-+ if (having)
-+ {
-+ nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
-+ thd->where="having clause";
-+ thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level;
-+ select_lex->having_fix_field= 1;
-+ bool having_fix_rc= (!having->fixed &&
-+ (having->fix_fields(thd, &having) ||
-+ having->check_cols(1)));
-+ select_lex->having_fix_field= 0;
-+ if (having_fix_rc || thd->is_error())
-+ DBUG_RETURN(-1); /* purecov: inspected */
-+ thd->lex->allow_sum_func= save_allow_sum_func;
-+ }
-+
-+ if (!(thd->lex->context_analysis_only & CONTEXT_ANALYSIS_ONLY_VIEW) &&
-+ !(select_options & SELECT_DESCRIBE))
-+ {
-+ Item_subselect *subselect;
-+ /* Is it subselect? */
-+ if ((subselect= select_lex->master_unit()->item))
-+ {
-+ Item_subselect::trans_res res;
-+ if ((res= subselect->select_transformer(this)) !=
-+ Item_subselect::RES_OK)
-+ {
-+ select_lex->fix_prepare_information(thd, &conds, &having);
-+ DBUG_RETURN((res == Item_subselect::RES_ERROR));
-+ }
-+ }
-+ }
-+
-+ select_lex->fix_prepare_information(thd, &conds, &having);
-+
-+ if (order)
-+ {
-+ bool real_order= FALSE;
-+ ORDER *ord;
-+ for (ord= order; ord; ord= ord->next)
-+ {
-+ Item *item= *ord->item;
-+ /*
-+ Disregard sort order if there's only
-+ zero length NOT NULL fields (e.g. {VAR}CHAR(0) NOT NULL") or
-+ zero length NOT NULL string functions there.
-+ Such tuples don't contain any data to sort.
-+ */
-+ if (!real_order &&
-+ /* Not a zero length NOT NULL field */
-+ ((item->type() != Item::FIELD_ITEM ||
-+ ((Item_field *) item)->field->maybe_null() ||
-+ ((Item_field *) item)->field->sort_length()) &&
-+ /* AND not a zero length NOT NULL string function. */
-+ (item->type() != Item::FUNC_ITEM ||
-+ item->maybe_null ||
-+ item->result_type() != STRING_RESULT ||
-+ item->max_length)))
-+ real_order= TRUE;
-+
-+ if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
-+ item->split_sum_func(thd, ref_pointer_array, all_fields);
-+ }
-+ if (!real_order)
-+ order= NULL;
-+ }
-+
-+ if (having && having->with_sum_func)
-+ having->split_sum_func2(thd, ref_pointer_array, all_fields,
-+ &having, TRUE);
-+ if (select_lex->inner_sum_func_list)
-+ {
-+ Item_sum *end=select_lex->inner_sum_func_list;
-+ Item_sum *item_sum= end;
-+ do
-+ {
-+ item_sum= item_sum->next;
-+ item_sum->split_sum_func2(thd, ref_pointer_array,
-+ all_fields, item_sum->ref_by, FALSE);
-+ } while (item_sum != end);
-+ }
-+
-+ if (select_lex->inner_refs_list.elements &&
-+ fix_inner_refs(thd, all_fields, select_lex, ref_pointer_array,
-+ group_list))
-+ DBUG_RETURN(-1);
-+
-+ if (group_list)
-+ {
-+ /*
-+ Because HEAP tables can't index BIT fields we need to use an
-+ additional hidden field for grouping because later it will be
-+ converted to a LONG field. Original field will remain of the
-+ BIT type and will be returned to a client.
-+ */
-+ for (ORDER *ord= group_list; ord; ord= ord->next)
-+ {
-+ if ((*ord->item)->type() == Item::FIELD_ITEM &&
-+ (*ord->item)->field_type() == MYSQL_TYPE_BIT)
-+ {
-+ Item_field *field= new Item_field(thd, *(Item_field**)ord->item);
-+ int el= all_fields.elements;
-+ ref_pointer_array[el]= field;
-+ all_fields.push_front(field);
-+ ord->item= ref_pointer_array + el;
-+ }
-+ }
-+ }
-+
-+ if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */
-+ DBUG_RETURN(-1);
-+
-+
-+ /*
-+ Check if there are references to un-aggregated columns when computing
-+ aggregate functions with implicit grouping (there is no GROUP BY).
-+ */
-+ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list &&
-+ select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED))
-+ {
-+ my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS,
-+ ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0));
-+ DBUG_RETURN(-1);
-+ }
-+ {
-+ /* Caclulate the number of groups */
-+ send_group_parts= 0;
-+ for (ORDER *group_tmp= group_list ; group_tmp ; group_tmp= group_tmp->next)
-+ send_group_parts++;
-+ }
-+
-+ procedure= setup_procedure(thd, proc_param, result, fields_list, &error);
-+ if (error)
-+ goto err; /* purecov: inspected */
-+ if (procedure)
-+ {
-+ if (setup_new_fields(thd, fields_list, all_fields,
-+ procedure->param_fields))
-+ goto err; /* purecov: inspected */
-+ if (procedure->group)
-+ {
-+ if (!test_if_subpart(procedure->group,group_list))
-+ { /* purecov: inspected */
-+ my_message(ER_DIFF_GROUPS_PROC, ER(ER_DIFF_GROUPS_PROC),
-+ MYF(0)); /* purecov: inspected */
-+ goto err; /* purecov: inspected */
-+ }
-+ }
-+ if (order && (procedure->flags & PROC_NO_SORT))
-+ { /* purecov: inspected */
-+ my_message(ER_ORDER_WITH_PROC, ER(ER_ORDER_WITH_PROC),
-+ MYF(0)); /* purecov: inspected */
-+ goto err; /* purecov: inspected */
-+ }
-+ if (thd->lex->derived_tables)
-+ {
-+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE",
-+ thd->lex->derived_tables & DERIVED_VIEW ?
-+ "view" : "subquery");
-+ goto err;
-+ }
-+ if (thd->lex->sql_command != SQLCOM_SELECT)
-+ {
-+ my_error(ER_WRONG_USAGE, MYF(0), "PROCEDURE", "non-SELECT");
-+ goto err;
-+ }
-+ }
-+
-+ if (!procedure && result && result->prepare(fields_list, unit_arg))
-+ goto err; /* purecov: inspected */
-+
-+ /* Init join struct */
-+ count_field_types(select_lex, &tmp_table_param, all_fields, 0);
-+ ref_pointer_array_size= all_fields.elements*sizeof(Item*);
-+ this->group= group_list != 0;
-+ unit= unit_arg;
-+
-+ if (tmp_table_param.sum_func_count && !group_list)
-+ implicit_grouping= TRUE;
-+
-+#ifdef RESTRICTED_GROUP
-+ if (implicit_grouping)
-+ {
-+ my_message(ER_WRONG_SUM_SELECT,ER(ER_WRONG_SUM_SELECT),MYF(0));
-+ goto err;
-+ }
-+#endif
-+ if (select_lex->olap == ROLLUP_TYPE && rollup_init())
-+ goto err;
-+ if (alloc_func_list())
-+ goto err;
-+
-+ DBUG_RETURN(0); // All OK
-+
-+err:
-+ delete procedure; /* purecov: inspected */
-+ procedure= 0;
-+ DBUG_RETURN(-1); /* purecov: inspected */
-+}
-+
-+
-+/*
-+ Remove the predicates pushed down into the subquery
-+
-+ SYNOPSIS
-+ JOIN::remove_subq_pushed_predicates()
-+ where IN Must be NULL
-+ OUT The remaining WHERE condition, or NULL
-+
-+ DESCRIPTION
-+ Given that this join will be executed using (unique|index)_subquery,
-+ without "checking NULL", remove the predicates that were pushed down
-+ into the subquery.
-+
-+ If the subquery compares scalar values, we can remove the condition that
-+ was wrapped into trig_cond (it will be checked when needed by the subquery
-+ engine)
-+
-+ If the subquery compares row values, we need to keep the wrapped
-+ equalities in the WHERE clause: when the left (outer) tuple has both NULL
-+ and non-NULL values, we'll do a full table scan and will rely on the
-+ equalities corresponding to non-NULL parts of left tuple to filter out
-+ non-matching records.
-+
-+ TODO: We can remove the equalities that will be guaranteed to be true by the
-+ fact that subquery engine will be using index lookup. This must be done only
-+ for cases where there are no conversion errors of significance, e.g. 257
-+ that is searched in a byte. But this requires homogenization of the return
-+ codes of all Field*::store() methods.
-+*/
-+
-+void JOIN::remove_subq_pushed_predicates(Item **where)
-+{
-+ if (conds->type() == Item::FUNC_ITEM &&
-+ ((Item_func *)this->conds)->functype() == Item_func::EQ_FUNC &&
-+ ((Item_func *)conds)->arguments()[0]->type() == Item::REF_ITEM &&
-+ ((Item_func *)conds)->arguments()[1]->type() == Item::FIELD_ITEM &&
-+ test_if_ref ((Item_field *)((Item_func *)conds)->arguments()[1],
-+ ((Item_func *)conds)->arguments()[0]))
-+ {
-+ *where= 0;
-+ return;
-+ }
-+}
-+
-+
-+/*
-+ Index lookup-based subquery: save some flags for EXPLAIN output
-+
-+ SYNOPSIS
-+ save_index_subquery_explain_info()
-+ join_tab Subquery's join tab (there is only one as index lookup is
-+ only used for subqueries that are single-table SELECTs)
-+ where Subquery's WHERE clause
-+
-+ DESCRIPTION
-+ For index lookup-based subquery (i.e. one executed with
-+ subselect_uniquesubquery_engine or subselect_indexsubquery_engine),
-+ check its EXPLAIN output row should contain
-+ "Using index" (TAB_INFO_FULL_SCAN_ON_NULL)
-+ "Using Where" (TAB_INFO_USING_WHERE)
-+ "Full scan on NULL key" (TAB_INFO_FULL_SCAN_ON_NULL)
-+ and set appropriate flags in join_tab->packed_info.
-+*/
-+
-+static void save_index_subquery_explain_info(JOIN_TAB *join_tab, Item* where)
-+{
-+ join_tab->packed_info= TAB_INFO_HAVE_VALUE;
-+ if (join_tab->table->covering_keys.is_set(join_tab->ref.key))
-+ join_tab->packed_info |= TAB_INFO_USING_INDEX;
-+ if (where)
-+ join_tab->packed_info |= TAB_INFO_USING_WHERE;
-+ for (uint i = 0; i < join_tab->ref.key_parts; i++)
-+ {
-+ if (join_tab->ref.cond_guards[i])
-+ {
-+ join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
-+ break;
-+ }
-+ }
-+}
-+
-+
-+/**
-+ global select optimisation.
-+
-+ @note
-+ error code saved in field 'error'
-+
-+ @retval
-+ 0 success
-+ @retval
-+ 1 error
-+*/
-+
-+int
-+JOIN::optimize()
-+{
-+ DBUG_ENTER("JOIN::optimize");
-+ // to prevent double initialization on EXPLAIN
-+ if (optimized)
-+ DBUG_RETURN(0);
-+ optimized= 1;
-+
-+ thd_proc_info(thd, "optimizing");
-+ row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
-+ unit->select_limit_cnt);
-+ /* select_limit is used to decide if we are likely to scan the whole table */
-+ select_limit= unit->select_limit_cnt;
-+ if (having || (select_options & OPTION_FOUND_ROWS))
-+ select_limit= HA_POS_ERROR;
-+ do_send_rows = (unit->select_limit_cnt) ? 1 : 0;
-+ // Ignore errors of execution if option IGNORE present
-+ if (thd->lex->ignore)
-+ thd->lex->current_select->no_error= 1;
-+#ifdef HAVE_REF_TO_FIELDS // Not done yet
-+ /* Add HAVING to WHERE if possible */
-+ if (having && !group_list && !sum_func_count)
-+ {
-+ if (!conds)
-+ {
-+ conds= having;
-+ having= 0;
-+ }
-+ else if ((conds=new Item_cond_and(conds,having)))
-+ {
-+ /*
-+ Item_cond_and can't be fixed after creation, so we do not check
-+ conds->fixed
-+ */
-+ conds->fix_fields(thd, &conds);
-+ conds->change_ref_to_fields(thd, tables_list);
-+ conds->top_level_item();
-+ having= 0;
-+ }
-+ }
-+#endif
-+ SELECT_LEX *sel= thd->lex->current_select;
-+ if (sel->first_cond_optimization)
-+ {
-+ /*
-+ The following code will allocate the new items in a permanent
-+ MEMROOT for prepared statements and stored procedures.
-+ */
-+
-+ Query_arena *arena= thd->stmt_arena, backup;
-+ if (arena->is_conventional())
-+ arena= 0; // For easier test
-+ else
-+ thd->set_n_backup_active_arena(arena, &backup);
-+
-+ sel->first_cond_optimization= 0;
-+
-+ /* Convert all outer joins to inner joins if possible */
-+ conds= simplify_joins(this, join_list, conds, TRUE);
-+ build_bitmap_for_nested_joins(join_list, 0);
-+
-+ sel->prep_where= conds ? conds->copy_andor_structure(thd) : 0;
-+
-+ if (arena)
-+ thd->restore_active_arena(arena, &backup);
-+ }
-+
-+ conds= optimize_cond(this, conds, join_list, &cond_value);
-+ if (thd->is_error())
-+ {
-+ error= 1;
-+ DBUG_PRINT("error",("Error from optimize_cond"));
-+ DBUG_RETURN(1);
-+ }
-+
-+ {
-+ having= optimize_cond(this, having, join_list, &having_value);
-+ if (thd->is_error())
-+ {
-+ error= 1;
-+ DBUG_PRINT("error",("Error from optimize_cond"));
-+ DBUG_RETURN(1);
-+ }
-+ if (select_lex->where)
-+ select_lex->cond_value= cond_value;
-+ if (select_lex->having)
-+ select_lex->having_value= having_value;
-+
-+ if (cond_value == Item::COND_FALSE || having_value == Item::COND_FALSE ||
-+ (!unit->select_limit_cnt && !(select_options & OPTION_FOUND_ROWS)))
-+ { /* Impossible cond */
-+ DBUG_PRINT("info", (having_value == Item::COND_FALSE ?
-+ "Impossible HAVING" : "Impossible WHERE"));
-+ zero_result_cause= having_value == Item::COND_FALSE ?
-+ "Impossible HAVING" : "Impossible WHERE";
-+ tables= 0;
-+ error= 0;
-+ DBUG_RETURN(0);
-+ }
-+ }
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ {
-+ TABLE_LIST *tbl;
-+ for (tbl= select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
-+ {
-+ /*
-+ If tbl->embedding!=NULL that means that this table is in the inner
-+ part of the nested outer join, and we can't do partition pruning
-+ (TODO: check if this limitation can be lifted)
-+ */
-+ if (!tbl->embedding)
-+ {
-+ Item *prune_cond= tbl->on_expr? tbl->on_expr : conds;
-+ tbl->table->no_partitions_used= prune_partitions(thd, tbl->table,
-+ prune_cond);
-+ }
-+ }
-+ }
-+#endif
-+
-+ /*
-+ Try to optimize count(*), min() and max() to const fields if
-+ there is implicit grouping (aggregate functions but no
-+ group_list). In this case, the result set shall only contain one
-+ row.
-+ */
-+ if (tables_list && implicit_grouping)
-+ {
-+ int res;
-+ /*
-+ opt_sum_query() returns HA_ERR_KEY_NOT_FOUND if no rows match
-+ to the WHERE conditions,
-+ or 1 if all items were resolved (optimized away),
-+ or 0, or an error number HA_ERR_...
-+
-+ If all items were resolved by opt_sum_query, there is no need to
-+ open any tables.
-+ */
-+ if ((res=opt_sum_query(select_lex->leaf_tables, all_fields, conds)))
-+ {
-+ if (res == HA_ERR_KEY_NOT_FOUND)
-+ {
-+ DBUG_PRINT("info",("No matching min/max row"));
-+ zero_result_cause= "No matching min/max row";
-+ tables= 0;
-+ error=0;
-+ DBUG_RETURN(0);
-+ }
-+ if (res > 1)
-+ {
-+ error= res;
-+ DBUG_PRINT("error",("Error from opt_sum_query"));
-+ DBUG_RETURN(1);
-+ }
-+ if (res < 0)
-+ {
-+ DBUG_PRINT("info",("No matching min/max row"));
-+ zero_result_cause= "No matching min/max row";
-+ tables= 0;
-+ error=0;
-+ DBUG_RETURN(0);
-+ }
-+ DBUG_PRINT("info",("Select tables optimized away"));
-+ zero_result_cause= "Select tables optimized away";
-+ tables_list= 0; // All tables resolved
-+ const_tables= tables;
-+ /*
-+ Extract all table-independent conditions and replace the WHERE
-+ clause with them. All other conditions were computed by opt_sum_query
-+ and the MIN/MAX/COUNT function(s) have been replaced by constants,
-+ so there is no need to compute the whole WHERE clause again.
-+ Notice that make_cond_for_table() will always succeed to remove all
-+ computed conditions, because opt_sum_query() is applicable only to
-+ conjunctions.
-+ Preserve conditions for EXPLAIN.
-+ */
-+ if (conds && !(thd->lex->describe & DESCRIBE_EXTENDED))
-+ {
-+ COND *table_independent_conds=
-+ make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0);
-+ DBUG_EXECUTE("where",
-+ print_where(table_independent_conds,
-+ "where after opt_sum_query()",
-+ QT_ORDINARY););
-+ conds= table_independent_conds;
-+ }
-+ }
-+ }
-+ if (!tables_list)
-+ {
-+ DBUG_PRINT("info",("No tables"));
-+ error= 0;
-+ DBUG_RETURN(0);
-+ }
-+ error= -1; // Error is sent to client
-+ sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
-+
-+ /* Calculate how to do the join */
-+ thd_proc_info(thd, "statistics");
-+ if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
-+ thd->is_fatal_error)
-+ {
-+ DBUG_PRINT("error",("Error: make_join_statistics() failed"));
-+ DBUG_RETURN(1);
-+ }
-+
-+ if (rollup.state != ROLLUP::STATE_NONE)
-+ {
-+ if (rollup_process_const_fields())
-+ {
-+ DBUG_PRINT("error", ("Error: rollup_process_fields() failed"));
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ else
-+ {
-+ /* Remove distinct if only const tables */
-+ select_distinct= select_distinct && (const_tables != tables);
-+ }
-+
-+ thd_proc_info(thd, "preparing");
-+ if (result->initialize_tables(this))
-+ {
-+ DBUG_PRINT("error",("Error: initialize_tables() failed"));
-+ DBUG_RETURN(1); // error == -1
-+ }
-+ if (const_table_map != found_const_table_map &&
-+ !(select_options & SELECT_DESCRIBE) &&
-+ (!conds ||
-+ !(conds->used_tables() & RAND_TABLE_BIT) ||
-+ select_lex->master_unit() == &thd->lex->unit)) // upper level SELECT
-+ {
-+ zero_result_cause= "no matching row in const table";
-+ DBUG_PRINT("error",("Error: %s", zero_result_cause));
-+ error= 0;
-+ DBUG_RETURN(0);
-+ }
-+ if (!(thd->options & OPTION_BIG_SELECTS) &&
-+ best_read > (double) thd->variables.max_join_size &&
-+ !(select_options & SELECT_DESCRIBE))
-+ { /* purecov: inspected */
-+ my_message(ER_TOO_BIG_SELECT, ER(ER_TOO_BIG_SELECT), MYF(0));
-+ error= -1;
-+ DBUG_RETURN(1);
-+ }
-+ if (const_tables && !thd->locked_tables &&
-+ !(select_options & SELECT_NO_UNLOCK))
-+ mysql_unlock_some_tables(thd, table, const_tables);
-+ if (!conds && outer_join)
-+ {
-+ /* Handle the case where we have an OUTER JOIN without a WHERE */
-+ conds=new Item_int((longlong) 1,1); // Always true
-+ }
-+ select= make_select(*table, const_table_map,
-+ const_table_map, conds, 1, &error);
-+ if (error)
-+ { /* purecov: inspected */
-+ error= -1; /* purecov: inspected */
-+ DBUG_PRINT("error",("Error: make_select() failed"));
-+ DBUG_RETURN(1);
-+ }
-+
-+ reset_nj_counters(join_list);
-+ make_outerjoin_info(this);
-+
-+ /*
-+ Among the equal fields belonging to the same multiple equality
-+ choose the one that is to be retrieved first and substitute
-+ all references to these in where condition for a reference for
-+ the selected field.
-+ */
-+ if (conds)
-+ {
-+ conds= substitute_for_best_equal_field(conds, cond_equal, map2table);
-+ conds->update_used_tables();
-+ DBUG_EXECUTE("where",
-+ print_where(conds,
-+ "after substitute_best_equal",
-+ QT_ORDINARY););
-+ }
-+
-+ /*
-+ Permorm the the optimization on fields evaluation mentioned above
-+ for all on expressions.
-+ */
-+ for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables ; tab++)
-+ {
-+ if (*tab->on_expr_ref)
-+ {
-+ *tab->on_expr_ref= substitute_for_best_equal_field(*tab->on_expr_ref,
-+ tab->cond_equal,
-+ map2table);
-+ (*tab->on_expr_ref)->update_used_tables();
-+ }
-+ }
-+
-+ if (conds && const_table_map != found_const_table_map &&
-+ (select_options & SELECT_DESCRIBE))
-+ {
-+ conds=new Item_int((longlong) 0,1); // Always false
-+ }
-+
-+ /*
-+ It's necessary to check const part of HAVING cond as
-+ there is a chance that some cond parts may become
-+ const items after make_join_statisctics(for example
-+ when Item is a reference to cost table field from
-+ outer join).
-+ This check is performed only for those conditions
-+ which do not use aggregate functions. In such case
-+ temporary table may not be used and const condition
-+ elements may be lost during further having
-+ condition transformation in JOIN::exec.
-+ */
-+ if (having && const_table_map && !having->with_sum_func)
-+ {
-+ having->update_used_tables();
-+ having= remove_eq_conds(thd, having, &having_value);
-+ if (having_value == Item::COND_FALSE)
-+ {
-+ having= new Item_int((longlong) 0,1);
-+ zero_result_cause= "Impossible HAVING noticed after reading const tables";
-+ DBUG_RETURN(0);
-+ }
-+ }
-+
-+ if (make_join_select(this, select, conds))
-+ {
-+ zero_result_cause=
-+ "Impossible WHERE noticed after reading const tables";
-+ DBUG_RETURN(0); // error == 0
-+ }
-+
-+ error= -1; /* if goto err */
-+
-+ /* Optimize distinct away if possible */
-+ {
-+ ORDER *org_order= order;
-+ order=remove_const(this, order,conds,1, &simple_order);
-+ if (thd->is_error())
-+ {
-+ error= 1;
-+ DBUG_PRINT("error",("Error from remove_const"));
-+ DBUG_RETURN(1);
-+ }
-+
-+ /*
-+ If we are using ORDER BY NULL or ORDER BY const_expression,
-+ return result in any order (even if we are using a GROUP BY)
-+ */
-+ if (!order && org_order)
-+ skip_sort_order= 1;
-+ }
-+ /*
-+ Check if we can optimize away GROUP BY/DISTINCT.
-+ We can do that if there are no aggregate functions, the
-+ fields in DISTINCT clause (if present) and/or columns in GROUP BY
-+ (if present) contain direct references to all key parts of
-+ an unique index (in whatever order) and if the key parts of the
-+ unique index cannot contain NULLs.
-+ Note that the unique keys for DISTINCT and GROUP BY should not
-+ be the same (as long as they are unique).
-+
-+ The FROM clause must contain a single non-constant table.
-+ */
-+ if (tables - const_tables == 1 && (group_list || select_distinct) &&
-+ !tmp_table_param.sum_func_count &&
-+ (!join_tab[const_tables].select ||
-+ !join_tab[const_tables].select->quick ||
-+ join_tab[const_tables].select->quick->get_type() !=
-+ QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))
-+ {
-+ if (group_list && rollup.state == ROLLUP::STATE_NONE &&
-+ list_contains_unique_index(join_tab[const_tables].table,
-+ find_field_in_order_list,
-+ (void *) group_list))
-+ {
-+ /*
-+ We have found that grouping can be removed since groups correspond to
-+ only one row anyway, but we still have to guarantee correct result
-+ order. The line below effectively rewrites the query from GROUP BY
-+ <fields> to ORDER BY <fields>. There are two exceptions:
-+ - if skip_sort_order is set (see above), then we can simply skip
-+ GROUP BY;
-+ - we can only rewrite ORDER BY if the ORDER BY fields are 'compatible'
-+ with the GROUP BY ones, i.e. either one is a prefix of another.
-+ We only check if the ORDER BY is a prefix of GROUP BY. In this case
-+ test_if_subpart() copies the ASC/DESC attributes from the original
-+ ORDER BY fields.
-+ If GROUP BY is a prefix of ORDER BY, then it is safe to leave
-+ 'order' as is.
-+ */
-+ if (!order || test_if_subpart(group_list, order))
-+ order= skip_sort_order ? 0 : group_list;
-+ /*
-+ If we have an IGNORE INDEX FOR GROUP BY(fields) clause, this must be
-+ rewritten to IGNORE INDEX FOR ORDER BY(fields).
-+ */
-+ join_tab->table->keys_in_use_for_order_by=
-+ join_tab->table->keys_in_use_for_group_by;
-+ group_list= 0;
-+ group= 0;
-+ }
-+ if (select_distinct &&
-+ list_contains_unique_index(join_tab[const_tables].table,
-+ find_field_in_item_list,
-+ (void *) &fields_list))
-+ {
-+ select_distinct= 0;
-+ }
-+ }
-+ if (group_list || tmp_table_param.sum_func_count)
-+ {
-+ if (! hidden_group_fields && rollup.state == ROLLUP::STATE_NONE)
-+ select_distinct=0;
-+ }
-+ else if (select_distinct && tables - const_tables == 1 &&
-+ rollup.state == ROLLUP::STATE_NONE)
-+ {
-+ /*
-+ We are only using one table. In this case we change DISTINCT to a
-+ GROUP BY query if:
-+ - The GROUP BY can be done through indexes (no sort) and the ORDER
-+ BY only uses selected fields.
-+ (In this case we can later optimize away GROUP BY and ORDER BY)
-+ - We are scanning the whole table without LIMIT
-+ This can happen if:
-+ - We are using CALC_FOUND_ROWS
-+ - We are using an ORDER BY that can't be optimized away.
-+
-+ We don't want to use this optimization when we are using LIMIT
-+ because in this case we can just create a temporary table that
-+ holds LIMIT rows and stop when this table is full.
-+ */
-+ JOIN_TAB *tab= &join_tab[const_tables];
-+ bool all_order_fields_used;
-+ if (order)
-+ skip_sort_order= test_if_skip_sort_order(tab, order, select_limit, 1,
-+ &tab->table->keys_in_use_for_order_by);
-+ if ((group_list=create_distinct_group(thd, select_lex->ref_pointer_array,
-+ order, fields_list, all_fields,
-+ &all_order_fields_used)))
-+ {
-+ bool skip_group= (skip_sort_order &&
-+ test_if_skip_sort_order(tab, group_list, select_limit, 1,
-+ &tab->table->keys_in_use_for_group_by) != 0);
-+ count_field_types(select_lex, &tmp_table_param, all_fields, 0);
-+ if ((skip_group && all_order_fields_used) ||
-+ select_limit == HA_POS_ERROR ||
-+ (order && !skip_sort_order))
-+ {
-+ /* Change DISTINCT to GROUP BY */
-+ select_distinct= 0;
-+ no_order= !order;
-+ if (all_order_fields_used)
-+ {
-+ if (order && skip_sort_order)
-+ {
-+ /*
-+ Force MySQL to read the table in sorted order to get result in
-+ ORDER BY order.
-+ */
-+ tmp_table_param.quick_group=0;
-+ }
-+ order=0;
-+ }
-+ group=1; // For end_write_group
-+ }
-+ else
-+ group_list= 0;
-+ }
-+ else if (thd->is_fatal_error) // End of memory
-+ DBUG_RETURN(1);
-+ }
-+ simple_group= 0;
-+ {
-+ ORDER *old_group_list;
-+ group_list= remove_const(this, (old_group_list= group_list), conds,
-+ rollup.state == ROLLUP::STATE_NONE,
-+ &simple_group);
-+ if (thd->is_error())
-+ {
-+ error= 1;
-+ DBUG_PRINT("error",("Error from remove_const"));
-+ DBUG_RETURN(1);
-+ }
-+ if (old_group_list && !group_list)
-+ select_distinct= 0;
-+ }
-+ if (!group_list && group)
-+ {
-+ order=0; // The output has only one row
-+ simple_order=1;
-+ select_distinct= 0; // No need in distinct for 1 row
-+ group_optimized_away= 1;
-+ }
-+
-+ calc_group_buffer(this, group_list);
-+ send_group_parts= tmp_table_param.group_parts; /* Save org parts */
-+ if (procedure && procedure->group)
-+ {
-+ group_list= procedure->group= remove_const(this, procedure->group, conds,
-+ 1, &simple_group);
-+ if (thd->is_error())
-+ {
-+ error= 1;
-+ DBUG_PRINT("error",("Error from remove_const"));
-+ DBUG_RETURN(1);
-+ }
-+ calc_group_buffer(this, group_list);
-+ }
-+
-+ if (test_if_subpart(group_list, order) ||
-+ (!group_list && tmp_table_param.sum_func_count))
-+ order=0;
-+
-+ // Can't use sort on head table if using join buffering
-+ if (full_join)
-+ {
-+ TABLE *stable= (sort_by_table == (TABLE *) 1 ?
-+ join_tab[const_tables].table : sort_by_table);
-+ /*
-+ FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
-+ sorting on the first table.
-+ */
-+ if (!stable || !stable->force_index_order)
-+ {
-+ if (group_list)
-+ simple_group= 0;
-+ if (order)
-+ simple_order= 0;
-+ }
-+ }
-+
-+ /*
-+ Check if we need to create a temporary table.
-+ This has to be done if all tables are not already read (const tables)
-+ and one of the following conditions holds:
-+ - We are using DISTINCT (simple distinct's are already optimized away)
-+ - We are using an ORDER BY or GROUP BY on fields not in the first table
-+ - We are using different ORDER BY and GROUP BY orders
-+ - The user wants us to buffer the result.
-+ When the WITH ROLLUP modifier is present, we cannot skip temporary table
-+ creation for the DISTINCT clause just because there are only const tables.
-+ */
-+ need_tmp= ((const_tables != tables &&
-+ ((select_distinct || !simple_order || !simple_group) ||
-+ (group_list && order) ||
-+ test(select_options & OPTION_BUFFER_RESULT))) ||
-+ (rollup.state != ROLLUP::STATE_NONE && select_distinct));
-+
-+ // No cache for MATCH
-+ make_join_readinfo(this,
-+ (select_options & (SELECT_DESCRIBE |
-+ SELECT_NO_JOIN_CACHE)) |
-+ (select_lex->ftfunc_list->elements ?
-+ SELECT_NO_JOIN_CACHE : 0));
-+
-+ /* Perform FULLTEXT search before all regular searches */
-+ if (!(select_options & SELECT_DESCRIBE))
-+ init_ftfuncs(thd, select_lex, test(order));
-+
-+ /*
-+ is this simple IN subquery?
-+ */
-+ if (!group_list && !order &&
-+ unit->item && unit->item->substype() == Item_subselect::IN_SUBS &&
-+ tables == 1 && conds &&
-+ !unit->is_union())
-+ {
-+ if (!having)
-+ {
-+ Item *where= conds;
-+ if (join_tab[0].type == JT_EQ_REF &&
-+ join_tab[0].ref.items[0]->name == in_left_expr_name)
-+ {
-+ remove_subq_pushed_predicates(&where);
-+ save_index_subquery_explain_info(join_tab, where);
-+ join_tab[0].type= JT_UNIQUE_SUBQUERY;
-+ error= 0;
-+ DBUG_RETURN(unit->item->
-+ change_engine(new
-+ subselect_uniquesubquery_engine(thd,
-+ join_tab,
-+ unit->item,
-+ where)));
-+ }
-+ else if (join_tab[0].type == JT_REF &&
-+ join_tab[0].ref.items[0]->name == in_left_expr_name)
-+ {
-+ remove_subq_pushed_predicates(&where);
-+ save_index_subquery_explain_info(join_tab, where);
-+ join_tab[0].type= JT_INDEX_SUBQUERY;
-+ error= 0;
-+ DBUG_RETURN(unit->item->
-+ change_engine(new
-+ subselect_indexsubquery_engine(thd,
-+ join_tab,
-+ unit->item,
-+ where,
-+ NULL,
-+ 0)));
-+ }
-+ } else if (join_tab[0].type == JT_REF_OR_NULL &&
-+ join_tab[0].ref.items[0]->name == in_left_expr_name &&
-+ having->name == in_having_cond)
-+ {
-+ join_tab[0].type= JT_INDEX_SUBQUERY;
-+ error= 0;
-+ conds= remove_additional_cond(conds);
-+ save_index_subquery_explain_info(join_tab, conds);
-+ DBUG_RETURN(unit->item->
-+ change_engine(new subselect_indexsubquery_engine(thd,
-+ join_tab,
-+ unit->item,
-+ conds,
-+ having,
-+ 1)));
-+ }
-+
-+ }
-+ /*
-+ Need to tell handlers that to play it safe, it should fetch all
-+ columns of the primary key of the tables: this is because MySQL may
-+ build row pointers for the rows, and for all columns of the primary key
-+ the read set has not necessarily been set by the server code.
-+ */
-+ if (need_tmp || select_distinct || group_list || order)
-+ {
-+ for (uint i = const_tables; i < tables; i++)
-+ join_tab[i].table->prepare_for_position();
-+ }
-+
-+ DBUG_EXECUTE("info",TEST_join(this););
-+
-+ if (const_tables != tables)
-+ {
-+ /*
-+ Because filesort always does a full table scan or a quick range scan
-+ we must add the removed reference to the select for the table.
-+ We only need to do this when we have a simple_order or simple_group
-+ as in other cases the join is done before the sort.
-+ */
-+ if ((order || group_list) &&
-+ join_tab[const_tables].type != JT_ALL &&
-+ join_tab[const_tables].type != JT_FT &&
-+ join_tab[const_tables].type != JT_REF_OR_NULL &&
-+ ((order && simple_order) || (group_list && simple_group)))
-+ {
-+ if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
-+ DBUG_RETURN(1);
-+ }
-+ }
-+
-+ if (!(select_options & SELECT_BIG_RESULT) &&
-+ ((group_list &&
-+ (!simple_group ||
-+ !test_if_skip_sort_order(&join_tab[const_tables], group_list,
-+ unit->select_limit_cnt, 0,
-+ &join_tab[const_tables].table->
-+ keys_in_use_for_group_by))) ||
-+ select_distinct) &&
-+ tmp_table_param.quick_group && !procedure)
-+ {
-+ need_tmp=1; simple_order=simple_group=0; // Force tmp table without sort
-+ }
-+ if (order)
-+ {
-+ /*
-+ Do we need a temporary table due to the ORDER BY not being equal to
-+ the GROUP BY? The call to test_if_skip_sort_order above tests for the
-+ GROUP BY clause only and hence is not valid in this case. So the
-+ estimated number of rows to be read from the first table is not valid.
-+ We clear it here so that it doesn't show up in EXPLAIN.
-+ */
-+ if (need_tmp && (select_options & SELECT_DESCRIBE) != 0)
-+ join_tab[const_tables].limit= 0;
-+ /*
-+ Force using of tmp table if sorting by a SP or UDF function due to
-+ their expensive and probably non-deterministic nature.
-+ */
-+ for (ORDER *tmp_order= order; tmp_order ; tmp_order=tmp_order->next)
-+ {
-+ Item *item= *tmp_order->item;
-+ if (item->walk(&Item::is_expensive_processor, 0, (uchar*)0))
-+ {
-+ /* Force tmp table without sort */
-+ need_tmp=1; simple_order=simple_group=0;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ tmp_having= having;
-+ if (select_options & SELECT_DESCRIBE)
-+ {
-+ error= 0;
-+ DBUG_RETURN(0);
-+ }
-+ having= 0;
-+
-+ /*
-+ The loose index scan access method guarantees that all grouping or
-+ duplicate row elimination (for distinct) is already performed
-+ during data retrieval, and that all MIN/MAX functions are already
-+ computed for each group. Thus all MIN/MAX functions should be
-+ treated as regular functions, and there is no need to perform
-+ grouping in the main execution loop.
-+ Notice that currently loose index scan is applicable only for
-+ single table queries, thus it is sufficient to test only the first
-+ join_tab element of the plan for its access method.
-+ */
-+ if (join_tab->is_using_loose_index_scan())
-+ tmp_table_param.precomputed_group_by= TRUE;
-+
-+ /* Create a tmp table if distinct or if the sort is too complicated */
-+ if (need_tmp)
-+ {
-+ DBUG_PRINT("info",("Creating tmp table"));
-+ thd_proc_info(thd, "Creating tmp table");
-+
-+ init_items_ref_array();
-+
-+ tmp_table_param.hidden_field_count= (all_fields.elements -
-+ fields_list.elements);
-+ ORDER *tmp_group= ((!simple_group && !procedure &&
-+ !(test_flags & TEST_NO_KEY_GROUP)) ? group_list :
-+ (ORDER*) 0);
-+ /*
-+ Pushing LIMIT to the temporary table creation is not applicable
-+ when there is ORDER BY or GROUP BY or there is no GROUP BY, but
-+ there are aggregate functions, because in all these cases we need
-+ all result rows.
-+ */
-+ ha_rows tmp_rows_limit= ((order == 0 || skip_sort_order) &&
-+ !tmp_group &&
-+ !thd->lex->current_select->with_sum_func) ?
-+ select_limit : HA_POS_ERROR;
-+
-+ if (!(exec_tmp_table1=
-+ create_tmp_table(thd, &tmp_table_param, all_fields,
-+ tmp_group,
-+ group_list ? 0 : select_distinct,
-+ group_list && simple_group,
-+ select_options,
-+ tmp_rows_limit,
-+ (char *) "")))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+
-+ /*
-+ We don't have to store rows in temp table that doesn't match HAVING if:
-+ - we are sorting the table and writing complete group rows to the
-+ temp table.
-+ - We are using DISTINCT without resolving the distinct as a GROUP BY
-+ on all columns.
-+
-+ If having is not handled here, it will be checked before the row
-+ is sent to the client.
-+ */
-+ if (tmp_having &&
-+ (sort_and_group || (exec_tmp_table1->distinct && !group_list)))
-+ having= tmp_having;
-+
-+ /* if group or order on first table, sort first */
-+ if (group_list && simple_group)
-+ {
-+ DBUG_PRINT("info",("Sorting for group"));
-+ thd_proc_info(thd, "Sorting for group");
-+ if (create_sort_index(thd, this, group_list,
-+ HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
-+ alloc_group_fields(this, group_list) ||
-+ make_sum_func_list(all_fields, fields_list, 1) ||
-+ setup_sum_funcs(thd, sum_funcs))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ group_list=0;
-+ }
-+ else
-+ {
-+ if (make_sum_func_list(all_fields, fields_list, 0) ||
-+ setup_sum_funcs(thd, sum_funcs))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+
-+ if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
-+ {
-+ thd_proc_info(thd, "Sorting for order");
-+ if (create_sort_index(thd, this, order,
-+ HA_POS_ERROR, HA_POS_ERROR, TRUE))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ order=0;
-+ }
-+ }
-+
-+ /*
-+ Optimize distinct when used on some of the tables
-+ SELECT DISTINCT t1.a FROM t1,t2 WHERE t1.b=t2.b
-+ In this case we can stop scanning t2 when we have found one t1.a
-+ */
-+
-+ if (exec_tmp_table1->distinct)
-+ {
-+ table_map used_tables= thd->used_tables;
-+ JOIN_TAB *last_join_tab= join_tab+tables-1;
-+ do
-+ {
-+ if (used_tables & last_join_tab->table->map)
-+ break;
-+ last_join_tab->not_used_in_distinct=1;
-+ } while (last_join_tab-- != join_tab);
-+ /* Optimize "select distinct b from t1 order by key_part_1 limit #" */
-+ if (order && skip_sort_order)
-+ {
-+ /* Should always succeed */
-+ if (test_if_skip_sort_order(&join_tab[const_tables],
-+ order, unit->select_limit_cnt, 0,
-+ &join_tab[const_tables].table->
-+ keys_in_use_for_order_by))
-+ order=0;
-+ }
-+ }
-+
-+ /* If this join belongs to an uncacheable query save the original join */
-+ if (select_lex->uncacheable && init_save_join_tab())
-+ DBUG_RETURN(-1); /* purecov: inspected */
-+ }
-+
-+ error= 0;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ Restore values in temporary join.
-+*/
-+void JOIN::restore_tmp()
-+{
-+ memcpy(tmp_join, this, (size_t) sizeof(JOIN));
-+}
-+
-+
-+int
-+JOIN::reinit()
-+{
-+ DBUG_ENTER("JOIN::reinit");
-+
-+ unit->offset_limit_cnt= (ha_rows)(select_lex->offset_limit ?
-+ select_lex->offset_limit->val_uint() :
-+ ULL(0));
-+
-+ first_record= 0;
-+
-+ if (exec_tmp_table1)
-+ {
-+ exec_tmp_table1->file->extra(HA_EXTRA_RESET_STATE);
-+ exec_tmp_table1->file->ha_delete_all_rows();
-+ free_io_cache(exec_tmp_table1);
-+ filesort_free_buffers(exec_tmp_table1,0);
-+ }
-+ if (exec_tmp_table2)
-+ {
-+ exec_tmp_table2->file->extra(HA_EXTRA_RESET_STATE);
-+ exec_tmp_table2->file->ha_delete_all_rows();
-+ free_io_cache(exec_tmp_table2);
-+ filesort_free_buffers(exec_tmp_table2,0);
-+ }
-+ if (items0)
-+ set_items_ref_array(items0);
-+
-+ if (join_tab_save)
-+ memcpy(join_tab, join_tab_save, sizeof(JOIN_TAB) * tables);
-+
-+ /* need to reset ref access state (see join_read_key) */
-+ if (join_tab)
-+ for (uint i= 0; i < tables; i++)
-+ join_tab[i].ref.key_err= TRUE;
-+
-+ if (tmp_join)
-+ restore_tmp();
-+
-+ /* Reset of sum functions */
-+ if (sum_funcs)
-+ {
-+ Item_sum *func, **func_ptr= sum_funcs;
-+ while ((func= *(func_ptr++)))
-+ func->clear();
-+ }
-+
-+ if (!(select_options & SELECT_DESCRIBE))
-+ init_ftfuncs(thd, select_lex, test(order));
-+
-+ DBUG_RETURN(0);
-+}
-+
-+/**
-+ @brief Save the original join layout
-+
-+ @details Saves the original join layout so it can be reused in
-+ re-execution and for EXPLAIN.
-+
-+ @return Operation status
-+ @retval 0 success.
-+ @retval 1 error occurred.
-+*/
-+
-+bool
-+JOIN::init_save_join_tab()
-+{
-+ if (!(tmp_join= (JOIN*)thd->alloc(sizeof(JOIN))))
-+ return 1; /* purecov: inspected */
-+ error= 0; // Ensure that tmp_join.error= 0
-+ restore_tmp();
-+ return 0;
-+}
-+
-+
-+bool
-+JOIN::save_join_tab()
-+{
-+ if (!join_tab_save && select_lex->master_unit()->uncacheable)
-+ {
-+ if (!(join_tab_save= (JOIN_TAB*)thd->memdup((uchar*) join_tab,
-+ sizeof(JOIN_TAB) * tables)))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Exec select.
-+
-+ @todo
-+ Note, that create_sort_index calls test_if_skip_sort_order and may
-+ finally replace sorting with index scan if there is a LIMIT clause in
-+ the query. It's never shown in EXPLAIN!
-+
-+ @todo
-+ When can we have here thd->net.report_error not zero?
-+*/
-+void
-+JOIN::exec()
-+{
-+ List<Item> *columns_list= &fields_list;
-+ int tmp_error;
-+ DBUG_ENTER("JOIN::exec");
-+
-+ thd_proc_info(thd, "executing");
-+ error= 0;
-+ if (procedure)
-+ {
-+ procedure_fields_list= fields_list;
-+ if (procedure->change_columns(procedure_fields_list) ||
-+ result->prepare(procedure_fields_list, unit))
-+ {
-+ thd->limit_found_rows= thd->examined_row_count= 0;
-+ DBUG_VOID_RETURN;
-+ }
-+ columns_list= &procedure_fields_list;
-+ }
-+ (void) result->prepare2(); // Currently, this cannot fail.
-+
-+ if (!tables_list && (tables || !select_lex->with_sum_func))
-+ { // Only test of functions
-+ if (select_options & SELECT_DESCRIBE)
-+ select_describe(this, FALSE, FALSE, FALSE,
-+ (zero_result_cause?zero_result_cause:"No tables used"));
-+ else
-+ {
-+ if (result->send_fields(*columns_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ {
-+ DBUG_VOID_RETURN;
-+ }
-+ /*
-+ We have to test for 'conds' here as the WHERE may not be constant
-+ even if we don't have any tables for prepared statements or if
-+ conds uses something like 'rand()'.
-+ If the HAVING clause is either impossible or always true, then
-+ JOIN::having is set to NULL by optimize_cond.
-+ In this case JOIN::exec must check for JOIN::having_value, in the
-+ same way it checks for JOIN::cond_value.
-+ */
-+ if (cond_value != Item::COND_FALSE &&
-+ having_value != Item::COND_FALSE &&
-+ (!conds || conds->val_int()) &&
-+ (!having || having->val_int()))
-+ {
-+ if (do_send_rows &&
-+ (procedure ? (procedure->send_row(procedure_fields_list) ||
-+ procedure->end_of_records()) : result->send_data(fields_list)))
-+ error= 1;
-+ else
-+ {
-+ error= (int) result->send_eof();
-+ send_records= ((select_options & OPTION_FOUND_ROWS) ? 1 :
-+ thd->sent_row_count);
-+ }
-+ }
-+ else
-+ {
-+ error=(int) result->send_eof();
-+ send_records= 0;
-+ }
-+ }
-+ /* Single select (without union) always returns 0 or 1 row */
-+ thd->limit_found_rows= send_records;
-+ thd->examined_row_count= 0;
-+ DBUG_VOID_RETURN;
-+ }
-+ /*
-+ Don't reset the found rows count if there're no tables as
-+ FOUND_ROWS() may be called. Never reset the examined row count here.
-+ It must be accumulated from all join iterations of all join parts.
-+ */
-+ if (tables)
-+ thd->limit_found_rows= 0;
-+
-+ if (zero_result_cause)
-+ {
-+ (void) return_zero_rows(this, result, select_lex->leaf_tables,
-+ *columns_list,
-+ send_row_on_empty_set(),
-+ select_options,
-+ zero_result_cause,
-+ having);
-+ DBUG_VOID_RETURN;
-+ }
-+
-+ if ((this->select_lex->options & OPTION_SCHEMA_TABLE) &&
-+ get_schema_tables_result(this, PROCESSED_BY_JOIN_EXEC))
-+ DBUG_VOID_RETURN;
-+
-+ if (select_options & SELECT_DESCRIBE)
-+ {
-+ /*
-+ Check if we managed to optimize ORDER BY away and don't use temporary
-+ table to resolve ORDER BY: in that case, we only may need to do
-+ filesort for GROUP BY.
-+ */
-+ if (!order && !no_order && (!skip_sort_order || !need_tmp))
-+ {
-+ /*
-+ Reset 'order' to 'group_list' and reinit variables describing
-+ 'order'
-+ */
-+ order= group_list;
-+ simple_order= simple_group;
-+ skip_sort_order= 0;
-+ }
-+ if (order &&
-+ (order != group_list || !(select_options & SELECT_BIG_RESULT)) &&
-+ (const_tables == tables ||
-+ ((simple_order || skip_sort_order) &&
-+ test_if_skip_sort_order(&join_tab[const_tables], order,
-+ select_limit, 0,
-+ &join_tab[const_tables].table->
-+ keys_in_use_for_query))))
-+ order=0;
-+ having= tmp_having;
-+ select_describe(this, need_tmp,
-+ order != 0 && !skip_sort_order,
-+ select_distinct,
-+ !tables ? "No tables used" : NullS);
-+ DBUG_VOID_RETURN;
-+ }
-+
-+ JOIN *curr_join= this;
-+ List<Item> *curr_all_fields= &all_fields;
-+ List<Item> *curr_fields_list= &fields_list;
-+ TABLE *curr_tmp_table= 0;
-+ /*
-+ Initialize examined rows here because the values from all join parts
-+ must be accumulated in examined_row_count. Hence every join
-+ iteration must count from zero.
-+ */
-+ curr_join->examined_rows= 0;
-+
-+ /* Create a tmp table if distinct or if the sort is too complicated */
-+ if (need_tmp)
-+ {
-+ if (tmp_join)
-+ {
-+ /*
-+ We are in a non cacheable sub query. Get the saved join structure
-+ after optimization.
-+ (curr_join may have been modified during last exection and we need
-+ to reset it)
-+ */
-+ curr_join= tmp_join;
-+ }
-+ curr_tmp_table= exec_tmp_table1;
-+
-+ /* Copy data to the temporary table */
-+ thd_proc_info(thd, "Copying to tmp table");
-+ DBUG_PRINT("info", ("%s", thd->proc_info));
-+ if (!curr_join->sort_and_group &&
-+ curr_join->const_tables != curr_join->tables)
-+ curr_join->join_tab[curr_join->const_tables].sorted= 0;
-+ if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
-+ {
-+ error= tmp_error;
-+ DBUG_VOID_RETURN;
-+ }
-+ curr_tmp_table->file->info(HA_STATUS_VARIABLE);
-+
-+ if (curr_join->having)
-+ curr_join->having= curr_join->tmp_having= 0; // Allready done
-+
-+ /* Change sum_fields reference to calculated fields in tmp_table */
-+ if (curr_join != this)
-+ curr_join->all_fields= *curr_all_fields;
-+ if (!items1)
-+ {
-+ items1= items0 + all_fields.elements;
-+ if (sort_and_group || curr_tmp_table->group ||
-+ tmp_table_param.precomputed_group_by)
-+ {
-+ if (change_to_use_tmp_fields(thd, items1,
-+ tmp_fields_list1, tmp_all_fields1,
-+ fields_list.elements, all_fields))
-+ DBUG_VOID_RETURN;
-+ }
-+ else
-+ {
-+ if (change_refs_to_tmp_fields(thd, items1,
-+ tmp_fields_list1, tmp_all_fields1,
-+ fields_list.elements, all_fields))
-+ DBUG_VOID_RETURN;
-+ }
-+ if (curr_join != this)
-+ {
-+ curr_join->tmp_all_fields1= tmp_all_fields1;
-+ curr_join->tmp_fields_list1= tmp_fields_list1;
-+ }
-+ curr_join->items1= items1;
-+ }
-+ curr_all_fields= &tmp_all_fields1;
-+ curr_fields_list= &tmp_fields_list1;
-+ curr_join->set_items_ref_array(items1);
-+
-+ if (sort_and_group || curr_tmp_table->group)
-+ {
-+ curr_join->tmp_table_param.field_count+=
-+ curr_join->tmp_table_param.sum_func_count+
-+ curr_join->tmp_table_param.func_count;
-+ curr_join->tmp_table_param.sum_func_count=
-+ curr_join->tmp_table_param.func_count= 0;
-+ }
-+ else
-+ {
-+ curr_join->tmp_table_param.field_count+=
-+ curr_join->tmp_table_param.func_count;
-+ curr_join->tmp_table_param.func_count= 0;
-+ }
-+
-+ // procedure can't be used inside subselect => we do nothing special for it
-+ if (procedure)
-+ procedure->update_refs();
-+
-+ if (curr_tmp_table->group)
-+ { // Already grouped
-+ if (!curr_join->order && !curr_join->no_order && !skip_sort_order)
-+ curr_join->order= curr_join->group_list; /* order by group */
-+ curr_join->group_list= 0;
-+ }
-+
-+ /*
-+ If we have different sort & group then we must sort the data by group
-+ and copy it to another tmp table
-+ This code is also used if we are using distinct something
-+ we haven't been able to store in the temporary table yet
-+ like SEC_TO_TIME(SUM(...)).
-+ */
-+
-+ if ((curr_join->group_list && (!test_if_subpart(curr_join->group_list,
-+ curr_join->order) ||
-+ curr_join->select_distinct)) ||
-+ (curr_join->select_distinct &&
-+ curr_join->tmp_table_param.using_indirect_summary_function))
-+ { /* Must copy to another table */
-+ DBUG_PRINT("info",("Creating group table"));
-+
-+ /* Free first data from old join */
-+ curr_join->join_free();
-+ if (curr_join->make_simple_join(this, curr_tmp_table))
-+ DBUG_VOID_RETURN;
-+ calc_group_buffer(curr_join, group_list);
-+ count_field_types(select_lex, &curr_join->tmp_table_param,
-+ curr_join->tmp_all_fields1,
-+ curr_join->select_distinct && !curr_join->group_list);
-+ curr_join->tmp_table_param.hidden_field_count=
-+ (curr_join->tmp_all_fields1.elements-
-+ curr_join->tmp_fields_list1.elements);
-+
-+
-+ if (exec_tmp_table2)
-+ curr_tmp_table= exec_tmp_table2;
-+ else
-+ {
-+ /* group data to new table */
-+
-+ /*
-+ If the access method is loose index scan then all MIN/MAX
-+ functions are precomputed, and should be treated as regular
-+ functions. See extended comment in JOIN::exec.
-+ */
-+ if (curr_join->join_tab->is_using_loose_index_scan())
-+ curr_join->tmp_table_param.precomputed_group_by= TRUE;
-+
-+ if (!(curr_tmp_table=
-+ exec_tmp_table2= create_tmp_table(thd,
-+ &curr_join->tmp_table_param,
-+ *curr_all_fields,
-+ (ORDER*) 0,
-+ curr_join->select_distinct &&
-+ !curr_join->group_list,
-+ 1, curr_join->select_options,
-+ HA_POS_ERROR,
-+ (char *) "")))
-+ DBUG_VOID_RETURN;
-+ curr_join->exec_tmp_table2= exec_tmp_table2;
-+ }
-+ if (curr_join->group_list)
-+ {
-+ thd_proc_info(thd, "Creating sort index");
-+ if (curr_join->join_tab == join_tab && save_join_tab())
-+ {
-+ DBUG_VOID_RETURN;
-+ }
-+ if (create_sort_index(thd, curr_join, curr_join->group_list,
-+ HA_POS_ERROR, HA_POS_ERROR, FALSE) ||
-+ make_group_fields(this, curr_join))
-+ {
-+ DBUG_VOID_RETURN;
-+ }
-+ sortorder= curr_join->sortorder;
-+ }
-+
-+ thd_proc_info(thd, "Copying to group table");
-+ DBUG_PRINT("info", ("%s", thd->proc_info));
-+ tmp_error= -1;
-+ if (curr_join != this)
-+ {
-+ if (sum_funcs2)
-+ {
-+ curr_join->sum_funcs= sum_funcs2;
-+ curr_join->sum_funcs_end= sum_funcs_end2;
-+ }
-+ else
-+ {
-+ curr_join->alloc_func_list();
-+ sum_funcs2= curr_join->sum_funcs;
-+ sum_funcs_end2= curr_join->sum_funcs_end;
-+ }
-+ }
-+ if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
-+ 1, TRUE))
-+ DBUG_VOID_RETURN;
-+ curr_join->group_list= 0;
-+ if (!curr_join->sort_and_group &&
-+ curr_join->const_tables != curr_join->tables)
-+ curr_join->join_tab[curr_join->const_tables].sorted= 0;
-+ if (setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
-+ (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
-+ 0)))
-+ {
-+ error= tmp_error;
-+ DBUG_VOID_RETURN;
-+ }
-+ end_read_record(&curr_join->join_tab->read_record);
-+ curr_join->const_tables= curr_join->tables; // Mark free for cleanup()
-+ curr_join->join_tab[0].table= 0; // Table is freed
-+
-+ // No sum funcs anymore
-+ if (!items2)
-+ {
-+ items2= items1 + all_fields.elements;
-+ if (change_to_use_tmp_fields(thd, items2,
-+ tmp_fields_list2, tmp_all_fields2,
-+ fields_list.elements, tmp_all_fields1))
-+ DBUG_VOID_RETURN;
-+ if (curr_join != this)
-+ {
-+ curr_join->tmp_fields_list2= tmp_fields_list2;
-+ curr_join->tmp_all_fields2= tmp_all_fields2;
-+ }
-+ }
-+ curr_fields_list= &curr_join->tmp_fields_list2;
-+ curr_all_fields= &curr_join->tmp_all_fields2;
-+ curr_join->set_items_ref_array(items2);
-+ curr_join->tmp_table_param.field_count+=
-+ curr_join->tmp_table_param.sum_func_count;
-+ curr_join->tmp_table_param.sum_func_count= 0;
-+ }
-+ if (curr_tmp_table->distinct)
-+ curr_join->select_distinct=0; /* Each row is unique */
-+
-+ curr_join->join_free(); /* Free quick selects */
-+ if (curr_join->select_distinct && ! curr_join->group_list)
-+ {
-+ thd_proc_info(thd, "Removing duplicates");
-+ if (curr_join->tmp_having)
-+ curr_join->tmp_having->update_used_tables();
-+ if (remove_duplicates(curr_join, curr_tmp_table,
-+ *curr_fields_list, curr_join->tmp_having))
-+ DBUG_VOID_RETURN;
-+ curr_join->tmp_having=0;
-+ curr_join->select_distinct=0;
-+ }
-+ curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
-+ if (curr_join->make_simple_join(this, curr_tmp_table))
-+ DBUG_VOID_RETURN;
-+ calc_group_buffer(curr_join, curr_join->group_list);
-+ count_field_types(select_lex, &curr_join->tmp_table_param,
-+ *curr_all_fields, 0);
-+
-+ }
-+ if (procedure)
-+ count_field_types(select_lex, &curr_join->tmp_table_param,
-+ *curr_all_fields, 0);
-+
-+ if (curr_join->group || curr_join->implicit_grouping ||
-+ curr_join->tmp_table_param.sum_func_count ||
-+ (procedure && (procedure->flags & PROC_GROUP)))
-+ {
-+ if (make_group_fields(this, curr_join))
-+ {
-+ DBUG_VOID_RETURN;
-+ }
-+ if (!items3)
-+ {
-+ if (!items0)
-+ init_items_ref_array();
-+ items3= ref_pointer_array + (all_fields.elements*4);
-+ setup_copy_fields(thd, &curr_join->tmp_table_param,
-+ items3, tmp_fields_list3, tmp_all_fields3,
-+ curr_fields_list->elements, *curr_all_fields);
-+ tmp_table_param.save_copy_funcs= curr_join->tmp_table_param.copy_funcs;
-+ tmp_table_param.save_copy_field= curr_join->tmp_table_param.copy_field;
-+ tmp_table_param.save_copy_field_end=
-+ curr_join->tmp_table_param.copy_field_end;
-+ if (curr_join != this)
-+ {
-+ curr_join->tmp_all_fields3= tmp_all_fields3;
-+ curr_join->tmp_fields_list3= tmp_fields_list3;
-+ }
-+ }
-+ else
-+ {
-+ curr_join->tmp_table_param.copy_funcs= tmp_table_param.save_copy_funcs;
-+ curr_join->tmp_table_param.copy_field= tmp_table_param.save_copy_field;
-+ curr_join->tmp_table_param.copy_field_end=
-+ tmp_table_param.save_copy_field_end;
-+ }
-+ curr_fields_list= &tmp_fields_list3;
-+ curr_all_fields= &tmp_all_fields3;
-+ curr_join->set_items_ref_array(items3);
-+
-+ if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
-+ 1, TRUE) ||
-+ setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
-+ thd->is_fatal_error)
-+ DBUG_VOID_RETURN;
-+ }
-+ if (curr_join->group_list || curr_join->order)
-+ {
-+ DBUG_PRINT("info",("Sorting for send_fields"));
-+ thd_proc_info(thd, "Sorting result");
-+ /* If we have already done the group, add HAVING to sorted table */
-+ if (curr_join->tmp_having && ! curr_join->group_list &&
-+ ! curr_join->sort_and_group)
-+ {
-+ // Some tables may have been const
-+ curr_join->tmp_having->update_used_tables();
-+ JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables];
-+ table_map used_tables= (curr_join->const_table_map |
-+ curr_table->table->map);
-+
-+ Item* sort_table_cond= make_cond_for_table(curr_join->tmp_having,
-+ used_tables,
-+ used_tables);
-+ if (sort_table_cond)
-+ {
-+ if (!curr_table->select)
-+ if (!(curr_table->select= new SQL_SELECT))
-+ DBUG_VOID_RETURN;
-+ if (!curr_table->select->cond)
-+ curr_table->select->cond= sort_table_cond;
-+ else
-+ {
-+ if (!(curr_table->select->cond=
-+ new Item_cond_and(curr_table->select->cond,
-+ sort_table_cond)))
-+ DBUG_VOID_RETURN;
-+ curr_table->select->cond->fix_fields(thd, 0);
-+ }
-+ curr_table->select_cond= curr_table->select->cond;
-+ curr_table->select_cond->top_level_item();
-+ DBUG_EXECUTE("where",print_where(curr_table->select->cond,
-+ "select and having",
-+ QT_ORDINARY););
-+ curr_join->tmp_having= make_cond_for_table(curr_join->tmp_having,
-+ ~ (table_map) 0,
-+ ~used_tables);
-+ DBUG_EXECUTE("where",print_where(curr_join->tmp_having,
-+ "having after sort",
-+ QT_ORDINARY););
-+ }
-+ }
-+ {
-+ if (group)
-+ curr_join->select_limit= HA_POS_ERROR;
-+ else
-+ {
-+ /*
-+ We can abort sorting after thd->select_limit rows if we there is no
-+ WHERE clause for any tables after the sorted one.
-+ */
-+ JOIN_TAB *curr_table= &curr_join->join_tab[curr_join->const_tables+1];
-+ JOIN_TAB *end_table= &curr_join->join_tab[curr_join->tables];
-+ for (; curr_table < end_table ; curr_table++)
-+ {
-+ /*
-+ table->keyuse is set in the case there was an original WHERE clause
-+ on the table that was optimized away.
-+ */
-+ if (curr_table->select_cond ||
-+ (curr_table->keyuse && !curr_table->first_inner))
-+ {
-+ /* We have to sort all rows */
-+ curr_join->select_limit= HA_POS_ERROR;
-+ break;
-+ }
-+ }
-+ }
-+ if (curr_join->join_tab == join_tab && save_join_tab())
-+ {
-+ DBUG_VOID_RETURN;
-+ }
-+ /*
-+ Here we sort rows for ORDER BY/GROUP BY clause, if the optimiser
-+ chose FILESORT to be faster than INDEX SCAN or there is no
-+ suitable index present.
-+ Note, that create_sort_index calls test_if_skip_sort_order and may
-+ finally replace sorting with index scan if there is a LIMIT clause in
-+ the query. XXX: it's never shown in EXPLAIN!
-+ OPTION_FOUND_ROWS supersedes LIMIT and is taken into account.
-+ */
-+ if (create_sort_index(thd, curr_join,
-+ curr_join->group_list ?
-+ curr_join->group_list : curr_join->order,
-+ curr_join->select_limit,
-+ (select_options & OPTION_FOUND_ROWS ?
-+ HA_POS_ERROR : unit->select_limit_cnt),
-+ curr_join->group_list ? TRUE : FALSE))
-+ DBUG_VOID_RETURN;
-+ sortorder= curr_join->sortorder;
-+ if (curr_join->const_tables != curr_join->tables &&
-+ !curr_join->join_tab[curr_join->const_tables].table->sort.io_cache)
-+ {
-+ /*
-+ If no IO cache exists for the first table then we are using an
-+ INDEX SCAN and no filesort. Thus we should not remove the sorted
-+ attribute on the INDEX SCAN.
-+ */
-+ skip_sort_order= 1;
-+ }
-+ }
-+ }
-+ /* XXX: When can we have here thd->is_error() not zero? */
-+ if (thd->is_error())
-+ {
-+ error= thd->is_error();
-+ DBUG_VOID_RETURN;
-+ }
-+ curr_join->having= curr_join->tmp_having;
-+ curr_join->fields= curr_fields_list;
-+ curr_join->procedure= procedure;
-+
-+ if (is_top_level_join() && thd->cursor && tables != const_tables)
-+ {
-+ /*
-+ We are here if this is JOIN::exec for the last select of the main unit
-+ and the client requested to open a cursor.
-+ We check that not all tables are constant because this case is not
-+ handled by do_select() separately, and this case is not implemented
-+ for cursors yet.
-+ */
-+ DBUG_ASSERT(error == 0);
-+ /*
-+ curr_join is used only for reusable joins - that is,
-+ to perform SELECT for each outer row (like in subselects).
-+ This join is main, so we know for sure that curr_join == join.
-+ */
-+ DBUG_ASSERT(curr_join == this);
-+ /* Open cursor for the last join sweep */
-+ error= thd->cursor->open(this);
-+ }
-+ else
-+ {
-+ thd_proc_info(thd, "Sending data");
-+ DBUG_PRINT("info", ("%s", thd->proc_info));
-+ result->send_fields((procedure ? curr_join->procedure_fields_list :
-+ *curr_fields_list),
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
-+ error= do_select(curr_join, curr_fields_list, NULL, procedure);
-+ thd->limit_found_rows= curr_join->send_records;
-+ }
-+
-+ /* Accumulate the counts from all join iterations of all join parts. */
-+ thd->examined_row_count+= curr_join->examined_rows;
-+ DBUG_PRINT("counts", ("thd->examined_row_count: %lu",
-+ (ulong) thd->examined_row_count));
-+
-+ /*
-+ With EXPLAIN EXTENDED we have to restore original ref_array
-+ for a derived table which is always materialized.
-+ We also need to do this when we have temp table(s).
-+ Otherwise we would not be able to print the query correctly.
-+ */
-+ if (items0 && (thd->lex->describe & DESCRIBE_EXTENDED) &&
-+ (select_lex->linkage == DERIVED_TABLE_TYPE ||
-+ exec_tmp_table1 || exec_tmp_table2))
-+ set_items_ref_array(items0);
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Clean up join.
-+
-+ @return
-+ Return error that hold JOIN.
-+*/
-+
-+int
-+JOIN::destroy()
-+{
-+ DBUG_ENTER("JOIN::destroy");
-+ select_lex->join= 0;
-+
-+ if (tmp_join)
-+ {
-+ if (join_tab != tmp_join->join_tab)
-+ {
-+ JOIN_TAB *tab, *end;
-+ for (tab= join_tab, end= tab+tables ; tab != end ; tab++)
-+ tab->cleanup();
-+ }
-+ tmp_join->tmp_join= 0;
-+ /*
-+ We need to clean up tmp_table_param for reusable JOINs (having non-zero
-+ and different from self tmp_join) because it's not being cleaned up
-+ anywhere else (as we need to keep the join is reusable).
-+ */
-+ tmp_table_param.cleanup();
-+ tmp_table_param.copy_field= tmp_join->tmp_table_param.copy_field= 0;
-+ DBUG_RETURN(tmp_join->destroy());
-+ }
-+ cond_equal= 0;
-+
-+ cleanup(1);
-+ /* Cleanup items referencing temporary table columns */
-+ cleanup_item_list(tmp_all_fields1);
-+ cleanup_item_list(tmp_all_fields3);
-+ if (exec_tmp_table1)
-+ free_tmp_table(thd, exec_tmp_table1);
-+ if (exec_tmp_table2)
-+ free_tmp_table(thd, exec_tmp_table2);
-+ delete select;
-+ delete_dynamic(&keyuse);
-+ delete procedure;
-+ DBUG_RETURN(error);
-+}
-+
-+
-+void JOIN::cleanup_item_list(List<Item> &items) const
-+{
-+ if (!items.is_empty())
-+ {
-+ List_iterator_fast<Item> it(items);
-+ Item *item;
-+ while ((item= it++))
-+ item->cleanup();
-+ }
-+}
-+
-+
-+/**
-+ An entry point to single-unit select (a select without UNION).
-+
-+ @param thd thread handler
-+ @param rref_pointer_array a reference to ref_pointer_array of
-+ the top-level select_lex for this query
-+ @param tables list of all tables used in this query.
-+ The tables have been pre-opened.
-+ @param wild_num number of wildcards used in the top level
-+ select of this query.
-+ For example statement
-+ SELECT *, t1.*, catalog.t2.* FROM t0, t1, t2;
-+ has 3 wildcards.
-+ @param fields list of items in SELECT list of the top-level
-+ select
-+ e.g. SELECT a, b, c FROM t1 will have Item_field
-+ for a, b and c in this list.
-+ @param conds top level item of an expression representing
-+ WHERE clause of the top level select
-+ @param og_num total number of ORDER BY and GROUP BY clauses
-+ arguments
-+ @param order linked list of ORDER BY agruments
-+ @param group linked list of GROUP BY arguments
-+ @param having top level item of HAVING expression
-+ @param proc_param list of PROCEDUREs
-+ @param select_options select options (BIG_RESULT, etc)
-+ @param result an instance of result set handling class.
-+ This object is responsible for send result
-+ set rows to the client or inserting them
-+ into a table.
-+ @param select_lex the only SELECT_LEX of this query
-+ @param unit top-level UNIT of this query
-+ UNIT is an artificial object created by the
-+ parser for every SELECT clause.
-+ e.g.
-+ SELECT * FROM t1 WHERE a1 IN (SELECT * FROM t2)
-+ has 2 unions.
-+
-+ @retval
-+ FALSE success
-+ @retval
-+ TRUE an error
-+*/
-+
-+bool
-+mysql_select(THD *thd, Item ***rref_pointer_array,
-+ TABLE_LIST *tables, uint wild_num, List<Item> &fields,
-+ COND *conds, uint og_num, ORDER *order, ORDER *group,
-+ Item *having, ORDER *proc_param, ulonglong select_options,
-+ select_result *result, SELECT_LEX_UNIT *unit,
-+ SELECT_LEX *select_lex)
-+{
-+ bool err;
-+ bool free_join= 1;
-+ DBUG_ENTER("mysql_select");
-+
-+ select_lex->context.resolve_in_select_list= TRUE;
-+ JOIN *join;
-+ if (select_lex->join != 0)
-+ {
-+ join= select_lex->join;
-+ /*
-+ is it single SELECT in derived table, called in derived table
-+ creation
-+ */
-+ if (select_lex->linkage != DERIVED_TABLE_TYPE ||
-+ (select_options & SELECT_DESCRIBE))
-+ {
-+ if (select_lex->linkage != GLOBAL_OPTIONS_TYPE)
-+ {
-+ //here is EXPLAIN of subselect or derived table
-+ if (join->change_result(result))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ /*
-+ Original join tabs might be overwritten at first
-+ subselect execution. So we need to restore them.
-+ */
-+ Item_subselect *subselect= select_lex->master_unit()->item;
-+ if (subselect && subselect->is_uncacheable() && join->reinit())
-+ DBUG_RETURN(TRUE);
-+ }
-+ else
-+ {
-+ err= join->prepare(rref_pointer_array, tables, wild_num,
-+ conds, og_num, order, group, having, proc_param,
-+ select_lex, unit);
-+ if (err)
-+ {
-+ goto err;
-+ }
-+ }
-+ }
-+ free_join= 0;
-+ join->select_options= select_options;
-+ }
-+ else
-+ {
-+ if (!(join= new JOIN(thd, fields, select_options, result)))
-+ DBUG_RETURN(TRUE);
-+ thd_proc_info(thd, "init");
-+ thd->used_tables=0; // Updated by setup_fields
-+ err= join->prepare(rref_pointer_array, tables, wild_num,
-+ conds, og_num, order, group, having, proc_param,
-+ select_lex, unit);
-+ if (err)
-+ {
-+ goto err;
-+ }
-+ }
-+
-+ if ((err= join->optimize()))
-+ {
-+ goto err; // 1
-+ }
-+
-+ if (thd->lex->describe & DESCRIBE_EXTENDED)
-+ {
-+ join->conds_history= join->conds;
-+ join->having_history= (join->having?join->having:join->tmp_having);
-+ }
-+
-+ if (thd->is_error())
-+ goto err;
-+
-+ join->exec();
-+
-+ if (thd->cursor && thd->cursor->is_open())
-+ {
-+ /*
-+ A cursor was opened for the last sweep in exec().
-+ We are here only if this is mysql_select for top-level SELECT_LEX_UNIT
-+ and there were no error.
-+ */
-+ free_join= 0;
-+ }
-+
-+ if (thd->lex->describe & DESCRIBE_EXTENDED)
-+ {
-+ select_lex->where= join->conds_history;
-+ select_lex->having= join->having_history;
-+ }
-+
-+err:
-+ if (free_join)
-+ {
-+ thd_proc_info(thd, "end");
-+ err|= select_lex->cleanup();
-+ DBUG_RETURN(err || thd->is_error());
-+ }
-+ DBUG_RETURN(join->error);
-+}
-+
-+/*****************************************************************************
-+ Create JOIN_TABS, make a guess about the table types,
-+ Approximate how many records will be used in each table
-+*****************************************************************************/
-+
-+static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select,
-+ TABLE *table,
-+ const key_map *keys,ha_rows limit)
-+{
-+ int error;
-+ DBUG_ENTER("get_quick_record_count");
-+#ifndef EMBEDDED_LIBRARY // Avoid compiler warning
-+ uchar buff[STACK_BUFF_ALLOC];
-+#endif
-+ if (check_stack_overrun(thd, STACK_MIN_SIZE, buff))
-+ DBUG_RETURN(0); // Fatal error flag is set
-+ if (select)
-+ {
-+ select->head=table;
-+ if ((error= select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,
-+ limit, 0)) == 1)
-+ DBUG_RETURN(select->quick->records);
-+ if (error == -1)
-+ {
-+ table->reginfo.impossible_range=1;
-+ DBUG_RETURN(0);
-+ }
-+ DBUG_PRINT("warning",("Couldn't use record count on const keypart"));
-+ }
-+ DBUG_RETURN(HA_POS_ERROR); /* This shouldn't happend */
-+}
-+
-+/*
-+ This structure is used to collect info on potentially sargable
-+ predicates in order to check whether they become sargable after
-+ reading const tables.
-+ We form a bitmap of indexes that can be used for sargable predicates.
-+ Only such indexes are involved in range analysis.
-+*/
-+typedef struct st_sargable_param
-+{
-+ Field *field; /* field against which to check sargability */
-+ Item **arg_value; /* values of potential keys for lookups */
-+ uint num_values; /* number of values in the above array */
-+} SARGABLE_PARAM;
-+
-+/**
-+ Calculate the best possible join and initialize the join structure.
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 Fatal error
-+*/
-+
-+static bool
-+make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
-+ DYNAMIC_ARRAY *keyuse_array)
-+{
-+ int error;
-+ TABLE *table;
-+ TABLE_LIST *tables= tables_arg;
-+ uint i,table_count,const_count,key;
-+ table_map found_const_table_map, all_table_map, found_ref, refs;
-+ key_map const_ref, eq_part;
-+ TABLE **table_vector;
-+ JOIN_TAB *stat,*stat_end,*s,**stat_ref;
-+ KEYUSE *keyuse,*start_keyuse;
-+ table_map outer_join=0;
-+ SARGABLE_PARAM *sargables= 0;
-+ JOIN_TAB *stat_vector[MAX_TABLES+1];
-+ DBUG_ENTER("make_join_statistics");
-+
-+ table_count=join->tables;
-+ stat=(JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB)*table_count);
-+ stat_ref=(JOIN_TAB**) join->thd->alloc(sizeof(JOIN_TAB*)*MAX_TABLES);
-+ table_vector=(TABLE**) join->thd->alloc(sizeof(TABLE*)*(table_count*2));
-+ if (!stat || !stat_ref || !table_vector)
-+ DBUG_RETURN(1); // Eom /* purecov: inspected */
-+
-+ join->best_ref=stat_vector;
-+
-+ stat_end=stat+table_count;
-+ found_const_table_map= all_table_map=0;
-+ const_count=0;
-+
-+ for (s= stat, i= 0;
-+ tables;
-+ s++, tables= tables->next_leaf, i++)
-+ {
-+ TABLE_LIST *embedding= tables->embedding;
-+ stat_vector[i]=s;
-+ s->keys.init();
-+ s->const_keys.init();
-+ s->checked_keys.init();
-+ s->needed_reg.init();
-+ table_vector[i]=s->table=table=tables->table;
-+ table->pos_in_table_list= tables;
-+ error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
-+ if (error)
-+ {
-+ table->file->print_error(error, MYF(0));
-+ goto error;
-+ }
-+ table->quick_keys.clear_all();
-+ table->reginfo.join_tab=s;
-+ table->reginfo.not_exists_optimize=0;
-+ bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
-+ all_table_map|= table->map;
-+ s->join=join;
-+ s->info=0; // For describe
-+
-+ s->dependent= tables->dep_tables;
-+ s->key_dependent= 0;
-+ if (tables->schema_table)
-+ table->file->stats.records= 2;
-+ table->quick_condition_rows= table->file->stats.records;
-+
-+ s->on_expr_ref= &tables->on_expr;
-+ if (*s->on_expr_ref)
-+ {
-+ /* s is the only inner table of an outer join */
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if ((!table->file->stats.records || table->no_partitions_used) && !embedding)
-+#else
-+ if (!table->file->stats.records && !embedding)
-+#endif
-+ { // Empty table
-+ s->dependent= 0; // Ignore LEFT JOIN depend.
-+ set_position(join,const_count++,s,(KEYUSE*) 0);
-+ continue;
-+ }
-+ outer_join|= table->map;
-+ s->embedding_map= 0;
-+ for (;embedding; embedding= embedding->embedding)
-+ s->embedding_map|= embedding->nested_join->nj_map;
-+ continue;
-+ }
-+ if (embedding)
-+ {
-+ /* s belongs to a nested join, maybe to several embedded joins */
-+ s->embedding_map= 0;
-+ do
-+ {
-+ NESTED_JOIN *nested_join= embedding->nested_join;
-+ s->embedding_map|=nested_join->nj_map;
-+ s->dependent|= embedding->dep_tables;
-+ embedding= embedding->embedding;
-+ outer_join|= nested_join->used_tables;
-+ }
-+ while (embedding);
-+ continue;
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ const bool no_partitions_used= table->no_partitions_used;
-+#else
-+ const bool no_partitions_used= FALSE;
-+#endif
-+ if ((table->s->system || table->file->stats.records <= 1 ||
-+ no_partitions_used) &&
-+ !s->dependent &&
-+ (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
-+ !table->fulltext_searched && !join->no_const_tables)
-+ {
-+ set_position(join,const_count++,s,(KEYUSE*) 0);
-+ }
-+ }
-+ stat_vector[i]=0;
-+ join->outer_join=outer_join;
-+
-+ if (join->outer_join)
-+ {
-+ /*
-+ Build transitive closure for relation 'to be dependent on'.
-+ This will speed up the plan search for many cases with outer joins,
-+ as well as allow us to catch illegal cross references.
-+ Warshall's algorithm is used to build the transitive closure.
-+ As we may restart the outer loop upto 'table_count' times, the
-+ complexity of the algorithm is O((number of tables)^3).
-+ However, most of the iterations will be shortcircuited when
-+ there are no pedendencies to propogate.
-+ */
-+ for (i= 0 ; i < table_count ; i++)
-+ {
-+ uint j;
-+ table= stat[i].table;
-+
-+ if (!table->reginfo.join_tab->dependent)
-+ continue;
-+
-+ /* Add my dependencies to other tables depending on me */
-+ for (j= 0, s= stat ; j < table_count ; j++, s++)
-+ {
-+ if (s->dependent & table->map)
-+ {
-+ table_map was_dependent= s->dependent;
-+ s->dependent |= table->reginfo.join_tab->dependent;
-+ /*
-+ If we change dependencies for a table we already have
-+ processed: Redo dependency propagation from this table.
-+ */
-+ if (i > j && s->dependent != was_dependent)
-+ {
-+ i = j-1;
-+ break;
-+ }
-+ }
-+ }
-+ }
-+
-+ for (i= 0, s= stat ; i < table_count ; i++, s++)
-+ {
-+ /* Catch illegal cross references for outer joins */
-+ if (s->dependent & s->table->map)
-+ {
-+ join->tables=0; // Don't use join->table
-+ my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
-+ goto error;
-+ }
-+
-+ if (outer_join & s->table->map)
-+ s->table->maybe_null= 1;
-+ s->key_dependent= s->dependent;
-+ }
-+ }
-+
-+ if (conds || outer_join)
-+ if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
-+ conds, join->cond_equal,
-+ ~outer_join, join->select_lex, &sargables))
-+ goto error;
-+
-+ /* Read tables with 0 or 1 rows (system tables) */
-+ join->const_table_map= 0;
-+
-+ for (POSITION *p_pos=join->positions, *p_end=p_pos+const_count;
-+ p_pos < p_end ;
-+ p_pos++)
-+ {
-+ int tmp;
-+ s= p_pos->table;
-+ s->type=JT_SYSTEM;
-+ join->const_table_map|=s->table->map;
-+ if ((tmp=join_read_const_table(s, p_pos)))
-+ {
-+ if (tmp > 0)
-+ goto error; // Fatal error
-+ }
-+ else
-+ found_const_table_map|= s->table->map;
-+ }
-+
-+ /* loop until no more const tables are found */
-+ int ref_changed;
-+ do
-+ {
-+ more_const_tables_found:
-+ ref_changed = 0;
-+ found_ref=0;
-+
-+ /*
-+ We only have to loop from stat_vector + const_count as
-+ set_position() will move all const_tables first in stat_vector
-+ */
-+
-+ for (JOIN_TAB **pos=stat_vector+const_count ; (s= *pos) ; pos++)
-+ {
-+ table=s->table;
-+
-+ /*
-+ If equi-join condition by a key is null rejecting and after a
-+ substitution of a const table the key value happens to be null
-+ then we can state that there are no matches for this equi-join.
-+ */
-+ if ((keyuse= s->keyuse) && *s->on_expr_ref && !s->embedding_map)
-+ {
-+ /*
-+ When performing an outer join operation if there are no matching rows
-+ for the single row of the outer table all the inner tables are to be
-+ null complemented and thus considered as constant tables.
-+ Here we apply this consideration to the case of outer join operations
-+ with a single inner table only because the case with nested tables
-+ would require a more thorough analysis.
-+ TODO. Apply single row substitution to null complemented inner tables
-+ for nested outer join operations.
-+ */
-+ while (keyuse->table == table)
-+ {
-+ if (!(keyuse->val->used_tables() & ~join->const_table_map) &&
-+ keyuse->val->is_null() && keyuse->null_rejecting)
-+ {
-+ s->type= JT_CONST;
-+ mark_as_null_row(table);
-+ found_const_table_map|= table->map;
-+ join->const_table_map|= table->map;
-+ set_position(join,const_count++,s,(KEYUSE*) 0);
-+ goto more_const_tables_found;
-+ }
-+ keyuse++;
-+ }
-+ }
-+
-+ if (s->dependent) // If dependent on some table
-+ {
-+ // All dep. must be constants
-+ if (s->dependent & ~(found_const_table_map))
-+ continue;
-+ if (table->file->stats.records <= 1L &&
-+ (table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
-+ !table->pos_in_table_list->embedding)
-+ { // system table
-+ int tmp= 0;
-+ s->type=JT_SYSTEM;
-+ join->const_table_map|=table->map;
-+ set_position(join,const_count++,s,(KEYUSE*) 0);
-+ if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
-+ {
-+ if (tmp > 0)
-+ goto error; // Fatal error
-+ }
-+ else
-+ found_const_table_map|= table->map;
-+ continue;
-+ }
-+ }
-+ /* check if table can be read by key or table only uses const refs */
-+ if ((keyuse=s->keyuse))
-+ {
-+ s->type= JT_REF;
-+ while (keyuse->table == table)
-+ {
-+ start_keyuse=keyuse;
-+ key=keyuse->key;
-+ s->keys.set_bit(key); // QQ: remove this ?
-+
-+ refs=0;
-+ const_ref.clear_all();
-+ eq_part.clear_all();
-+ do
-+ {
-+ if (keyuse->val->type() != Item::NULL_ITEM && !keyuse->optimize)
-+ {
-+ if (!((~found_const_table_map) & keyuse->used_tables))
-+ const_ref.set_bit(keyuse->keypart);
-+ else
-+ refs|=keyuse->used_tables;
-+ eq_part.set_bit(keyuse->keypart);
-+ }
-+ keyuse++;
-+ } while (keyuse->table == table && keyuse->key == key);
-+
-+ if (eq_part.is_prefix(table->key_info[key].key_parts) &&
-+ !table->fulltext_searched &&
-+ !table->pos_in_table_list->embedding)
-+ {
-+ if ((table->key_info[key].flags & (HA_NOSAME | HA_END_SPACE_KEY))
-+ == HA_NOSAME)
-+ {
-+ if (const_ref == eq_part)
-+ { // Found everything for ref.
-+ int tmp;
-+ ref_changed = 1;
-+ s->type= JT_CONST;
-+ join->const_table_map|=table->map;
-+ set_position(join,const_count++,s,start_keyuse);
-+ if (create_ref_for_key(join, s, start_keyuse,
-+ found_const_table_map))
-+ goto error;
-+ if ((tmp=join_read_const_table(s,
-+ join->positions+const_count-1)))
-+ {
-+ if (tmp > 0)
-+ goto error; // Fatal error
-+ }
-+ else
-+ found_const_table_map|= table->map;
-+ break;
-+ }
-+ else
-+ found_ref|= refs; // Table is const if all refs are const
-+ }
-+ else if (const_ref == eq_part)
-+ s->const_keys.set_bit(key);
-+ }
-+ }
-+ }
-+ }
-+ } while (join->const_table_map & found_ref && ref_changed);
-+
-+ /*
-+ Update info on indexes that can be used for search lookups as
-+ reading const tables may has added new sargable predicates.
-+ */
-+ if (const_count && sargables)
-+ {
-+ for( ; sargables->field ; sargables++)
-+ {
-+ Field *field= sargables->field;
-+ JOIN_TAB *join_tab= field->table->reginfo.join_tab;
-+ key_map possible_keys= field->key_start;
-+ possible_keys.intersect(field->table->keys_in_use_for_query);
-+ bool is_const= 1;
-+ for (uint j=0; j < sargables->num_values; j++)
-+ is_const&= sargables->arg_value[j]->const_item();
-+ if (is_const)
-+ join_tab[0].const_keys.merge(possible_keys);
-+ }
-+ }
-+
-+ /* Calc how many (possible) matched records in each table */
-+
-+ for (s=stat ; s < stat_end ; s++)
-+ {
-+ if (s->type == JT_SYSTEM || s->type == JT_CONST)
-+ {
-+ /* Only one matching row */
-+ s->found_records=s->records=s->read_time=1; s->worst_seeks=1.0;
-+ continue;
-+ }
-+ /* Approximate found rows and time to read them */
-+ s->found_records=s->records=s->table->file->stats.records;
-+ s->read_time=(ha_rows) s->table->file->scan_time();
-+
-+ /*
-+ Set a max range of how many seeks we can expect when using keys
-+ This is can't be to high as otherwise we are likely to use
-+ table scan.
-+ */
-+ s->worst_seeks= min((double) s->found_records / 10,
-+ (double) s->read_time*3);
-+ if (s->worst_seeks < 2.0) // Fix for small tables
-+ s->worst_seeks=2.0;
-+
-+ /*
-+ Add to stat->const_keys those indexes for which all group fields or
-+ all select distinct fields participate in one index.
-+ */
-+ add_group_and_distinct_keys(join, s);
-+
-+ if (!s->const_keys.is_clear_all() &&
-+ !s->table->pos_in_table_list->embedding)
-+ {
-+ ha_rows records;
-+ SQL_SELECT *select;
-+ select= make_select(s->table, found_const_table_map,
-+ found_const_table_map,
-+ *s->on_expr_ref ? *s->on_expr_ref : conds,
-+ 1, &error);
-+ if (!select)
-+ goto error;
-+ records= get_quick_record_count(join->thd, select, s->table,
-+ &s->const_keys, join->row_limit);
-+ s->quick=select->quick;
-+ s->needed_reg=select->needed_reg;
-+ select->quick=0;
-+ if (records == 0 && s->table->reginfo.impossible_range)
-+ {
-+ /*
-+ Impossible WHERE or ON expression
-+ In case of ON, we mark that the we match one empty NULL row.
-+ In case of WHERE, don't set found_const_table_map to get the
-+ caller to abort with a zero row result.
-+ */
-+ join->const_table_map|= s->table->map;
-+ set_position(join,const_count++,s,(KEYUSE*) 0);
-+ s->type= JT_CONST;
-+ if (*s->on_expr_ref)
-+ {
-+ /* Generate empty row */
-+ s->info= "Impossible ON condition";
-+ found_const_table_map|= s->table->map;
-+ s->type= JT_CONST;
-+ mark_as_null_row(s->table); // All fields are NULL
-+ }
-+ }
-+ if (records != HA_POS_ERROR)
-+ {
-+ s->found_records=records;
-+ s->read_time= (ha_rows) (s->quick ? s->quick->read_time : 0.0);
-+ }
-+ delete select;
-+ }
-+ }
-+
-+ join->join_tab=stat;
-+ join->map2table=stat_ref;
-+ join->table= join->all_tables=table_vector;
-+ join->const_tables=const_count;
-+ join->found_const_table_map=found_const_table_map;
-+
-+ /* Find an optimal join order of the non-constant tables. */
-+ if (join->const_tables != join->tables)
-+ {
-+ optimize_keyuse(join, keyuse_array);
-+ if (choose_plan(join, all_table_map & ~join->const_table_map))
-+ goto error;
-+ }
-+ else
-+ {
-+ memcpy((uchar*) join->best_positions,(uchar*) join->positions,
-+ sizeof(POSITION)*join->const_tables);
-+ join->best_read=1.0;
-+ }
-+ /* Generate an execution plan from the found optimal join order. */
-+ DBUG_RETURN(join->thd->killed || get_best_combination(join));
-+
-+error:
-+ /*
-+ Need to clean up join_tab from TABLEs in case of error.
-+ They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
-+ may not be assigned yet by this function (which is building join_tab).
-+ Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke.
-+ */
-+ for (tables= tables_arg; tables; tables= tables->next_leaf)
-+ tables->table->reginfo.join_tab= NULL;
-+ DBUG_RETURN (1);
-+}
-+
-+
-+/*****************************************************************************
-+ Check with keys are used and with tables references with tables
-+ Updates in stat:
-+ keys Bitmap of all used keys
-+ const_keys Bitmap of all keys with may be used with quick_select
-+ keyuse Pointer to possible keys
-+*****************************************************************************/
-+
-+/// Used when finding key fields
-+typedef struct key_field_t {
-+ Field *field;
-+ Item *val; ///< May be empty if diff constant
-+ uint level;
-+ uint optimize;
-+ bool eq_func;
-+ /**
-+ If true, the condition this struct represents will not be satisfied
-+ when val IS NULL.
-+ */
-+ bool null_rejecting;
-+ bool *cond_guard; /* See KEYUSE::cond_guard */
-+} KEY_FIELD;
-+
-+/* Values in optimize */
-+#define KEY_OPTIMIZE_EXISTS 1
-+#define KEY_OPTIMIZE_REF_OR_NULL 2
-+
-+/**
-+ Merge new key definitions to old ones, remove those not used in both.
-+
-+ This is called for OR between different levels.
-+
-+ To be able to do 'ref_or_null' we merge a comparison of a column
-+ and 'column IS NULL' to one test. This is useful for sub select queries
-+ that are internally transformed to something like:.
-+
-+ @code
-+ SELECT * FROM t1 WHERE t1.key=outer_ref_field or t1.key IS NULL
-+ @endcode
-+
-+ KEY_FIELD::null_rejecting is processed as follows: @n
-+ result has null_rejecting=true if it is set for both ORed references.
-+ for example:
-+ - (t2.key = t1.field OR t2.key = t1.field) -> null_rejecting=true
-+ - (t2.key = t1.field OR t2.key <=> t1.field) -> null_rejecting=false
-+
-+ @todo
-+ The result of this is that we're missing some 'ref' accesses.
-+ OptimizerTeam: Fix this
-+*/
-+
-+static KEY_FIELD *
-+merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
-+ uint and_level)
-+{
-+ if (start == new_fields)
-+ return start; // Impossible or
-+ if (new_fields == end)
-+ return start; // No new fields, skip all
-+
-+ KEY_FIELD *first_free=new_fields;
-+
-+ /* Mark all found fields in old array */
-+ for (; new_fields != end ; new_fields++)
-+ {
-+ for (KEY_FIELD *old=start ; old != first_free ; old++)
-+ {
-+ if (old->field == new_fields->field)
-+ {
-+ /*
-+ NOTE: below const_item() call really works as "!used_tables()", i.e.
-+ it can return FALSE where it is feasible to make it return TRUE.
-+
-+ The cause is as follows: Some of the tables are already known to be
-+ const tables (the detection code is in make_join_statistics(),
-+ above the update_ref_and_keys() call), but we didn't propagate
-+ information about this: TABLE::const_table is not set to TRUE, and
-+ Item::update_used_tables() hasn't been called for each item.
-+ The result of this is that we're missing some 'ref' accesses.
-+ TODO: OptimizerTeam: Fix this
-+ */
-+ if (!new_fields->val->const_item())
-+ {
-+ /*
-+ If the value matches, we can use the key reference.
-+ If not, we keep it until we have examined all new values
-+ */
-+ if (old->val->eq(new_fields->val, old->field->binary()))
-+ {
-+ old->level= and_level;
-+ old->optimize= ((old->optimize & new_fields->optimize &
-+ KEY_OPTIMIZE_EXISTS) |
-+ ((old->optimize | new_fields->optimize) &
-+ KEY_OPTIMIZE_REF_OR_NULL));
-+ old->null_rejecting= (old->null_rejecting &&
-+ new_fields->null_rejecting);
-+ }
-+ }
-+ else if (old->eq_func && new_fields->eq_func &&
-+ old->val->eq_by_collation(new_fields->val,
-+ old->field->binary(),
-+ old->field->charset()))
-+
-+ {
-+ old->level= and_level;
-+ old->optimize= ((old->optimize & new_fields->optimize &
-+ KEY_OPTIMIZE_EXISTS) |
-+ ((old->optimize | new_fields->optimize) &
-+ KEY_OPTIMIZE_REF_OR_NULL));
-+ old->null_rejecting= (old->null_rejecting &&
-+ new_fields->null_rejecting);
-+ }
-+ else if (old->eq_func && new_fields->eq_func &&
-+ ((old->val->const_item() && old->val->is_null()) ||
-+ new_fields->val->is_null()))
-+ {
-+ /* field = expression OR field IS NULL */
-+ old->level= and_level;
-+ old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
-+ /*
-+ Remember the NOT NULL value unless the value does not depend
-+ on other tables.
-+ */
-+ if (!old->val->used_tables() && old->val->is_null())
-+ old->val= new_fields->val;
-+ /* The referred expression can be NULL: */
-+ old->null_rejecting= 0;
-+ }
-+ else
-+ {
-+ /*
-+ We are comparing two different const. In this case we can't
-+ use a key-lookup on this so it's better to remove the value
-+ and let the range optimzier handle it
-+ */
-+ if (old == --first_free) // If last item
-+ break;
-+ *old= *first_free; // Remove old value
-+ old--; // Retry this value
-+ }
-+ }
-+ }
-+ }
-+ /* Remove all not used items */
-+ for (KEY_FIELD *old=start ; old != first_free ;)
-+ {
-+ if (old->level != and_level)
-+ { // Not used in all levels
-+ if (old == --first_free)
-+ break;
-+ *old= *first_free; // Remove old value
-+ continue;
-+ }
-+ old++;
-+ }
-+ return first_free;
-+}
-+
-+
-+/**
-+ Add a possible key to array of possible keys if it's usable as a key
-+
-+ @param key_fields Pointer to add key, if usable
-+ @param and_level And level, to be stored in KEY_FIELD
-+ @param cond Condition predicate
-+ @param field Field used in comparision
-+ @param eq_func True if we used =, <=> or IS NULL
-+ @param value Value used for comparison with field
-+ @param usable_tables Tables which can be used for key optimization
-+ @param sargables IN/OUT Array of found sargable candidates
-+
-+ @note
-+ If we are doing a NOT NULL comparison on a NOT NULL field in a outer join
-+ table, we store this to be able to do not exists optimization later.
-+
-+ @returns
-+ *key_fields is incremented if we stored a key in the array
-+*/
-+
-+static void
-+add_key_field(KEY_FIELD **key_fields,uint and_level, Item_func *cond,
-+ Field *field, bool eq_func, Item **value, uint num_values,
-+ table_map usable_tables, SARGABLE_PARAM **sargables)
-+{
-+ uint exists_optimize= 0;
-+ if (!(field->flags & PART_KEY_FLAG))
-+ {
-+ // Don't remove column IS NULL on a LEFT JOIN table
-+ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
-+ !field->table->maybe_null || field->null_ptr)
-+ return; // Not a key. Skip it
-+ exists_optimize= KEY_OPTIMIZE_EXISTS;
-+ DBUG_ASSERT(num_values == 1);
-+ }
-+ else
-+ {
-+ table_map used_tables=0;
-+ bool optimizable=0;
-+ for (uint i=0; i<num_values; i++)
-+ {
-+ used_tables|=(value[i])->used_tables();
-+ if (!((value[i])->used_tables() & (field->table->map | RAND_TABLE_BIT)))
-+ optimizable=1;
-+ }
-+ if (!optimizable)
-+ return;
-+ if (!(usable_tables & field->table->map))
-+ {
-+ if (!eq_func || (*value)->type() != Item::NULL_ITEM ||
-+ !field->table->maybe_null || field->null_ptr)
-+ return; // Can't use left join optimize
-+ exists_optimize= KEY_OPTIMIZE_EXISTS;
-+ }
-+ else
-+ {
-+ JOIN_TAB *stat=field->table->reginfo.join_tab;
-+ key_map possible_keys=field->key_start;
-+ possible_keys.intersect(field->table->keys_in_use_for_query);
-+ stat[0].keys.merge(possible_keys); // Add possible keys
-+
-+ /*
-+ Save the following cases:
-+ Field op constant
-+ Field LIKE constant where constant doesn't start with a wildcard
-+ Field = field2 where field2 is in a different table
-+ Field op formula
-+ Field IS NULL
-+ Field IS NOT NULL
-+ Field BETWEEN ...
-+ Field IN ...
-+ */
-+ stat[0].key_dependent|=used_tables;
-+
-+ bool is_const=1;
-+ for (uint i=0; i<num_values; i++)
-+ {
-+ if (!(is_const&= value[i]->const_item()))
-+ break;
-+ }
-+ if (is_const)
-+ stat[0].const_keys.merge(possible_keys);
-+ else if (!eq_func)
-+ {
-+ /*
-+ Save info to be able check whether this predicate can be
-+ considered as sargable for range analisis after reading const tables.
-+ We do not save info about equalities as update_const_equal_items
-+ will take care of updating info on keys from sargable equalities.
-+ */
-+ (*sargables)--;
-+ (*sargables)->field= field;
-+ (*sargables)->arg_value= value;
-+ (*sargables)->num_values= num_values;
-+ }
-+ /*
-+ We can't always use indexes when comparing a string index to a
-+ number. cmp_type() is checked to allow compare of dates to numbers.
-+ eq_func is NEVER true when num_values > 1
-+ */
-+ if (!eq_func)
-+ return;
-+ if (field->result_type() == STRING_RESULT)
-+ {
-+ if ((*value)->result_type() != STRING_RESULT)
-+ {
-+ if (field->cmp_type() != (*value)->result_type())
-+ return;
-+ }
-+ else
-+ {
-+ /*
-+ We can't use indexes if the effective collation
-+ of the operation differ from the field collation.
-+ */
-+ if (field->cmp_type() == STRING_RESULT &&
-+ ((Field_str*)field)->charset() != cond->compare_collation())
-+ return;
-+ }
-+ }
-+ }
-+ }
-+ /*
-+ For the moment eq_func is always true. This slot is reserved for future
-+ extensions where we want to remembers other things than just eq comparisons
-+ */
-+ DBUG_ASSERT(eq_func);
-+ /* Store possible eq field */
-+ (*key_fields)->field= field;
-+ (*key_fields)->eq_func= eq_func;
-+ (*key_fields)->val= *value;
-+ (*key_fields)->level= and_level;
-+ (*key_fields)->optimize= exists_optimize;
-+ /*
-+ If the condition has form "tbl.keypart = othertbl.field" and
-+ othertbl.field can be NULL, there will be no matches if othertbl.field
-+ has NULL value.
-+ We use null_rejecting in add_not_null_conds() to add
-+ 'othertbl.field IS NOT NULL' to tab->select_cond.
-+ */
-+ (*key_fields)->null_rejecting= ((cond->functype() == Item_func::EQ_FUNC ||
-+ cond->functype() == Item_func::MULT_EQUAL_FUNC) &&
-+ ((*value)->type() == Item::FIELD_ITEM) &&
-+ ((Item_field*)*value)->field->maybe_null());
-+ (*key_fields)->cond_guard= NULL;
-+ (*key_fields)++;
-+}
-+
-+/**
-+ Add possible keys to array of possible keys originated from a simple
-+ predicate.
-+
-+ @param key_fields Pointer to add key, if usable
-+ @param and_level And level, to be stored in KEY_FIELD
-+ @param cond Condition predicate
-+ @param field Field used in comparision
-+ @param eq_func True if we used =, <=> or IS NULL
-+ @param value Value used for comparison with field
-+ Is NULL for BETWEEN and IN
-+ @param usable_tables Tables which can be used for key optimization
-+ @param sargables IN/OUT Array of found sargable candidates
-+
-+ @note
-+ If field items f1 and f2 belong to the same multiple equality and
-+ a key is added for f1, the the same key is added for f2.
-+
-+ @returns
-+ *key_fields is incremented if we stored a key in the array
-+*/
-+
-+static void
-+add_key_equal_fields(KEY_FIELD **key_fields, uint and_level,
-+ Item_func *cond, Item_field *field_item,
-+ bool eq_func, Item **val,
-+ uint num_values, table_map usable_tables,
-+ SARGABLE_PARAM **sargables)
-+{
-+ Field *field= field_item->field;
-+ add_key_field(key_fields, and_level, cond, field,
-+ eq_func, val, num_values, usable_tables, sargables);
-+ Item_equal *item_equal= field_item->item_equal;
-+ if (item_equal)
-+ {
-+ /*
-+ Add to the set of possible key values every substitution of
-+ the field for an equal field included into item_equal
-+ */
-+ Item_equal_iterator it(*item_equal);
-+ Item_field *item;
-+ while ((item= it++))
-+ {
-+ if (!field->eq(item->field))
-+ {
-+ add_key_field(key_fields, and_level, cond, item->field,
-+ eq_func, val, num_values, usable_tables,
-+ sargables);
-+ }
-+ }
-+ }
-+}
-+
-+
-+/**
-+ Check if an expression is a non-outer field.
-+
-+ Checks if an expression is a field and belongs to the current select.
-+
-+ @param field Item expression to check
-+
-+ @return boolean
-+ @retval TRUE the expression is a local field
-+ @retval FALSE it's something else
-+*/
-+
-+static bool
-+is_local_field (Item *field)
-+{
-+ return field->real_item()->type() == Item::FIELD_ITEM
-+ && !(field->used_tables() & OUTER_REF_TABLE_BIT)
-+ && !((Item_field *)field->real_item())->depended_from;
-+}
-+
-+
-+static void
-+add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
-+ COND *cond, table_map usable_tables,
-+ SARGABLE_PARAM **sargables)
-+{
-+ if (cond->type() == Item_func::COND_ITEM)
-+ {
-+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
-+ KEY_FIELD *org_key_fields= *key_fields;
-+
-+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ {
-+ Item *item;
-+ while ((item=li++))
-+ add_key_fields(join, key_fields, and_level, item, usable_tables,
-+ sargables);
-+ for (; org_key_fields != *key_fields ; org_key_fields++)
-+ org_key_fields->level= *and_level;
-+ }
-+ else
-+ {
-+ (*and_level)++;
-+ add_key_fields(join, key_fields, and_level, li++, usable_tables,
-+ sargables);
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ KEY_FIELD *start_key_fields= *key_fields;
-+ (*and_level)++;
-+ add_key_fields(join, key_fields, and_level, item, usable_tables,
-+ sargables);
-+ *key_fields=merge_key_fields(org_key_fields,start_key_fields,
-+ *key_fields,++(*and_level));
-+ }
-+ }
-+ return;
-+ }
-+
-+ /*
-+ Subquery optimization: Conditions that are pushed down into subqueries
-+ are wrapped into Item_func_trig_cond. We process the wrapped condition
-+ but need to set cond_guard for KEYUSE elements generated from it.
-+ */
-+ {
-+ if (cond->type() == Item::FUNC_ITEM &&
-+ ((Item_func*)cond)->functype() == Item_func::TRIG_COND_FUNC)
-+ {
-+ Item *cond_arg= ((Item_func*)cond)->arguments()[0];
-+ if (!join->group_list && !join->order &&
-+ join->unit->item &&
-+ join->unit->item->substype() == Item_subselect::IN_SUBS &&
-+ !join->unit->is_union())
-+ {
-+ KEY_FIELD *save= *key_fields;
-+ add_key_fields(join, key_fields, and_level, cond_arg, usable_tables,
-+ sargables);
-+ // Indicate that this ref access candidate is for subquery lookup:
-+ for (; save != *key_fields; save++)
-+ save->cond_guard= ((Item_func_trig_cond*)cond)->get_trig_var();
-+ }
-+ return;
-+ }
-+ }
-+
-+ /* If item is of type 'field op field/constant' add it to key_fields */
-+ if (cond->type() != Item::FUNC_ITEM)
-+ return;
-+ Item_func *cond_func= (Item_func*) cond;
-+ switch (cond_func->select_optimize()) {
-+ case Item_func::OPTIMIZE_NONE:
-+ break;
-+ case Item_func::OPTIMIZE_KEY:
-+ {
-+ Item **values;
-+ /*
-+ Build list of possible keys for 'a BETWEEN low AND high'.
-+ It is handled similar to the equivalent condition
-+ 'a >= low AND a <= high':
-+ */
-+ if (cond_func->functype() == Item_func::BETWEEN)
-+ {
-+ Item_field *field_item;
-+ bool equal_func= FALSE;
-+ uint num_values= 2;
-+ values= cond_func->arguments();
-+
-+ bool binary_cmp= (values[0]->real_item()->type() == Item::FIELD_ITEM)
-+ ? ((Item_field*)values[0]->real_item())->field->binary()
-+ : TRUE;
-+
-+ /*
-+ Additional optimization: If 'low = high':
-+ Handle as if the condition was "t.key = low".
-+ */
-+ if (!((Item_func_between*)cond_func)->negated &&
-+ values[1]->eq(values[2], binary_cmp))
-+ {
-+ equal_func= TRUE;
-+ num_values= 1;
-+ }
-+
-+ /*
-+ Append keys for 'field <cmp> value[]' if the
-+ condition is of the form::
-+ '<field> BETWEEN value[1] AND value[2]'
-+ */
-+ if (is_local_field (values[0]))
-+ {
-+ field_item= (Item_field *) (values[0]->real_item());
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ field_item, equal_func, &values[1],
-+ num_values, usable_tables, sargables);
-+ }
-+ /*
-+ Append keys for 'value[0] <cmp> field' if the
-+ condition is of the form:
-+ 'value[0] BETWEEN field1 AND field2'
-+ */
-+ for (uint i= 1; i <= num_values; i++)
-+ {
-+ if (is_local_field (values[i]))
-+ {
-+ field_item= (Item_field *) (values[i]->real_item());
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ field_item, equal_func, values,
-+ 1, usable_tables, sargables);
-+ }
-+ }
-+ } // if ( ... Item_func::BETWEEN)
-+
-+ // IN, NE
-+ else if (is_local_field (cond_func->key_item()) &&
-+ !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
-+ {
-+ values= cond_func->arguments()+1;
-+ if (cond_func->functype() == Item_func::NE_FUNC &&
-+ is_local_field (cond_func->arguments()[1]))
-+ values--;
-+ DBUG_ASSERT(cond_func->functype() != Item_func::IN_FUNC ||
-+ cond_func->argument_count() != 2);
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ (Item_field*) (cond_func->key_item()->real_item()),
-+ 0, values,
-+ cond_func->argument_count()-1,
-+ usable_tables, sargables);
-+ }
-+ break;
-+ }
-+ case Item_func::OPTIMIZE_OP:
-+ {
-+ bool equal_func=(cond_func->functype() == Item_func::EQ_FUNC ||
-+ cond_func->functype() == Item_func::EQUAL_FUNC);
-+
-+ if (is_local_field (cond_func->arguments()[0]))
-+ {
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ (Item_field*) (cond_func->arguments()[0])->real_item(),
-+ equal_func,
-+ cond_func->arguments()+1, 1, usable_tables,
-+ sargables);
-+ }
-+ if (is_local_field (cond_func->arguments()[1]) &&
-+ cond_func->functype() != Item_func::LIKE_FUNC)
-+ {
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ (Item_field*) (cond_func->arguments()[1])->real_item(),
-+ equal_func,
-+ cond_func->arguments(),1,usable_tables,
-+ sargables);
-+ }
-+ break;
-+ }
-+ case Item_func::OPTIMIZE_NULL:
-+ /* column_name IS [NOT] NULL */
-+ if (is_local_field (cond_func->arguments()[0]) &&
-+ !(cond_func->used_tables() & OUTER_REF_TABLE_BIT))
-+ {
-+ Item *tmp=new Item_null;
-+ if (unlikely(!tmp)) // Should never be true
-+ return;
-+ add_key_equal_fields(key_fields, *and_level, cond_func,
-+ (Item_field*) (cond_func->arguments()[0])->real_item(),
-+ cond_func->functype() == Item_func::ISNULL_FUNC,
-+ &tmp, 1, usable_tables, sargables);
-+ }
-+ break;
-+ case Item_func::OPTIMIZE_EQUAL:
-+ Item_equal *item_equal= (Item_equal *) cond;
-+ Item *const_item= item_equal->get_const();
-+ Item_equal_iterator it(*item_equal);
-+ Item_field *item;
-+ if (const_item)
-+ {
-+ /*
-+ For each field field1 from item_equal consider the equality
-+ field1=const_item as a condition allowing an index access of the table
-+ with field1 by the keys value of field1.
-+ */
-+ while ((item= it++))
-+ {
-+ add_key_field(key_fields, *and_level, cond_func, item->field,
-+ TRUE, &const_item, 1, usable_tables, sargables);
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ Consider all pairs of different fields included into item_equal.
-+ For each of them (field1, field1) consider the equality
-+ field1=field2 as a condition allowing an index access of the table
-+ with field1 by the keys value of field2.
-+ */
-+ Item_equal_iterator fi(*item_equal);
-+ while ((item= fi++))
-+ {
-+ Field *field= item->field;
-+ while ((item= it++))
-+ {
-+ if (!field->eq(item->field))
-+ {
-+ add_key_field(key_fields, *and_level, cond_func, field,
-+ TRUE, (Item **) &item, 1, usable_tables,
-+ sargables);
-+ }
-+ }
-+ it.rewind();
-+ }
-+ }
-+ break;
-+ }
-+}
-+
-+
-+static uint
-+max_part_bit(key_part_map bits)
-+{
-+ uint found;
-+ for (found=0; bits & 1 ; found++,bits>>=1) ;
-+ return found;
-+}
-+
-+/*
-+ Add all keys with uses 'field' for some keypart
-+ If field->and_level != and_level then only mark key_part as const_part
-+
-+ RETURN
-+ 0 - OK
-+ 1 - Out of memory.
-+*/
-+
-+static bool
-+add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
-+{
-+ Field *field=key_field->field;
-+ TABLE *form= field->table;
-+ KEYUSE keyuse;
-+
-+ if (key_field->eq_func && !(key_field->optimize & KEY_OPTIMIZE_EXISTS))
-+ {
-+ for (uint key=0 ; key < form->s->keys ; key++)
-+ {
-+ if (!(form->keys_in_use_for_query.is_set(key)))
-+ continue;
-+ if (form->key_info[key].flags & (HA_FULLTEXT | HA_SPATIAL))
-+ continue; // ToDo: ft-keys in non-ft queries. SerG
-+
-+ uint key_parts= (uint) form->key_info[key].key_parts;
-+ for (uint part=0 ; part < key_parts ; part++)
-+ {
-+ if (field->eq(form->key_info[key].key_part[part].field))
-+ {
-+ keyuse.table= field->table;
-+ keyuse.val = key_field->val;
-+ keyuse.key = key;
-+ keyuse.keypart=part;
-+ keyuse.keypart_map= (key_part_map) 1 << part;
-+ keyuse.used_tables=key_field->val->used_tables();
-+ keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
-+ keyuse.null_rejecting= key_field->null_rejecting;
-+ keyuse.cond_guard= key_field->cond_guard;
-+ if (insert_dynamic(keyuse_array,(uchar*) &keyuse))
-+ return TRUE;
-+ }
-+ }
-+ }
-+ }
-+ return FALSE;
-+}
-+
-+
-+#define FT_KEYPART (MAX_REF_PARTS+10)
-+
-+static bool
-+add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
-+ JOIN_TAB *stat,COND *cond,table_map usable_tables)
-+{
-+ Item_func_match *cond_func=NULL;
-+
-+ if (!cond)
-+ return FALSE;
-+
-+ if (cond->type() == Item::FUNC_ITEM)
-+ {
-+ Item_func *func=(Item_func *)cond;
-+ Item_func::Functype functype= func->functype();
-+ if (functype == Item_func::FT_FUNC)
-+ cond_func=(Item_func_match *)cond;
-+ else if (func->arg_count == 2)
-+ {
-+ Item *arg0= func->arguments()[0],
-+ *arg1= func->arguments()[1];
-+ if (arg1->const_item() && arg1->cols() == 1 &&
-+ ((functype == Item_func::GE_FUNC && arg1->val_real() > 0) ||
-+ (functype == Item_func::GT_FUNC && arg1->val_real() >= 0)) &&
-+ arg0->type() == Item::FUNC_ITEM &&
-+ ((Item_func *) arg0)->functype() == Item_func::FT_FUNC)
-+ cond_func= (Item_func_match *) arg0;
-+ else if (arg0->const_item() && arg0->cols() == 1 &&
-+ ((functype == Item_func::LE_FUNC && arg0->val_real() > 0) ||
-+ (functype == Item_func::LT_FUNC && arg0->val_real() >= 0)) &&
-+ arg1->type() == Item::FUNC_ITEM &&
-+ ((Item_func *) arg1)->functype() == Item_func::FT_FUNC)
-+ cond_func= (Item_func_match *) arg1;
-+ }
-+ }
-+ else if (cond->type() == Item::COND_ITEM)
-+ {
-+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
-+
-+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ {
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ if (add_ft_keys(keyuse_array,stat,item,usable_tables))
-+ return TRUE;
-+ }
-+ }
-+ }
-+
-+ if (!cond_func || cond_func->key == NO_SUCH_KEY ||
-+ !(usable_tables & cond_func->table->map))
-+ return FALSE;
-+
-+ KEYUSE keyuse;
-+ keyuse.table= cond_func->table;
-+ keyuse.val = cond_func;
-+ keyuse.key = cond_func->key;
-+ keyuse.keypart= FT_KEYPART;
-+ keyuse.used_tables=cond_func->key_item()->used_tables();
-+ keyuse.optimize= 0;
-+ keyuse.keypart_map= 0;
-+ return insert_dynamic(keyuse_array,(uchar*) &keyuse);
-+}
-+
-+
-+static int
-+sort_keyuse(KEYUSE *a,KEYUSE *b)
-+{
-+ int res;
-+ if (a->table->tablenr != b->table->tablenr)
-+ return (int) (a->table->tablenr - b->table->tablenr);
-+ if (a->key != b->key)
-+ return (int) (a->key - b->key);
-+ if (a->keypart != b->keypart)
-+ return (int) (a->keypart - b->keypart);
-+ // Place const values before other ones
-+ if ((res= test((a->used_tables & ~OUTER_REF_TABLE_BIT)) -
-+ test((b->used_tables & ~OUTER_REF_TABLE_BIT))))
-+ return res;
-+ /* Place rows that are not 'OPTIMIZE_REF_OR_NULL' first */
-+ return (int) ((a->optimize & KEY_OPTIMIZE_REF_OR_NULL) -
-+ (b->optimize & KEY_OPTIMIZE_REF_OR_NULL));
-+}
-+
-+
-+/*
-+ Add to KEY_FIELD array all 'ref' access candidates within nested join.
-+
-+ This function populates KEY_FIELD array with entries generated from the
-+ ON condition of the given nested join, and does the same for nested joins
-+ contained within this nested join.
-+
-+ @param[in] nested_join_table Nested join pseudo-table to process
-+ @param[in,out] end End of the key field array
-+ @param[in,out] and_level And-level
-+ @param[in,out] sargables Array of found sargable candidates
-+
-+
-+ @note
-+ We can add accesses to the tables that are direct children of this nested
-+ join (1), and are not inner tables w.r.t their neighbours (2).
-+
-+ Example for #1 (outer brackets pair denotes nested join this function is
-+ invoked for):
-+ @code
-+ ... LEFT JOIN (t1 LEFT JOIN (t2 ... ) ) ON cond
-+ @endcode
-+ Example for #2:
-+ @code
-+ ... LEFT JOIN (t1 LEFT JOIN t2 ) ON cond
-+ @endcode
-+ In examples 1-2 for condition cond, we can add 'ref' access candidates to
-+ t1 only.
-+ Example #3:
-+ @code
-+ ... LEFT JOIN (t1, t2 LEFT JOIN t3 ON inner_cond) ON cond
-+ @endcode
-+ Here we can add 'ref' access candidates for t1 and t2, but not for t3.
-+*/
-+
-+static void add_key_fields_for_nj(JOIN *join, TABLE_LIST *nested_join_table,
-+ KEY_FIELD **end, uint *and_level,
-+ SARGABLE_PARAM **sargables)
-+{
-+ List_iterator<TABLE_LIST> li(nested_join_table->nested_join->join_list);
-+ table_map tables= 0;
-+ TABLE_LIST *table;
-+ DBUG_ASSERT(nested_join_table->nested_join);
-+
-+ while ((table= li++))
-+ {
-+ if (table->nested_join)
-+ add_key_fields_for_nj(join, table, end, and_level, sargables);
-+ else
-+ if (!table->on_expr)
-+ tables |= table->table->map;
-+ }
-+ add_key_fields(join, end, and_level, nested_join_table->on_expr, tables,
-+ sargables);
-+}
-+
-+
-+/**
-+ Update keyuse array with all possible keys we can use to fetch rows.
-+
-+ @param thd
-+ @param[out] keyuse Put here ordered array of KEYUSE structures
-+ @param join_tab Array in tablenr_order
-+ @param tables Number of tables in join
-+ @param cond WHERE condition (note that the function analyzes
-+ join_tab[i]->on_expr too)
-+ @param normal_tables Tables not inner w.r.t some outer join (ones
-+ for which we can make ref access based the WHERE
-+ clause)
-+ @param select_lex current SELECT
-+ @param[out] sargables Array of found sargable candidates
-+
-+ @retval
-+ 0 OK
-+ @retval
-+ 1 Out of memory.
-+*/
-+
-+static bool
-+update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
-+ uint tables, COND *cond, COND_EQUAL *cond_equal,
-+ table_map normal_tables, SELECT_LEX *select_lex,
-+ SARGABLE_PARAM **sargables)
-+{
-+ uint and_level,i,found_eq_constant;
-+ KEY_FIELD *key_fields, *end, *field;
-+ uint sz;
-+ uint m= max(select_lex->max_equal_elems,1);
-+
-+ /*
-+ We use the same piece of memory to store both KEY_FIELD
-+ and SARGABLE_PARAM structure.
-+ KEY_FIELD values are placed at the beginning this memory
-+ while SARGABLE_PARAM values are put at the end.
-+ All predicates that are used to fill arrays of KEY_FIELD
-+ and SARGABLE_PARAM structures have at most 2 arguments
-+ except BETWEEN predicates that have 3 arguments and
-+ IN predicates.
-+ This any predicate if it's not BETWEEN/IN can be used
-+ directly to fill at most 2 array elements, either of KEY_FIELD
-+ or SARGABLE_PARAM type. For a BETWEEN predicate 3 elements
-+ can be filled as this predicate is considered as
-+ saragable with respect to each of its argument.
-+ An IN predicate can require at most 1 element as currently
-+ it is considered as sargable only for its first argument.
-+ Multiple equality can add elements that are filled after
-+ substitution of field arguments by equal fields. There
-+ can be not more than select_lex->max_equal_elems such
-+ substitutions.
-+ */
-+ sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
-+ (((thd->lex->current_select->cond_count+1)*2 +
-+ thd->lex->current_select->between_count)*m+1);
-+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
-+ return TRUE; /* purecov: inspected */
-+ and_level= 0;
-+ field= end= key_fields;
-+ *sargables= (SARGABLE_PARAM *) key_fields +
-+ (sz - sizeof((*sargables)[0].field))/sizeof(SARGABLE_PARAM);
-+ /* set a barrier for the array of SARGABLE_PARAM */
-+ (*sargables)[0].field= 0;
-+
-+ if (my_init_dynamic_array(keyuse,sizeof(KEYUSE),20,64))
-+ return TRUE;
-+ if (cond)
-+ {
-+ add_key_fields(join_tab->join, &end, &and_level, cond, normal_tables,
-+ sargables);
-+ for (; field != end ; field++)
-+ {
-+ if (add_key_part(keyuse,field))
-+ return TRUE;
-+ /* Mark that we can optimize LEFT JOIN */
-+ if (field->val->type() == Item::NULL_ITEM &&
-+ !field->field->real_maybe_null())
-+ field->field->table->reginfo.not_exists_optimize=1;
-+ }
-+ }
-+ for (i=0 ; i < tables ; i++)
-+ {
-+ /*
-+ Block the creation of keys for inner tables of outer joins.
-+ Here only the outer joins that can not be converted to
-+ inner joins are left and all nests that can be eliminated
-+ are flattened.
-+ In the future when we introduce conditional accesses
-+ for inner tables in outer joins these keys will be taken
-+ into account as well.
-+ */
-+ if (*join_tab[i].on_expr_ref)
-+ add_key_fields(join_tab->join, &end, &and_level,
-+ *join_tab[i].on_expr_ref,
-+ join_tab[i].table->map, sargables);
-+ }
-+
-+ /* Process ON conditions for the nested joins */
-+ {
-+ List_iterator<TABLE_LIST> li(*join_tab->join->join_list);
-+ TABLE_LIST *table;
-+ while ((table= li++))
-+ {
-+ if (table->nested_join)
-+ add_key_fields_for_nj(join_tab->join, table, &end, &and_level,
-+ sargables);
-+ }
-+ }
-+
-+ /* fill keyuse with found key parts */
-+ for ( ; field != end ; field++)
-+ {
-+ if (add_key_part(keyuse,field))
-+ return TRUE;
-+ }
-+
-+ if (select_lex->ftfunc_list->elements)
-+ {
-+ if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
-+ return TRUE;
-+ }
-+
-+ /*
-+ Sort the array of possible keys and remove the following key parts:
-+ - ref if there is a keypart which is a ref and a const.
-+ (e.g. if there is a key(a,b) and the clause is a=3 and b=7 and b=t2.d,
-+ then we skip the key part corresponding to b=t2.d)
-+ - keyparts without previous keyparts
-+ (e.g. if there is a key(a,b,c) but only b < 5 (or a=2 and c < 3) is
-+ used in the query, we drop the partial key parts from consideration).
-+ Special treatment for ft-keys.
-+ */
-+ if (keyuse->elements)
-+ {
-+ KEYUSE key_end,*prev,*save_pos,*use;
-+
-+ my_qsort(keyuse->buffer,keyuse->elements,sizeof(KEYUSE),
-+ (qsort_cmp) sort_keyuse);
-+
-+ bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */
-+ if (insert_dynamic(keyuse,(uchar*) &key_end))
-+ return TRUE;
-+
-+ use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
-+ prev= &key_end;
-+ found_eq_constant=0;
-+ for (i=0 ; i < keyuse->elements-1 ; i++,use++)
-+ {
-+ if (!use->used_tables && use->optimize != KEY_OPTIMIZE_REF_OR_NULL)
-+ use->table->const_key_parts[use->key]|= use->keypart_map;
-+ if (use->keypart != FT_KEYPART)
-+ {
-+ if (use->key == prev->key && use->table == prev->table)
-+ {
-+ if (prev->keypart+1 < use->keypart ||
-+ (prev->keypart == use->keypart && found_eq_constant))
-+ continue; /* remove */
-+ }
-+ else if (use->keypart != 0) // First found must be 0
-+ continue;
-+ }
-+
-+#if defined(__GNUC__) && !MY_GNUC_PREREQ(4,4)
-+ /*
-+ Old gcc used a memcpy(), which is undefined if save_pos==use:
-+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19410
-+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39480
-+ */
-+ if (save_pos != use)
-+#endif
-+ *save_pos= *use;
-+ prev=use;
-+ found_eq_constant= !use->used_tables;
-+ /* Save ptr to first use */
-+ if (!use->table->reginfo.join_tab->keyuse)
-+ use->table->reginfo.join_tab->keyuse=save_pos;
-+ use->table->reginfo.join_tab->checked_keys.set_bit(use->key);
-+ save_pos++;
-+ }
-+ i=(uint) (save_pos-(KEYUSE*) keyuse->buffer);
-+ VOID(set_dynamic(keyuse,(uchar*) &key_end,i));
-+ keyuse->elements=i;
-+ }
-+ return FALSE;
-+}
-+
-+/**
-+ Update some values in keyuse for faster choose_plan() loop.
-+*/
-+
-+static void optimize_keyuse(JOIN *join, DYNAMIC_ARRAY *keyuse_array)
-+{
-+ KEYUSE *end,*keyuse= dynamic_element(keyuse_array, 0, KEYUSE*);
-+
-+ for (end= keyuse+ keyuse_array->elements ; keyuse < end ; keyuse++)
-+ {
-+ table_map map;
-+ /*
-+ If we find a ref, assume this table matches a proportional
-+ part of this table.
-+ For example 100 records matching a table with 5000 records
-+ gives 5000/100 = 50 records per key
-+ Constant tables are ignored.
-+ To avoid bad matches, we don't make ref_table_rows less than 100.
-+ */
-+ keyuse->ref_table_rows= ~(ha_rows) 0; // If no ref
-+ if (keyuse->used_tables &
-+ (map= (keyuse->used_tables & ~join->const_table_map &
-+ ~OUTER_REF_TABLE_BIT)))
-+ {
-+ uint tablenr;
-+ for (tablenr=0 ; ! (map & 1) ; map>>=1, tablenr++) ;
-+ if (map == 1) // Only one table
-+ {
-+ TABLE *tmp_table=join->all_tables[tablenr];
-+ keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
-+ }
-+ }
-+ /*
-+ Outer reference (external field) is constant for single executing
-+ of subquery
-+ */
-+ if (keyuse->used_tables == OUTER_REF_TABLE_BIT)
-+ keyuse->ref_table_rows= 1;
-+ }
-+}
-+
-+
-+/**
-+ Discover the indexes that can be used for GROUP BY or DISTINCT queries.
-+
-+ If the query has a GROUP BY clause, find all indexes that contain all
-+ GROUP BY fields, and add those indexes to join->const_keys.
-+
-+ If the query has a DISTINCT clause, find all indexes that contain all
-+ SELECT fields, and add those indexes to join->const_keys.
-+ This allows later on such queries to be processed by a
-+ QUICK_GROUP_MIN_MAX_SELECT.
-+
-+ @param join
-+ @param join_tab
-+
-+ @return
-+ None
-+*/
-+
-+static void
-+add_group_and_distinct_keys(JOIN *join, JOIN_TAB *join_tab)
-+{
-+ List<Item_field> indexed_fields;
-+ List_iterator<Item_field> indexed_fields_it(indexed_fields);
-+ ORDER *cur_group;
-+ Item_field *cur_item;
-+ key_map possible_keys(0);
-+
-+ if (join->group_list)
-+ { /* Collect all query fields referenced in the GROUP clause. */
-+ for (cur_group= join->group_list; cur_group; cur_group= cur_group->next)
-+ (*cur_group->item)->walk(&Item::collect_item_field_processor, 0,
-+ (uchar*) &indexed_fields);
-+ }
-+ else if (join->select_distinct)
-+ { /* Collect all query fields referenced in the SELECT clause. */
-+ List<Item> &select_items= join->fields_list;
-+ List_iterator<Item> select_items_it(select_items);
-+ Item *item;
-+ while ((item= select_items_it++))
-+ item->walk(&Item::collect_item_field_processor, 0,
-+ (uchar*) &indexed_fields);
-+ }
-+ else
-+ return;
-+
-+ if (indexed_fields.elements == 0)
-+ return;
-+
-+ /* Intersect the keys of all group fields. */
-+ cur_item= indexed_fields_it++;
-+ possible_keys.merge(cur_item->field->part_of_key);
-+ while ((cur_item= indexed_fields_it++))
-+ {
-+ possible_keys.intersect(cur_item->field->part_of_key);
-+ }
-+
-+ if (!possible_keys.is_clear_all())
-+ join_tab->const_keys.merge(possible_keys);
-+}
-+
-+
-+/*****************************************************************************
-+ Go through all combinations of not marked tables and find the one
-+ which uses least records
-+*****************************************************************************/
-+
-+/** Save const tables first as used tables. */
-+
-+static void
-+set_position(JOIN *join,uint idx,JOIN_TAB *table,KEYUSE *key)
-+{
-+ join->positions[idx].table= table;
-+ join->positions[idx].key=key;
-+ join->positions[idx].records_read=1.0; /* This is a const table */
-+ join->positions[idx].ref_depend_map= 0;
-+
-+ /* Move the const table as down as possible in best_ref */
-+ JOIN_TAB **pos=join->best_ref+idx+1;
-+ JOIN_TAB *next=join->best_ref[idx];
-+ for (;next != table ; pos++)
-+ {
-+ JOIN_TAB *tmp=pos[0];
-+ pos[0]=next;
-+ next=tmp;
-+ }
-+ join->best_ref[idx]=table;
-+}
-+
-+
-+/**
-+ Find the best access path for an extension of a partial execution
-+ plan and add this path to the plan.
-+
-+ The function finds the best access path to table 's' from the passed
-+ partial plan where an access path is the general term for any means to
-+ access the data in 's'. An access path may use either an index or a scan,
-+ whichever is cheaper. The input partial plan is passed via the array
-+ 'join->positions' of length 'idx'. The chosen access method for 's' and its
-+ cost are stored in 'join->positions[idx]'.
-+
-+ @param join pointer to the structure providing all context info
-+ for the query
-+ @param s the table to be joined by the function
-+ @param thd thread for the connection that submitted the query
-+ @param remaining_tables set of tables not included into the partial plan yet
-+ @param idx the length of the partial plan
-+ @param record_count estimate for the number of records returned by the
-+ partial plan
-+ @param read_time the cost of the partial plan
-+
-+ @return
-+ None
-+*/
-+
-+static void
-+best_access_path(JOIN *join,
-+ JOIN_TAB *s,
-+ THD *thd,
-+ table_map remaining_tables,
-+ uint idx,
-+ double record_count,
-+ double read_time)
-+{
-+ KEYUSE *best_key= 0;
-+ uint best_max_key_part= 0;
-+ my_bool found_constraint= 0;
-+ double best= DBL_MAX;
-+ double best_time= DBL_MAX;
-+ double records= DBL_MAX;
-+ table_map best_ref_depends_map= 0;
-+ double tmp;
-+ ha_rows rec;
-+ DBUG_ENTER("best_access_path");
-+
-+ if (s->keyuse)
-+ { /* Use key if possible */
-+ TABLE *table= s->table;
-+ KEYUSE *keyuse,*start_key=0;
-+ double best_records= DBL_MAX;
-+ uint max_key_part=0;
-+
-+ /* Test how we can use keys */
-+ rec= s->records/MATCHING_ROWS_IN_OTHER_TABLE; // Assumed records/key
-+ for (keyuse=s->keyuse ; keyuse->table == table ;)
-+ {
-+ key_part_map found_part= 0;
-+ table_map found_ref= 0;
-+ uint key= keyuse->key;
-+ KEY *keyinfo= table->key_info+key;
-+ bool ft_key= (keyuse->keypart == FT_KEYPART);
-+ /* Bitmap of keyparts where the ref access is over 'keypart=const': */
-+ key_part_map const_part= 0;
-+ /* The or-null keypart in ref-or-null access: */
-+ key_part_map ref_or_null_part= 0;
-+
-+ /* Calculate how many key segments of the current key we can use */
-+ start_key= keyuse;
-+
-+ do /* For each keypart */
-+ {
-+ uint keypart= keyuse->keypart;
-+ table_map best_part_found_ref= 0;
-+ double best_prev_record_reads= DBL_MAX;
-+
-+ do /* For each way to access the keypart */
-+ {
-+
-+ /*
-+ if 1. expression doesn't refer to forward tables
-+ 2. we won't get two ref-or-null's
-+ */
-+ if (!(remaining_tables & keyuse->used_tables) &&
-+ !(ref_or_null_part && (keyuse->optimize &
-+ KEY_OPTIMIZE_REF_OR_NULL)))
-+ {
-+ found_part|= keyuse->keypart_map;
-+ if (!(keyuse->used_tables & ~join->const_table_map))
-+ const_part|= keyuse->keypart_map;
-+
-+ double tmp2= prev_record_reads(join, idx, (found_ref |
-+ keyuse->used_tables));
-+ if (tmp2 < best_prev_record_reads)
-+ {
-+ best_part_found_ref= keyuse->used_tables & ~join->const_table_map;
-+ best_prev_record_reads= tmp2;
-+ }
-+ if (rec > keyuse->ref_table_rows)
-+ rec= keyuse->ref_table_rows;
-+ /*
-+ If there is one 'key_column IS NULL' expression, we can
-+ use this ref_or_null optimisation of this field
-+ */
-+ if (keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL)
-+ ref_or_null_part |= keyuse->keypart_map;
-+ }
-+ keyuse++;
-+ } while (keyuse->table == table && keyuse->key == key &&
-+ keyuse->keypart == keypart);
-+ found_ref|= best_part_found_ref;
-+ } while (keyuse->table == table && keyuse->key == key);
-+
-+ /*
-+ Assume that that each key matches a proportional part of table.
-+ */
-+ if (!found_part && !ft_key)
-+ continue; // Nothing usable found
-+
-+ if (rec < MATCHING_ROWS_IN_OTHER_TABLE)
-+ rec= MATCHING_ROWS_IN_OTHER_TABLE; // Fix for small tables
-+
-+ /*
-+ ft-keys require special treatment
-+ */
-+ if (ft_key)
-+ {
-+ /*
-+ Really, there should be records=0.0 (yes!)
-+ but 1.0 would be probably safer
-+ */
-+ tmp= prev_record_reads(join, idx, found_ref);
-+ records= 1.0;
-+ }
-+ else
-+ {
-+ found_constraint= 1;
-+ /*
-+ Check if we found full key
-+ */
-+ if (found_part == PREV_BITS(uint,keyinfo->key_parts) &&
-+ !ref_or_null_part)
-+ { /* use eq key */
-+ max_key_part= (uint) ~0;
-+ if ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME)
-+ {
-+ tmp = prev_record_reads(join, idx, found_ref);
-+ records=1.0;
-+ }
-+ else
-+ {
-+ if (!found_ref)
-+ { /* We found a const key */
-+ /*
-+ ReuseRangeEstimateForRef-1:
-+ We get here if we've found a ref(const) (c_i are constants):
-+ "(keypart1=c1) AND ... AND (keypartN=cN)" [ref_const_cond]
-+
-+ If range optimizer was able to construct a "range"
-+ access on this index, then its condition "quick_cond" was
-+ eqivalent to ref_const_cond (*), and we can re-use E(#rows)
-+ from the range optimizer.
-+
-+ Proof of (*): By properties of range and ref optimizers
-+ quick_cond will be equal or tighther than ref_const_cond.
-+ ref_const_cond already covers "smallest" possible interval -
-+ a singlepoint interval over all keyparts. Therefore,
-+ quick_cond is equivalent to ref_const_cond (if it was an
-+ empty interval we wouldn't have got here).
-+ */
-+ if (table->quick_keys.is_set(key))
-+ records= (double) table->quick_rows[key];
-+ else
-+ {
-+ /* quick_range couldn't use key! */
-+ records= (double) s->records/rec;
-+ }
-+ }
-+ else
-+ {
-+ if (!(records=keyinfo->rec_per_key[keyinfo->key_parts-1]))
-+ { /* Prefer longer keys */
-+ records=
-+ ((double) s->records / (double) rec *
-+ (1.0 +
-+ ((double) (table->s->max_key_length-keyinfo->key_length) /
-+ (double) table->s->max_key_length)));
-+ if (records < 2.0)
-+ records=2.0; /* Can't be as good as a unique */
-+ }
-+ /*
-+ ReuseRangeEstimateForRef-2: We get here if we could not reuse
-+ E(#rows) from range optimizer. Make another try:
-+
-+ If range optimizer produced E(#rows) for a prefix of the ref
-+ access we're considering, and that E(#rows) is lower then our
-+ current estimate, make an adjustment. The criteria of when we
-+ can make an adjustment is a special case of the criteria used
-+ in ReuseRangeEstimateForRef-3.
-+ */
-+ if (table->quick_keys.is_set(key) &&
-+ const_part & (1 << table->quick_key_parts[key]) &&
-+ table->quick_n_ranges[key] == 1 &&
-+ records > (double) table->quick_rows[key])
-+ {
-+ records= (double) table->quick_rows[key];
-+ }
-+ }
-+ /* Limit the number of matched rows */
-+ tmp= records;
-+ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
-+ if (table->covering_keys.is_set(key))
-+ {
-+ /* we can use only index tree */
-+ uint keys_per_block= table->file->stats.block_size/2/
-+ (keyinfo->key_length+table->file->ref_length)+1;
-+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
-+ }
-+ else
-+ tmp= record_count*min(tmp,s->worst_seeks);
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ Use as much key-parts as possible and a uniq key is better
-+ than a not unique key
-+ Set tmp to (previous record count) * (records / combination)
-+ */
-+ if ((found_part & 1) &&
-+ (!(table->file->index_flags(key, 0, 0) & HA_ONLY_WHOLE_INDEX) ||
-+ found_part == PREV_BITS(uint,keyinfo->key_parts)))
-+ {
-+ max_key_part= max_part_bit(found_part);
-+ /*
-+ ReuseRangeEstimateForRef-3:
-+ We're now considering a ref[or_null] access via
-+ (t.keypart1=e1 AND ... AND t.keypartK=eK) [ OR
-+ (same-as-above but with one cond replaced
-+ with "t.keypart_i IS NULL")] (**)
-+
-+ Try re-using E(#rows) from "range" optimizer:
-+ We can do so if "range" optimizer used the same intervals as
-+ in (**). The intervals used by range optimizer may be not
-+ available at this point (as "range" access might have choosen to
-+ create quick select over another index), so we can't compare
-+ them to (**). We'll make indirect judgements instead.
-+ The sufficient conditions for re-use are:
-+ (C1) All e_i in (**) are constants, i.e. found_ref==FALSE. (if
-+ this is not satisfied we have no way to know which ranges
-+ will be actually scanned by 'ref' until we execute the
-+ join)
-+ (C2) max #key parts in 'range' access == K == max_key_part (this
-+ is apparently a necessary requirement)
-+
-+ We also have a property that "range optimizer produces equal or
-+ tighter set of scan intervals than ref(const) optimizer". Each
-+ of the intervals in (**) are "tightest possible" intervals when
-+ one limits itself to using keyparts 1..K (which we do in #2).
-+ From here it follows that range access used either one, or
-+ both of the (I1) and (I2) intervals:
-+
-+ (t.keypart1=c1 AND ... AND t.keypartK=eK) (I1)
-+ (same-as-above but with one cond replaced
-+ with "t.keypart_i IS NULL") (I2)
-+
-+ The remaining part is to exclude the situation where range
-+ optimizer used one interval while we're considering
-+ ref-or-null and looking for estimate for two intervals. This
-+ is done by last limitation:
-+
-+ (C3) "range optimizer used (have ref_or_null?2:1) intervals"
-+ */
-+ if (table->quick_keys.is_set(key) && !found_ref && //(C1)
-+ table->quick_key_parts[key] == max_key_part && //(C2)
-+ table->quick_n_ranges[key] == 1+test(ref_or_null_part)) //(C3)
-+ {
-+ tmp= records= (double) table->quick_rows[key];
-+ }
-+ else
-+ {
-+ /* Check if we have statistic about the distribution */
-+ if ((records= keyinfo->rec_per_key[max_key_part-1]))
-+ {
-+ /*
-+ Fix for the case where the index statistics is too
-+ optimistic: If
-+ (1) We're considering ref(const) and there is quick select
-+ on the same index,
-+ (2) and that quick select uses more keyparts (i.e. it will
-+ scan equal/smaller interval then this ref(const))
-+ (3) and E(#rows) for quick select is higher then our
-+ estimate,
-+ Then
-+ We'll use E(#rows) from quick select.
-+
-+ Q: Why do we choose to use 'ref'? Won't quick select be
-+ cheaper in some cases ?
-+ TODO: figure this out and adjust the plan choice if needed.
-+ */
-+ if (!found_ref && table->quick_keys.is_set(key) && // (1)
-+ table->quick_key_parts[key] > max_key_part && // (2)
-+ records < (double)table->quick_rows[key]) // (3)
-+ records= (double)table->quick_rows[key];
-+
-+ tmp= records;
-+ }
-+ else
-+ {
-+ /*
-+ Assume that the first key part matches 1% of the file
-+ and that the whole key matches 10 (duplicates) or 1
-+ (unique) records.
-+ Assume also that more key matches proportionally more
-+ records
-+ This gives the formula:
-+ records = (x * (b-a) + a*c-b)/(c-1)
-+
-+ b = records matched by whole key
-+ a = records matched by first key part (1% of all records?)
-+ c = number of key parts in key
-+ x = used key parts (1 <= x <= c)
-+ */
-+ double rec_per_key;
-+ if (!(rec_per_key=(double)
-+ keyinfo->rec_per_key[keyinfo->key_parts-1]))
-+ rec_per_key=(double) s->records/rec+1;
-+
-+ if (!s->records)
-+ tmp = 0;
-+ else if (rec_per_key/(double) s->records >= 0.01)
-+ tmp = rec_per_key;
-+ else
-+ {
-+ double a=s->records*0.01;
-+ if (keyinfo->key_parts > 1)
-+ tmp= (max_key_part * (rec_per_key - a) +
-+ a*keyinfo->key_parts - rec_per_key)/
-+ (keyinfo->key_parts-1);
-+ else
-+ tmp= a;
-+ set_if_bigger(tmp,1.0);
-+ }
-+ records = (ulong) tmp;
-+ }
-+
-+ if (ref_or_null_part)
-+ {
-+ /* We need to do two key searches to find key */
-+ tmp *= 2.0;
-+ records *= 2.0;
-+ }
-+
-+ /*
-+ ReuseRangeEstimateForRef-4: We get here if we could not reuse
-+ E(#rows) from range optimizer. Make another try:
-+
-+ If range optimizer produced E(#rows) for a prefix of the ref
-+ access we're considering, and that E(#rows) is lower then our
-+ current estimate, make the adjustment.
-+
-+ The decision whether we can re-use the estimate from the range
-+ optimizer is the same as in ReuseRangeEstimateForRef-3,
-+ applied to first table->quick_key_parts[key] key parts.
-+ */
-+ if (table->quick_keys.is_set(key) &&
-+ table->quick_key_parts[key] <= max_key_part &&
-+ const_part & (1 << table->quick_key_parts[key]) &&
-+ table->quick_n_ranges[key] == 1 + test(ref_or_null_part &
-+ const_part) &&
-+ records > (double) table->quick_rows[key])
-+ {
-+ tmp= records= (double) table->quick_rows[key];
-+ }
-+ }
-+
-+ /* Limit the number of matched rows */
-+ set_if_smaller(tmp, (double) thd->variables.max_seeks_for_key);
-+ if (table->covering_keys.is_set(key))
-+ {
-+ /* we can use only index tree */
-+ uint keys_per_block= table->file->stats.block_size/2/
-+ (keyinfo->key_length+table->file->ref_length)+1;
-+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
-+ }
-+ else
-+ tmp= record_count*min(tmp,s->worst_seeks);
-+ }
-+ else
-+ tmp= best_time; // Do nothing
-+ }
-+ } /* not ft_key */
-+ if (tmp < best_time - records/(double) TIME_FOR_COMPARE)
-+ {
-+ best_time= tmp + records/(double) TIME_FOR_COMPARE;
-+ best= tmp;
-+ best_records= records;
-+ best_key= start_key;
-+ best_max_key_part= max_key_part;
-+ best_ref_depends_map= found_ref;
-+ }
-+ }
-+ records= best_records;
-+ }
-+
-+ /*
-+ Don't test table scan if it can't be better.
-+ Prefer key lookup if we would use the same key for scanning.
-+
-+ Don't do a table scan on InnoDB tables, if we can read the used
-+ parts of the row from any of the used index.
-+ This is because table scans uses index and we would not win
-+ anything by using a table scan.
-+
-+ A word for word translation of the below if-statement in psergey's
-+ understanding: we check if we should use table scan if:
-+ (1) The found 'ref' access produces more records than a table scan
-+ (or index scan, or quick select), or 'ref' is more expensive than
-+ any of them.
-+ (2) This doesn't hold: the best way to perform table scan is to to perform
-+ 'range' access using index IDX, and the best way to perform 'ref'
-+ access is to use the same index IDX, with the same or more key parts.
-+ (note: it is not clear how this rule is/should be extended to
-+ index_merge quick selects)
-+ (3) See above note about InnoDB.
-+ (4) NOT ("FORCE INDEX(...)" is used for table and there is 'ref' access
-+ path, but there is no quick select)
-+ If the condition in the above brackets holds, then the only possible
-+ "table scan" access method is ALL/index (there is no quick select).
-+ Since we have a 'ref' access path, and FORCE INDEX instructs us to
-+ choose it over ALL/index, there is no need to consider a full table
-+ scan.
-+ */
-+ if ((records >= s->found_records || best > s->read_time) && // (1)
-+ !(s->quick && best_key && s->quick->index == best_key->key && // (2)
-+ best_max_key_part >= s->table->quick_key_parts[best_key->key]) &&// (2)
-+ !((s->table->file->ha_table_flags() & HA_TABLE_SCAN_ON_INDEX) && // (3)
-+ ! s->table->covering_keys.is_clear_all() && best_key && !s->quick) &&// (3)
-+ !(s->table->force_index && best_key && !s->quick)) // (4)
-+ { // Check full join
-+ ha_rows rnd_records= s->found_records;
-+ /*
-+ If there is a filtering condition on the table (i.e. ref analyzer found
-+ at least one "table.keyXpartY= exprZ", where exprZ refers only to tables
-+ preceding this table in the join order we're now considering), then
-+ assume that 25% of the rows will be filtered out by this condition.
-+
-+ This heuristic is supposed to force tables used in exprZ to be before
-+ this table in join order.
-+ */
-+ if (found_constraint)
-+ rnd_records-= rnd_records/4;
-+
-+ /*
-+ If applicable, get a more accurate estimate. Don't use the two
-+ heuristics at once.
-+ */
-+ if (s->table->quick_condition_rows != s->found_records)
-+ rnd_records= s->table->quick_condition_rows;
-+
-+ /*
-+ Range optimizer never proposes a RANGE if it isn't better
-+ than FULL: so if RANGE is present, it's always preferred to FULL.
-+ Here we estimate its cost.
-+ */
-+ if (s->quick)
-+ {
-+ /*
-+ For each record we:
-+ - read record range through 'quick'
-+ - skip rows which does not satisfy WHERE constraints
-+ TODO:
-+ We take into account possible use of join cache for ALL/index
-+ access (see first else-branch below), but we don't take it into
-+ account here for range/index_merge access. Find out why this is so.
-+ */
-+ tmp= record_count *
-+ (s->quick->read_time +
-+ (s->found_records - rnd_records)/(double) TIME_FOR_COMPARE);
-+ }
-+ else
-+ {
-+ /* Estimate cost of reading table. */
-+ tmp= s->table->file->scan_time();
-+ if (s->table->map & join->outer_join) // Can't use join cache
-+ {
-+ /*
-+ For each record we have to:
-+ - read the whole table record
-+ - skip rows which does not satisfy join condition
-+ */
-+ tmp= record_count *
-+ (tmp +
-+ (s->records - rnd_records)/(double) TIME_FOR_COMPARE);
-+ }
-+ else
-+ {
-+ /* We read the table as many times as join buffer becomes full. */
-+ tmp*= (1.0 + floor((double) cache_record_length(join,idx) *
-+ record_count /
-+ (double) thd->variables.join_buff_size));
-+ /*
-+ We don't make full cartesian product between rows in the scanned
-+ table and existing records because we skip all rows from the
-+ scanned table, which does not satisfy join condition when
-+ we read the table (see flush_cached_records for details). Here we
-+ take into account cost to read and skip these records.
-+ */
-+ tmp+= (s->records - rnd_records)/(double) TIME_FOR_COMPARE;
-+ }
-+ }
-+
-+ /*
-+ We estimate the cost of evaluating WHERE clause for found records
-+ as record_count * rnd_records / TIME_FOR_COMPARE. This cost plus
-+ tmp give us total cost of using TABLE SCAN
-+ */
-+ if (best == DBL_MAX ||
-+ (tmp + record_count/(double) TIME_FOR_COMPARE*rnd_records <
-+ best + record_count/(double) TIME_FOR_COMPARE*records))
-+ {
-+ /*
-+ If the table has a range (s->quick is set) make_join_select()
-+ will ensure that this will be used
-+ */
-+ best= tmp;
-+ records= rows2double(rnd_records);
-+ best_key= 0;
-+ /* range/index_merge/ALL/index access method are "independent", so: */
-+ best_ref_depends_map= 0;
-+ }
-+ }
-+
-+ /* Update the cost information for the current partial plan */
-+ join->positions[idx].records_read= records;
-+ join->positions[idx].read_time= best;
-+ join->positions[idx].key= best_key;
-+ join->positions[idx].table= s;
-+ join->positions[idx].ref_depend_map= best_ref_depends_map;
-+
-+ if (!best_key &&
-+ idx == join->const_tables &&
-+ s->table == join->sort_by_table &&
-+ join->unit->select_limit_cnt >= records)
-+ join->sort_by_table= (TABLE*) 1; // Must use temporary table
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Selects and invokes a search strategy for an optimal query plan.
-+
-+ The function checks user-configurable parameters that control the search
-+ strategy for an optimal plan, selects the search method and then invokes
-+ it. Each specific optimization procedure stores the final optimal plan in
-+ the array 'join->best_positions', and the cost of the plan in
-+ 'join->best_read'.
-+
-+ @param join pointer to the structure providing all context info for
-+ the query
-+ @param join_tables set of the tables in the query
-+
-+ @todo
-+ 'MAX_TABLES+2' denotes the old implementation of find_best before
-+ the greedy version. Will be removed when greedy_search is approved.
-+
-+ @retval
-+ FALSE ok
-+ @retval
-+ TRUE Fatal error
-+*/
-+
-+static bool
-+choose_plan(JOIN *join, table_map join_tables)
-+{
-+ uint search_depth= join->thd->variables.optimizer_search_depth;
-+ uint prune_level= join->thd->variables.optimizer_prune_level;
-+ bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
-+ DBUG_ENTER("choose_plan");
-+
-+ join->cur_embedding_map= 0;
-+ reset_nj_counters(join->join_list);
-+ /*
-+ if (SELECT_STRAIGHT_JOIN option is set)
-+ reorder tables so dependent tables come after tables they depend
-+ on, otherwise keep tables in the order they were specified in the query
-+ else
-+ Apply heuristic: pre-sort all access plans with respect to the number of
-+ records accessed.
-+ */
-+ my_qsort(join->best_ref + join->const_tables,
-+ join->tables - join->const_tables, sizeof(JOIN_TAB*),
-+ straight_join ? join_tab_cmp_straight : join_tab_cmp);
-+
-+ if (straight_join)
-+ {
-+ optimize_straight_join(join, join_tables);
-+ }
-+ else
-+ {
-+ if (search_depth == MAX_TABLES+2)
-+ { /*
-+ TODO: 'MAX_TABLES+2' denotes the old implementation of find_best before
-+ the greedy version. Will be removed when greedy_search is approved.
-+ */
-+ join->best_read= DBL_MAX;
-+ if (find_best(join, join_tables, join->const_tables, 1.0, 0.0))
-+ DBUG_RETURN(TRUE);
-+ }
-+ else
-+ {
-+ if (search_depth == 0)
-+ /* Automatically determine a reasonable value for 'search_depth' */
-+ search_depth= determine_search_depth(join);
-+ if (greedy_search(join, join_tables, search_depth, prune_level))
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+
-+ /*
-+ Store the cost of this query into a user variable
-+ Don't update last_query_cost for statements that are not "flat joins" :
-+ i.e. they have subqueries, unions or call stored procedures.
-+ TODO: calculate a correct cost for a query with subqueries and UNIONs.
-+ */
-+ if (join->thd->lex->is_single_level_stmt())
-+ join->thd->status_var.last_query_cost= join->best_read;
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Compare two JOIN_TAB objects based on the number of accessed records.
-+
-+ @param ptr1 pointer to first JOIN_TAB object
-+ @param ptr2 pointer to second JOIN_TAB object
-+
-+ NOTES
-+ The order relation implemented by join_tab_cmp() is not transitive,
-+ i.e. it is possible to choose such a, b and c that (a < b) && (b < c)
-+ but (c < a). This implies that result of a sort using the relation
-+ implemented by join_tab_cmp() depends on the order in which
-+ elements are compared, i.e. the result is implementation-specific.
-+ Example:
-+ a: dependent = 0x0 table->map = 0x1 found_records = 3 ptr = 0x907e6b0
-+ b: dependent = 0x0 table->map = 0x2 found_records = 3 ptr = 0x907e838
-+ c: dependent = 0x6 table->map = 0x10 found_records = 2 ptr = 0x907ecd0
-+
-+ @retval
-+ 1 if first is bigger
-+ @retval
-+ -1 if second is bigger
-+ @retval
-+ 0 if equal
-+*/
-+
-+static int
-+join_tab_cmp(const void* ptr1, const void* ptr2)
-+{
-+ JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
-+ JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
-+
-+ if (jt1->dependent & jt2->table->map)
-+ return 1;
-+ if (jt2->dependent & jt1->table->map)
-+ return -1;
-+ if (jt1->found_records > jt2->found_records)
-+ return 1;
-+ if (jt1->found_records < jt2->found_records)
-+ return -1;
-+ return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
-+}
-+
-+
-+/**
-+ Same as join_tab_cmp, but for use with SELECT_STRAIGHT_JOIN.
-+*/
-+
-+static int
-+join_tab_cmp_straight(const void* ptr1, const void* ptr2)
-+{
-+ JOIN_TAB *jt1= *(JOIN_TAB**) ptr1;
-+ JOIN_TAB *jt2= *(JOIN_TAB**) ptr2;
-+
-+ if (jt1->dependent & jt2->table->map)
-+ return 1;
-+ if (jt2->dependent & jt1->table->map)
-+ return -1;
-+ return jt1 > jt2 ? 1 : (jt1 < jt2 ? -1 : 0);
-+}
-+
-+/**
-+ Heuristic procedure to automatically guess a reasonable degree of
-+ exhaustiveness for the greedy search procedure.
-+
-+ The procedure estimates the optimization time and selects a search depth
-+ big enough to result in a near-optimal QEP, that doesn't take too long to
-+ find. If the number of tables in the query exceeds some constant, then
-+ search_depth is set to this constant.
-+
-+ @param join pointer to the structure providing all context info for
-+ the query
-+
-+ @note
-+ This is an extremely simplistic implementation that serves as a stub for a
-+ more advanced analysis of the join. Ideally the search depth should be
-+ determined by learning from previous query optimizations, because it will
-+ depend on the CPU power (and other factors).
-+
-+ @todo
-+ this value should be determined dynamically, based on statistics:
-+ uint max_tables_for_exhaustive_opt= 7;
-+
-+ @todo
-+ this value could be determined by some mapping of the form:
-+ depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
-+
-+ @return
-+ A positive integer that specifies the search depth (and thus the
-+ exhaustiveness) of the depth-first search algorithm used by
-+ 'greedy_search'.
-+*/
-+
-+static uint
-+determine_search_depth(JOIN *join)
-+{
-+ uint table_count= join->tables - join->const_tables;
-+ uint search_depth;
-+ /* TODO: this value should be determined dynamically, based on statistics: */
-+ uint max_tables_for_exhaustive_opt= 7;
-+
-+ if (table_count <= max_tables_for_exhaustive_opt)
-+ search_depth= table_count+1; // use exhaustive for small number of tables
-+ else
-+ /*
-+ TODO: this value could be determined by some mapping of the form:
-+ depth : table_count -> [max_tables_for_exhaustive_opt..MAX_EXHAUSTIVE]
-+ */
-+ search_depth= max_tables_for_exhaustive_opt; // use greedy search
-+
-+ return search_depth;
-+}
-+
-+
-+/**
-+ Select the best ways to access the tables in a query without reordering them.
-+
-+ Find the best access paths for each query table and compute their costs
-+ according to their order in the array 'join->best_ref' (thus without
-+ reordering the join tables). The function calls sequentially
-+ 'best_access_path' for each table in the query to select the best table
-+ access method. The final optimal plan is stored in the array
-+ 'join->best_positions', and the corresponding cost in 'join->best_read'.
-+
-+ @param join pointer to the structure providing all context info for
-+ the query
-+ @param join_tables set of the tables in the query
-+
-+ @note
-+ This function can be applied to:
-+ - queries with STRAIGHT_JOIN
-+ - internally to compute the cost of an arbitrary QEP
-+ @par
-+ Thus 'optimize_straight_join' can be used at any stage of the query
-+ optimization process to finalize a QEP as it is.
-+*/
-+
-+static void
-+optimize_straight_join(JOIN *join, table_map join_tables)
-+{
-+ JOIN_TAB *s;
-+ uint idx= join->const_tables;
-+ double record_count= 1.0;
-+ double read_time= 0.0;
-+
-+ for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
-+ {
-+ /* Find the best access method from 's' to the current partial plan */
-+ best_access_path(join, s, join->thd, join_tables, idx,
-+ record_count, read_time);
-+ /* compute the cost of the new plan extended with 's' */
-+ record_count*= join->positions[idx].records_read;
-+ read_time+= join->positions[idx].read_time;
-+ join_tables&= ~(s->table->map);
-+ ++idx;
-+ }
-+
-+ read_time+= record_count / (double) TIME_FOR_COMPARE;
-+ if (join->sort_by_table &&
-+ join->sort_by_table != join->positions[join->const_tables].table->table)
-+ read_time+= record_count; // We have to make a temp table
-+ memcpy((uchar*) join->best_positions, (uchar*) join->positions,
-+ sizeof(POSITION)*idx);
-+ join->best_read= read_time;
-+}
-+
-+
-+/**
-+ Find a good, possibly optimal, query execution plan (QEP) by a greedy search.
-+
-+ The search procedure uses a hybrid greedy/exhaustive search with controlled
-+ exhaustiveness. The search is performed in N = card(remaining_tables)
-+ steps. Each step evaluates how promising is each of the unoptimized tables,
-+ selects the most promising table, and extends the current partial QEP with
-+ that table. Currenly the most 'promising' table is the one with least
-+ expensive extension.\
-+
-+ There are two extreme cases:
-+ -# When (card(remaining_tables) < search_depth), the estimate finds the
-+ best complete continuation of the partial QEP. This continuation can be
-+ used directly as a result of the search.
-+ -# When (search_depth == 1) the 'best_extension_by_limited_search'
-+ consideres the extension of the current QEP with each of the remaining
-+ unoptimized tables.
-+
-+ All other cases are in-between these two extremes. Thus the parameter
-+ 'search_depth' controlls the exhaustiveness of the search. The higher the
-+ value, the longer the optimizaton time and possibly the better the
-+ resulting plan. The lower the value, the fewer alternative plans are
-+ estimated, but the more likely to get a bad QEP.
-+
-+ All intermediate and final results of the procedure are stored in 'join':
-+ - join->positions : modified for every partial QEP that is explored
-+ - join->best_positions: modified for the current best complete QEP
-+ - join->best_read : modified for the current best complete QEP
-+ - join->best_ref : might be partially reordered
-+
-+ The final optimal plan is stored in 'join->best_positions', and its
-+ corresponding cost in 'join->best_read'.
-+
-+ @note
-+ The following pseudocode describes the algorithm of 'greedy_search':
-+
-+ @code
-+ procedure greedy_search
-+ input: remaining_tables
-+ output: pplan;
-+ {
-+ pplan = <>;
-+ do {
-+ (t, a) = best_extension(pplan, remaining_tables);
-+ pplan = concat(pplan, (t, a));
-+ remaining_tables = remaining_tables - t;
-+ } while (remaining_tables != {})
-+ return pplan;
-+ }
-+
-+ @endcode
-+ where 'best_extension' is a placeholder for a procedure that selects the
-+ most "promising" of all tables in 'remaining_tables'.
-+ Currently this estimate is performed by calling
-+ 'best_extension_by_limited_search' to evaluate all extensions of the
-+ current QEP of size 'search_depth', thus the complexity of 'greedy_search'
-+ mainly depends on that of 'best_extension_by_limited_search'.
-+
-+ @par
-+ If 'best_extension()' == 'best_extension_by_limited_search()', then the
-+ worst-case complexity of this algorithm is <=
-+ O(N*N^search_depth/search_depth). When serch_depth >= N, then the
-+ complexity of greedy_search is O(N!).
-+
-+ @par
-+ In the future, 'greedy_search' might be extended to support other
-+ implementations of 'best_extension', e.g. some simpler quadratic procedure.
-+
-+ @param join pointer to the structure providing all context info
-+ for the query
-+ @param remaining_tables set of tables not included into the partial plan yet
-+ @param search_depth controlls the exhaustiveness of the search
-+ @param prune_level the pruning heuristics that should be applied during
-+ search
-+
-+ @retval
-+ FALSE ok
-+ @retval
-+ TRUE Fatal error
-+*/
-+
-+static bool
-+greedy_search(JOIN *join,
-+ table_map remaining_tables,
-+ uint search_depth,
-+ uint prune_level)
-+{
-+ double record_count= 1.0;
-+ double read_time= 0.0;
-+ uint idx= join->const_tables; // index into 'join->best_ref'
-+ uint best_idx;
-+ uint size_remain; // cardinality of remaining_tables
-+ POSITION best_pos;
-+ JOIN_TAB *best_table; // the next plan node to be added to the curr QEP
-+
-+ DBUG_ENTER("greedy_search");
-+
-+ /* number of tables that remain to be optimized */
-+ size_remain= my_count_bits(remaining_tables);
-+
-+ do {
-+ /* Find the extension of the current QEP with the lowest cost */
-+ join->best_read= DBL_MAX;
-+ if (best_extension_by_limited_search(join, remaining_tables, idx, record_count,
-+ read_time, search_depth, prune_level))
-+ DBUG_RETURN(TRUE);
-+ /*
-+ 'best_read < DBL_MAX' means that optimizer managed to find
-+ some plan and updated 'best_positions' array accordingly.
-+ */
-+ DBUG_ASSERT(join->best_read < DBL_MAX);
-+
-+ if (size_remain <= search_depth)
-+ {
-+ /*
-+ 'join->best_positions' contains a complete optimal extension of the
-+ current partial QEP.
-+ */
-+ DBUG_EXECUTE("opt", print_plan(join, join->tables,
-+ record_count, read_time, read_time,
-+ "optimal"););
-+ DBUG_RETURN(FALSE);
-+ }
-+
-+ /* select the first table in the optimal extension as most promising */
-+ best_pos= join->best_positions[idx];
-+ best_table= best_pos.table;
-+ /*
-+ Each subsequent loop of 'best_extension_by_limited_search' uses
-+ 'join->positions' for cost estimates, therefore we have to update its
-+ value.
-+ */
-+ join->positions[idx]= best_pos;
-+
-+ /*
-+ Update the interleaving state after extending the current partial plan
-+ with a new table.
-+ We are doing this here because best_extension_by_limited_search reverts
-+ the interleaving state to the one of the non-extended partial plan
-+ on exit.
-+ */
-+ IF_DBUG(bool is_interleave_error= )
-+ check_interleaving_with_nj (best_table);
-+ /* This has been already checked by best_extension_by_limited_search */
-+ DBUG_ASSERT(!is_interleave_error);
-+
-+ /* find the position of 'best_table' in 'join->best_ref' */
-+ best_idx= idx;
-+ JOIN_TAB *pos= join->best_ref[best_idx];
-+ while (pos && best_table != pos)
-+ pos= join->best_ref[++best_idx];
-+ DBUG_ASSERT((pos != NULL)); // should always find 'best_table'
-+ /* move 'best_table' at the first free position in the array of joins */
-+ swap_variables(JOIN_TAB*, join->best_ref[idx], join->best_ref[best_idx]);
-+
-+ /* compute the cost of the new plan extended with 'best_table' */
-+ record_count*= join->positions[idx].records_read;
-+ read_time+= join->positions[idx].read_time;
-+
-+ remaining_tables&= ~(best_table->table->map);
-+ --size_remain;
-+ ++idx;
-+
-+ DBUG_EXECUTE("opt", print_plan(join, idx,
-+ record_count, read_time, read_time,
-+ "extended"););
-+ } while (TRUE);
-+}
-+
-+
-+/**
-+ Find a good, possibly optimal, query execution plan (QEP) by a possibly
-+ exhaustive search.
-+
-+ The procedure searches for the optimal ordering of the query tables in set
-+ 'remaining_tables' of size N, and the corresponding optimal access paths to
-+ each table. The choice of a table order and an access path for each table
-+ constitutes a query execution plan (QEP) that fully specifies how to
-+ execute the query.
-+
-+ The maximal size of the found plan is controlled by the parameter
-+ 'search_depth'. When search_depth == N, the resulting plan is complete and
-+ can be used directly as a QEP. If search_depth < N, the found plan consists
-+ of only some of the query tables. Such "partial" optimal plans are useful
-+ only as input to query optimization procedures, and cannot be used directly
-+ to execute a query.
-+
-+ The algorithm begins with an empty partial plan stored in 'join->positions'
-+ and a set of N tables - 'remaining_tables'. Each step of the algorithm
-+ evaluates the cost of the partial plan extended by all access plans for
-+ each of the relations in 'remaining_tables', expands the current partial
-+ plan with the access plan that results in lowest cost of the expanded
-+ partial plan, and removes the corresponding relation from
-+ 'remaining_tables'. The algorithm continues until it either constructs a
-+ complete optimal plan, or constructs an optimal plartial plan with size =
-+ search_depth.
-+
-+ The final optimal plan is stored in 'join->best_positions'. The
-+ corresponding cost of the optimal plan is in 'join->best_read'.
-+
-+ @note
-+ The procedure uses a recursive depth-first search where the depth of the
-+ recursion (and thus the exhaustiveness of the search) is controlled by the
-+ parameter 'search_depth'.
-+
-+ @note
-+ The pseudocode below describes the algorithm of
-+ 'best_extension_by_limited_search'. The worst-case complexity of this
-+ algorithm is O(N*N^search_depth/search_depth). When serch_depth >= N, then
-+ the complexity of greedy_search is O(N!).
-+
-+ @code
-+ procedure best_extension_by_limited_search(
-+ pplan in, // in, partial plan of tables-joined-so-far
-+ pplan_cost, // in, cost of pplan
-+ remaining_tables, // in, set of tables not referenced in pplan
-+ best_plan_so_far, // in/out, best plan found so far
-+ best_plan_so_far_cost,// in/out, cost of best_plan_so_far
-+ search_depth) // in, maximum size of the plans being considered
-+ {
-+ for each table T from remaining_tables
-+ {
-+ // Calculate the cost of using table T as above
-+ cost = complex-series-of-calculations;
-+
-+ // Add the cost to the cost so far.
-+ pplan_cost+= cost;
-+
-+ if (pplan_cost >= best_plan_so_far_cost)
-+ // pplan_cost already too great, stop search
-+ continue;
-+
-+ pplan= expand pplan by best_access_method;
-+ remaining_tables= remaining_tables - table T;
-+ if (remaining_tables is not an empty set
-+ and
-+ search_depth > 1)
-+ {
-+ best_extension_by_limited_search(pplan, pplan_cost,
-+ remaining_tables,
-+ best_plan_so_far,
-+ best_plan_so_far_cost,
-+ search_depth - 1);
-+ }
-+ else
-+ {
-+ best_plan_so_far_cost= pplan_cost;
-+ best_plan_so_far= pplan;
-+ }
-+ }
-+ }
-+ @endcode
-+
-+ @note
-+ When 'best_extension_by_limited_search' is called for the first time,
-+ 'join->best_read' must be set to the largest possible value (e.g. DBL_MAX).
-+ The actual implementation provides a way to optionally use pruning
-+ heuristic (controlled by the parameter 'prune_level') to reduce the search
-+ space by skipping some partial plans.
-+
-+ @note
-+ The parameter 'search_depth' provides control over the recursion
-+ depth, and thus the size of the resulting optimal plan.
-+
-+ @param join pointer to the structure providing all context info
-+ for the query
-+ @param remaining_tables set of tables not included into the partial plan yet
-+ @param idx length of the partial QEP in 'join->positions';
-+ since a depth-first search is used, also corresponds
-+ to the current depth of the search tree;
-+ also an index in the array 'join->best_ref';
-+ @param record_count estimate for the number of records returned by the
-+ best partial plan
-+ @param read_time the cost of the best partial plan
-+ @param search_depth maximum depth of the recursion and thus size of the
-+ found optimal plan
-+ (0 < search_depth <= join->tables+1).
-+ @param prune_level pruning heuristics that should be applied during
-+ optimization
-+ (values: 0 = EXHAUSTIVE, 1 = PRUNE_BY_TIME_OR_ROWS)
-+
-+ @retval
-+ FALSE ok
-+ @retval
-+ TRUE Fatal error
-+*/
-+
-+static bool
-+best_extension_by_limited_search(JOIN *join,
-+ table_map remaining_tables,
-+ uint idx,
-+ double record_count,
-+ double read_time,
-+ uint search_depth,
-+ uint prune_level)
-+{
-+ DBUG_ENTER("best_extension_by_limited_search");
-+
-+ THD *thd= join->thd;
-+ if (thd->killed) // Abort
-+ DBUG_RETURN(TRUE);
-+
-+ DBUG_EXECUTE("opt", print_plan(join, idx, read_time, record_count, idx,
-+ "SOFAR:"););
-+
-+ /*
-+ 'join' is a partial plan with lower cost than the best plan so far,
-+ so continue expanding it further with the tables in 'remaining_tables'.
-+ */
-+ JOIN_TAB *s;
-+ double best_record_count= DBL_MAX;
-+ double best_read_time= DBL_MAX;
-+
-+ DBUG_EXECUTE("opt", print_plan(join, idx, record_count, read_time, read_time,
-+ "part_plan"););
-+
-+ for (JOIN_TAB **pos= join->best_ref + idx ; (s= *pos) ; pos++)
-+ {
-+ table_map real_table_bit= s->table->map;
-+ if ((remaining_tables & real_table_bit) &&
-+ !(remaining_tables & s->dependent) &&
-+ (!idx || !check_interleaving_with_nj(s)))
-+ {
-+ double current_record_count, current_read_time;
-+
-+ /* Find the best access method from 's' to the current partial plan */
-+ best_access_path(join, s, thd, remaining_tables, idx,
-+ record_count, read_time);
-+ /* Compute the cost of extending the plan with 's' */
-+ current_record_count= record_count * join->positions[idx].records_read;
-+ current_read_time= read_time + join->positions[idx].read_time;
-+
-+ /* Expand only partial plans with lower cost than the best QEP so far */
-+ if ((current_read_time +
-+ current_record_count / (double) TIME_FOR_COMPARE) >= join->best_read)
-+ {
-+ DBUG_EXECUTE("opt", print_plan(join, idx+1,
-+ current_record_count,
-+ read_time,
-+ (current_read_time +
-+ current_record_count /
-+ (double) TIME_FOR_COMPARE),
-+ "prune_by_cost"););
-+ restore_prev_nj_state(s);
-+ continue;
-+ }
-+
-+ /*
-+ Prune some less promising partial plans. This heuristic may miss
-+ the optimal QEPs, thus it results in a non-exhaustive search.
-+ */
-+ if (prune_level == 1)
-+ {
-+ if (best_record_count > current_record_count ||
-+ best_read_time > current_read_time ||
-+ (idx == join->const_tables && // 's' is the first table in the QEP
-+ s->table == join->sort_by_table))
-+ {
-+ if (best_record_count >= current_record_count &&
-+ best_read_time >= current_read_time &&
-+ /* TODO: What is the reasoning behind this condition? */
-+ (!(s->key_dependent & remaining_tables) ||
-+ join->positions[idx].records_read < 2.0))
-+ {
-+ best_record_count= current_record_count;
-+ best_read_time= current_read_time;
-+ }
-+ }
-+ else
-+ {
-+ DBUG_EXECUTE("opt", print_plan(join, idx+1,
-+ current_record_count,
-+ read_time,
-+ current_read_time,
-+ "pruned_by_heuristic"););
-+ restore_prev_nj_state(s);
-+ continue;
-+ }
-+ }
-+
-+ if ( (search_depth > 1) && (remaining_tables & ~real_table_bit) )
-+ { /* Recursively expand the current partial plan */
-+ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
-+ if (best_extension_by_limited_search(join,
-+ remaining_tables & ~real_table_bit,
-+ idx + 1,
-+ current_record_count,
-+ current_read_time,
-+ search_depth - 1,
-+ prune_level))
-+ DBUG_RETURN(TRUE);
-+ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
-+ }
-+ else
-+ { /*
-+ 'join' is either the best partial QEP with 'search_depth' relations,
-+ or the best complete QEP so far, whichever is smaller.
-+ */
-+ current_read_time+= current_record_count / (double) TIME_FOR_COMPARE;
-+ if (join->sort_by_table &&
-+ join->sort_by_table !=
-+ join->positions[join->const_tables].table->table)
-+ /* We have to make a temp table */
-+ current_read_time+= current_record_count;
-+ if ((search_depth == 1) || (current_read_time < join->best_read))
-+ {
-+ memcpy((uchar*) join->best_positions, (uchar*) join->positions,
-+ sizeof(POSITION) * (idx + 1));
-+ join->best_read= current_read_time - 0.001;
-+ }
-+ DBUG_EXECUTE("opt", print_plan(join, idx+1,
-+ current_record_count,
-+ read_time,
-+ current_read_time,
-+ "full_plan"););
-+ }
-+ restore_prev_nj_state(s);
-+ }
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ @todo
-+ - TODO: this function is here only temporarily until 'greedy_search' is
-+ tested and accepted.
-+
-+ RETURN VALUES
-+ FALSE ok
-+ TRUE Fatal error
-+*/
-+static bool
-+find_best(JOIN *join,table_map rest_tables,uint idx,double record_count,
-+ double read_time)
-+{
-+ DBUG_ENTER("find_best");
-+ THD *thd= join->thd;
-+ if (thd->killed)
-+ DBUG_RETURN(TRUE);
-+ if (!rest_tables)
-+ {
-+ DBUG_PRINT("best",("read_time: %g record_count: %g",read_time,
-+ record_count));
-+
-+ read_time+=record_count/(double) TIME_FOR_COMPARE;
-+ if (join->sort_by_table &&
-+ join->sort_by_table !=
-+ join->positions[join->const_tables].table->table)
-+ read_time+=record_count; // We have to make a temp table
-+ if (read_time < join->best_read)
-+ {
-+ memcpy((uchar*) join->best_positions,(uchar*) join->positions,
-+ sizeof(POSITION)*idx);
-+ join->best_read= read_time - 0.001;
-+ }
-+ DBUG_RETURN(FALSE);
-+ }
-+ if (read_time+record_count/(double) TIME_FOR_COMPARE >= join->best_read)
-+ DBUG_RETURN(FALSE); /* Found better before */
-+
-+ JOIN_TAB *s;
-+ double best_record_count=DBL_MAX,best_read_time=DBL_MAX;
-+ for (JOIN_TAB **pos=join->best_ref+idx ; (s=*pos) ; pos++)
-+ {
-+ table_map real_table_bit=s->table->map;
-+ if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
-+ (!idx|| !check_interleaving_with_nj(s)))
-+ {
-+ double records, best;
-+ best_access_path(join, s, thd, rest_tables, idx, record_count,
-+ read_time);
-+ records= join->positions[idx].records_read;
-+ best= join->positions[idx].read_time;
-+ /*
-+ Go to the next level only if there hasn't been a better key on
-+ this level! This will cut down the search for a lot simple cases!
-+ */
-+ double current_record_count=record_count*records;
-+ double current_read_time=read_time+best;
-+ if (best_record_count > current_record_count ||
-+ best_read_time > current_read_time ||
-+ (idx == join->const_tables && s->table == join->sort_by_table))
-+ {
-+ if (best_record_count >= current_record_count &&
-+ best_read_time >= current_read_time &&
-+ (!(s->key_dependent & rest_tables) || records < 2.0))
-+ {
-+ best_record_count=current_record_count;
-+ best_read_time=current_read_time;
-+ }
-+ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
-+ if (find_best(join,rest_tables & ~real_table_bit,idx+1,
-+ current_record_count,current_read_time))
-+ DBUG_RETURN(TRUE);
-+ swap_variables(JOIN_TAB*, join->best_ref[idx], *pos);
-+ }
-+ restore_prev_nj_state(s);
-+ if (join->select_options & SELECT_STRAIGHT_JOIN)
-+ break; // Don't test all combinations
-+ }
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Find how much space the prevous read not const tables takes in cache.
-+*/
-+
-+static void calc_used_field_length(THD *thd, JOIN_TAB *join_tab)
-+{
-+ uint null_fields,blobs,fields,rec_length;
-+ Field **f_ptr,*field;
-+ MY_BITMAP *read_set= join_tab->table->read_set;;
-+
-+ null_fields= blobs= fields= rec_length=0;
-+ for (f_ptr=join_tab->table->field ; (field= *f_ptr) ; f_ptr++)
-+ {
-+ if (bitmap_is_set(read_set, field->field_index))
-+ {
-+ uint flags=field->flags;
-+ fields++;
-+ rec_length+=field->pack_length();
-+ if (flags & BLOB_FLAG)
-+ blobs++;
-+ if (!(flags & NOT_NULL_FLAG))
-+ null_fields++;
-+ }
-+ }
-+ if (null_fields)
-+ rec_length+=(join_tab->table->s->null_fields+7)/8;
-+ if (join_tab->table->maybe_null)
-+ rec_length+=sizeof(my_bool);
-+ if (blobs)
-+ {
-+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
-+ (join_tab->table->s->reclength- rec_length));
-+ rec_length+=(uint) max(4,blob_length);
-+ }
-+ join_tab->used_fields=fields;
-+ join_tab->used_fieldlength=rec_length;
-+ join_tab->used_blobs=blobs;
-+}
-+
-+
-+static uint
-+cache_record_length(JOIN *join,uint idx)
-+{
-+ uint length=0;
-+ JOIN_TAB **pos,**end;
-+ THD *thd=join->thd;
-+
-+ for (pos=join->best_ref+join->const_tables,end=join->best_ref+idx ;
-+ pos != end ;
-+ pos++)
-+ {
-+ JOIN_TAB *join_tab= *pos;
-+ if (!join_tab->used_fieldlength) /* Not calced yet */
-+ calc_used_field_length(thd, join_tab);
-+ length+=join_tab->used_fieldlength;
-+ }
-+ return length;
-+}
-+
-+
-+/*
-+ Get the number of different row combinations for subset of partial join
-+
-+ SYNOPSIS
-+ prev_record_reads()
-+ join The join structure
-+ idx Number of tables in the partial join order (i.e. the
-+ partial join order is in join->positions[0..idx-1])
-+ found_ref Bitmap of tables for which we need to find # of distinct
-+ row combinations.
-+
-+ DESCRIPTION
-+ Given a partial join order (in join->positions[0..idx-1]) and a subset of
-+ tables within that join order (specified in found_ref), find out how many
-+ distinct row combinations of subset tables will be in the result of the
-+ partial join order.
-+
-+ This is used as follows: Suppose we have a table accessed with a ref-based
-+ method. The ref access depends on current rows of tables in found_ref.
-+ We want to count # of different ref accesses. We assume two ref accesses
-+ will be different if at least one of access parameters is different.
-+ Example: consider a query
-+
-+ SELECT * FROM t1, t2, t3 WHERE t1.key=c1 AND t2.key=c2 AND t3.key=t1.field
-+
-+ and a join order:
-+ t1, ref access on t1.key=c1
-+ t2, ref access on t2.key=c2
-+ t3, ref access on t3.key=t1.field
-+
-+ For t1: n_ref_scans = 1, n_distinct_ref_scans = 1
-+ For t2: n_ref_scans = records_read(t1), n_distinct_ref_scans=1
-+ For t3: n_ref_scans = records_read(t1)*records_read(t2)
-+ n_distinct_ref_scans = #records_read(t1)
-+
-+ The reason for having this function (at least the latest version of it)
-+ is that we need to account for buffering in join execution.
-+
-+ An edge-case example: if we have a non-first table in join accessed via
-+ ref(const) or ref(param) where there is a small number of different
-+ values of param, then the access will likely hit the disk cache and will
-+ not require any disk seeks.
-+
-+ The proper solution would be to assume an LRU disk cache of some size,
-+ calculate probability of cache hits, etc. For now we just count
-+ identical ref accesses as one.
-+
-+ RETURN
-+ Expected number of row combinations
-+*/
-+
-+static double
-+prev_record_reads(JOIN *join, uint idx, table_map found_ref)
-+{
-+ double found=1.0;
-+ POSITION *pos_end= join->positions - 1;
-+ for (POSITION *pos= join->positions + idx - 1; pos != pos_end; pos--)
-+ {
-+ if (pos->table->table->map & found_ref)
-+ {
-+ found_ref|= pos->ref_depend_map;
-+ /*
-+ For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
-+ with no matching row we will get position[t2].records_read==0.
-+ Actually the size of output is one null-complemented row, therefore
-+ we will use value of 1 whenever we get records_read==0.
-+
-+ Note
-+ - the above case can't occur if inner part of outer join has more
-+ than one table: table with no matches will not be marked as const.
-+
-+ - Ideally we should add 1 to records_read for every possible null-
-+ complemented row. We're not doing it because: 1. it will require
-+ non-trivial code and add overhead. 2. The value of records_read
-+ is an inprecise estimate and adding 1 (or, in the worst case,
-+ #max_nested_outer_joins=64-1) will not make it any more precise.
-+ */
-+ if (pos->records_read)
-+ found*= pos->records_read;
-+ }
-+ }
-+ return found;
-+}
-+
-+
-+/**
-+ Set up join struct according to best position.
-+*/
-+
-+static bool
-+get_best_combination(JOIN *join)
-+{
-+ uint i,tablenr;
-+ table_map used_tables;
-+ JOIN_TAB *join_tab,*j;
-+ KEYUSE *keyuse;
-+ uint table_count;
-+ THD *thd=join->thd;
-+ DBUG_ENTER("get_best_combination");
-+
-+ table_count=join->tables;
-+ if (!(join->join_tab=join_tab=
-+ (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)*table_count)))
-+ DBUG_RETURN(TRUE);
-+
-+ join->full_join=0;
-+
-+ used_tables= OUTER_REF_TABLE_BIT; // Outer row is already read
-+ for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
-+ {
-+ TABLE *form;
-+ *j= *join->best_positions[tablenr].table;
-+ form=join->table[tablenr]=j->table;
-+ used_tables|= form->map;
-+ form->reginfo.join_tab=j;
-+ if (!*j->on_expr_ref)
-+ form->reginfo.not_exists_optimize=0; // Only with LEFT JOIN
-+ DBUG_PRINT("info",("type: %d", j->type));
-+ if (j->type == JT_CONST)
-+ continue; // Handled in make_join_stat..
-+
-+ j->ref.key = -1;
-+ j->ref.key_parts=0;
-+
-+ if (j->type == JT_SYSTEM)
-+ continue;
-+ if (j->keys.is_clear_all() || !(keyuse= join->best_positions[tablenr].key))
-+ {
-+ j->type=JT_ALL;
-+ if (tablenr != join->const_tables)
-+ join->full_join=1;
-+ }
-+ else if (create_ref_for_key(join, j, keyuse, used_tables))
-+ DBUG_RETURN(TRUE); // Something went wrong
-+ }
-+
-+ for (i=0 ; i < table_count ; i++)
-+ join->map2table[join->join_tab[i].table->tablenr]=join->join_tab+i;
-+ update_depend_map(join);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse,
-+ table_map used_tables)
-+{
-+ KEYUSE *keyuse=org_keyuse;
-+ bool ftkey=(keyuse->keypart == FT_KEYPART);
-+ THD *thd= join->thd;
-+ uint keyparts,length,key;
-+ TABLE *table;
-+ KEY *keyinfo;
-+ DBUG_ENTER("create_ref_for_key");
-+
-+ /* Use best key from find_best */
-+ table=j->table;
-+ key=keyuse->key;
-+ keyinfo=table->key_info+key;
-+
-+ if (ftkey)
-+ {
-+ Item_func_match *ifm=(Item_func_match *)keyuse->val;
-+
-+ length=0;
-+ keyparts=1;
-+ ifm->join_key=1;
-+ }
-+ else
-+ {
-+ keyparts=length=0;
-+ uint found_part_ref_or_null= 0;
-+ /*
-+ Calculate length for the used key
-+ Stop if there is a missing key part or when we find second key_part
-+ with KEY_OPTIMIZE_REF_OR_NULL
-+ */
-+ do
-+ {
-+ if (!(~used_tables & keyuse->used_tables))
-+ {
-+ if (keyparts == keyuse->keypart &&
-+ !(found_part_ref_or_null & keyuse->optimize))
-+ {
-+ keyparts++;
-+ length+= keyinfo->key_part[keyuse->keypart].store_length;
-+ found_part_ref_or_null|= keyuse->optimize;
-+ }
-+ }
-+ keyuse++;
-+ } while (keyuse->table == table && keyuse->key == key);
-+ } /* not ftkey */
-+
-+ /* set up fieldref */
-+ keyinfo=table->key_info+key;
-+ j->ref.key_parts=keyparts;
-+ j->ref.key_length=length;
-+ j->ref.key=(int) key;
-+ if (!(j->ref.key_buff= (uchar*) thd->calloc(ALIGN_SIZE(length)*2)) ||
-+ !(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
-+ (keyparts+1)))) ||
-+ !(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
-+ !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ j->ref.key_buff2=j->ref.key_buff+ALIGN_SIZE(length);
-+ j->ref.key_err=1;
-+ j->ref.has_record= FALSE;
-+ j->ref.null_rejecting= 0;
-+ j->ref.use_count= 0;
-+ keyuse=org_keyuse;
-+
-+ store_key **ref_key= j->ref.key_copy;
-+ uchar *key_buff=j->ref.key_buff, *null_ref_key= 0;
-+ bool keyuse_uses_no_tables= TRUE;
-+ if (ftkey)
-+ {
-+ j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
-+ /* Predicates pushed down into subquery can't be used FT access */
-+ j->ref.cond_guards[0]= NULL;
-+ if (keyuse->used_tables)
-+ DBUG_RETURN(TRUE); // not supported yet. SerG
-+
-+ j->type=JT_FT;
-+ }
-+ else
-+ {
-+ uint i;
-+ for (i=0 ; i < keyparts ; keyuse++,i++)
-+ {
-+ while (keyuse->keypart != i ||
-+ ((~used_tables) & keyuse->used_tables))
-+ keyuse++; /* Skip other parts */
-+
-+ uint maybe_null= test(keyinfo->key_part[i].null_bit);
-+ j->ref.items[i]=keyuse->val; // Save for cond removal
-+ j->ref.cond_guards[i]= keyuse->cond_guard;
-+ if (keyuse->null_rejecting)
-+ j->ref.null_rejecting |= 1 << i;
-+ keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
-+ if (!keyuse->used_tables &&
-+ !(join->select_options & SELECT_DESCRIBE))
-+ { // Compare against constant
-+ store_key_item tmp(thd, keyinfo->key_part[i].field,
-+ key_buff + maybe_null,
-+ maybe_null ? key_buff : 0,
-+ keyinfo->key_part[i].length, keyuse->val);
-+ if (thd->is_fatal_error)
-+ DBUG_RETURN(TRUE);
-+ tmp.copy();
-+ }
-+ else
-+ *ref_key++= get_store_key(thd,
-+ keyuse,join->const_table_map,
-+ &keyinfo->key_part[i],
-+ key_buff, maybe_null);
-+ /*
-+ Remember if we are going to use REF_OR_NULL
-+ But only if field _really_ can be null i.e. we force JT_REF
-+ instead of JT_REF_OR_NULL in case if field can't be null
-+ */
-+ if ((keyuse->optimize & KEY_OPTIMIZE_REF_OR_NULL) && maybe_null)
-+ null_ref_key= key_buff;
-+ key_buff+=keyinfo->key_part[i].store_length;
-+ }
-+ } /* not ftkey */
-+ *ref_key=0; // end_marker
-+ if (j->type == JT_FT)
-+ DBUG_RETURN(0);
-+ if (j->type == JT_CONST)
-+ j->table->const_table= 1;
-+ else if (((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY |
-+ HA_END_SPACE_KEY)) != HA_NOSAME) ||
-+ keyparts != keyinfo->key_parts || null_ref_key)
-+ {
-+ /* Must read with repeat */
-+ j->type= null_ref_key ? JT_REF_OR_NULL : JT_REF;
-+ j->ref.null_ref_key= null_ref_key;
-+ }
-+ else if (keyuse_uses_no_tables)
-+ {
-+ /*
-+ This happen if we are using a constant expression in the ON part
-+ of an LEFT JOIN.
-+ SELECT * FROM a LEFT JOIN b ON b.key=30
-+ Here we should not mark the table as a 'const' as a field may
-+ have a 'normal' value or a NULL value.
-+ */
-+ j->type=JT_CONST;
-+ }
-+ else
-+ j->type=JT_EQ_REF;
-+ DBUG_RETURN(0);
-+}
-+
-+
-+
-+static store_key *
-+get_store_key(THD *thd, KEYUSE *keyuse, table_map used_tables,
-+ KEY_PART_INFO *key_part, uchar *key_buff, uint maybe_null)
-+{
-+ if (!((~used_tables) & keyuse->used_tables)) // if const item
-+ {
-+ return new store_key_const_item(thd,
-+ key_part->field,
-+ key_buff + maybe_null,
-+ maybe_null ? key_buff : 0,
-+ key_part->length,
-+ keyuse->val);
-+ }
-+ else if (keyuse->val->type() == Item::FIELD_ITEM ||
-+ (keyuse->val->type() == Item::REF_ITEM &&
-+ ((Item_ref*)keyuse->val)->ref_type() == Item_ref::OUTER_REF &&
-+ (*(Item_ref**)((Item_ref*)keyuse->val)->ref)->ref_type() ==
-+ Item_ref::DIRECT_REF &&
-+ keyuse->val->real_item()->type() == Item::FIELD_ITEM))
-+ return new store_key_field(thd,
-+ key_part->field,
-+ key_buff + maybe_null,
-+ maybe_null ? key_buff : 0,
-+ key_part->length,
-+ ((Item_field*) keyuse->val->real_item())->field,
-+ keyuse->val->full_name());
-+ return new store_key_item(thd,
-+ key_part->field,
-+ key_buff + maybe_null,
-+ maybe_null ? key_buff : 0,
-+ key_part->length,
-+ keyuse->val);
-+}
-+
-+/**
-+ This function is only called for const items on fields which are keys.
-+
-+ @return
-+ returns 1 if there was some conversion made when the field was stored.
-+*/
-+
-+bool
-+store_val_in_field(Field *field, Item *item, enum_check_fields check_flag)
-+{
-+ bool error;
-+ TABLE *table= field->table;
-+ THD *thd= table->in_use;
-+ ha_rows cuted_fields=thd->cuted_fields;
-+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table,
-+ table->write_set);
-+
-+ /*
-+ we should restore old value of count_cuted_fields because
-+ store_val_in_field can be called from mysql_insert
-+ with select_insert, which make count_cuted_fields= 1
-+ */
-+ enum_check_fields old_count_cuted_fields= thd->count_cuted_fields;
-+ thd->count_cuted_fields= check_flag;
-+ error= item->save_in_field(field, 1);
-+ thd->count_cuted_fields= old_count_cuted_fields;
-+ dbug_tmp_restore_column_map(table->write_set, old_map);
-+ return error || cuted_fields != thd->cuted_fields;
-+}
-+
-+
-+/**
-+ @details Initialize a JOIN as a query execution plan
-+ that accesses a single table via a table scan.
-+
-+ @param parent contains JOIN_TAB and TABLE object buffers for this join
-+ @param tmp_table temporary table
-+
-+ @retval FALSE success
-+ @retval TRUE error occurred
-+*/
-+bool
-+JOIN::make_simple_join(JOIN *parent, TABLE *temp_table)
-+{
-+ DBUG_ENTER("JOIN::make_simple_join");
-+
-+ /*
-+ Reuse TABLE * and JOIN_TAB if already allocated by a previous call
-+ to this function through JOIN::exec (may happen for sub-queries).
-+ */
-+ if (!parent->join_tab_reexec &&
-+ !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
-+ DBUG_RETURN(TRUE); /* purecov: inspected */
-+
-+ join_tab= parent->join_tab_reexec;
-+ table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table;
-+ tables= 1;
-+ const_tables= 0;
-+ const_table_map= 0;
-+ tmp_table_param.field_count= tmp_table_param.sum_func_count=
-+ tmp_table_param.func_count= 0;
-+ /*
-+ We need to destruct the copy_field (allocated in create_tmp_table())
-+ before setting it to 0 if the join is not "reusable".
-+ */
-+ if (!tmp_join || tmp_join != this)
-+ tmp_table_param.cleanup();
-+ tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
-+ first_record= sort_and_group=0;
-+ send_records= (ha_rows) 0;
-+ group= 0;
-+ row_limit= unit->select_limit_cnt;
-+ do_send_rows= row_limit ? 1 : 0;
-+
-+ join_tab->cache.buff=0; /* No caching */
-+ join_tab->table=temp_table;
-+ join_tab->select=0;
-+ join_tab->select_cond=0;
-+ join_tab->quick=0;
-+ join_tab->type= JT_ALL; /* Map through all records */
-+ join_tab->keys.init();
-+ join_tab->keys.set_all(); /* test everything in quick */
-+ join_tab->info=0;
-+ join_tab->on_expr_ref=0;
-+ join_tab->last_inner= 0;
-+ join_tab->first_unmatched= 0;
-+ join_tab->ref.key = -1;
-+ join_tab->not_used_in_distinct=0;
-+ join_tab->read_first_record= join_init_read_record;
-+ join_tab->join= this;
-+ join_tab->ref.key_parts= 0;
-+ bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
-+ temp_table->status=0;
-+ temp_table->null_row=0;
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+inline void add_cond_and_fix(Item **e1, Item *e2)
-+{
-+ if (*e1)
-+ {
-+ Item *res;
-+ if ((res= new Item_cond_and(*e1, e2)))
-+ {
-+ *e1= res;
-+ res->quick_fix_field();
-+ res->update_used_tables();
-+ }
-+ }
-+ else
-+ *e1= e2;
-+}
-+
-+
-+/**
-+ Add to join_tab->select_cond[i] "table.field IS NOT NULL" conditions
-+ we've inferred from ref/eq_ref access performed.
-+
-+ This function is a part of "Early NULL-values filtering for ref access"
-+ optimization.
-+
-+ Example of this optimization:
-+ For query SELECT * FROM t1,t2 WHERE t2.key=t1.field @n
-+ and plan " any-access(t1), ref(t2.key=t1.field) " @n
-+ add "t1.field IS NOT NULL" to t1's table condition. @n
-+
-+ Description of the optimization:
-+
-+ We look through equalities choosen to perform ref/eq_ref access,
-+ pick equalities that have form "tbl.part_of_key = othertbl.field"
-+ (where othertbl is a non-const table and othertbl.field may be NULL)
-+ and add them to conditions on correspoding tables (othertbl in this
-+ example).
-+
-+ Exception from that is the case when referred_tab->join != join.
-+ I.e. don't add NOT NULL constraints from any embedded subquery.
-+ Consider this query:
-+ @code
-+ SELECT A.f2 FROM t1 LEFT JOIN t2 A ON A.f2 = f1
-+ WHERE A.f3=(SELECT MIN(f3) FROM t2 C WHERE A.f4 = C.f4) OR A.f3 IS NULL;
-+ @endocde
-+ Here condition A.f3 IS NOT NULL is going to be added to the WHERE
-+ condition of the embedding query.
-+ Another example:
-+ SELECT * FROM t10, t11 WHERE (t10.a < 10 OR t10.a IS NULL)
-+ AND t11.b <=> t10.b AND (t11.a = (SELECT MAX(a) FROM t12
-+ WHERE t12.b = t10.a ));
-+ Here condition t10.a IS NOT NULL is going to be added.
-+ In both cases addition of NOT NULL condition will erroneously reject
-+ some rows of the result set.
-+ referred_tab->join != join constraint would disallow such additions.
-+
-+ This optimization doesn't affect the choices that ref, range, or join
-+ optimizer make. This was intentional because this was added after 4.1
-+ was GA.
-+
-+ Implementation overview
-+ 1. update_ref_and_keys() accumulates info about null-rejecting
-+ predicates in in KEY_FIELD::null_rejecting
-+ 1.1 add_key_part saves these to KEYUSE.
-+ 2. create_ref_for_key copies them to TABLE_REF.
-+ 3. add_not_null_conds adds "x IS NOT NULL" to join_tab->select_cond of
-+ appropiate JOIN_TAB members.
-+*/
-+
-+static void add_not_null_conds(JOIN *join)
-+{
-+ DBUG_ENTER("add_not_null_conds");
-+ for (uint i=join->const_tables ; i < join->tables ; i++)
-+ {
-+ JOIN_TAB *tab=join->join_tab+i;
-+ if ((tab->type == JT_REF || tab->type == JT_EQ_REF ||
-+ tab->type == JT_REF_OR_NULL) &&
-+ !tab->table->maybe_null)
-+ {
-+ for (uint keypart= 0; keypart < tab->ref.key_parts; keypart++)
-+ {
-+ if (tab->ref.null_rejecting & (1 << keypart))
-+ {
-+ Item *item= tab->ref.items[keypart];
-+ Item *notnull;
-+ DBUG_ASSERT(item->type() == Item::FIELD_ITEM);
-+ Item_field *not_null_item= (Item_field*)item;
-+ JOIN_TAB *referred_tab= not_null_item->field->table->reginfo.join_tab;
-+ /*
-+ For UPDATE queries such as:
-+ UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
-+ not_null_item is the t1.f1, but it's referred_tab is 0.
-+ */
-+ if (!referred_tab || referred_tab->join != join)
-+ continue;
-+ if (!(notnull= new Item_func_isnotnull(not_null_item)))
-+ DBUG_VOID_RETURN;
-+ /*
-+ We need to do full fix_fields() call here in order to have correct
-+ notnull->const_item(). This is needed e.g. by test_quick_select
-+ when it is called from make_join_select after this function is
-+ called.
-+ */
-+ if (notnull->fix_fields(join->thd, ¬null))
-+ DBUG_VOID_RETURN;
-+ DBUG_EXECUTE("where",print_where(notnull,
-+ referred_tab->table->alias,
-+ QT_ORDINARY););
-+ add_cond_and_fix(&referred_tab->select_cond, notnull);
-+ }
-+ }
-+ }
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+/**
-+ Build a predicate guarded by match variables for embedding outer joins.
-+ The function recursively adds guards for predicate cond
-+ assending from tab to the first inner table next embedding
-+ nested outer join and so on until it reaches root_tab
-+ (root_tab can be 0).
-+
-+ @param tab the first inner table for most nested outer join
-+ @param cond the predicate to be guarded (must be set)
-+ @param root_tab the first inner table to stop
-+
-+ @return
-+ - pointer to the guarded predicate, if success
-+ - 0, otherwise
-+*/
-+
-+static COND*
-+add_found_match_trig_cond(JOIN_TAB *tab, COND *cond, JOIN_TAB *root_tab)
-+{
-+ COND *tmp;
-+ DBUG_ASSERT(cond != 0);
-+ if (tab == root_tab)
-+ return cond;
-+ if ((tmp= add_found_match_trig_cond(tab->first_upper, cond, root_tab)))
-+ tmp= new Item_func_trig_cond(tmp, &tab->found);
-+ if (tmp)
-+ {
-+ tmp->quick_fix_field();
-+ tmp->update_used_tables();
-+ }
-+ return tmp;
-+}
-+
-+
-+/**
-+ Fill in outer join related info for the execution plan structure.
-+
-+ For each outer join operation left after simplification of the
-+ original query the function set up the following pointers in the linear
-+ structure join->join_tab representing the selected execution plan.
-+ The first inner table t0 for the operation is set to refer to the last
-+ inner table tk through the field t0->last_inner.
-+ Any inner table ti for the operation are set to refer to the first
-+ inner table ti->first_inner.
-+ The first inner table t0 for the operation is set to refer to the
-+ first inner table of the embedding outer join operation, if there is any,
-+ through the field t0->first_upper.
-+ The on expression for the outer join operation is attached to the
-+ corresponding first inner table through the field t0->on_expr_ref.
-+ Here ti are structures of the JOIN_TAB type.
-+
-+ EXAMPLE. For the query:
-+ @code
-+ SELECT * FROM t1
-+ LEFT JOIN
-+ (t2, t3 LEFT JOIN t4 ON t3.a=t4.a)
-+ ON (t1.a=t2.a AND t1.b=t3.b)
-+ WHERE t1.c > 5,
-+ @endcode
-+
-+ given the execution plan with the table order t1,t2,t3,t4
-+ is selected, the following references will be set;
-+ t4->last_inner=[t4], t4->first_inner=[t4], t4->first_upper=[t2]
-+ t2->last_inner=[t4], t2->first_inner=t3->first_inner=[t2],
-+ on expression (t1.a=t2.a AND t1.b=t3.b) will be attached to
-+ *t2->on_expr_ref, while t3.a=t4.a will be attached to *t4->on_expr_ref.
-+
-+ @param join reference to the info fully describing the query
-+
-+ @note
-+ The function assumes that the simplification procedure has been
-+ already applied to the join query (see simplify_joins).
-+ This function can be called only after the execution plan
-+ has been chosen.
-+*/
-+
-+static void
-+make_outerjoin_info(JOIN *join)
-+{
-+ DBUG_ENTER("make_outerjoin_info");
-+ for (uint i=join->const_tables ; i < join->tables ; i++)
-+ {
-+ JOIN_TAB *tab=join->join_tab+i;
-+ TABLE *table=tab->table;
-+ TABLE_LIST *tbl= table->pos_in_table_list;
-+ TABLE_LIST *embedding= tbl->embedding;
-+
-+ if (tbl->outer_join)
-+ {
-+ /*
-+ Table tab is the only one inner table for outer join.
-+ (Like table t4 for the table reference t3 LEFT JOIN t4 ON t3.a=t4.a
-+ is in the query above.)
-+ */
-+ tab->last_inner= tab->first_inner= tab;
-+ tab->on_expr_ref= &tbl->on_expr;
-+ tab->cond_equal= tbl->cond_equal;
-+ if (embedding)
-+ tab->first_upper= embedding->nested_join->first_nested;
-+ }
-+ for ( ; embedding ; embedding= embedding->embedding)
-+ {
-+ NESTED_JOIN *nested_join= embedding->nested_join;
-+ if (!nested_join->counter)
-+ {
-+ /*
-+ Table tab is the first inner table for nested_join.
-+ Save reference to it in the nested join structure.
-+ */
-+ nested_join->first_nested= tab;
-+ tab->on_expr_ref= &embedding->on_expr;
-+ tab->cond_equal= tbl->cond_equal;
-+ if (embedding->embedding)
-+ tab->first_upper= embedding->embedding->nested_join->first_nested;
-+ }
-+ if (!tab->first_inner)
-+ tab->first_inner= nested_join->first_nested;
-+ if (++nested_join->counter < nested_join->join_list.elements)
-+ break;
-+ /* Table tab is the last inner table for nested join. */
-+ nested_join->first_nested->last_inner= tab;
-+ }
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+static bool
-+make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
-+{
-+ THD *thd= join->thd;
-+ DBUG_ENTER("make_join_select");
-+ if (select)
-+ {
-+ add_not_null_conds(join);
-+ table_map used_tables;
-+ if (cond) /* Because of QUICK_GROUP_MIN_MAX_SELECT */
-+ { /* there may be a select without a cond. */
-+ if (join->tables > 1)
-+ cond->update_used_tables(); // Tablenr may have changed
-+ if (join->const_tables == join->tables &&
-+ thd->lex->current_select->master_unit() ==
-+ &thd->lex->unit) // not upper level SELECT
-+ join->const_table_map|=RAND_TABLE_BIT;
-+ { // Check const tables
-+ COND *const_cond=
-+ make_cond_for_table(cond,
-+ join->const_table_map,
-+ (table_map) 0);
-+ DBUG_EXECUTE("where",print_where(const_cond,"constants", QT_ORDINARY););
-+ for (JOIN_TAB *tab= join->join_tab+join->const_tables;
-+ tab < join->join_tab+join->tables ; tab++)
-+ {
-+ if (*tab->on_expr_ref)
-+ {
-+ JOIN_TAB *cond_tab= tab->first_inner;
-+ COND *tmp= make_cond_for_table(*tab->on_expr_ref,
-+ join->const_table_map,
-+ ( table_map) 0);
-+ if (!tmp)
-+ continue;
-+ tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
-+ if (!tmp)
-+ DBUG_RETURN(1);
-+ tmp->quick_fix_field();
-+ cond_tab->select_cond= !cond_tab->select_cond ? tmp :
-+ new Item_cond_and(cond_tab->select_cond,
-+ tmp);
-+ if (!cond_tab->select_cond)
-+ DBUG_RETURN(1);
-+ cond_tab->select_cond->quick_fix_field();
-+ }
-+ }
-+ if (const_cond && !const_cond->val_int())
-+ {
-+ DBUG_PRINT("info",("Found impossible WHERE condition"));
-+ DBUG_RETURN(1); // Impossible const condition
-+ }
-+ }
-+ }
-+ used_tables=((select->const_tables=join->const_table_map) |
-+ OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
-+ for (uint i=join->const_tables ; i < join->tables ; i++)
-+ {
-+ JOIN_TAB *tab=join->join_tab+i;
-+ /*
-+ first_inner is the X in queries like:
-+ SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
-+ */
-+ JOIN_TAB *first_inner_tab= tab->first_inner;
-+ table_map current_map= tab->table->map;
-+ bool use_quick_range=0;
-+ COND *tmp;
-+
-+ /*
-+ Following force including random expression in last table condition.
-+ It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
-+ */
-+ if (i == join->tables-1)
-+ current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
-+ used_tables|=current_map;
-+
-+ if (tab->type == JT_REF && tab->quick &&
-+ (uint) tab->ref.key == tab->quick->index &&
-+ tab->ref.key_length < tab->quick->max_used_key_length)
-+ {
-+ /* Range uses longer key; Use this instead of ref on key */
-+ tab->type=JT_ALL;
-+ use_quick_range=1;
-+ tab->use_quick=1;
-+ tab->ref.key= -1;
-+ tab->ref.key_parts=0; // Don't use ref key.
-+ join->best_positions[i].records_read= rows2double(tab->quick->records);
-+ /*
-+ We will use join cache here : prevent sorting of the first
-+ table only and sort at the end.
-+ */
-+ if (i != join->const_tables && join->tables > join->const_tables + 1)
-+ join->full_join= 1;
-+ }
-+
-+ tmp= NULL;
-+ if (cond)
-+ tmp= make_cond_for_table(cond,used_tables,current_map);
-+ if (cond && !tmp && tab->quick)
-+ { // Outer join
-+ if (tab->type != JT_ALL)
-+ {
-+ /*
-+ Don't use the quick method
-+ We come here in the case where we have 'key=constant' and
-+ the test is removed by make_cond_for_table()
-+ */
-+ delete tab->quick;
-+ tab->quick= 0;
-+ }
-+ else
-+ {
-+ /*
-+ Hack to handle the case where we only refer to a table
-+ in the ON part of an OUTER JOIN. In this case we want the code
-+ below to check if we should use 'quick' instead.
-+ */
-+ DBUG_PRINT("info", ("Item_int"));
-+ tmp= new Item_int((longlong) 1,1); // Always true
-+ }
-+
-+ }
-+ if (tmp || !cond || tab->type == JT_REF)
-+ {
-+ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
-+ SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
-+ thd->memdup((uchar*) select,
-+ sizeof(*select)));
-+ if (!sel)
-+ DBUG_RETURN(1); // End of memory
-+ /*
-+ If tab is an inner table of an outer join operation,
-+ add a match guard to the pushed down predicate.
-+ The guard will turn the predicate on only after
-+ the first match for outer tables is encountered.
-+ */
-+ if (cond && tmp)
-+ {
-+ /*
-+ Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
-+ a cond, so neutralize the hack above.
-+ */
-+ 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 */
-+ if (thd->variables.engine_condition_pushdown)
-+ {
-+ COND *push_cond=
-+ make_cond_for_table(tmp, current_map, current_map);
-+ if (push_cond)
-+ {
-+ /* Push condition to handler */
-+ if (!tab->table->file->cond_push(push_cond))
-+ tab->table->file->pushed_cond= push_cond;
-+ }
-+ }
-+ }
-+ else
-+ tab->select_cond= sel->cond= NULL;
-+
-+ sel->head=tab->table;
-+ DBUG_EXECUTE("where",print_where(tmp,tab->table->alias, QT_ORDINARY););
-+ if (tab->quick)
-+ {
-+ /* Use quick key read if it's a constant and it's not used
-+ with key reading */
-+ if (tab->needed_reg.is_clear_all() && tab->type != JT_EQ_REF
-+ && tab->type != JT_FT && (tab->type != JT_REF ||
-+ (uint) tab->ref.key == tab->quick->index))
-+ {
-+ sel->quick=tab->quick; // Use value from get_quick_...
-+ sel->quick_keys.clear_all();
-+ sel->needed_reg.clear_all();
-+ }
-+ else
-+ {
-+ delete tab->quick;
-+ }
-+ tab->quick=0;
-+ }
-+ uint ref_key=(uint) sel->head->reginfo.join_tab->ref.key+1;
-+ if (i == join->const_tables && ref_key)
-+ {
-+ if (!tab->const_keys.is_clear_all() &&
-+ tab->table->reginfo.impossible_range)
-+ DBUG_RETURN(1);
-+ }
-+ else if (tab->type == JT_ALL && ! use_quick_range)
-+ {
-+ if (!tab->const_keys.is_clear_all() &&
-+ tab->table->reginfo.impossible_range)
-+ DBUG_RETURN(1); // Impossible range
-+ /*
-+ We plan to scan all rows.
-+ Check again if we should use an index.
-+ We could have used an column from a previous table in
-+ the index if we are using limit and this is the first table
-+ */
-+
-+ if ((cond &&
-+ !tab->keys.is_subset(tab->const_keys) && i > 0) ||
-+ (!tab->const_keys.is_clear_all() && i == join->const_tables &&
-+ join->unit->select_limit_cnt <
-+ join->best_positions[i].records_read &&
-+ !(join->select_options & OPTION_FOUND_ROWS)))
-+ {
-+ /* Join with outer join condition */
-+ COND *orig_cond=sel->cond;
-+ sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
-+
-+ /*
-+ We can't call sel->cond->fix_fields,
-+ as it will break tab->on_expr if it's AND condition
-+ (fix_fields currently removes extra AND/OR levels).
-+ Yet attributes of the just built condition are not needed.
-+ Thus we call sel->cond->quick_fix_field for safety.
-+ */
-+ if (sel->cond && !sel->cond->fixed)
-+ sel->cond->quick_fix_field();
-+
-+ if (sel->test_quick_select(thd, tab->keys,
-+ used_tables & ~ current_map,
-+ (join->select_options &
-+ OPTION_FOUND_ROWS ?
-+ HA_POS_ERROR :
-+ join->unit->select_limit_cnt), 0) < 0)
-+ {
-+ /*
-+ Before reporting "Impossible WHERE" for the whole query
-+ we have to check isn't it only "impossible ON" instead
-+ */
-+ sel->cond=orig_cond;
-+ if (!*tab->on_expr_ref ||
-+ sel->test_quick_select(thd, tab->keys,
-+ used_tables & ~ current_map,
-+ (join->select_options &
-+ OPTION_FOUND_ROWS ?
-+ HA_POS_ERROR :
-+ join->unit->select_limit_cnt),0) < 0)
-+ DBUG_RETURN(1); // Impossible WHERE
-+ }
-+ else
-+ sel->cond=orig_cond;
-+
-+ /* Fix for EXPLAIN */
-+ if (sel->quick)
-+ join->best_positions[i].records_read= (double)sel->quick->records;
-+ }
-+ else
-+ {
-+ sel->needed_reg=tab->needed_reg;
-+ sel->quick_keys.clear_all();
-+ }
-+ if (!sel->quick_keys.is_subset(tab->checked_keys) ||
-+ !sel->needed_reg.is_subset(tab->checked_keys))
-+ {
-+ tab->keys=sel->quick_keys;
-+ tab->keys.merge(sel->needed_reg);
-+ tab->use_quick= (!sel->needed_reg.is_clear_all() &&
-+ (select->quick_keys.is_clear_all() ||
-+ (select->quick &&
-+ (select->quick->records >= 100L)))) ?
-+ 2 : 1;
-+ sel->read_tables= used_tables & ~current_map;
-+ }
-+ if (i != join->const_tables && tab->use_quick != 2)
-+ { /* Read with cache */
-+ if (cond &&
-+ (tmp=make_cond_for_table(cond,
-+ join->const_table_map |
-+ current_map,
-+ current_map)))
-+ {
-+ DBUG_EXECUTE("where",print_where(tmp,"cache", QT_ORDINARY););
-+ tab->cache.select=(SQL_SELECT*)
-+ thd->memdup((uchar*) sel, sizeof(SQL_SELECT));
-+ tab->cache.select->cond=tmp;
-+ tab->cache.select->read_tables=join->const_table_map;
-+ }
-+ }
-+ }
-+ }
-+
-+ /*
-+ Push down conditions from all on expressions.
-+ Each of these conditions are guarded by a variable
-+ that turns if off just before null complemented row for
-+ outer joins is formed. Thus, the condition from an
-+ 'on expression' are guaranteed not to be checked for
-+ the null complemented row.
-+ */
-+
-+ /* First push down constant conditions from on expressions */
-+ for (JOIN_TAB *join_tab= join->join_tab+join->const_tables;
-+ join_tab < join->join_tab+join->tables ; join_tab++)
-+ {
-+ if (*join_tab->on_expr_ref)
-+ {
-+ JOIN_TAB *cond_tab= join_tab->first_inner;
-+ COND *tmp= make_cond_for_table(*join_tab->on_expr_ref,
-+ join->const_table_map,
-+ (table_map) 0);
-+ if (!tmp)
-+ continue;
-+ tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
-+ if (!tmp)
-+ DBUG_RETURN(1);
-+ tmp->quick_fix_field();
-+ cond_tab->select_cond= !cond_tab->select_cond ? tmp :
-+ new Item_cond_and(cond_tab->select_cond,tmp);
-+ if (!cond_tab->select_cond)
-+ DBUG_RETURN(1);
-+ cond_tab->select_cond->quick_fix_field();
-+ }
-+ }
-+
-+ /* Push down non-constant conditions from on expressions */
-+ JOIN_TAB *last_tab= tab;
-+ while (first_inner_tab && first_inner_tab->last_inner == last_tab)
-+ {
-+ /*
-+ Table tab is the last inner table of an outer join.
-+ An on expression is always attached to it.
-+ */
-+ COND *on_expr= *first_inner_tab->on_expr_ref;
-+
-+ table_map used_tables2= (join->const_table_map |
-+ OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
-+ for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
-+ {
-+ current_map= tab->table->map;
-+ used_tables2|= current_map;
-+ COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
-+ current_map);
-+ if (tmp_cond)
-+ {
-+ JOIN_TAB *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
-+ /*
-+ First add the guards for match variables of
-+ all embedding outer join operations.
-+ */
-+ if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
-+ tmp_cond,
-+ first_inner_tab)))
-+ DBUG_RETURN(1);
-+ /*
-+ Now add the guard turning the predicate off for
-+ the null complemented row.
-+ */
-+ DBUG_PRINT("info", ("Item_func_trig_cond"));
-+ tmp_cond= new Item_func_trig_cond(tmp_cond,
-+ &first_inner_tab->
-+ not_null_compl);
-+ DBUG_PRINT("info", ("Item_func_trig_cond 0x%lx",
-+ (ulong) tmp_cond));
-+ if (tmp_cond)
-+ tmp_cond->quick_fix_field();
-+ /* Add the predicate to other pushed down predicates */
-+ DBUG_PRINT("info", ("Item_cond_and"));
-+ cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
-+ new Item_cond_and(cond_tab->select_cond,
-+ tmp_cond);
-+ DBUG_PRINT("info", ("Item_cond_and 0x%lx",
-+ (ulong)cond_tab->select_cond));
-+ if (!cond_tab->select_cond)
-+ DBUG_RETURN(1);
-+ cond_tab->select_cond->quick_fix_field();
-+ }
-+ }
-+ first_inner_tab= first_inner_tab->first_upper;
-+ }
-+ }
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ The default implementation of unlock-row method of READ_RECORD,
-+ used in all access methods.
-+*/
-+
-+void rr_unlock_row(st_join_table *tab)
-+{
-+ READ_RECORD *info= &tab->read_record;
-+ info->file->unlock_row();
-+}
-+
-+
-+
-+/**
-+ Pick the appropriate access method functions
-+
-+ Sets the functions for the selected table access method
-+
-+ @param tab Table reference to put access method
-+*/
-+
-+static void
-+pick_table_access_method(JOIN_TAB *tab)
-+{
-+ switch (tab->type)
-+ {
-+ case JT_REF:
-+ tab->read_first_record= join_read_always_key;
-+ tab->read_record.read_record= join_read_next_same;
-+ break;
-+
-+ case JT_REF_OR_NULL:
-+ tab->read_first_record= join_read_always_key_or_null;
-+ tab->read_record.read_record= join_read_next_same_or_null;
-+ break;
-+
-+ case JT_CONST:
-+ tab->read_first_record= join_read_const;
-+ tab->read_record.read_record= join_no_more_records;
-+ break;
-+
-+ case JT_EQ_REF:
-+ tab->read_first_record= join_read_key;
-+ tab->read_record.read_record= join_no_more_records;
-+ break;
-+
-+ case JT_FT:
-+ tab->read_first_record= join_ft_read_first;
-+ tab->read_record.read_record= join_ft_read_next;
-+ break;
-+
-+ case JT_SYSTEM:
-+ tab->read_first_record= join_read_system;
-+ tab->read_record.read_record= join_no_more_records;
-+ break;
-+
-+ /* keep gcc happy */
-+ default:
-+ break;
-+ }
-+}
-+
-+
-+static void
-+make_join_readinfo(JOIN *join, ulonglong options)
-+{
-+ uint i;
-+ bool statistics= test(!(join->select_options & SELECT_DESCRIBE));
-+ bool ordered_set= 0;
-+ bool sorted= 1;
-+ DBUG_ENTER("make_join_readinfo");
-+
-+ for (i=join->const_tables ; i < join->tables ; i++)
-+ {
-+ JOIN_TAB *tab=join->join_tab+i;
-+ TABLE *table=tab->table;
-+ tab->read_record.table= table;
-+ tab->read_record.file=table->file;
-+ tab->read_record.unlock_row= rr_unlock_row;
-+ tab->next_select=sub_select; /* normal select */
-+
-+ /*
-+ Determine if the set is already ordered for ORDER BY, so it can
-+ disable join cache because it will change the ordering of the results.
-+ Code handles sort table that is at any location (not only first after
-+ the const tables) despite the fact that it's currently prohibited.
-+ We must disable join cache if the first non-const table alone is
-+ ordered. If there is a temp table the ordering is done as a last
-+ operation and doesn't prevent join cache usage.
-+ */
-+ if (!ordered_set && !join->need_tmp &&
-+ (table == join->sort_by_table ||
-+ (join->sort_by_table == (TABLE *) 1 && i != join->const_tables)))
-+ ordered_set= 1;
-+
-+ tab->sorted= sorted;
-+ sorted= 0; // only first must be sorted
-+ table->status=STATUS_NO_RECORD;
-+ pick_table_access_method (tab);
-+
-+ switch (tab->type) {
-+ case JT_EQ_REF:
-+ tab->read_record.unlock_row= join_read_key_unlock_row;
-+ /* fall through */
-+ case JT_REF_OR_NULL:
-+ case JT_REF:
-+ if (tab->select)
-+ {
-+ delete tab->select->quick;
-+ tab->select->quick=0;
-+ }
-+ delete tab->quick;
-+ tab->quick=0;
-+ /* fall through */
-+ case JT_CONST: // Only happens with left join
-+ if (table->covering_keys.is_set(tab->ref.key) &&
-+ !table->no_keyread)
-+ table->set_keyread(TRUE);
-+ break;
-+ case JT_ALL:
-+ /*
-+ If previous table use cache
-+ If the incoming data set is already sorted don't use cache.
-+ */
-+ if (i != join->const_tables && !(options & SELECT_NO_JOIN_CACHE) &&
-+ tab->use_quick != 2 && !tab->first_inner && !ordered_set)
-+ {
-+ if ((options & SELECT_DESCRIBE) ||
-+ !join_init_cache(join->thd,join->join_tab+join->const_tables,
-+ i-join->const_tables))
-+ {
-+ tab[-1].next_select=sub_select_cache; /* Patch previous */
-+ }
-+ }
-+ /* These init changes read_record */
-+ if (tab->use_quick == 2)
-+ {
-+ join->thd->server_status|=SERVER_QUERY_NO_GOOD_INDEX_USED;
-+ tab->read_first_record= join_init_quick_read_record;
-+ if (statistics)
-+ status_var_increment(join->thd->status_var.select_range_check_count);
-+ }
-+ else
-+ {
-+ tab->read_first_record= join_init_read_record;
-+ if (i == join->const_tables)
-+ {
-+ if (tab->select && tab->select->quick)
-+ {
-+ if (statistics)
-+ status_var_increment(join->thd->status_var.select_range_count);
-+ }
-+ else
-+ {
-+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-+ if (statistics)
-+ status_var_increment(join->thd->status_var.select_scan_count);
-+ }
-+ }
-+ else
-+ {
-+ if (tab->select && tab->select->quick)
-+ {
-+ if (statistics)
-+ status_var_increment(join->thd->status_var.select_full_range_join_count);
-+ }
-+ else
-+ {
-+ join->thd->server_status|=SERVER_QUERY_NO_INDEX_USED;
-+ if (statistics)
-+ status_var_increment(join->thd->status_var.select_full_join_count);
-+ }
-+ }
-+ if (!table->no_keyread)
-+ {
-+ if (tab->select && tab->select->quick &&
-+ tab->select->quick->index != MAX_KEY && //not index_merge
-+ table->covering_keys.is_set(tab->select->quick->index))
-+ table->set_keyread(TRUE);
-+ else if (!table->covering_keys.is_clear_all() &&
-+ !(tab->select && tab->select->quick))
-+ { // Only read index tree
-+ /*
-+ It has turned out that the below change, while speeding things
-+ up for disk-bound loads, slows them down for cases when the data
-+ is in disk cache (see BUG#35850):
-+ // See bug #26447: "Using the clustered index for a table scan
-+ // is always faster than using a secondary index".
-+ if (table->s->primary_key != MAX_KEY &&
-+ table->file->primary_key_is_clustered())
-+ tab->index= table->s->primary_key;
-+ else
-+ */
-+ tab->index=find_shortest_key(table, & table->covering_keys);
-+ tab->read_first_record= join_read_first;
-+ tab->type=JT_NEXT; // Read with index_first / index_next
-+ }
-+ }
-+ }
-+ break;
-+ case JT_FT:
-+ case JT_SYSTEM:
-+ break;
-+ default:
-+ DBUG_PRINT("error",("Table type %d found",tab->type)); /* purecov: deadcode */
-+ break; /* purecov: deadcode */
-+ case JT_UNKNOWN:
-+ case JT_MAYBE_REF:
-+ abort(); /* purecov: deadcode */
-+ }
-+ }
-+ join->join_tab[join->tables-1].next_select=0; /* Set by do_select */
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Give error if we some tables are done with a full join.
-+
-+ This is used by multi_table_update and multi_table_delete when running
-+ in safe mode.
-+
-+ @param join Join condition
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 Error (full join used)
-+*/
-+
-+bool error_if_full_join(JOIN *join)
-+{
-+ for (JOIN_TAB *tab=join->join_tab, *end=join->join_tab+join->tables;
-+ tab < end;
-+ tab++)
-+ {
-+ if (tab->type == JT_ALL && (!tab->select || !tab->select->quick))
-+ {
-+ /* This error should not be ignored. */
-+ join->select_lex->no_error= FALSE;
-+ my_message(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE,
-+ ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
-+ return(1);
-+ }
-+ }
-+ return(0);
-+}
-+
-+
-+/**
-+ cleanup JOIN_TAB.
-+*/
-+
-+void JOIN_TAB::cleanup()
-+{
-+ delete select;
-+ select= 0;
-+ delete quick;
-+ quick= 0;
-+ x_free(cache.buff);
-+ cache.buff= 0;
-+ limit= 0;
-+ if (table)
-+ {
-+ table->set_keyread(FALSE);
-+ table->file->ha_index_or_rnd_end();
-+ /*
-+ We need to reset this for next select
-+ (Tested in part_of_refkey)
-+ */
-+ table->reginfo.join_tab= 0;
-+ }
-+ end_read_record(&read_record);
-+}
-+
-+
-+/**
-+ Partially cleanup JOIN after it has executed: close index or rnd read
-+ (table cursors), free quick selects.
-+
-+ This function is called in the end of execution of a JOIN, before the used
-+ tables are unlocked and closed.
-+
-+ For a join that is resolved using a temporary table, the first sweep is
-+ performed against actual tables and an intermediate result is inserted
-+ into the temprorary table.
-+ The last sweep is performed against the temporary table. Therefore,
-+ the base tables and associated buffers used to fill the temporary table
-+ are no longer needed, and this function is called to free them.
-+
-+ For a join that is performed without a temporary table, this function
-+ is called after all rows are sent, but before EOF packet is sent.
-+
-+ For a simple SELECT with no subqueries this function performs a full
-+ cleanup of the JOIN and calls mysql_unlock_read_tables to free used base
-+ tables.
-+
-+ If a JOIN is executed for a subquery or if it has a subquery, we can't
-+ do the full cleanup and need to do a partial cleanup only.
-+ - If a JOIN is not the top level join, we must not unlock the tables
-+ because the outer select may not have been evaluated yet, and we
-+ can't unlock only selected tables of a query.
-+ - Additionally, if this JOIN corresponds to a correlated subquery, we
-+ should not free quick selects and join buffers because they will be
-+ needed for the next execution of the correlated subquery.
-+ - However, if this is a JOIN for a [sub]select, which is not
-+ a correlated subquery itself, but has subqueries, we can free it
-+ fully and also free JOINs of all its subqueries. The exception
-+ is a subquery in SELECT list, e.g: @n
-+ SELECT a, (select max(b) from t1) group by c @n
-+ This subquery will not be evaluated at first sweep and its value will
-+ not be inserted into the temporary table. Instead, it's evaluated
-+ when selecting from the temporary table. Therefore, it can't be freed
-+ here even though it's not correlated.
-+
-+ @todo
-+ Unlock tables even if the join isn't top level select in the tree
-+*/
-+
-+void JOIN::join_free()
-+{
-+ SELECT_LEX_UNIT *tmp_unit;
-+ SELECT_LEX *sl;
-+ /*
-+ Optimization: if not EXPLAIN and we are done with the JOIN,
-+ free all tables.
-+ */
-+ bool full= (!select_lex->uncacheable && !thd->lex->describe);
-+ bool can_unlock= full;
-+ DBUG_ENTER("JOIN::join_free");
-+
-+ cleanup(full);
-+
-+ for (tmp_unit= select_lex->first_inner_unit();
-+ tmp_unit;
-+ tmp_unit= tmp_unit->next_unit())
-+ for (sl= tmp_unit->first_select(); sl; sl= sl->next_select())
-+ {
-+ Item_subselect *subselect= sl->master_unit()->item;
-+ bool full_local= full && (!subselect || subselect->is_evaluated());
-+ /*
-+ If this join is evaluated, we can fully clean it up and clean up all
-+ its underlying joins even if they are correlated -- they will not be
-+ used any more anyway.
-+ If this join is not yet evaluated, we still must clean it up to
-+ close its table cursors -- it may never get evaluated, as in case of
-+ ... HAVING FALSE OR a IN (SELECT ...))
-+ but all table cursors must be closed before the unlock.
-+ */
-+ sl->cleanup_all_joins(full_local);
-+ /* Can't unlock if at least one JOIN is still needed */
-+ can_unlock= can_unlock && full_local;
-+ }
-+
-+ /*
-+ We are not using tables anymore
-+ Unlock all tables. We may be in an INSERT .... SELECT statement.
-+ */
-+ if (can_unlock && lock && thd->lock &&
-+ !(select_options & SELECT_NO_UNLOCK) &&
-+ !select_lex->subquery_in_having &&
-+ (select_lex == (thd->lex->unit.fake_select_lex ?
-+ thd->lex->unit.fake_select_lex : &thd->lex->select_lex)))
-+ {
-+ /*
-+ TODO: unlock tables even if the join isn't top level select in the
-+ tree.
-+ */
-+ mysql_unlock_read_tables(thd, lock); // Don't free join->lock
-+ lock= 0;
-+ }
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Free resources of given join.
-+
-+ @param fill true if we should free all resources, call with full==1
-+ should be last, before it this function can be called with
-+ full==0
-+
-+ @note
-+ With subquery this function definitely will be called several times,
-+ but even for simple query it can be called several times.
-+*/
-+
-+void JOIN::cleanup(bool full)
-+{
-+ DBUG_ENTER("JOIN::cleanup");
-+
-+ if (table)
-+ {
-+ JOIN_TAB *tab,*end;
-+ /*
-+ Only a sorted table may be cached. This sorted table is always the
-+ first non const table in join->table
-+ */
-+ if (tables > const_tables) // Test for not-const tables
-+ {
-+ free_io_cache(table[const_tables]);
-+ filesort_free_buffers(table[const_tables],full);
-+ }
-+
-+ if (full)
-+ {
-+ for (tab= join_tab, end= tab+tables; tab != end; tab++)
-+ tab->cleanup();
-+ table= 0;
-+ }
-+ else
-+ {
-+ for (tab= join_tab, end= tab+tables; tab != end; tab++)
-+ {
-+ if (tab->table)
-+ tab->table->file->ha_index_or_rnd_end();
-+ }
-+ }
-+ }
-+ /*
-+ We are not using tables anymore
-+ Unlock all tables. We may be in an INSERT .... SELECT statement.
-+ */
-+ if (full)
-+ {
-+ if (tmp_join)
-+ tmp_table_param.copy_field= 0;
-+ group_fields.delete_elements();
-+ /*
-+ Ensure that the above delete_elements() would not be called
-+ twice for the same list.
-+ */
-+ if (tmp_join && tmp_join != this)
-+ tmp_join->group_fields= group_fields;
-+ /*
-+ We can't call delete_elements() on copy_funcs as this will cause
-+ problems in free_elements() as some of the elements are then deleted.
-+ */
-+ tmp_table_param.copy_funcs.empty();
-+ /*
-+ If we have tmp_join and 'this' JOIN is not tmp_join and
-+ tmp_table_param.copy_field's of them are equal then we have to remove
-+ pointer to tmp_table_param.copy_field from tmp_join, because it qill
-+ be removed in tmp_table_param.cleanup().
-+ */
-+ if (tmp_join &&
-+ tmp_join != this &&
-+ tmp_join->tmp_table_param.copy_field ==
-+ tmp_table_param.copy_field)
-+ {
-+ tmp_join->tmp_table_param.copy_field=
-+ tmp_join->tmp_table_param.save_copy_field= 0;
-+ }
-+ tmp_table_param.cleanup();
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Remove the following expressions from ORDER BY and GROUP BY:
-+ Constant expressions @n
-+ Expression that only uses tables that are of type EQ_REF and the reference
-+ is in the ORDER list or if all refereed tables are of the above type.
-+
-+ In the following, the X field can be removed:
-+ @code
-+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
-+ SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
-+ @endcode
-+
-+ These can't be optimized:
-+ @code
-+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
-+ SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
-+ SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
-+ @endcode
-+*/
-+
-+static bool
-+eq_ref_table(JOIN *join, ORDER *start_order, JOIN_TAB *tab)
-+{
-+ if (tab->cached_eq_ref_table) // If cached
-+ return tab->eq_ref_table;
-+ tab->cached_eq_ref_table=1;
-+ /* We can skip const tables only if not an outer table */
-+ if (tab->type == JT_CONST && !tab->first_inner)
-+ return (tab->eq_ref_table=1); /* purecov: inspected */
-+ if (tab->type != JT_EQ_REF || tab->table->maybe_null)
-+ return (tab->eq_ref_table=0); // We must use this
-+ Item **ref_item=tab->ref.items;
-+ Item **end=ref_item+tab->ref.key_parts;
-+ uint found=0;
-+ table_map map=tab->table->map;
-+
-+ for (; ref_item != end ; ref_item++)
-+ {
-+ if (! (*ref_item)->const_item())
-+ { // Not a const ref
-+ ORDER *order;
-+ for (order=start_order ; order ; order=order->next)
-+ {
-+ if ((*ref_item)->eq(order->item[0],0))
-+ break;
-+ }
-+ if (order)
-+ {
-+ if (!(order->used & map))
-+ {
-+ found++;
-+ order->used|= map;
-+ }
-+ continue; // Used in ORDER BY
-+ }
-+ if (!only_eq_ref_tables(join,start_order, (*ref_item)->used_tables()))
-+ return (tab->eq_ref_table=0);
-+ }
-+ }
-+ /* Check that there was no reference to table before sort order */
-+ for (; found && start_order ; start_order=start_order->next)
-+ {
-+ if (start_order->used & map)
-+ {
-+ found--;
-+ continue;
-+ }
-+ if (start_order->depend_map & map)
-+ return (tab->eq_ref_table=0);
-+ }
-+ return tab->eq_ref_table=1;
-+}
-+
-+
-+static bool
-+only_eq_ref_tables(JOIN *join,ORDER *order,table_map tables)
-+{
-+ if (specialflag & SPECIAL_SAFE_MODE)
-+ return 0; // skip this optimize /* purecov: inspected */
-+ tables&= ~PSEUDO_TABLE_BITS;
-+ for (JOIN_TAB **tab=join->map2table ; tables ; tab++, tables>>=1)
-+ {
-+ if (tables & 1 && !eq_ref_table(join, order, *tab))
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+
-+/** Update the dependency map for the tables. */
-+
-+static void update_depend_map(JOIN *join)
-+{
-+ JOIN_TAB *join_tab=join->join_tab, *end=join_tab+join->tables;
-+
-+ for (; join_tab != end ; join_tab++)
-+ {
-+ TABLE_REF *ref= &join_tab->ref;
-+ table_map depend_map=0;
-+ Item **item=ref->items;
-+ uint i;
-+ for (i=0 ; i < ref->key_parts ; i++,item++)
-+ depend_map|=(*item)->used_tables();
-+ ref->depend_map=depend_map & ~OUTER_REF_TABLE_BIT;
-+ depend_map&= ~OUTER_REF_TABLE_BIT;
-+ for (JOIN_TAB **tab=join->map2table;
-+ depend_map ;
-+ tab++,depend_map>>=1 )
-+ {
-+ if (depend_map & 1)
-+ ref->depend_map|=(*tab)->ref.depend_map;
-+ }
-+ }
-+}
-+
-+
-+/** Update the dependency map for the sort order. */
-+
-+static void update_depend_map(JOIN *join, ORDER *order)
-+{
-+ for (; order ; order=order->next)
-+ {
-+ table_map depend_map;
-+ order->item[0]->update_used_tables();
-+ order->depend_map=depend_map=order->item[0]->used_tables();
-+ order->used= 0;
-+ // Not item_sum(), RAND() and no reference to table outside of sub select
-+ if (!(order->depend_map & (OUTER_REF_TABLE_BIT | RAND_TABLE_BIT))
-+ && !order->item[0]->with_sum_func)
-+ {
-+ for (JOIN_TAB **tab=join->map2table;
-+ depend_map ;
-+ tab++, depend_map>>=1)
-+ {
-+ if (depend_map & 1)
-+ order->depend_map|=(*tab)->ref.depend_map;
-+ }
-+ }
-+ }
-+}
-+
-+
-+/**
-+ Remove all constants and check if ORDER only contains simple
-+ expressions.
-+
-+ simple_order is set to 1 if sort_order only uses fields from head table
-+ and the head table is not a LEFT JOIN table.
-+
-+ @param join Join handler
-+ @param first_order List of SORT or GROUP order
-+ @param cond WHERE statement
-+ @param change_list Set to 1 if we should remove things from list.
-+ If this is not set, then only simple_order is
-+ calculated.
-+ @param simple_order Set to 1 if we are only using simple expressions
-+
-+ @return
-+ Returns new sort order
-+*/
-+
-+static ORDER *
-+remove_const(JOIN *join,ORDER *first_order, COND *cond,
-+ bool change_list, bool *simple_order)
-+{
-+ if (join->tables == join->const_tables)
-+ return change_list ? 0 : first_order; // No need to sort
-+
-+ ORDER *order,**prev_ptr;
-+ table_map first_table= join->join_tab[join->const_tables].table->map;
-+ table_map not_const_tables= ~join->const_table_map;
-+ table_map ref;
-+ DBUG_ENTER("remove_const");
-+
-+ prev_ptr= &first_order;
-+ *simple_order= *join->join_tab[join->const_tables].on_expr_ref ? 0 : 1;
-+
-+ /* NOTE: A variable of not_const_tables ^ first_table; breaks gcc 2.7 */
-+
-+ update_depend_map(join, first_order);
-+ for (order=first_order; order ; order=order->next)
-+ {
-+ table_map order_tables=order->item[0]->used_tables();
-+ if (order->item[0]->with_sum_func ||
-+ /*
-+ If the outer table of an outer join is const (either by itself or
-+ after applying WHERE condition), grouping on a field from such a
-+ table will be optimized away and filesort without temporary table
-+ will be used unless we prevent that now. Filesort is not fit to
-+ handle joins and the join condition is not applied. We can't detect
-+ the case without an expensive test, however, so we force temporary
-+ table for all queries containing more than one table, ROLLUP, and an
-+ outer join.
-+ */
-+ (join->tables > 1 && join->rollup.state == ROLLUP::STATE_INITED &&
-+ join->outer_join))
-+ *simple_order=0; // Must do a temp table to sort
-+ else if (!(order_tables & not_const_tables))
-+ {
-+ if (order->item[0]->with_subselect &&
-+ !(join->select_lex->options & SELECT_DESCRIBE))
-+ order->item[0]->val_str(&order->item[0]->str_value);
-+ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
-+ continue; // skip const item
-+ }
-+ else
-+ {
-+ if (order_tables & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT))
-+ *simple_order=0;
-+ else
-+ {
-+ Item *comp_item=0;
-+ if (cond && const_expression_in_where(cond,order->item[0], &comp_item))
-+ {
-+ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
-+ continue;
-+ }
-+ if ((ref=order_tables & (not_const_tables ^ first_table)))
-+ {
-+ if (!(order_tables & first_table) &&
-+ only_eq_ref_tables(join,first_order, ref))
-+ {
-+ DBUG_PRINT("info",("removing: %s", order->item[0]->full_name()));
-+ continue;
-+ }
-+ *simple_order=0; // Must do a temp table to sort
-+ }
-+ }
-+ }
-+ if (change_list)
-+ *prev_ptr= order; // use this entry
-+ prev_ptr= &order->next;
-+ }
-+ if (change_list)
-+ *prev_ptr=0;
-+ if (prev_ptr == &first_order) // Nothing to sort/group
-+ *simple_order=1;
-+ DBUG_PRINT("exit",("simple_order: %d",(int) *simple_order));
-+ DBUG_RETURN(first_order);
-+}
-+
-+
-+static int
-+return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
-+ List<Item> &fields, bool send_row, ulonglong select_options,
-+ const char *info, Item *having)
-+{
-+ DBUG_ENTER("return_zero_rows");
-+
-+ if (select_options & SELECT_DESCRIBE)
-+ {
-+ select_describe(join, FALSE, FALSE, FALSE, info);
-+ DBUG_RETURN(0);
-+ }
-+
-+ join->join_free();
-+
-+ if (send_row)
-+ {
-+ for (TABLE_LIST *table= tables; table; table= table->next_leaf)
-+ mark_as_null_row(table->table); // All fields are NULL
-+ if (having && having->val_int() == 0)
-+ send_row=0;
-+ }
-+ if (!(result->send_fields(fields,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)))
-+ {
-+ bool send_error= FALSE;
-+ if (send_row)
-+ {
-+ List_iterator_fast<Item> it(fields);
-+ Item *item;
-+ while ((item= it++))
-+ item->no_rows_in_result();
-+ send_error= result->send_data(fields);
-+ }
-+ if (!send_error)
-+ result->send_eof(); // Should be safe
-+ }
-+ /* Update results for FOUND_ROWS */
-+ join->thd->limit_found_rows= join->thd->examined_row_count= 0;
-+ DBUG_RETURN(0);
-+}
-+
-+/*
-+ used only in JOIN::clear
-+*/
-+static void clear_tables(JOIN *join)
-+{
-+ /*
-+ must clear only the non-const tables, as const tables
-+ are not re-calculated.
-+ */
-+ for (uint i=join->const_tables ; i < join->tables ; i++)
-+ mark_as_null_row(join->table[i]); // All fields are NULL
-+}
-+
-+/*****************************************************************************
-+ Make som simple condition optimization:
-+ If there is a test 'field = const' change all refs to 'field' to 'const'
-+ Remove all dummy tests 'item = item', 'const op const'.
-+ Remove all 'item is NULL', when item can never be null!
-+ item->marker should be 0 for all items on entry
-+ Return in cond_value FALSE if condition is impossible (1 = 2)
-+*****************************************************************************/
-+
-+class COND_CMP :public ilink {
-+public:
-+ static void *operator new(size_t size)
-+ {
-+ return (void*) sql_alloc((uint) size);
-+ }
-+ static void operator delete(void *ptr __attribute__((unused)),
-+ size_t size __attribute__((unused)))
-+ { TRASH(ptr, size); }
-+
-+ Item *and_level;
-+ Item_func *cmp_func;
-+ COND_CMP(Item *a,Item_func *b) :and_level(a),cmp_func(b) {}
-+};
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class I_List<COND_CMP>;
-+template class I_List_iterator<COND_CMP>;
-+template class List<Item_func_match>;
-+template class List_iterator<Item_func_match>;
-+#endif
-+
-+
-+/**
-+ Find the multiple equality predicate containing a field.
-+
-+ The function retrieves the multiple equalities accessed through
-+ the con_equal structure from current level and up looking for
-+ an equality containing field. It stops retrieval as soon as the equality
-+ is found and set up inherited_fl to TRUE if it's found on upper levels.
-+
-+ @param cond_equal multiple equalities to search in
-+ @param field field to look for
-+ @param[out] inherited_fl set up to TRUE if multiple equality is found
-+ on upper levels (not on current level of
-+ cond_equal)
-+
-+ @return
-+ - Item_equal for the found multiple equality predicate if a success;
-+ - NULL otherwise.
-+*/
-+
-+Item_equal *find_item_equal(COND_EQUAL *cond_equal, Field *field,
-+ bool *inherited_fl)
-+{
-+ Item_equal *item= 0;
-+ bool in_upper_level= FALSE;
-+ while (cond_equal)
-+ {
-+ List_iterator_fast<Item_equal> li(cond_equal->current_level);
-+ while ((item= li++))
-+ {
-+ if (item->contains(field))
-+ goto finish;
-+ }
-+ in_upper_level= TRUE;
-+ cond_equal= cond_equal->upper_levels;
-+ }
-+ in_upper_level= FALSE;
-+finish:
-+ *inherited_fl= in_upper_level;
-+ return item;
-+}
-+
-+
-+/**
-+ Check whether an equality can be used to build multiple equalities.
-+
-+ This function first checks whether the equality (left_item=right_item)
-+ is a simple equality i.e. the one that equates a field with another field
-+ or a constant (field=field_item or field=const_item).
-+ If this is the case the function looks for a multiple equality
-+ in the lists referenced directly or indirectly by cond_equal inferring
-+ the given simple equality. If it doesn't find any, it builds a multiple
-+ equality that covers the predicate, i.e. the predicate can be inferred
-+ from this multiple equality.
-+ The built multiple equality could be obtained in such a way:
-+ create a binary multiple equality equivalent to the predicate, then
-+ merge it, if possible, with one of old multiple equalities.
-+ This guarantees that the set of multiple equalities covering equality
-+ predicates will be minimal.
-+
-+ EXAMPLE:
-+ For the where condition
-+ @code
-+ WHERE a=b AND b=c AND
-+ (b=2 OR f=e)
-+ @endcode
-+ the check_equality will be called for the following equality
-+ predicates a=b, b=c, b=2 and f=e.
-+ - For a=b it will be called with *cond_equal=(0,[]) and will transform
-+ *cond_equal into (0,[Item_equal(a,b)]).
-+ - For b=c it will be called with *cond_equal=(0,[Item_equal(a,b)])
-+ and will transform *cond_equal into CE=(0,[Item_equal(a,b,c)]).
-+ - For b=2 it will be called with *cond_equal=(ptr(CE),[])
-+ and will transform *cond_equal into (ptr(CE),[Item_equal(2,a,b,c)]).
-+ - For f=e it will be called with *cond_equal=(ptr(CE), [])
-+ and will transform *cond_equal into (ptr(CE),[Item_equal(f,e)]).
-+
-+ @note
-+ Now only fields that have the same type definitions (verified by
-+ the Field::eq_def method) are placed to the same multiple equalities.
-+ Because of this some equality predicates are not eliminated and
-+ can be used in the constant propagation procedure.
-+ We could weeken the equlity test as soon as at least one of the
-+ equal fields is to be equal to a constant. It would require a
-+ more complicated implementation: we would have to store, in
-+ general case, its own constant for each fields from the multiple
-+ equality. But at the same time it would allow us to get rid
-+ of constant propagation completely: it would be done by the call
-+ to build_equal_items_for_cond.
-+
-+
-+ The implementation does not follow exactly the above rules to
-+ build a new multiple equality for the equality predicate.
-+ If it processes the equality of the form field1=field2, it
-+ looks for multiple equalities me1 containig field1 and me2 containing
-+ field2. If only one of them is found the fuction expands it with
-+ the lacking field. If multiple equalities for both fields are
-+ found they are merged. If both searches fail a new multiple equality
-+ containing just field1 and field2 is added to the existing
-+ multiple equalities.
-+ If the function processes the predicate of the form field1=const,
-+ it looks for a multiple equality containing field1. If found, the
-+ function checks the constant of the multiple equality. If the value
-+ is unknown, it is setup to const. Otherwise the value is compared with
-+ const and the evaluation of the equality predicate is performed.
-+ When expanding/merging equality predicates from the upper levels
-+ the function first copies them for the current level. It looks
-+ acceptable, as this happens rarely. The implementation without
-+ copying would be much more complicated.
-+
-+ @param left_item left term of the quality to be checked
-+ @param right_item right term of the equality to be checked
-+ @param item equality item if the equality originates from a condition
-+ predicate, 0 if the equality is the result of row
-+ elimination
-+ @param cond_equal multiple equalities that must hold together with the
-+ equality
-+
-+ @retval
-+ TRUE if the predicate is a simple equality predicate to be used
-+ for building multiple equalities
-+ @retval
-+ FALSE otherwise
-+*/
-+
-+static bool check_simple_equality(Item *left_item, Item *right_item,
-+ Item *item, COND_EQUAL *cond_equal)
-+{
-+ if (left_item->type() == Item::REF_ITEM &&
-+ ((Item_ref*)left_item)->ref_type() == Item_ref::VIEW_REF)
-+ {
-+ if (((Item_ref*)left_item)->depended_from)
-+ return FALSE;
-+ left_item= left_item->real_item();
-+ }
-+ if (right_item->type() == Item::REF_ITEM &&
-+ ((Item_ref*)right_item)->ref_type() == Item_ref::VIEW_REF)
-+ {
-+ if (((Item_ref*)right_item)->depended_from)
-+ return FALSE;
-+ right_item= right_item->real_item();
-+ }
-+ if (left_item->type() == Item::FIELD_ITEM &&
-+ right_item->type() == Item::FIELD_ITEM &&
-+ !((Item_field*)left_item)->depended_from &&
-+ !((Item_field*)right_item)->depended_from)
-+ {
-+ /* The predicate the form field1=field2 is processed */
-+
-+ Field *left_field= ((Item_field*) left_item)->field;
-+ Field *right_field= ((Item_field*) right_item)->field;
-+
-+ if (!left_field->eq_def(right_field))
-+ return FALSE;
-+
-+ /* Search for multiple equalities containing field1 and/or field2 */
-+ bool left_copyfl, right_copyfl;
-+ Item_equal *left_item_equal=
-+ find_item_equal(cond_equal, left_field, &left_copyfl);
-+ Item_equal *right_item_equal=
-+ find_item_equal(cond_equal, right_field, &right_copyfl);
-+
-+ /* As (NULL=NULL) != TRUE we can't just remove the predicate f=f */
-+ if (left_field->eq(right_field)) /* f = f */
-+ return (!(left_field->maybe_null() && !left_item_equal));
-+
-+ if (left_item_equal && left_item_equal == right_item_equal)
-+ {
-+ /*
-+ The equality predicate is inference of one of the existing
-+ multiple equalities, i.e the condition is already covered
-+ by upper level equalities
-+ */
-+ return TRUE;
-+ }
-+
-+ /* Copy the found multiple equalities at the current level if needed */
-+ if (left_copyfl)
-+ {
-+ /* left_item_equal of an upper level contains left_item */
-+ left_item_equal= new Item_equal(left_item_equal);
-+ cond_equal->current_level.push_back(left_item_equal);
-+ }
-+ if (right_copyfl)
-+ {
-+ /* right_item_equal of an upper level contains right_item */
-+ right_item_equal= new Item_equal(right_item_equal);
-+ cond_equal->current_level.push_back(right_item_equal);
-+ }
-+
-+ if (left_item_equal)
-+ {
-+ /* left item was found in the current or one of the upper levels */
-+ if (! right_item_equal)
-+ left_item_equal->add((Item_field *) right_item);
-+ else
-+ {
-+ /* Merge two multiple equalities forming a new one */
-+ left_item_equal->merge(right_item_equal);
-+ /* Remove the merged multiple equality from the list */
-+ List_iterator<Item_equal> li(cond_equal->current_level);
-+ while ((li++) != right_item_equal) ;
-+ li.remove();
-+ }
-+ }
-+ else
-+ {
-+ /* left item was not found neither the current nor in upper levels */
-+ if (right_item_equal)
-+ right_item_equal->add((Item_field *) left_item);
-+ else
-+ {
-+ /* None of the fields was found in multiple equalities */
-+ Item_equal *item_equal= new Item_equal((Item_field *) left_item,
-+ (Item_field *) right_item);
-+ cond_equal->current_level.push_back(item_equal);
-+ }
-+ }
-+ return TRUE;
-+ }
-+
-+ {
-+ /* The predicate of the form field=const/const=field is processed */
-+ Item *const_item= 0;
-+ Item_field *field_item= 0;
-+ if (left_item->type() == Item::FIELD_ITEM &&
-+ !((Item_field*)left_item)->depended_from &&
-+ right_item->const_item())
-+ {
-+ field_item= (Item_field*) left_item;
-+ const_item= right_item;
-+ }
-+ else if (right_item->type() == Item::FIELD_ITEM &&
-+ !((Item_field*)right_item)->depended_from &&
-+ left_item->const_item())
-+ {
-+ field_item= (Item_field*) right_item;
-+ const_item= left_item;
-+ }
-+
-+ if (const_item &&
-+ field_item->result_type() == const_item->result_type())
-+ {
-+ bool copyfl;
-+
-+ if (field_item->result_type() == STRING_RESULT)
-+ {
-+ CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
-+ if (!item)
-+ {
-+ Item_func_eq *eq_item;
-+ if ((eq_item= new Item_func_eq(left_item, right_item)))
-+ return FALSE;
-+ eq_item->set_cmp_func();
-+ eq_item->quick_fix_field();
-+ item= eq_item;
-+ }
-+ if ((cs != ((Item_func *) item)->compare_collation()) ||
-+ !cs->coll->propagate(cs, 0, 0))
-+ return FALSE;
-+ }
-+
-+ Item_equal *item_equal = find_item_equal(cond_equal,
-+ field_item->field, ©fl);
-+ if (copyfl)
-+ {
-+ item_equal= new Item_equal(item_equal);
-+ cond_equal->current_level.push_back(item_equal);
-+ }
-+ if (item_equal)
-+ {
-+ /*
-+ The flag cond_false will be set to 1 after this, if item_equal
-+ already contains a constant and its value is not equal to
-+ the value of const_item.
-+ */
-+ item_equal->add(const_item, field_item);
-+ }
-+ else
-+ {
-+ item_equal= new Item_equal(const_item, field_item);
-+ cond_equal->current_level.push_back(item_equal);
-+ }
-+ return TRUE;
-+ }
-+ }
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Convert row equalities into a conjunction of regular equalities.
-+
-+ The function converts a row equality of the form (E1,...,En)=(E'1,...,E'n)
-+ into a list of equalities E1=E'1,...,En=E'n. For each of these equalities
-+ Ei=E'i the function checks whether it is a simple equality or a row
-+ equality. If it is a simple equality it is used to expand multiple
-+ equalities of cond_equal. If it is a row equality it converted to a
-+ sequence of equalities between row elements. If Ei=E'i is neither a
-+ simple equality nor a row equality the item for this predicate is added
-+ to eq_list.
-+
-+ @param thd thread handle
-+ @param left_row left term of the row equality to be processed
-+ @param right_row right term of the row equality to be processed
-+ @param cond_equal multiple equalities that must hold together with the
-+ predicate
-+ @param eq_list results of conversions of row equalities that are not
-+ simple enough to form multiple equalities
-+
-+ @retval
-+ TRUE if conversion has succeeded (no fatal error)
-+ @retval
-+ FALSE otherwise
-+*/
-+
-+static bool check_row_equality(THD *thd, Item *left_row, Item_row *right_row,
-+ COND_EQUAL *cond_equal, List<Item>* eq_list)
-+{
-+ uint n= left_row->cols();
-+ for (uint i= 0 ; i < n; i++)
-+ {
-+ bool is_converted;
-+ Item *left_item= left_row->element_index(i);
-+ Item *right_item= right_row->element_index(i);
-+ if (left_item->type() == Item::ROW_ITEM &&
-+ right_item->type() == Item::ROW_ITEM)
-+ {
-+ is_converted= check_row_equality(thd,
-+ (Item_row *) left_item,
-+ (Item_row *) right_item,
-+ cond_equal, eq_list);
-+ if (!is_converted)
-+ thd->lex->current_select->cond_count++;
-+ }
-+ else
-+ {
-+ is_converted= check_simple_equality(left_item, right_item, 0, cond_equal);
-+ thd->lex->current_select->cond_count++;
-+ }
-+
-+ if (!is_converted)
-+ {
-+ Item_func_eq *eq_item;
-+ if (!(eq_item= new Item_func_eq(left_item, right_item)))
-+ return FALSE;
-+ eq_item->set_cmp_func();
-+ eq_item->quick_fix_field();
-+ eq_list->push_back(eq_item);
-+ }
-+ }
-+ return TRUE;
-+}
-+
-+
-+/**
-+ Eliminate row equalities and form multiple equalities predicates.
-+
-+ This function checks whether the item is a simple equality
-+ i.e. the one that equates a field with another field or a constant
-+ (field=field_item or field=constant_item), or, a row equality.
-+ For a simple equality the function looks for a multiple equality
-+ in the lists referenced directly or indirectly by cond_equal inferring
-+ the given simple equality. If it doesn't find any, it builds/expands
-+ multiple equality that covers the predicate.
-+ Row equalities are eliminated substituted for conjunctive regular
-+ equalities which are treated in the same way as original equality
-+ predicates.
-+
-+ @param thd thread handle
-+ @param item predicate to process
-+ @param cond_equal multiple equalities that must hold together with the
-+ predicate
-+ @param eq_list results of conversions of row equalities that are not
-+ simple enough to form multiple equalities
-+
-+ @retval
-+ TRUE if re-writing rules have been applied
-+ @retval
-+ FALSE otherwise, i.e.
-+ if the predicate is not an equality,
-+ or, if the equality is neither a simple one nor a row equality,
-+ or, if the procedure fails by a fatal error.
-+*/
-+
-+static bool check_equality(THD *thd, Item *item, COND_EQUAL *cond_equal,
-+ List<Item> *eq_list)
-+{
-+ if (item->type() == Item::FUNC_ITEM &&
-+ ((Item_func*) item)->functype() == Item_func::EQ_FUNC)
-+ {
-+ Item *left_item= ((Item_func*) item)->arguments()[0];
-+ Item *right_item= ((Item_func*) item)->arguments()[1];
-+
-+ if (left_item->type() == Item::ROW_ITEM &&
-+ right_item->type() == Item::ROW_ITEM)
-+ {
-+ thd->lex->current_select->cond_count--;
-+ return check_row_equality(thd,
-+ (Item_row *) left_item,
-+ (Item_row *) right_item,
-+ cond_equal, eq_list);
-+ }
-+ else
-+ return check_simple_equality(left_item, right_item, item, cond_equal);
-+ }
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Replace all equality predicates in a condition by multiple equality items.
-+
-+ At each 'and' level the function detects items for equality predicates
-+ and replaced them by a set of multiple equality items of class Item_equal,
-+ taking into account inherited equalities from upper levels.
-+ If an equality predicate is used not in a conjunction it's just
-+ replaced by a multiple equality predicate.
-+ For each 'and' level the function set a pointer to the inherited
-+ multiple equalities in the cond_equal field of the associated
-+ object of the type Item_cond_and.
-+ The function also traverses the cond tree and and for each field reference
-+ sets a pointer to the multiple equality item containing the field, if there
-+ is any. If this multiple equality equates fields to a constant the
-+ function replaces the field reference by the constant in the cases
-+ when the field is not of a string type or when the field reference is
-+ just an argument of a comparison predicate.
-+ The function also determines the maximum number of members in
-+ equality lists of each Item_cond_and object assigning it to
-+ thd->lex->current_select->max_equal_elems.
-+
-+ @note
-+ Multiple equality predicate =(f1,..fn) is equivalent to the conjuction of
-+ f1=f2, .., fn-1=fn. It substitutes any inference from these
-+ equality predicates that is equivalent to the conjunction.
-+ Thus, =(a1,a2,a3) can substitute for ((a1=a3) AND (a2=a3) AND (a2=a1)) as
-+ it is equivalent to ((a1=a2) AND (a2=a3)).
-+ The function always makes a substitution of all equality predicates occured
-+ in a conjuction for a minimal set of multiple equality predicates.
-+ This set can be considered as a canonical representation of the
-+ sub-conjunction of the equality predicates.
-+ E.g. (t1.a=t2.b AND t2.b>5 AND t1.a=t3.c) is replaced by
-+ (=(t1.a,t2.b,t3.c) AND t2.b>5), not by
-+ (=(t1.a,t2.b) AND =(t1.a,t3.c) AND t2.b>5);
-+ while (t1.a=t2.b AND t2.b>5 AND t3.c=t4.d) is replaced by
-+ (=(t1.a,t2.b) AND =(t3.c=t4.d) AND t2.b>5),
-+ but if additionally =(t4.d,t2.b) is inherited, it
-+ will be replaced by (=(t1.a,t2.b,t3.c,t4.d) AND t2.b>5)
-+
-+ The function performs the substitution in a recursive descent by
-+ the condtion tree, passing to the next AND level a chain of multiple
-+ equality predicates which have been built at the upper levels.
-+ The Item_equal items built at the level are attached to other
-+ non-equality conjucts as a sublist. The pointer to the inherited
-+ multiple equalities is saved in the and condition object (Item_cond_and).
-+ This chain allows us for any field reference occurence easyly to find a
-+ multiple equality that must be held for this occurence.
-+ For each AND level we do the following:
-+ - scan it for all equality predicate (=) items
-+ - join them into disjoint Item_equal() groups
-+ - process the included OR conditions recursively to do the same for
-+ lower AND levels.
-+
-+ We need to do things in this order as lower AND levels need to know about
-+ all possible Item_equal objects in upper levels.
-+
-+ @param thd thread handle
-+ @param cond condition(expression) where to make replacement
-+ @param inherited path to all inherited multiple equality items
-+
-+ @return
-+ pointer to the transformed condition
-+*/
-+
-+static COND *build_equal_items_for_cond(THD *thd, COND *cond,
-+ COND_EQUAL *inherited)
-+{
-+ Item_equal *item_equal;
-+ COND_EQUAL cond_equal;
-+ cond_equal.upper_levels= inherited;
-+
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ List<Item> eq_list;
-+ bool and_level= ((Item_cond*) cond)->functype() ==
-+ Item_func::COND_AND_FUNC;
-+ List<Item> *args= ((Item_cond*) cond)->argument_list();
-+
-+ List_iterator<Item> li(*args);
-+ Item *item;
-+
-+ if (and_level)
-+ {
-+ /*
-+ Retrieve all conjuncts of this level detecting the equality
-+ that are subject to substitution by multiple equality items and
-+ removing each such predicate from the conjunction after having
-+ found/created a multiple equality whose inference the predicate is.
-+ */
-+ while ((item= li++))
-+ {
-+ /*
-+ PS/SP note: we can safely remove a node from AND-OR
-+ structure here because it's restored before each
-+ re-execution of any prepared statement/stored procedure.
-+ */
-+ if (check_equality(thd, item, &cond_equal, &eq_list))
-+ li.remove();
-+ }
-+
-+ /*
-+ Check if we eliminated all the predicates of the level, e.g.
-+ (a=a AND b=b AND a=a).
-+ */
-+ if (!args->elements &&
-+ !cond_equal.current_level.elements &&
-+ !eq_list.elements)
-+ return new Item_int((longlong) 1, 1);
-+
-+ List_iterator_fast<Item_equal> it(cond_equal.current_level);
-+ while ((item_equal= it++))
-+ {
-+ item_equal->fix_length_and_dec();
-+ item_equal->update_used_tables();
-+ set_if_bigger(thd->lex->current_select->max_equal_elems,
-+ item_equal->members());
-+ }
-+
-+ ((Item_cond_and*)cond)->cond_equal= cond_equal;
-+ inherited= &(((Item_cond_and*)cond)->cond_equal);
-+ }
-+ /*
-+ Make replacement of equality predicates for lower levels
-+ of the condition expression.
-+ */
-+ li.rewind();
-+ while ((item= li++))
-+ {
-+ Item *new_item;
-+ if ((new_item= build_equal_items_for_cond(thd, item, inherited)) != item)
-+ {
-+ /* This replacement happens only for standalone equalities */
-+ /*
-+ This is ok with PS/SP as the replacement is done for
-+ arguments of an AND/OR item, which are restored for each
-+ execution of PS/SP.
-+ */
-+ li.replace(new_item);
-+ }
-+ }
-+ if (and_level)
-+ {
-+ args->concat(&eq_list);
-+ args->concat((List<Item> *)&cond_equal.current_level);
-+ }
-+ }
-+ else if (cond->type() == Item::FUNC_ITEM)
-+ {
-+ List<Item> eq_list;
-+ /*
-+ If an equality predicate forms the whole and level,
-+ we call it standalone equality and it's processed here.
-+ E.g. in the following where condition
-+ WHERE a=5 AND (b=5 or a=c)
-+ (b=5) and (a=c) are standalone equalities.
-+ In general we can't leave alone standalone eqalities:
-+ for WHERE a=b AND c=d AND (b=c OR d=5)
-+ b=c is replaced by =(a,b,c,d).
-+ */
-+ if (check_equality(thd, cond, &cond_equal, &eq_list))
-+ {
-+ int n= cond_equal.current_level.elements + eq_list.elements;
-+ if (n == 0)
-+ return new Item_int((longlong) 1,1);
-+ else if (n == 1)
-+ {
-+ if ((item_equal= cond_equal.current_level.pop()))
-+ {
-+ item_equal->fix_length_and_dec();
-+ item_equal->update_used_tables();
-+ set_if_bigger(thd->lex->current_select->max_equal_elems,
-+ item_equal->members());
-+ return item_equal;
-+ }
-+
-+ return eq_list.pop();
-+ }
-+ else
-+ {
-+ /*
-+ Here a new AND level must be created. It can happen only
-+ when a row equality is processed as a standalone predicate.
-+ */
-+ Item_cond_and *and_cond= new Item_cond_and(eq_list);
-+ and_cond->quick_fix_field();
-+ List<Item> *args= and_cond->argument_list();
-+ List_iterator_fast<Item_equal> it(cond_equal.current_level);
-+ while ((item_equal= it++))
-+ {
-+ item_equal->fix_length_and_dec();
-+ item_equal->update_used_tables();
-+ set_if_bigger(thd->lex->current_select->max_equal_elems,
-+ item_equal->members());
-+ }
-+ and_cond->cond_equal= cond_equal;
-+ args->concat((List<Item> *)&cond_equal.current_level);
-+
-+ return and_cond;
-+ }
-+ }
-+ /*
-+ For each field reference in cond, not from equal item predicates,
-+ set a pointer to the multiple equality it belongs to (if there is any)
-+ as soon the field is not of a string type or the field reference is
-+ an argument of a comparison predicate.
-+ */
-+ uchar *is_subst_valid= (uchar *) 1;
-+ cond= cond->compile(&Item::subst_argument_checker,
-+ &is_subst_valid,
-+ &Item::equal_fields_propagator,
-+ (uchar *) inherited);
-+ cond->update_used_tables();
-+ }
-+ return cond;
-+}
-+
-+
-+/**
-+ Build multiple equalities for a condition and all on expressions that
-+ inherit these multiple equalities.
-+
-+ The function first applies the build_equal_items_for_cond function
-+ to build all multiple equalities for condition cond utilizing equalities
-+ referred through the parameter inherited. The extended set of
-+ equalities is returned in the structure referred by the cond_equal_ref
-+ parameter. After this the function calls itself recursively for
-+ all on expressions whose direct references can be found in join_list
-+ and who inherit directly the multiple equalities just having built.
-+
-+ @note
-+ The on expression used in an outer join operation inherits all equalities
-+ from the on expression of the embedding join, if there is any, or
-+ otherwise - from the where condition.
-+ This fact is not obvious, but presumably can be proved.
-+ Consider the following query:
-+ @code
-+ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t2.a=t4.a
-+ WHERE t1.a=t2.a;
-+ @endcode
-+ If the on expression in the query inherits =(t1.a,t2.a), then we
-+ can build the multiple equality =(t1.a,t2.a,t3.a,t4.a) that infers
-+ the equality t3.a=t4.a. Although the on expression
-+ t1.a=t3.a AND t2.a=t4.a AND t3.a=t4.a is not equivalent to the one
-+ in the query the latter can be replaced by the former: the new query
-+ will return the same result set as the original one.
-+
-+ Interesting that multiple equality =(t1.a,t2.a,t3.a,t4.a) allows us
-+ to use t1.a=t3.a AND t3.a=t4.a under the on condition:
-+ @code
-+ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a
-+ WHERE t1.a=t2.a
-+ @endcode
-+ This query equivalent to:
-+ @code
-+ SELECT * FROM (t1 LEFT JOIN (t3,t4) ON t1.a=t3.a AND t3.a=t4.a),t2
-+ WHERE t1.a=t2.a
-+ @endcode
-+ Similarly the original query can be rewritten to the query:
-+ @code
-+ SELECT * FROM (t1,t2) LEFT JOIN (t3,t4) ON t2.a=t4.a AND t3.a=t4.a
-+ WHERE t1.a=t2.a
-+ @endcode
-+ that is equivalent to:
-+ @code
-+ SELECT * FROM (t2 LEFT JOIN (t3,t4)ON t2.a=t4.a AND t3.a=t4.a), t1
-+ WHERE t1.a=t2.a
-+ @endcode
-+ Thus, applying equalities from the where condition we basically
-+ can get more freedom in performing join operations.
-+ Althogh we don't use this property now, it probably makes sense to use
-+ it in the future.
-+ @param thd Thread handler
-+ @param cond condition to build the multiple equalities for
-+ @param inherited path to all inherited multiple equality items
-+ @param join_list list of join tables to which the condition
-+ refers to
-+ @param[out] cond_equal_ref pointer to the structure to place built
-+ equalities in
-+
-+ @return
-+ pointer to the transformed condition containing multiple equalities
-+*/
-+
-+static COND *build_equal_items(THD *thd, COND *cond,
-+ COND_EQUAL *inherited,
-+ List<TABLE_LIST> *join_list,
-+ COND_EQUAL **cond_equal_ref)
-+{
-+ COND_EQUAL *cond_equal= 0;
-+
-+ if (cond)
-+ {
-+ cond= build_equal_items_for_cond(thd, cond, inherited);
-+ cond->update_used_tables();
-+ if (cond->type() == Item::COND_ITEM &&
-+ ((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ cond_equal= &((Item_cond_and*) cond)->cond_equal;
-+ else if (cond->type() == Item::FUNC_ITEM &&
-+ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
-+ {
-+ cond_equal= new COND_EQUAL;
-+ cond_equal->current_level.push_back((Item_equal *) cond);
-+ }
-+ }
-+ if (cond_equal)
-+ {
-+ cond_equal->upper_levels= inherited;
-+ inherited= cond_equal;
-+ }
-+ *cond_equal_ref= cond_equal;
-+
-+ if (join_list)
-+ {
-+ TABLE_LIST *table;
-+ List_iterator<TABLE_LIST> li(*join_list);
-+
-+ while ((table= li++))
-+ {
-+ if (table->on_expr)
-+ {
-+ List<TABLE_LIST> *nested_join_list= table->nested_join ?
-+ &table->nested_join->join_list : NULL;
-+ /*
-+ We can modify table->on_expr because its old value will
-+ be restored before re-execution of PS/SP.
-+ */
-+ table->on_expr= build_equal_items(thd, table->on_expr, inherited,
-+ nested_join_list,
-+ &table->cond_equal);
-+ }
-+ }
-+ }
-+
-+ return cond;
-+}
-+
-+
-+/**
-+ Compare field items by table order in the execution plan.
-+
-+ field1 considered as better than field2 if the table containing
-+ field1 is accessed earlier than the table containing field2.
-+ The function finds out what of two fields is better according
-+ this criteria.
-+
-+ @param field1 first field item to compare
-+ @param field2 second field item to compare
-+ @param table_join_idx index to tables determining table order
-+
-+ @retval
-+ 1 if field1 is better than field2
-+ @retval
-+ -1 if field2 is better than field1
-+ @retval
-+ 0 otherwise
-+*/
-+
-+static int compare_fields_by_table_order(Item_field *field1,
-+ Item_field *field2,
-+ void *table_join_idx)
-+{
-+ int cmp= 0;
-+ bool outer_ref= 0;
-+ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
-+ {
-+ outer_ref= 1;
-+ cmp= -1;
-+ }
-+ if (field2->used_tables() & OUTER_REF_TABLE_BIT)
-+ {
-+ outer_ref= 1;
-+ cmp++;
-+ }
-+ if (outer_ref)
-+ return cmp;
-+ JOIN_TAB **idx= (JOIN_TAB **) table_join_idx;
-+ cmp= idx[field2->field->table->tablenr]-idx[field1->field->table->tablenr];
-+ return cmp < 0 ? -1 : (cmp ? 1 : 0);
-+}
-+
-+
-+/**
-+ Generate minimal set of simple equalities equivalent to a multiple equality.
-+
-+ The function retrieves the fields of the multiple equality item
-+ item_equal and for each field f:
-+ - if item_equal contains const it generates the equality f=const_item;
-+ - otherwise, if f is not the first field, generates the equality
-+ f=item_equal->get_first().
-+ All generated equality are added to the cond conjunction.
-+
-+ @param cond condition to add the generated equality to
-+ @param upper_levels structure to access multiple equality of upper levels
-+ @param item_equal multiple equality to generate simple equality from
-+
-+ @note
-+ Before generating an equality function checks that it has not
-+ been generated for multiple equalities of the upper levels.
-+ E.g. for the following where condition
-+ WHERE a=5 AND ((a=b AND b=c) OR c>4)
-+ the upper level AND condition will contain =(5,a),
-+ while the lower level AND condition will contain =(5,a,b,c).
-+ When splitting =(5,a,b,c) into a separate equality predicates
-+ we should omit 5=a, as we have it already in the upper level.
-+ The following where condition gives us a more complicated case:
-+ WHERE t1.a=t2.b AND t3.c=t4.d AND (t2.b=t3.c OR t4.e>5 ...) AND ...
-+ Given the tables are accessed in the order t1->t2->t3->t4 for
-+ the selected query execution plan the lower level multiple
-+ equality =(t1.a,t2.b,t3.c,t4.d) formally should be converted to
-+ t1.a=t2.b AND t1.a=t3.c AND t1.a=t4.d. But t1.a=t2.a will be
-+ generated for the upper level. Also t3.c=t4.d will be generated there.
-+ So only t1.a=t3.c should be left in the lower level.
-+ If cond is equal to 0, then not more then one equality is generated
-+ and a pointer to it is returned as the result of the function.
-+
-+ @return
-+ - The condition with generated simple equalities or
-+ a pointer to the simple generated equality, if success.
-+ - 0, otherwise.
-+*/
-+
-+static Item *eliminate_item_equal(COND *cond, COND_EQUAL *upper_levels,
-+ Item_equal *item_equal)
-+{
-+ List<Item> eq_list;
-+ Item_func_eq *eq_item= 0;
-+ if (((Item *) item_equal)->const_item() && !item_equal->val_int())
-+ return new Item_int((longlong) 0,1);
-+ Item *item_const= item_equal->get_const();
-+ Item_equal_iterator it(*item_equal);
-+ Item *head;
-+ if (item_const)
-+ head= item_const;
-+ else
-+ {
-+ head= item_equal->get_first();
-+ it++;
-+ }
-+ Item_field *item_field;
-+ while ((item_field= it++))
-+ {
-+ Item_equal *upper= item_field->find_item_equal(upper_levels);
-+ Item_field *item= item_field;
-+ if (upper)
-+ {
-+ if (item_const && upper->get_const())
-+ item= 0;
-+ else
-+ {
-+ Item_equal_iterator li(*item_equal);
-+ while ((item= li++) != item_field)
-+ {
-+ if (item->find_item_equal(upper_levels) == upper)
-+ break;
-+ }
-+ }
-+ }
-+ if (item == item_field)
-+ {
-+ if (eq_item)
-+ eq_list.push_back(eq_item);
-+ eq_item= new Item_func_eq(item_field, head);
-+ if (!eq_item)
-+ return 0;
-+ eq_item->set_cmp_func();
-+ eq_item->quick_fix_field();
-+ }
-+ }
-+
-+ if (!cond && !eq_list.head())
-+ {
-+ if (!eq_item)
-+ return new Item_int((longlong) 1,1);
-+ return eq_item;
-+ }
-+
-+ if (eq_item)
-+ eq_list.push_back(eq_item);
-+ if (!cond)
-+ cond= new Item_cond_and(eq_list);
-+ else
-+ {
-+ DBUG_ASSERT(cond->type() == Item::COND_ITEM);
-+ if (eq_list.elements)
-+ ((Item_cond *) cond)->add_at_head(&eq_list);
-+ }
-+
-+ cond->quick_fix_field();
-+ cond->update_used_tables();
-+
-+ return cond;
-+}
-+
-+
-+/**
-+ Substitute every field reference in a condition by the best equal field
-+ and eliminate all multiple equality predicates.
-+
-+ The function retrieves the cond condition and for each encountered
-+ multiple equality predicate it sorts the field references in it
-+ according to the order of tables specified by the table_join_idx
-+ parameter. Then it eliminates the multiple equality predicate it
-+ replacing it by the conjunction of simple equality predicates
-+ equating every field from the multiple equality to the first
-+ field in it, or to the constant, if there is any.
-+ After this the function retrieves all other conjuncted
-+ predicates substitute every field reference by the field reference
-+ to the first equal field or equal constant if there are any.
-+ @param cond condition to process
-+ @param cond_equal multiple equalities to take into consideration
-+ @param table_join_idx index to tables determining field preference
-+
-+ @note
-+ At the first glance full sort of fields in multiple equality
-+ seems to be an overkill. Yet it's not the case due to possible
-+ new fields in multiple equality item of lower levels. We want
-+ the order in them to comply with the order of upper levels.
-+
-+ @return
-+ The transformed condition
-+*/
-+
-+static COND* substitute_for_best_equal_field(COND *cond,
-+ COND_EQUAL *cond_equal,
-+ void *table_join_idx)
-+{
-+ Item_equal *item_equal;
-+
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
-+
-+ bool and_level= ((Item_cond*) cond)->functype() ==
-+ Item_func::COND_AND_FUNC;
-+ if (and_level)
-+ {
-+ cond_equal= &((Item_cond_and *) cond)->cond_equal;
-+ cond_list->disjoin((List<Item> *) &cond_equal->current_level);
-+
-+ List_iterator_fast<Item_equal> it(cond_equal->current_level);
-+ while ((item_equal= it++))
-+ {
-+ item_equal->sort(&compare_fields_by_table_order, table_join_idx);
-+ }
-+ }
-+
-+ List_iterator<Item> li(*cond_list);
-+ Item *item;
-+ while ((item= li++))
-+ {
-+ Item *new_item =substitute_for_best_equal_field(item, cond_equal,
-+ table_join_idx);
-+ /*
-+ This works OK with PS/SP re-execution as changes are made to
-+ the arguments of AND/OR items only
-+ */
-+ if (new_item != item)
-+ li.replace(new_item);
-+ }
-+
-+ if (and_level)
-+ {
-+ List_iterator_fast<Item_equal> it(cond_equal->current_level);
-+ while ((item_equal= it++))
-+ {
-+ cond= eliminate_item_equal(cond, cond_equal->upper_levels, item_equal);
-+ // This occurs when eliminate_item_equal() founds that cond is
-+ // always false and substitutes it with Item_int 0.
-+ // Due to this, value of item_equal will be 0, so just return it.
-+ if (cond->type() != Item::COND_ITEM)
-+ break;
-+ }
-+ }
-+ if (cond->type() == Item::COND_ITEM &&
-+ !((Item_cond*)cond)->argument_list()->elements)
-+ cond= new Item_int((int32)cond->val_bool());
-+
-+ }
-+ else if (cond->type() == Item::FUNC_ITEM &&
-+ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
-+ {
-+ item_equal= (Item_equal *) cond;
-+ item_equal->sort(&compare_fields_by_table_order, table_join_idx);
-+ if (cond_equal && cond_equal->current_level.head() == item_equal)
-+ cond_equal= 0;
-+ return eliminate_item_equal(0, cond_equal, item_equal);
-+ }
-+ else
-+ cond->transform(&Item::replace_equal_field, 0);
-+ return cond;
-+}
-+
-+
-+/**
-+ Check appearance of new constant items in multiple equalities
-+ of a condition after reading a constant table.
-+
-+ The function retrieves the cond condition and for each encountered
-+ multiple equality checks whether new constants have appeared after
-+ reading the constant (single row) table tab. If so it adjusts
-+ the multiple equality appropriately.
-+
-+ @param cond condition whose multiple equalities are to be checked
-+ @param table constant table that has been read
-+*/
-+
-+static void update_const_equal_items(COND *cond, JOIN_TAB *tab)
-+{
-+ if (!(cond->used_tables() & tab->table->map))
-+ return;
-+
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ List<Item> *cond_list= ((Item_cond*) cond)->argument_list();
-+ List_iterator_fast<Item> li(*cond_list);
-+ Item *item;
-+ while ((item= li++))
-+ update_const_equal_items(item, tab);
-+ }
-+ else if (cond->type() == Item::FUNC_ITEM &&
-+ ((Item_cond*) cond)->functype() == Item_func::MULT_EQUAL_FUNC)
-+ {
-+ Item_equal *item_equal= (Item_equal *) cond;
-+ bool contained_const= item_equal->get_const() != NULL;
-+ item_equal->update_const();
-+ if (!contained_const && item_equal->get_const())
-+ {
-+ /* Update keys for range analysis */
-+ Item_equal_iterator it(*item_equal);
-+ Item_field *item_field;
-+ while ((item_field= it++))
-+ {
-+ Field *field= item_field->field;
-+ JOIN_TAB *stat= field->table->reginfo.join_tab;
-+ key_map possible_keys= field->key_start;
-+ possible_keys.intersect(field->table->keys_in_use_for_query);
-+ stat[0].const_keys.merge(possible_keys);
-+
-+ /*
-+ For each field in the multiple equality (for which we know that it
-+ is a constant) we have to find its corresponding key part, and set
-+ that key part in const_key_parts.
-+ */
-+ if (!possible_keys.is_clear_all())
-+ {
-+ TABLE *tab= field->table;
-+ KEYUSE *use;
-+ for (use= stat->keyuse; use && use->table == tab; use++)
-+ if (possible_keys.is_set(use->key) &&
-+ tab->key_info[use->key].key_part[use->keypart].field ==
-+ field)
-+ tab->const_key_parts[use->key]|= use->keypart_map;
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+
-+/*
-+ change field = field to field = const for each found field = const in the
-+ and_level
-+*/
-+
-+static void
-+change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
-+ Item *and_father, Item *cond,
-+ Item *field, Item *value)
-+{
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ bool and_level= ((Item_cond*) cond)->functype() ==
-+ Item_func::COND_AND_FUNC;
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ change_cond_ref_to_const(thd, save_list,and_level ? cond : item, item,
-+ field, value);
-+ return;
-+ }
-+ if (cond->eq_cmp_result() == Item::COND_OK)
-+ return; // Not a boolean function
-+
-+ Item_bool_func2 *func= (Item_bool_func2*) cond;
-+ Item **args= func->arguments();
-+ Item *left_item= args[0];
-+ Item *right_item= args[1];
-+ Item_func::Functype functype= func->functype();
-+
-+ if (right_item->eq(field,0) && left_item != value &&
-+ right_item->cmp_context == field->cmp_context &&
-+ (left_item->result_type() != STRING_RESULT ||
-+ value->result_type() != STRING_RESULT ||
-+ left_item->collation.collation == value->collation.collation))
-+ {
-+ Item *tmp=value->clone_item();
-+ tmp->collation.set(right_item->collation);
-+
-+ if (tmp)
-+ {
-+ thd->change_item_tree(args + 1, tmp);
-+ func->update_used_tables();
-+ if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
-+ && and_father != cond && !left_item->const_item())
-+ {
-+ cond->marker=1;
-+ COND_CMP *tmp2;
-+ if ((tmp2=new COND_CMP(and_father,func)))
-+ save_list->push_back(tmp2);
-+ }
-+ func->set_cmp_func();
-+ }
-+ }
-+ else if (left_item->eq(field,0) && right_item != value &&
-+ left_item->cmp_context == field->cmp_context &&
-+ (right_item->result_type() != STRING_RESULT ||
-+ value->result_type() != STRING_RESULT ||
-+ right_item->collation.collation == value->collation.collation))
-+ {
-+ Item *tmp= value->clone_item();
-+ tmp->collation.set(left_item->collation);
-+
-+ if (tmp)
-+ {
-+ thd->change_item_tree(args, tmp);
-+ value= tmp;
-+ func->update_used_tables();
-+ if ((functype == Item_func::EQ_FUNC || functype == Item_func::EQUAL_FUNC)
-+ && and_father != cond && !right_item->const_item())
-+ {
-+ args[0]= args[1]; // For easy check
-+ thd->change_item_tree(args + 1, value);
-+ cond->marker=1;
-+ COND_CMP *tmp2;
-+ if ((tmp2=new COND_CMP(and_father,func)))
-+ save_list->push_back(tmp2);
-+ }
-+ func->set_cmp_func();
-+ }
-+ }
-+}
-+
-+/**
-+ Remove additional condition inserted by IN/ALL/ANY transformation.
-+
-+ @param conds condition for processing
-+
-+ @return
-+ new conditions
-+*/
-+
-+static Item *remove_additional_cond(Item* conds)
-+{
-+ if (conds->name == in_additional_cond)
-+ return 0;
-+ if (conds->type() == Item::COND_ITEM)
-+ {
-+ Item_cond *cnd= (Item_cond*) conds;
-+ List_iterator<Item> li(*(cnd->argument_list()));
-+ Item *item;
-+ while ((item= li++))
-+ {
-+ if (item->name == in_additional_cond)
-+ {
-+ li.remove();
-+ if (cnd->argument_list()->elements == 1)
-+ return cnd->argument_list()->head();
-+ return conds;
-+ }
-+ }
-+ }
-+ return conds;
-+}
-+
-+static void
-+propagate_cond_constants(THD *thd, I_List<COND_CMP> *save_list,
-+ COND *and_father, COND *cond)
-+{
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ bool and_level= ((Item_cond*) cond)->functype() ==
-+ Item_func::COND_AND_FUNC;
-+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ I_List<COND_CMP> save;
-+ while ((item=li++))
-+ {
-+ propagate_cond_constants(thd, &save,and_level ? cond : item, item);
-+ }
-+ if (and_level)
-+ { // Handle other found items
-+ I_List_iterator<COND_CMP> cond_itr(save);
-+ COND_CMP *cond_cmp;
-+ while ((cond_cmp=cond_itr++))
-+ {
-+ Item **args= cond_cmp->cmp_func->arguments();
-+ if (!args[0]->const_item())
-+ change_cond_ref_to_const(thd, &save,cond_cmp->and_level,
-+ cond_cmp->and_level, args[0], args[1]);
-+ }
-+ }
-+ }
-+ else if (and_father != cond && !cond->marker) // In a AND group
-+ {
-+ if (cond->type() == Item::FUNC_ITEM &&
-+ (((Item_func*) cond)->functype() == Item_func::EQ_FUNC ||
-+ ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC))
-+ {
-+ Item_func_eq *func=(Item_func_eq*) cond;
-+ Item **args= func->arguments();
-+ bool left_const= args[0]->const_item();
-+ bool right_const= args[1]->const_item();
-+ if (!(left_const && right_const) &&
-+ args[0]->result_type() == args[1]->result_type())
-+ {
-+ if (right_const)
-+ {
-+ resolve_const_item(thd, &args[1], args[0]);
-+ func->update_used_tables();
-+ change_cond_ref_to_const(thd, save_list, and_father, and_father,
-+ args[0], args[1]);
-+ }
-+ else if (left_const)
-+ {
-+ resolve_const_item(thd, &args[0], args[1]);
-+ func->update_used_tables();
-+ change_cond_ref_to_const(thd, save_list, and_father, and_father,
-+ args[1], args[0]);
-+ }
-+ }
-+ }
-+ }
-+}
-+
-+
-+/**
-+ Simplify joins replacing outer joins by inner joins whenever it's
-+ possible.
-+
-+ The function, during a retrieval of join_list, eliminates those
-+ outer joins that can be converted into inner join, possibly nested.
-+ It also moves the on expressions for the converted outer joins
-+ and from inner joins to conds.
-+ The function also calculates some attributes for nested joins:
-+ - used_tables
-+ - not_null_tables
-+ - dep_tables.
-+ - on_expr_dep_tables
-+ The first two attributes are used to test whether an outer join can
-+ be substituted for an inner join. The third attribute represents the
-+ relation 'to be dependent on' for tables. If table t2 is dependent
-+ on table t1, then in any evaluated execution plan table access to
-+ table t2 must precede access to table t2. This relation is used also
-+ to check whether the query contains invalid cross-references.
-+ The forth attribute is an auxiliary one and is used to calculate
-+ dep_tables.
-+ As the attribute dep_tables qualifies possibles orders of tables in the
-+ execution plan, the dependencies required by the straight join
-+ modifiers are reflected in this attribute as well.
-+ The function also removes all braces that can be removed from the join
-+ expression without changing its meaning.
-+
-+ @note
-+ An outer join can be replaced by an inner join if the where condition
-+ or the on expression for an embedding nested join contains a conjunctive
-+ predicate rejecting null values for some attribute of the inner tables.
-+
-+ E.g. in the query:
-+ @code
-+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
-+ @endcode
-+ the predicate t2.b < 5 rejects nulls.
-+ The query is converted first to:
-+ @code
-+ SELECT * FROM t1 INNER JOIN t2 ON t2.a=t1.a WHERE t2.b < 5
-+ @endcode
-+ then to the equivalent form:
-+ @code
-+ SELECT * FROM t1, t2 ON t2.a=t1.a WHERE t2.b < 5 AND t2.a=t1.a
-+ @endcode
-+
-+
-+ Similarly the following query:
-+ @code
-+ SELECT * from t1 LEFT JOIN (t2, t3) ON t2.a=t1.a t3.b=t1.b
-+ WHERE t2.c < 5
-+ @endcode
-+ is converted to:
-+ @code
-+ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a t3.b=t1.b
-+
-+ @endcode
-+
-+ One conversion might trigger another:
-+ @code
-+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a
-+ LEFT JOIN t3 ON t3.b=t2.b
-+ WHERE t3 IS NOT NULL =>
-+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t1.a, t3
-+ WHERE t3 IS NOT NULL AND t3.b=t2.b =>
-+ SELECT * FROM t1, t2, t3
-+ WHERE t3 IS NOT NULL AND t3.b=t2.b AND t2.a=t1.a
-+ @endcode
-+
-+ The function removes all unnecessary braces from the expression
-+ produced by the conversions.
-+ E.g.
-+ @code
-+ SELECT * FROM t1, (t2, t3) WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
-+ @endcode
-+ finally is converted to:
-+ @code
-+ SELECT * FROM t1, t2, t3 WHERE t2.c < 5 AND t2.a=t1.a AND t3.b=t1.b
-+
-+ @endcode
-+
-+
-+ It also will remove braces from the following queries:
-+ @code
-+ SELECT * from (t1 LEFT JOIN t2 ON t2.a=t1.a) LEFT JOIN t3 ON t3.b=t2.b
-+ SELECT * from (t1, (t2,t3)) WHERE t1.a=t2.a AND t2.b=t3.b.
-+ @endcode
-+
-+ The benefit of this simplification procedure is that it might return
-+ a query for which the optimizer can evaluate execution plan with more
-+ join orders. With a left join operation the optimizer does not
-+ consider any plan where one of the inner tables is before some of outer
-+ tables.
-+
-+
-+ The function is implemented by a recursive procedure. On the recursive
-+ ascent all attributes are calculated, all outer joins that can be
-+ converted are replaced and then all unnecessary braces are removed.
-+ As join list contains join tables in the reverse order sequential
-+ elimination of outer joins does not require extra recursive calls.
-+
-+ Here is an example of a join query with invalid cross references:
-+ @code
-+ SELECT * FROM t1 LEFT JOIN t2 ON t2.a=t3.a LEFT JOIN t3 ON t3.b=t1.b
-+ @endcode
-+
-+ @param join reference to the query info
-+ @param join_list list representation of the join to be converted
-+ @param conds conditions to add on expressions for converted joins
-+ @param top true <=> conds is the where condition
-+
-+ @return
-+ - The new condition, if success
-+ - 0, otherwise
-+*/
-+
-+static COND *
-+simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
-+{
-+ TABLE_LIST *table;
-+ NESTED_JOIN *nested_join;
-+ TABLE_LIST *prev_table= 0;
-+ List_iterator<TABLE_LIST> li(*join_list);
-+ bool straight_join= test(join->select_options & SELECT_STRAIGHT_JOIN);
-+ DBUG_ENTER("simplify_joins");
-+
-+ /*
-+ Try to simplify join operations from join_list.
-+ The most outer join operation is checked for conversion first.
-+ */
-+ while ((table= li++))
-+ {
-+ table_map used_tables;
-+ table_map not_null_tables= (table_map) 0;
-+
-+ if ((nested_join= table->nested_join))
-+ {
-+ /*
-+ If the element of join_list is a nested join apply
-+ the procedure to its nested join list first.
-+ */
-+ if (table->on_expr)
-+ {
-+ Item *expr= table->on_expr;
-+ /*
-+ If an on expression E is attached to the table,
-+ check all null rejected predicates in this expression.
-+ If such a predicate over an attribute belonging to
-+ an inner table of an embedded outer join is found,
-+ the outer join is converted to an inner join and
-+ the corresponding on expression is added to E.
-+ */
-+ expr= simplify_joins(join, &nested_join->join_list,
-+ expr, FALSE);
-+
-+ if (!table->prep_on_expr || expr != table->on_expr)
-+ {
-+ DBUG_ASSERT(expr);
-+
-+ table->on_expr= expr;
-+ table->prep_on_expr= expr->copy_andor_structure(join->thd);
-+ }
-+ }
-+ nested_join->used_tables= (table_map) 0;
-+ nested_join->not_null_tables=(table_map) 0;
-+ conds= simplify_joins(join, &nested_join->join_list, conds, top);
-+ used_tables= nested_join->used_tables;
-+ not_null_tables= nested_join->not_null_tables;
-+ }
-+ else
-+ {
-+ if (!table->prep_on_expr)
-+ table->prep_on_expr= table->on_expr;
-+ used_tables= table->table->map;
-+ if (conds)
-+ not_null_tables= conds->not_null_tables();
-+ }
-+
-+ if (table->embedding)
-+ {
-+ table->embedding->nested_join->used_tables|= used_tables;
-+ table->embedding->nested_join->not_null_tables|= not_null_tables;
-+ }
-+
-+ if (!table->outer_join || (used_tables & not_null_tables))
-+ {
-+ /*
-+ For some of the inner tables there are conjunctive predicates
-+ that reject nulls => the outer join can be replaced by an inner join.
-+ */
-+ table->outer_join= 0;
-+ if (table->on_expr)
-+ {
-+ /* Add on expression to the where condition. */
-+ if (conds)
-+ {
-+ conds= and_conds(conds, table->on_expr);
-+ conds->top_level_item();
-+ /* conds is always a new item as both cond and on_expr existed */
-+ DBUG_ASSERT(!conds->fixed);
-+ conds->fix_fields(join->thd, &conds);
-+ }
-+ else
-+ conds= table->on_expr;
-+ table->prep_on_expr= table->on_expr= 0;
-+ }
-+ }
-+
-+ if (!top)
-+ continue;
-+
-+ /*
-+ Only inner tables of non-convertible outer joins
-+ remain with on_expr.
-+ */
-+ if (table->on_expr)
-+ {
-+ table->dep_tables|= table->on_expr->used_tables();
-+ if (table->embedding)
-+ {
-+ table->dep_tables&= ~table->embedding->nested_join->used_tables;
-+ /*
-+ Embedding table depends on tables used
-+ in embedded on expressions.
-+ */
-+ table->embedding->on_expr_dep_tables|= table->on_expr->used_tables();
-+ }
-+ else
-+ table->dep_tables&= ~table->table->map;
-+ }
-+
-+ if (prev_table)
-+ {
-+ /* The order of tables is reverse: prev_table follows table */
-+ if (prev_table->straight || straight_join)
-+ prev_table->dep_tables|= used_tables;
-+ if (prev_table->on_expr)
-+ {
-+ prev_table->dep_tables|= table->on_expr_dep_tables;
-+ table_map prev_used_tables= prev_table->nested_join ?
-+ prev_table->nested_join->used_tables :
-+ prev_table->table->map;
-+ /*
-+ If on expression contains only references to inner tables
-+ we still make the inner tables dependent on the outer tables.
-+ It would be enough to set dependency only on one outer table
-+ for them. Yet this is really a rare case.
-+ Note:
-+ RAND_TABLE_BIT mask should not be counted as it
-+ prevents update of inner table dependences.
-+ For example it might happen if RAND() function
-+ is used in JOIN ON clause.
-+ */
-+ if (!((prev_table->on_expr->used_tables() & ~RAND_TABLE_BIT) &
-+ ~prev_used_tables))
-+ prev_table->dep_tables|= used_tables;
-+ }
-+ }
-+ prev_table= table;
-+ }
-+
-+ /* Flatten nested joins that can be flattened. */
-+ TABLE_LIST *right_neighbor= NULL;
-+ li.rewind();
-+ while ((table= li++))
-+ {
-+ bool fix_name_res= FALSE;
-+ nested_join= table->nested_join;
-+ if (nested_join && !table->on_expr)
-+ {
-+ TABLE_LIST *tbl;
-+ List_iterator<TABLE_LIST> it(nested_join->join_list);
-+ while ((tbl= it++))
-+ {
-+ tbl->embedding= table->embedding;
-+ tbl->join_list= table->join_list;
-+ }
-+ li.replace(nested_join->join_list);
-+ /* Need to update the name resolution table chain when flattening joins */
-+ fix_name_res= TRUE;
-+ table= *li.ref();
-+ }
-+ if (fix_name_res)
-+ table->next_name_resolution_table= right_neighbor ?
-+ right_neighbor->first_leaf_for_name_resolution() :
-+ NULL;
-+ right_neighbor= table;
-+ }
-+ DBUG_RETURN(conds);
-+}
-+
-+
-+/**
-+ Assign each nested join structure a bit in nested_join_map.
-+
-+ Assign each nested join structure (except "confluent" ones - those that
-+ embed only one element) a bit in nested_join_map.
-+
-+ @param join Join being processed
-+ @param join_list List of tables
-+ @param first_unused Number of first unused bit in nested_join_map before the
-+ call
-+
-+ @note
-+ This function is called after simplify_joins(), when there are no
-+ redundant nested joins, #non_confluent_nested_joins <= #tables_in_join so
-+ we will not run out of bits in nested_join_map.
-+
-+ @return
-+ First unused bit in nested_join_map after the call.
-+*/
-+
-+static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
-+ uint first_unused)
-+{
-+ List_iterator<TABLE_LIST> li(*join_list);
-+ TABLE_LIST *table;
-+ DBUG_ENTER("build_bitmap_for_nested_joins");
-+ while ((table= li++))
-+ {
-+ NESTED_JOIN *nested_join;
-+ if ((nested_join= table->nested_join))
-+ {
-+ /*
-+ It is guaranteed by simplify_joins() function that a nested join
-+ that has only one child represents a single table VIEW (and the child
-+ is an underlying table). We don't assign bits to such nested join
-+ structures because
-+ 1. it is redundant (a "sequence" of one table cannot be interleaved
-+ with anything)
-+ 2. we could run out bits in nested_join_map otherwise.
-+ */
-+ if (nested_join->join_list.elements != 1)
-+ {
-+ nested_join->nj_map= (nested_join_map) 1 << first_unused++;
-+ first_unused= build_bitmap_for_nested_joins(&nested_join->join_list,
-+ first_unused);
-+ }
-+ }
-+ }
-+ DBUG_RETURN(first_unused);
-+}
-+
-+
-+/**
-+ Set NESTED_JOIN::counter=0 in all nested joins in passed list.
-+
-+ Recursively set NESTED_JOIN::counter=0 for all nested joins contained in
-+ the passed join_list.
-+
-+ @param join_list List of nested joins to process. It may also contain base
-+ tables which will be ignored.
-+*/
-+
-+static void reset_nj_counters(List<TABLE_LIST> *join_list)
-+{
-+ List_iterator<TABLE_LIST> li(*join_list);
-+ TABLE_LIST *table;
-+ DBUG_ENTER("reset_nj_counters");
-+ while ((table= li++))
-+ {
-+ NESTED_JOIN *nested_join;
-+ if ((nested_join= table->nested_join))
-+ {
-+ nested_join->counter= 0;
-+ reset_nj_counters(&nested_join->join_list);
-+ }
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/**
-+ Check interleaving with an inner tables of an outer join for
-+ extension table.
-+
-+ Check if table next_tab can be added to current partial join order, and
-+ if yes, record that it has been added.
-+
-+ The function assumes that both current partial join order and its
-+ extension with next_tab are valid wrt table dependencies.
-+
-+ @verbatim
-+ IMPLEMENTATION
-+ LIMITATIONS ON JOIN ORDER
-+ The nested [outer] joins executioner algorithm imposes these limitations
-+ on join order:
-+ 1. "Outer tables first" - any "outer" table must be before any
-+ corresponding "inner" table.
-+ 2. "No interleaving" - tables inside a nested join must form a continuous
-+ sequence in join order (i.e. the sequence must not be interrupted by
-+ tables that are outside of this nested join).
-+
-+ #1 is checked elsewhere, this function checks #2 provided that #1 has
-+ been already checked.
-+
-+ WHY NEED NON-INTERLEAVING
-+ Consider an example:
-+
-+ select * from t0 join t1 left join (t2 join t3) on cond1
-+
-+ The join order "t1 t2 t0 t3" is invalid:
-+
-+ table t0 is outside of the nested join, so WHERE condition for t0 is
-+ attached directly to t0 (without triggers, and it may be used to access
-+ t0). Applying WHERE(t0) to (t2,t0,t3) record is invalid as we may miss
-+ combinations of (t1, t2, t3) that satisfy condition cond1, and produce a
-+ null-complemented (t1, t2.NULLs, t3.NULLs) row, which should not have
-+ been produced.
-+
-+ If table t0 is not between t2 and t3, the problem doesn't exist:
-+ If t0 is located after (t2,t3), WHERE(t0) is applied after nested join
-+ processing has finished.
-+ If t0 is located before (t2,t3), predicates like WHERE_cond(t0, t2) are
-+ wrapped into condition triggers, which takes care of correct nested
-+ join processing.
-+
-+ HOW IT IS IMPLEMENTED
-+ The limitations on join order can be rephrased as follows: for valid
-+ join order one must be able to:
-+ 1. write down the used tables in the join order on one line.
-+ 2. for each nested join, put one '(' and one ')' on the said line
-+ 3. write "LEFT JOIN" and "ON (...)" where appropriate
-+ 4. get a query equivalent to the query we're trying to execute.
-+
-+ Calls to check_interleaving_with_nj() are equivalent to writing the
-+ above described line from left to right.
-+ A single check_interleaving_with_nj(A,B) call is equivalent to writing
-+ table B and appropriate brackets on condition that table A and
-+ appropriate brackets is the last what was written. Graphically the
-+ transition is as follows:
-+
-+ +---- current position
-+ |
-+ ... last_tab ))) | ( next_tab ) )..) | ...
-+ X Y Z |
-+ +- need to move to this
-+ position.
-+
-+ Notes about the position:
-+ The caller guarantees that there is no more then one X-bracket by
-+ checking "!(remaining_tables & s->dependent)" before calling this
-+ function. X-bracket may have a pair in Y-bracket.
-+
-+ When "writing" we store/update this auxilary info about the current
-+ position:
-+ 1. join->cur_embedding_map - bitmap of pairs of brackets (aka nested
-+ joins) we've opened but didn't close.
-+ 2. {each NESTED_JOIN structure not simplified away}->counter - number
-+ of this nested join's children that have already been added to to
-+ the partial join order.
-+ @endverbatim
-+
-+ @param next_tab Table we're going to extend the current partial join with
-+
-+ @retval
-+ FALSE Join order extended, nested joins info about current join
-+ order (see NOTE section) updated.
-+ @retval
-+ TRUE Requested join order extension not allowed.
-+*/
-+
-+static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
-+{
-+ TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
-+ JOIN *join= next_tab->join;
-+
-+ if (join->cur_embedding_map & ~next_tab->embedding_map)
-+ {
-+ /*
-+ next_tab is outside of the "pair of brackets" we're currently in.
-+ Cannot add it.
-+ */
-+ return TRUE;
-+ }
-+
-+ /*
-+ Do update counters for "pairs of brackets" that we've left (marked as
-+ X,Y,Z in the above picture)
-+ */
-+ for (;next_emb; next_emb= next_emb->embedding)
-+ {
-+ next_emb->nested_join->counter++;
-+ if (next_emb->nested_join->counter == 1)
-+ {
-+ /*
-+ next_emb is the first table inside a nested join we've "entered". In
-+ the picture above, we're looking at the 'X' bracket. Don't exit yet as
-+ X bracket might have Y pair bracket.
-+ */
-+ join->cur_embedding_map |= next_emb->nested_join->nj_map;
-+ }
-+
-+ if (next_emb->nested_join->join_list.elements !=
-+ next_emb->nested_join->counter)
-+ break;
-+
-+ /*
-+ We're currently at Y or Z-bracket as depicted in the above picture.
-+ Mark that we've left it and continue walking up the brackets hierarchy.
-+ */
-+ join->cur_embedding_map &= ~next_emb->nested_join->nj_map;
-+ }
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Nested joins perspective: Remove the last table from the join order.
-+
-+ The algorithm is the reciprocal of check_interleaving_with_nj(), hence
-+ parent join nest nodes are updated only when the last table in its child
-+ node is removed. The ASCII graphic below will clarify.
-+
-+ %A table nesting such as <tt> t1 x [ ( t2 x t3 ) x ( t4 x t5 ) ] </tt>is
-+ represented by the below join nest tree.
-+
-+ @verbatim
-+ NJ1
-+ _/ / \
-+ _/ / NJ2
-+ _/ / / \
-+ / / / \
-+ t1 x [ (t2 x t3) x (t4 x t5) ]
-+ @endverbatim
-+
-+ At the point in time when check_interleaving_with_nj() adds the table t5 to
-+ the query execution plan, QEP, it also directs the node named NJ2 to mark
-+ the table as covered. NJ2 does so by incrementing its @c counter
-+ member. Since all of NJ2's tables are now covered by the QEP, the algorithm
-+ proceeds up the tree to NJ1, incrementing its counter as well. All join
-+ nests are now completely covered by the QEP.
-+
-+ restore_prev_nj_state() does the above in reverse. As seen above, the node
-+ NJ1 contains the nodes t2, t3, and NJ2. Its counter being equal to 3 means
-+ that the plan covers t2, t3, and NJ2, @e and that the sub-plan (t4 x t5)
-+ completely covers NJ2. The removal of t5 from the partial plan will first
-+ decrement NJ2's counter to 1. It will then detect that NJ2 went from being
-+ completely to partially covered, and hence the algorithm must continue
-+ upwards to NJ1 and decrement its counter to 2. %A subsequent removal of t4
-+ will however not influence NJ1 since it did not un-cover the last table in
-+ NJ2.
-+
-+ SYNOPSIS
-+ restore_prev_nj_state()
-+ last join table to remove, it is assumed to be the last in current
-+ partial join order.
-+
-+ DESCRIPTION
-+
-+ Remove the last table from the partial join order and update the nested
-+ joins counters and join->cur_embedding_map. It is ok to call this
-+ function for the first table in join order (for which
-+ check_interleaving_with_nj has not been called)
-+
-+ @param last join table to remove, it is assumed to be the last in current
-+ partial join order.
-+*/
-+
-+static void restore_prev_nj_state(JOIN_TAB *last)
-+{
-+ TABLE_LIST *last_emb= last->table->pos_in_table_list->embedding;
-+ JOIN *join= last->join;
-+ for (;last_emb != NULL; last_emb= last_emb->embedding)
-+ {
-+ NESTED_JOIN *nest= last_emb->nested_join;
-+ DBUG_ASSERT(nest->counter > 0);
-+
-+ bool was_fully_covered= nest->is_fully_covered();
-+
-+ if (--nest->counter == 0)
-+ join->cur_embedding_map&= ~nest->nj_map;
-+
-+ if (!was_fully_covered)
-+ break;
-+
-+ join->cur_embedding_map|= nest->nj_map;
-+ }
-+}
-+
-+
-+static COND *
-+optimize_cond(JOIN *join, COND *conds, List<TABLE_LIST> *join_list,
-+ Item::cond_result *cond_value)
-+{
-+ THD *thd= join->thd;
-+ DBUG_ENTER("optimize_cond");
-+
-+ if (!conds)
-+ *cond_value= Item::COND_TRUE;
-+ else
-+ {
-+ /*
-+ Build all multiple equality predicates and eliminate equality
-+ predicates that can be inferred from these multiple equalities.
-+ For each reference of a field included into a multiple equality
-+ that occurs in a function set a pointer to the multiple equality
-+ predicate. Substitute a constant instead of this field if the
-+ multiple equality contains a constant.
-+ */
-+ DBUG_EXECUTE("where", print_where(conds, "original", QT_ORDINARY););
-+ conds= build_equal_items(join->thd, conds, NULL, join_list,
-+ &join->cond_equal);
-+ DBUG_EXECUTE("where",print_where(conds,"after equal_items", QT_ORDINARY););
-+
-+ /* change field = field to field = const for each found field = const */
-+ propagate_cond_constants(thd, (I_List<COND_CMP> *) 0, conds, conds);
-+ /*
-+ Remove all instances of item == item
-+ Remove all and-levels where CONST item != CONST item
-+ */
-+ DBUG_EXECUTE("where",print_where(conds,"after const change", QT_ORDINARY););
-+ conds= remove_eq_conds(thd, conds, cond_value) ;
-+ DBUG_EXECUTE("info",print_where(conds,"after remove", QT_ORDINARY););
-+ }
-+ DBUG_RETURN(conds);
-+}
-+
-+
-+/**
-+ Remove const and eq items.
-+
-+ @return
-+ Return new item, or NULL if no condition @n
-+ cond_value is set to according:
-+ - COND_OK : query is possible (field = constant)
-+ - COND_TRUE : always true ( 1 = 1 )
-+ - COND_FALSE : always false ( 1 = 2 )
-+*/
-+
-+COND *
-+remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
-+{
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ bool and_level= ((Item_cond*) cond)->functype()
-+ == Item_func::COND_AND_FUNC;
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item::cond_result tmp_cond_value;
-+ bool should_fix_fields=0;
-+
-+ *cond_value=Item::COND_UNDEF;
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
-+ if (!new_item)
-+ li.remove();
-+ else if (item != new_item)
-+ {
-+ VOID(li.replace(new_item));
-+ should_fix_fields=1;
-+ }
-+ if (*cond_value == Item::COND_UNDEF)
-+ *cond_value=tmp_cond_value;
-+ switch (tmp_cond_value) {
-+ case Item::COND_OK: // Not TRUE or FALSE
-+ if (and_level || *cond_value == Item::COND_FALSE)
-+ *cond_value=tmp_cond_value;
-+ break;
-+ case Item::COND_FALSE:
-+ if (and_level)
-+ {
-+ *cond_value=tmp_cond_value;
-+ return (COND*) 0; // Always false
-+ }
-+ break;
-+ case Item::COND_TRUE:
-+ if (!and_level)
-+ {
-+ *cond_value= tmp_cond_value;
-+ return (COND*) 0; // Always true
-+ }
-+ break;
-+ case Item::COND_UNDEF: // Impossible
-+ break; /* purecov: deadcode */
-+ }
-+ }
-+ if (should_fix_fields)
-+ cond->update_used_tables();
-+
-+ if (!((Item_cond*) cond)->argument_list()->elements ||
-+ *cond_value != Item::COND_OK)
-+ return (COND*) 0;
-+ if (((Item_cond*) cond)->argument_list()->elements == 1)
-+ { // Remove list
-+ item= ((Item_cond*) cond)->argument_list()->head();
-+ ((Item_cond*) cond)->argument_list()->empty();
-+ return item;
-+ }
-+ }
-+ else if (cond->type() == Item::FUNC_ITEM &&
-+ ((Item_func*) cond)->functype() == Item_func::ISNULL_FUNC)
-+ {
-+ /*
-+ Handles this special case for some ODBC applications:
-+ The are requesting the row that was just updated with a auto_increment
-+ value with this construct:
-+
-+ SELECT * from table_name where auto_increment_column IS NULL
-+ This will be changed to:
-+ SELECT * from table_name where auto_increment_column = LAST_INSERT_ID
-+ */
-+
-+ Item_func_isnull *func=(Item_func_isnull*) cond;
-+ Item **args= func->arguments();
-+ if (args[0]->type() == Item::FIELD_ITEM)
-+ {
-+ Field *field=((Item_field*) args[0])->field;
-+ if (field->flags & AUTO_INCREMENT_FLAG && !field->table->maybe_null &&
-+ (thd->options & OPTION_AUTO_IS_NULL) &&
-+ (thd->first_successful_insert_id_in_prev_stmt > 0 &&
-+ thd->substitute_null_with_insert_id))
-+ {
-+#ifdef HAVE_QUERY_CACHE
-+ query_cache_abort(&thd->net);
-+#endif
-+ COND *new_cond;
-+ if ((new_cond= new Item_func_eq(args[0],
-+ new Item_int("last_insert_id()",
-+ thd->read_first_successful_insert_id_in_prev_stmt(),
-+ MY_INT64_NUM_DECIMAL_DIGITS))))
-+ {
-+ cond=new_cond;
-+ /*
-+ Item_func_eq can't be fixed after creation so we do not check
-+ cond->fixed, also it do not need tables so we use 0 as second
-+ argument.
-+ */
-+ cond->fix_fields(thd, &cond);
-+ }
-+ /*
-+ IS NULL should be mapped to LAST_INSERT_ID only for first row, so
-+ clear for next row
-+ */
-+ thd->substitute_null_with_insert_id= FALSE;
-+ }
-+ /* fix to replace 'NULL' dates with '0' (shreeve@uci.edu) */
-+ else if (((field->type() == MYSQL_TYPE_DATE) ||
-+ (field->type() == MYSQL_TYPE_DATETIME)) &&
-+ (field->flags & NOT_NULL_FLAG) &&
-+ !field->table->maybe_null)
-+ {
-+ COND *new_cond;
-+ if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
-+ {
-+ cond=new_cond;
-+ /*
-+ Item_func_eq can't be fixed after creation so we do not check
-+ cond->fixed, also it do not need tables so we use 0 as second
-+ argument.
-+ */
-+ cond->fix_fields(thd, &cond);
-+ }
-+ }
-+ }
-+ if (cond->const_item())
-+ {
-+ *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
-+ return (COND*) 0;
-+ }
-+ }
-+ else if (cond->const_item())
-+ {
-+ *cond_value= eval_const_cond(cond) ? Item::COND_TRUE : Item::COND_FALSE;
-+ return (COND*) 0;
-+ }
-+ else if ((*cond_value= cond->eq_cmp_result()) != Item::COND_OK)
-+ { // boolan compare function
-+ Item *left_item= ((Item_func*) cond)->arguments()[0];
-+ Item *right_item= ((Item_func*) cond)->arguments()[1];
-+ if (left_item->eq(right_item,1))
-+ {
-+ if (!left_item->maybe_null ||
-+ ((Item_func*) cond)->functype() == Item_func::EQUAL_FUNC)
-+ return (COND*) 0; // Compare of identical items
-+ }
-+ }
-+ *cond_value=Item::COND_OK;
-+ return cond; // Point at next and level
-+}
-+
-+/*
-+ Check if equality can be used in removing components of GROUP BY/DISTINCT
-+
-+ SYNOPSIS
-+ test_if_equality_guarantees_uniqueness()
-+ l the left comparison argument (a field if any)
-+ r the right comparison argument (a const of any)
-+
-+ DESCRIPTION
-+ Checks if an equality predicate can be used to take away
-+ DISTINCT/GROUP BY because it is known to be true for exactly one
-+ distinct value (e.g. <expr> == <const>).
-+ Arguments must be of the same type because e.g.
-+ <string_field> = <int_const> may match more than 1 distinct value from
-+ the column.
-+ We must take into consideration and the optimization done for various
-+ string constants when compared to dates etc (see Item_int_with_ref) as
-+ well as the collation of the arguments.
-+
-+ RETURN VALUE
-+ TRUE can be used
-+ FALSE cannot be used
-+*/
-+static bool
-+test_if_equality_guarantees_uniqueness(Item *l, Item *r)
-+{
-+ return r->const_item() &&
-+ /* elements must be compared as dates */
-+ (Arg_comparator::can_compare_as_dates(l, r, 0) ||
-+ /* or of the same result type */
-+ (r->result_type() == l->result_type() &&
-+ /* and must have the same collation if compared as strings */
-+ (l->result_type() != STRING_RESULT ||
-+ l->collation.collation == r->collation.collation)));
-+}
-+
-+/**
-+ Return TRUE if the item is a const value in all the WHERE clause.
-+*/
-+
-+static bool
-+const_expression_in_where(COND *cond, Item *comp_item, Item **const_item)
-+{
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ bool and_level= (((Item_cond*) cond)->functype()
-+ == Item_func::COND_AND_FUNC);
-+ List_iterator_fast<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ bool res=const_expression_in_where(item, comp_item, const_item);
-+ if (res) // Is a const value
-+ {
-+ if (and_level)
-+ return 1;
-+ }
-+ else if (!and_level)
-+ return 0;
-+ }
-+ return and_level ? 0 : 1;
-+ }
-+ else if (cond->eq_cmp_result() != Item::COND_OK)
-+ { // boolan compare function
-+ Item_func* func= (Item_func*) cond;
-+ if (func->functype() != Item_func::EQUAL_FUNC &&
-+ func->functype() != Item_func::EQ_FUNC)
-+ return 0;
-+ Item *left_item= ((Item_func*) cond)->arguments()[0];
-+ Item *right_item= ((Item_func*) cond)->arguments()[1];
-+ if (left_item->eq(comp_item,1))
-+ {
-+ if (test_if_equality_guarantees_uniqueness (left_item, right_item))
-+ {
-+ if (*const_item)
-+ return right_item->eq(*const_item, 1);
-+ *const_item=right_item;
-+ return 1;
-+ }
-+ }
-+ else if (right_item->eq(comp_item,1))
-+ {
-+ if (test_if_equality_guarantees_uniqueness (right_item, left_item))
-+ {
-+ if (*const_item)
-+ return left_item->eq(*const_item, 1);
-+ *const_item=left_item;
-+ return 1;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+/****************************************************************************
-+ Create internal temporary table
-+****************************************************************************/
-+
-+/**
-+ Create field for temporary table from given field.
-+
-+ @param thd Thread handler
-+ @param org_field field from which new field will be created
-+ @param name New field name
-+ @param table Temporary table
-+ @param item !=NULL if item->result_field should point to new field.
-+ This is relevant for how fill_record() is going to work:
-+ If item != NULL then fill_record() will update
-+ the record in the original table.
-+ If item == NULL then fill_record() will update
-+ the temporary table
-+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
-+ field instead of blob.
-+
-+ @retval
-+ NULL on error
-+ @retval
-+ new_created field
-+*/
-+
-+Field *create_tmp_field_from_field(THD *thd, Field *org_field,
-+ const char *name, TABLE *table,
-+ Item_field *item, uint convert_blob_length)
-+{
-+ Field *new_field;
-+
-+ /*
-+ Make sure that the blob fits into a Field_varstring which has
-+ 2-byte lenght.
-+ */
-+ if (convert_blob_length && convert_blob_length <= Field_varstring::MAX_SIZE &&
-+ (org_field->flags & BLOB_FLAG))
-+ new_field= new Field_varstring(convert_blob_length,
-+ org_field->maybe_null(),
-+ org_field->field_name, table->s,
-+ org_field->charset());
-+ else
-+ new_field= org_field->new_field(thd->mem_root, table,
-+ table == org_field->table);
-+ if (new_field)
-+ {
-+ new_field->init(table);
-+ new_field->orig_table= org_field->orig_table;
-+ if (item)
-+ item->result_field= new_field;
-+ else
-+ new_field->field_name= name;
-+ new_field->flags|= (org_field->flags & NO_DEFAULT_VALUE_FLAG);
-+ if (org_field->maybe_null() || (item && item->maybe_null))
-+ new_field->flags&= ~NOT_NULL_FLAG; // Because of outer join
-+ if (org_field->type() == MYSQL_TYPE_VAR_STRING ||
-+ org_field->type() == MYSQL_TYPE_VARCHAR)
-+ table->s->db_create_options|= HA_OPTION_PACK_RECORD;
-+ else if (org_field->type() == FIELD_TYPE_DOUBLE)
-+ ((Field_double *) new_field)->not_fixed= TRUE;
-+ }
-+ return new_field;
-+}
-+
-+/**
-+ Create field for temporary table using type of given item.
-+
-+ @param thd Thread handler
-+ @param item Item to create a field for
-+ @param table Temporary table
-+ @param copy_func If set and item is a function, store copy of
-+ item in this array
-+ @param modify_item 1 if item->result_field should point to new
-+ item. This is relevent for how fill_record()
-+ is going to work:
-+ If modify_item is 1 then fill_record() will
-+ update the record in the original table.
-+ If modify_item is 0 then fill_record() will
-+ update the temporary table
-+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
-+ field instead of blob.
-+
-+ @retval
-+ 0 on error
-+ @retval
-+ new_created field
-+*/
-+
-+static Field *create_tmp_field_from_item(THD *thd, Item *item, TABLE *table,
-+ Item ***copy_func, bool modify_item,
-+ uint convert_blob_length)
-+{
-+ bool maybe_null= item->maybe_null;
-+ Field *new_field;
-+ LINT_INIT(new_field);
-+
-+ switch (item->result_type()) {
-+ case REAL_RESULT:
-+ new_field= new Field_double(item->max_length, maybe_null,
-+ item->name, item->decimals, TRUE);
-+ break;
-+ case INT_RESULT:
-+ /*
-+ Select an integer type with the minimal fit precision.
-+ MY_INT32_NUM_DECIMAL_DIGITS is sign inclusive, don't consider the sign.
-+ Values with MY_INT32_NUM_DECIMAL_DIGITS digits may or may not fit into
-+ Field_long : make them Field_longlong.
-+ */
-+ if (item->max_length >= (MY_INT32_NUM_DECIMAL_DIGITS - 1))
-+ new_field=new Field_longlong(item->max_length, maybe_null,
-+ item->name, item->unsigned_flag);
-+ else
-+ new_field=new Field_long(item->max_length, maybe_null,
-+ item->name, item->unsigned_flag);
-+ break;
-+ case STRING_RESULT:
-+ DBUG_ASSERT(item->collation.collation);
-+
-+ enum enum_field_types type;
-+ /*
-+ DATE/TIME and GEOMETRY fields have STRING_RESULT result type.
-+ To preserve type they needed to be handled separately.
-+ */
-+ if ((type= item->field_type()) == MYSQL_TYPE_DATETIME ||
-+ type == MYSQL_TYPE_TIME || type == MYSQL_TYPE_DATE ||
-+ type == MYSQL_TYPE_NEWDATE ||
-+ type == MYSQL_TYPE_TIMESTAMP || type == MYSQL_TYPE_GEOMETRY)
-+ new_field= item->tmp_table_field_from_field_type(table, 1);
-+ /*
-+ Make sure that the blob fits into a Field_varstring which has
-+ 2-byte lenght.
-+ */
-+ else if (item->max_length/item->collation.collation->mbmaxlen > 255 &&
-+ convert_blob_length <= Field_varstring::MAX_SIZE &&
-+ convert_blob_length)
-+ new_field= new Field_varstring(convert_blob_length, maybe_null,
-+ item->name, table->s,
-+ item->collation.collation);
-+ else
-+ new_field= item->make_string_field(table);
-+ new_field->set_derivation(item->collation.derivation);
-+ break;
-+ case DECIMAL_RESULT:
-+ new_field= Field_new_decimal::create_from_item(item);
-+ break;
-+ case ROW_RESULT:
-+ default:
-+ // This case should never be choosen
-+ DBUG_ASSERT(0);
-+ new_field= 0;
-+ break;
-+ }
-+ if (new_field)
-+ new_field->init(table);
-+
-+ if (copy_func && item->is_result_field())
-+ *((*copy_func)++) = item; // Save for copy_funcs
-+ if (modify_item)
-+ item->set_result_field(new_field);
-+ if (item->type() == Item::NULL_ITEM)
-+ new_field->is_created_from_null_item= TRUE;
-+ return new_field;
-+}
-+
-+
-+/**
-+ Create field for information schema table.
-+
-+ @param thd Thread handler
-+ @param table Temporary table
-+ @param item Item to create a field for
-+
-+ @retval
-+ 0 on error
-+ @retval
-+ new_created field
-+*/
-+
-+Field *create_tmp_field_for_schema(THD *thd, Item *item, TABLE *table)
-+{
-+ if (item->field_type() == MYSQL_TYPE_VARCHAR)
-+ {
-+ Field *field;
-+ if (item->max_length > MAX_FIELD_VARCHARLENGTH)
-+ field= new Field_blob(item->max_length, item->maybe_null,
-+ item->name, item->collation.collation);
-+ else
-+ field= new Field_varstring(item->max_length, item->maybe_null,
-+ item->name,
-+ table->s, item->collation.collation);
-+ if (field)
-+ field->init(table);
-+ return field;
-+ }
-+ return item->tmp_table_field_from_field_type(table, 0);
-+}
-+
-+
-+/**
-+ Create field for temporary table.
-+
-+ @param thd Thread handler
-+ @param table Temporary table
-+ @param item Item to create a field for
-+ @param type Type of item (normally item->type)
-+ @param copy_func If set and item is a function, store copy of item
-+ in this array
-+ @param from_field if field will be created using other field as example,
-+ pointer example field will be written here
-+ @param default_field If field has a default value field, store it here
-+ @param group 1 if we are going to do a relative group by on result
-+ @param modify_item 1 if item->result_field should point to new item.
-+ This is relevent for how fill_record() is going to
-+ work:
-+ If modify_item is 1 then fill_record() will update
-+ the record in the original table.
-+ If modify_item is 0 then fill_record() will update
-+ the temporary table
-+ @param convert_blob_length If >0 create a varstring(convert_blob_length)
-+ field instead of blob.
-+
-+ @retval
-+ 0 on error
-+ @retval
-+ new_created field
-+*/
-+
-+Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
-+ Item ***copy_func, Field **from_field,
-+ Field **default_field,
-+ bool group, bool modify_item,
-+ bool table_cant_handle_bit_fields,
-+ bool make_copy_field,
-+ uint convert_blob_length)
-+{
-+ Field *result;
-+ Item::Type orig_type= type;
-+ Item *orig_item= 0;
-+
-+ if (type != Item::FIELD_ITEM &&
-+ item->real_item()->type() == Item::FIELD_ITEM)
-+ {
-+ orig_item= item;
-+ item= item->real_item();
-+ type= Item::FIELD_ITEM;
-+ }
-+
-+ switch (type) {
-+ case Item::SUM_FUNC_ITEM:
-+ {
-+ Item_sum *item_sum=(Item_sum*) item;
-+ result= item_sum->create_tmp_field(group, table, convert_blob_length);
-+ if (!result)
-+ thd->fatal_error();
-+ return result;
-+ }
-+ case Item::FIELD_ITEM:
-+ case Item::DEFAULT_VALUE_ITEM:
-+ {
-+ Item_field *field= (Item_field*) item;
-+ bool orig_modify= modify_item;
-+ if (orig_type == Item::REF_ITEM)
-+ modify_item= 0;
-+ /*
-+ If item have to be able to store NULLs but underlaid field can't do it,
-+ create_tmp_field_from_field() can't be used for tmp field creation.
-+ */
-+ if (field->maybe_null && !field->field->maybe_null())
-+ {
-+ result= create_tmp_field_from_item(thd, item, table, NULL,
-+ modify_item, convert_blob_length);
-+ *from_field= field->field;
-+ if (result && modify_item)
-+ field->result_field= result;
-+ }
-+ else if (table_cant_handle_bit_fields && field->field->type() ==
-+ MYSQL_TYPE_BIT)
-+ {
-+ *from_field= field->field;
-+ result= create_tmp_field_from_item(thd, item, table, copy_func,
-+ modify_item, convert_blob_length);
-+ if (result && modify_item)
-+ field->result_field= result;
-+ }
-+ else
-+ result= create_tmp_field_from_field(thd, (*from_field= field->field),
-+ orig_item ? orig_item->name :
-+ item->name,
-+ table,
-+ modify_item ? field :
-+ NULL,
-+ convert_blob_length);
-+ if (orig_type == Item::REF_ITEM && orig_modify)
-+ ((Item_ref*)orig_item)->set_result_field(result);
-+ /*
-+ Fields that are used as arguments to the DEFAULT() function already have
-+ their data pointers set to the default value during name resulotion. See
-+ Item_default_value::fix_fields.
-+ */
-+ if (orig_type != Item::DEFAULT_VALUE_ITEM && field->field->eq_def(result))
-+ *default_field= field->field;
-+ return result;
-+ }
-+ /* Fall through */
-+ case Item::FUNC_ITEM:
-+ if (((Item_func *) item)->functype() == Item_func::FUNC_SP)
-+ {
-+ Item_func_sp *item_func_sp= (Item_func_sp *) item;
-+ Field *sp_result_field= item_func_sp->get_sp_result_field();
-+
-+ if (make_copy_field)
-+ {
-+ DBUG_ASSERT(item_func_sp->result_field);
-+ *from_field= item_func_sp->result_field;
-+ }
-+ else
-+ {
-+ *((*copy_func)++)= item;
-+ }
-+
-+ Field *result_field=
-+ create_tmp_field_from_field(thd,
-+ sp_result_field,
-+ item_func_sp->name,
-+ table,
-+ NULL,
-+ convert_blob_length);
-+
-+ if (modify_item)
-+ item->set_result_field(result_field);
-+
-+ return result_field;
-+ }
-+
-+ /* Fall through */
-+ case Item::COND_ITEM:
-+ case Item::FIELD_AVG_ITEM:
-+ case Item::FIELD_STD_ITEM:
-+ case Item::SUBSELECT_ITEM:
-+ /* The following can only happen with 'CREATE TABLE ... SELECT' */
-+ case Item::PROC_ITEM:
-+ case Item::INT_ITEM:
-+ case Item::REAL_ITEM:
-+ case Item::DECIMAL_ITEM:
-+ case Item::STRING_ITEM:
-+ case Item::REF_ITEM:
-+ case Item::NULL_ITEM:
-+ case Item::VARBIN_ITEM:
-+ if (make_copy_field)
-+ {
-+ DBUG_ASSERT(((Item_result_field*)item)->result_field);
-+ *from_field= ((Item_result_field*)item)->result_field;
-+ }
-+ return create_tmp_field_from_item(thd, item, table,
-+ (make_copy_field ? 0 : copy_func),
-+ modify_item, convert_blob_length);
-+ case Item::TYPE_HOLDER:
-+ result= ((Item_type_holder *)item)->make_field_by_type(table);
-+ result->set_derivation(item->collation.derivation);
-+ return result;
-+ default: // Dosen't have to be stored
-+ return 0;
-+ }
-+}
-+
-+/*
-+ Set up column usage bitmaps for a temporary table
-+
-+ IMPLEMENTATION
-+ For temporary tables, we need one bitmap with all columns set and
-+ a tmp_set bitmap to be used by things like filesort.
-+*/
-+
-+void setup_tmp_table_column_bitmaps(TABLE *table, uchar *bitmaps)
-+{
-+ uint field_count= table->s->fields;
-+ bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
-+ FALSE);
-+ bitmap_init(&table->tmp_set,
-+ (my_bitmap_map*) (bitmaps+ bitmap_buffer_size(field_count)),
-+ field_count, FALSE);
-+ /* write_set and all_set are copies of read_set */
-+ table->def_write_set= table->def_read_set;
-+ table->s->all_set= table->def_read_set;
-+ bitmap_set_all(&table->s->all_set);
-+ table->default_column_bitmaps();
-+}
-+
-+
-+/**
-+ Create a temp table according to a field list.
-+
-+ Given field pointers are changed to point at tmp_table for
-+ send_fields. The table object is self contained: it's
-+ allocated in its own memory root, as well as Field objects
-+ created for table columns.
-+ This function will replace Item_sum items in 'fields' list with
-+ corresponding Item_field items, pointing at the fields in the
-+ temporary table, unless this was prohibited by TRUE
-+ value of argument save_sum_fields. The Item_field objects
-+ are created in THD memory root.
-+
-+ @param thd thread handle
-+ @param param a description used as input to create the table
-+ @param fields list of items that will be used to define
-+ column types of the table (also see NOTES)
-+ @param group TODO document
-+ @param distinct should table rows be distinct
-+ @param save_sum_fields see NOTES
-+ @param select_options
-+ @param rows_limit
-+ @param table_alias possible name of the temporary table that can
-+ be used for name resolving; can be "".
-+*/
-+
-+#define STRING_TOTAL_LENGTH_TO_PACK_ROWS 128
-+#define AVG_STRING_LENGTH_TO_PACK_ROWS 64
-+#define RATIO_TO_PACK_ROWS 2
-+#define MIN_STRING_LENGTH_TO_PACK_ROWS 10
-+
-+TABLE *
-+create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
-+ ORDER *group, bool distinct, bool save_sum_fields,
-+ ulonglong select_options, ha_rows rows_limit,
-+ char *table_alias)
-+{
-+ MEM_ROOT *mem_root_save, own_root;
-+ TABLE *table;
-+ TABLE_SHARE *share;
-+ uint i,field_count,null_count,null_pack_length;
-+ uint copy_func_count= param->func_count;
-+ uint hidden_null_count, hidden_null_pack_length, hidden_field_count;
-+ uint blob_count,group_null_items, string_count;
-+ uint temp_pool_slot=MY_BIT_NONE;
-+ uint fieldnr= 0;
-+ ulong reclength, string_total_length;
-+ bool using_unique_constraint= 0;
-+ bool use_packed_rows= 0;
-+ bool not_all_columns= !(select_options & TMP_TABLE_ALL_COLUMNS);
-+ char *tmpname,path[FN_REFLEN];
-+ uchar *pos, *group_buff, *bitmaps;
-+ uchar *null_flags;
-+ Field **reg_field, **from_field, **default_field;
-+ uint *blob_field;
-+ Copy_field *copy=0;
-+ KEY *keyinfo;
-+ KEY_PART_INFO *key_part_info;
-+ Item **copy_func;
-+ MI_COLUMNDEF *recinfo;
-+ /*
-+ total_uneven_bit_length is uneven bit length for visible fields
-+ hidden_uneven_bit_length is uneven bit length for hidden fields
-+ */
-+ uint total_uneven_bit_length= 0, hidden_uneven_bit_length= 0;
-+ bool force_copy_fields= param->force_copy_fields;
-+ /* Treat sum functions as normal ones when loose index scan is used. */
-+ save_sum_fields|= param->precomputed_group_by;
-+ DBUG_ENTER("create_tmp_table");
-+ DBUG_PRINT("enter",
-+ ("distinct: %d save_sum_fields: %d rows_limit: %lu group: %d",
-+ (int) distinct, (int) save_sum_fields,
-+ (ulong) rows_limit,test(group)));
-+
-+ status_var_increment(thd->status_var.created_tmp_tables);
-+
-+ if (use_temp_pool && !(test_flags & TEST_KEEP_TMP_TABLES))
-+ temp_pool_slot = bitmap_lock_set_next(&temp_pool);
-+
-+ if (temp_pool_slot != MY_BIT_NONE) // we got a slot
-+ sprintf(path, "%s_%lx_%i", tmp_file_prefix,
-+ current_pid, temp_pool_slot);
-+ else
-+ {
-+ /* if we run out of slots or we are not using tempool */
-+ sprintf(path,"%s%lx_%lx_%x", tmp_file_prefix,current_pid,
-+ thd->thread_id, thd->tmp_table++);
-+ }
-+
-+ /*
-+ No need to change table name to lower case as we are only creating
-+ MyISAM or HEAP tables here
-+ */
-+ fn_format(path, path, mysql_tmpdir, "", MY_REPLACE_EXT|MY_UNPACK_FILENAME);
-+
-+
-+ if (group)
-+ {
-+ if (!param->quick_group)
-+ group=0; // Can't use group key
-+ else for (ORDER *tmp=group ; tmp ; tmp=tmp->next)
-+ {
-+ (*tmp->item)->marker=4; // Store null in key
-+ if ((*tmp->item)->max_length >= CONVERT_IF_BIGGER_TO_BLOB)
-+ using_unique_constraint=1;
-+ }
-+ if (param->group_length >= MAX_BLOB_WIDTH)
-+ using_unique_constraint=1;
-+ if (group)
-+ distinct=0; // Can't use distinct
-+ }
-+
-+ field_count=param->field_count+param->func_count+param->sum_func_count;
-+ hidden_field_count=param->hidden_field_count;
-+
-+ /*
-+ When loose index scan is employed as access method, it already
-+ computes all groups and the result of all aggregate functions. We
-+ make space for the items of the aggregate function in the list of
-+ functions TMP_TABLE_PARAM::items_to_copy, so that the values of
-+ these items are stored in the temporary table.
-+ */
-+ if (param->precomputed_group_by)
-+ copy_func_count+= param->sum_func_count;
-+
-+ init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0);
-+
-+ if (!multi_alloc_root(&own_root,
-+ &table, sizeof(*table),
-+ &share, sizeof(*share),
-+ ®_field, sizeof(Field*) * (field_count+1),
-+ &default_field, sizeof(Field*) * (field_count),
-+ &blob_field, sizeof(uint)*(field_count+1),
-+ &from_field, sizeof(Field*)*field_count,
-+ ©_func, sizeof(*copy_func)*(copy_func_count+1),
-+ ¶m->keyinfo, sizeof(*param->keyinfo),
-+ &key_part_info,
-+ sizeof(*key_part_info)*(param->group_parts+1),
-+ ¶m->start_recinfo,
-+ sizeof(*param->recinfo)*(field_count*2+4),
-+ &tmpname, (uint) strlen(path)+1,
-+ &group_buff, (group && ! using_unique_constraint ?
-+ param->group_length : 0),
-+ &bitmaps, bitmap_buffer_size(field_count)*2,
-+ NullS))
-+ {
-+ if (temp_pool_slot != MY_BIT_NONE)
-+ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
-+ DBUG_RETURN(NULL); /* purecov: inspected */
-+ }
-+ /* Copy_field belongs to TMP_TABLE_PARAM, allocate it in THD mem_root */
-+ if (!(param->copy_field= copy= new (thd->mem_root) Copy_field[field_count]))
-+ {
-+ if (temp_pool_slot != MY_BIT_NONE)
-+ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
-+ free_root(&own_root, MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(NULL); /* purecov: inspected */
-+ }
-+ param->items_to_copy= copy_func;
-+ strmov(tmpname,path);
-+ /* make table according to fields */
-+
-+ bzero((char*) table,sizeof(*table));
-+ bzero((char*) reg_field,sizeof(Field*)*(field_count+1));
-+ bzero((char*) default_field, sizeof(Field*) * (field_count));
-+ bzero((char*) from_field,sizeof(Field*)*field_count);
-+
-+ table->mem_root= own_root;
-+ mem_root_save= thd->mem_root;
-+ thd->mem_root= &table->mem_root;
-+
-+ table->field=reg_field;
-+ table->alias= table_alias;
-+ table->reginfo.lock_type=TL_WRITE; /* Will be updated */
-+ table->db_stat=HA_OPEN_KEYFILE+HA_OPEN_RNDFILE;
-+ table->map=1;
-+ table->temp_pool_slot = temp_pool_slot;
-+ table->copy_blobs= 1;
-+ table->in_use= thd;
-+ table->quick_keys.init();
-+ table->covering_keys.init();
-+ table->merge_keys.init();
-+ table->keys_in_use_for_query.init();
-+
-+ table->s= share;
-+ init_tmp_table_share(thd, share, "", 0, tmpname, tmpname);
-+ share->blob_field= blob_field;
-+ share->blob_ptr_size= portable_sizeof_char_ptr;
-+ share->db_low_byte_first=1; // True for HEAP and MyISAM
-+ share->table_charset= param->table_charset;
-+ share->primary_key= MAX_KEY; // Indicate no primary key
-+ share->keys_for_keyread.init();
-+ share->keys_in_use.init();
-+
-+ /* Calculate which type of fields we will store in the temporary table */
-+
-+ reclength= string_total_length= 0;
-+ blob_count= string_count= null_count= hidden_null_count= group_null_items= 0;
-+ param->using_indirect_summary_function=0;
-+
-+ List_iterator_fast<Item> li(fields);
-+ Item *item;
-+ Field **tmp_from_field=from_field;
-+ while ((item=li++))
-+ {
-+ Item::Type type=item->type();
-+ if (not_all_columns)
-+ {
-+ if (item->with_sum_func && type != Item::SUM_FUNC_ITEM)
-+ {
-+ if (item->used_tables() & OUTER_REF_TABLE_BIT)
-+ item->update_used_tables();
-+ if (type == Item::SUBSELECT_ITEM ||
-+ (item->used_tables() & ~OUTER_REF_TABLE_BIT))
-+ {
-+ /*
-+ Mark that the we have ignored an item that refers to a summary
-+ function. We need to know this if someone is going to use
-+ DISTINCT on the result.
-+ */
-+ param->using_indirect_summary_function=1;
-+ continue;
-+ }
-+ }
-+ if (item->const_item() && (int) hidden_field_count <= 0)
-+ continue; // We don't have to store this
-+ }
-+ if (type == Item::SUM_FUNC_ITEM && !group && !save_sum_fields)
-+ { /* Can't calc group yet */
-+ Item_sum *sum_item= (Item_sum *) item;
-+ sum_item->result_field=0;
-+ for (i=0 ; i < sum_item->get_arg_count() ; i++)
-+ {
-+ Item *arg= sum_item->get_arg(i);
-+ if (!arg->const_item())
-+ {
-+ Field *new_field=
-+ create_tmp_field(thd, table, arg, arg->type(), ©_func,
-+ tmp_from_field, &default_field[fieldnr],
-+ group != 0,not_all_columns,
-+ distinct, 0,
-+ param->convert_blob_length);
-+ if (!new_field)
-+ goto err; // Should be OOM
-+ tmp_from_field++;
-+ reclength+=new_field->pack_length();
-+ if (new_field->flags & BLOB_FLAG)
-+ {
-+ *blob_field++= fieldnr;
-+ blob_count++;
-+ }
-+ if (new_field->type() == MYSQL_TYPE_BIT)
-+ total_uneven_bit_length+= new_field->field_length & 7;
-+ *(reg_field++)= new_field;
-+ if (new_field->real_type() == MYSQL_TYPE_STRING ||
-+ new_field->real_type() == MYSQL_TYPE_VARCHAR)
-+ {
-+ string_count++;
-+ string_total_length+= new_field->pack_length();
-+ }
-+ thd->mem_root= mem_root_save;
-+ arg= sum_item->set_arg(i, thd, new Item_field(new_field));
-+ thd->mem_root= &table->mem_root;
-+ if (!(new_field->flags & NOT_NULL_FLAG))
-+ {
-+ null_count++;
-+ /*
-+ new_field->maybe_null() is still false, it will be
-+ changed below. But we have to setup Item_field correctly
-+ */
-+ arg->maybe_null=1;
-+ }
-+ new_field->field_index= fieldnr++;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ The last parameter to create_tmp_field() is a bit tricky:
-+
-+ We need to set it to 0 in union, to get fill_record() to modify the
-+ temporary table.
-+ We need to set it to 1 on multi-table-update and in select to
-+ write rows to the temporary table.
-+ We here distinguish between UNION and multi-table-updates by the fact
-+ that in the later case group is set to the row pointer.
-+
-+ The test for item->marker == 4 is ensure we don't create a group-by
-+ key over a bit field as heap tables can't handle that.
-+ */
-+ Field *new_field= (param->schema_table) ?
-+ create_tmp_field_for_schema(thd, item, table) :
-+ create_tmp_field(thd, table, item, type, ©_func,
-+ tmp_from_field, &default_field[fieldnr],
-+ group != 0,
-+ !force_copy_fields &&
-+ (not_all_columns || group !=0),
-+ item->marker == 4, force_copy_fields,
-+ param->convert_blob_length);
-+
-+ if (!new_field)
-+ {
-+ if (thd->is_fatal_error)
-+ goto err; // Got OOM
-+ continue; // Some kindf of const item
-+ }
-+ if (type == Item::SUM_FUNC_ITEM)
-+ ((Item_sum *) item)->result_field= new_field;
-+ tmp_from_field++;
-+ reclength+=new_field->pack_length();
-+ if (!(new_field->flags & NOT_NULL_FLAG))
-+ null_count++;
-+ if (new_field->type() == MYSQL_TYPE_BIT)
-+ total_uneven_bit_length+= new_field->field_length & 7;
-+ if (new_field->flags & BLOB_FLAG)
-+ {
-+ *blob_field++= fieldnr;
-+ blob_count++;
-+ }
-+ if (item->marker == 4 && item->maybe_null)
-+ {
-+ group_null_items++;
-+ new_field->flags|= GROUP_FLAG;
-+ }
-+ new_field->field_index= fieldnr++;
-+ *(reg_field++)= new_field;
-+ }
-+ if (!--hidden_field_count)
-+ {
-+ /*
-+ This was the last hidden field; Remember how many hidden fields could
-+ have null
-+ */
-+ hidden_null_count=null_count;
-+ /*
-+ We need to update hidden_field_count as we may have stored group
-+ functions with constant arguments
-+ */
-+ param->hidden_field_count= fieldnr;
-+ null_count= 0;
-+ /*
-+ On last hidden field we store uneven bit length in
-+ hidden_uneven_bit_length and proceed calculation of
-+ uneven bits for visible fields into
-+ total_uneven_bit_length variable.
-+ */
-+ hidden_uneven_bit_length= total_uneven_bit_length;
-+ total_uneven_bit_length= 0;
-+ }
-+ }
-+ DBUG_ASSERT(fieldnr == (uint) (reg_field - table->field));
-+ DBUG_ASSERT(field_count >= (uint) (reg_field - table->field));
-+ field_count= fieldnr;
-+ *reg_field= 0;
-+ *blob_field= 0; // End marker
-+ share->fields= field_count;
-+
-+ /* If result table is small; use a heap */
-+ /* future: storage engine selection can be made dynamic? */
-+ if (blob_count || using_unique_constraint ||
-+ (select_options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
-+ OPTION_BIG_TABLES || (select_options & TMP_TABLE_FORCE_MYISAM))
-+ {
-+ share->db_plugin= ha_lock_engine(0, myisam_hton);
-+ table->file= get_new_handler(share, &table->mem_root,
-+ share->db_type());
-+ if (group &&
-+ (param->group_parts > table->file->max_key_parts() ||
-+ param->group_length > table->file->max_key_length()))
-+ using_unique_constraint=1;
-+ }
-+ else
-+ {
-+ share->db_plugin= ha_lock_engine(0, heap_hton);
-+ table->file= get_new_handler(share, &table->mem_root,
-+ share->db_type());
-+ }
-+ if (!table->file)
-+ goto err;
-+
-+
-+ if (!using_unique_constraint)
-+ reclength+= group_null_items; // null flag is stored separately
-+
-+ share->blob_fields= blob_count;
-+ if (blob_count == 0)
-+ {
-+ /* We need to ensure that first byte is not 0 for the delete link */
-+ if (param->hidden_field_count)
-+ hidden_null_count++;
-+ else
-+ null_count++;
-+ }
-+ hidden_null_pack_length= (hidden_null_count + 7 +
-+ hidden_uneven_bit_length) / 8;
-+ null_pack_length= (hidden_null_pack_length +
-+ (null_count + total_uneven_bit_length + 7) / 8);
-+ reclength+=null_pack_length;
-+ if (!reclength)
-+ reclength=1; // Dummy select
-+ /* Use packed rows if there is blobs or a lot of space to gain */
-+ if (blob_count ||
-+ (string_total_length >= STRING_TOTAL_LENGTH_TO_PACK_ROWS &&
-+ (reclength / string_total_length <= RATIO_TO_PACK_ROWS ||
-+ string_total_length / string_count >= AVG_STRING_LENGTH_TO_PACK_ROWS)))
-+ use_packed_rows= 1;
-+
-+ share->reclength= reclength;
-+ {
-+ uint alloc_length=ALIGN_SIZE(reclength+MI_UNIQUE_HASH_LENGTH+1);
-+ share->rec_buff_length= alloc_length;
-+ if (!(table->record[0]= (uchar*)
-+ alloc_root(&table->mem_root, alloc_length*3)))
-+ goto err;
-+ table->record[1]= table->record[0]+alloc_length;
-+ share->default_values= table->record[1]+alloc_length;
-+ }
-+ copy_func[0]=0; // End marker
-+ param->func_count= copy_func - param->items_to_copy;
-+
-+ setup_tmp_table_column_bitmaps(table, bitmaps);
-+
-+ recinfo=param->start_recinfo;
-+ null_flags=(uchar*) table->record[0];
-+ pos=table->record[0]+ null_pack_length;
-+ if (null_pack_length)
-+ {
-+ bzero((uchar*) recinfo,sizeof(*recinfo));
-+ recinfo->type=FIELD_NORMAL;
-+ recinfo->length=null_pack_length;
-+ recinfo++;
-+ bfill(null_flags,null_pack_length,255); // Set null fields
-+
-+ table->null_flags= (uchar*) table->record[0];
-+ share->null_fields= null_count+ hidden_null_count;
-+ share->null_bytes= null_pack_length;
-+ }
-+ null_count= (blob_count == 0) ? 1 : 0;
-+ hidden_field_count=param->hidden_field_count;
-+ for (i=0,reg_field=table->field; i < field_count; i++,reg_field++,recinfo++)
-+ {
-+ Field *field= *reg_field;
-+ uint length;
-+ bzero((uchar*) recinfo,sizeof(*recinfo));
-+
-+ if (!(field->flags & NOT_NULL_FLAG))
-+ {
-+ if (field->flags & GROUP_FLAG && !using_unique_constraint)
-+ {
-+ /*
-+ We have to reserve one byte here for NULL bits,
-+ as this is updated by 'end_update()'
-+ */
-+ *pos++=0; // Null is stored here
-+ recinfo->length=1;
-+ recinfo->type=FIELD_NORMAL;
-+ recinfo++;
-+ bzero((uchar*) recinfo,sizeof(*recinfo));
-+ }
-+ else
-+ {
-+ recinfo->null_bit= 1 << (null_count & 7);
-+ recinfo->null_pos= null_count/8;
-+ }
-+ field->move_field(pos,null_flags+null_count/8,
-+ 1 << (null_count & 7));
-+ null_count++;
-+ }
-+ else
-+ field->move_field(pos,(uchar*) 0,0);
-+ if (field->type() == MYSQL_TYPE_BIT)
-+ {
-+ /* We have to reserve place for extra bits among null bits */
-+ ((Field_bit*) field)->set_bit_ptr(null_flags + null_count / 8,
-+ null_count & 7);
-+ null_count+= (field->field_length & 7);
-+ }
-+ field->reset();
-+
-+ /*
-+ Test if there is a default field value. The test for ->ptr is to skip
-+ 'offset' fields generated by initalize_tables
-+ */
-+ if (default_field[i] && default_field[i]->ptr)
-+ {
-+ /*
-+ default_field[i] is set only in the cases when 'field' can
-+ inherit the default value that is defined for the field referred
-+ by the Item_field object from which 'field' has been created.
-+ */
-+ my_ptrdiff_t diff;
-+ Field *orig_field= default_field[i];
-+ /* Get the value from default_values */
-+ diff= (my_ptrdiff_t) (orig_field->table->s->default_values-
-+ orig_field->table->record[0]);
-+ orig_field->move_field_offset(diff); // Points now at default_values
-+ if (orig_field->is_real_null())
-+ field->set_null();
-+ else
-+ {
-+ field->set_notnull();
-+ memcpy(field->ptr, orig_field->ptr, field->pack_length());
-+ }
-+ orig_field->move_field_offset(-diff); // Back to record[0]
-+ }
-+
-+ if (from_field[i])
-+ { /* Not a table Item */
-+ copy->set(field,from_field[i],save_sum_fields);
-+ copy++;
-+ }
-+ length=field->pack_length();
-+ pos+= length;
-+
-+ /* Make entry for create table */
-+ recinfo->length=length;
-+ if (field->flags & BLOB_FLAG)
-+ recinfo->type= (int) FIELD_BLOB;
-+ else if (use_packed_rows &&
-+ field->real_type() == MYSQL_TYPE_STRING &&
-+ length >= MIN_STRING_LENGTH_TO_PACK_ROWS)
-+ recinfo->type=FIELD_SKIP_ENDSPACE;
-+ else
-+ recinfo->type=FIELD_NORMAL;
-+ if (!--hidden_field_count)
-+ null_count=(null_count+7) & ~7; // move to next byte
-+
-+ // fix table name in field entry
-+ field->table_name= &table->alias;
-+ }
-+
-+ param->copy_field_end=copy;
-+ param->recinfo=recinfo;
-+ store_record(table,s->default_values); // Make empty default record
-+
-+ if (thd->variables.tmp_table_size == ~ (ulonglong) 0) // No limit
-+ share->max_rows= ~(ha_rows) 0;
-+ else
-+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
-+ min(thd->variables.tmp_table_size,
-+ thd->variables.max_heap_table_size) :
-+ thd->variables.tmp_table_size) /
-+ share->reclength);
-+ set_if_bigger(share->max_rows,1); // For dummy start options
-+ /*
-+ Push the LIMIT clause to the temporary table creation, so that we
-+ materialize only up to 'rows_limit' records instead of all result records.
-+ */
-+ set_if_smaller(share->max_rows, rows_limit);
-+ param->end_write_records= rows_limit;
-+
-+ keyinfo= param->keyinfo;
-+
-+ if (group)
-+ {
-+ DBUG_PRINT("info",("Creating group key in temporary table"));
-+ table->group=group; /* Table is grouped by key */
-+ param->group_buff=group_buff;
-+ share->keys=1;
-+ share->uniques= test(using_unique_constraint);
-+ table->key_info=keyinfo;
-+ keyinfo->key_part=key_part_info;
-+ keyinfo->flags=HA_NOSAME;
-+ keyinfo->usable_key_parts=keyinfo->key_parts= param->group_parts;
-+ keyinfo->key_length=0;
-+ keyinfo->rec_per_key=0;
-+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
-+ keyinfo->name= (char*) "group_key";
-+ ORDER *cur_group= group;
-+ for (; cur_group ; cur_group= cur_group->next, key_part_info++)
-+ {
-+ Field *field=(*cur_group->item)->get_tmp_table_field();
-+ DBUG_ASSERT(field->table == table);
-+ bool maybe_null=(*cur_group->item)->maybe_null;
-+ key_part_info->null_bit=0;
-+ key_part_info->field= field;
-+ key_part_info->offset= field->offset(table->record[0]);
-+ key_part_info->length= (uint16) field->key_length();
-+ key_part_info->type= (uint8) field->key_type();
-+ key_part_info->key_type =
-+ ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
-+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
-+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
-+ 0 : FIELDFLAG_BINARY;
-+ if (!using_unique_constraint)
-+ {
-+ cur_group->buff=(char*) group_buff;
-+ if (!(cur_group->field= field->new_key_field(thd->mem_root,table,
-+ group_buff +
-+ test(maybe_null),
-+ field->null_ptr,
-+ field->null_bit)))
-+ goto err; /* purecov: inspected */
-+ if (maybe_null)
-+ {
-+ /*
-+ To be able to group on NULL, we reserved place in group_buff
-+ for the NULL flag just before the column. (see above).
-+ The field data is after this flag.
-+ The NULL flag is updated in 'end_update()' and 'end_write()'
-+ */
-+ keyinfo->flags|= HA_NULL_ARE_EQUAL; // def. that NULL == NULL
-+ key_part_info->null_bit=field->null_bit;
-+ key_part_info->null_offset= (uint) (field->null_ptr -
-+ (uchar*) table->record[0]);
-+ cur_group->buff++; // Pointer to field data
-+ group_buff++; // Skipp null flag
-+ }
-+ /* In GROUP BY 'a' and 'a ' are equal for VARCHAR fields */
-+ key_part_info->key_part_flag|= HA_END_SPACE_ARE_EQUAL;
-+ group_buff+= cur_group->field->pack_length();
-+ }
-+ keyinfo->key_length+= key_part_info->length;
-+ }
-+ }
-+
-+ if (distinct && field_count != param->hidden_field_count)
-+ {
-+ /*
-+ Create an unique key or an unique constraint over all columns
-+ that should be in the result. In the temporary table, there are
-+ 'param->hidden_field_count' extra columns, whose null bits are stored
-+ in the first 'hidden_null_pack_length' bytes of the row.
-+ */
-+ DBUG_PRINT("info",("hidden_field_count: %d", param->hidden_field_count));
-+
-+ null_pack_length-=hidden_null_pack_length;
-+ keyinfo->key_parts= ((field_count-param->hidden_field_count)+
-+ test(null_pack_length));
-+ table->distinct= 1;
-+ share->keys= 1;
-+ if (blob_count)
-+ {
-+ using_unique_constraint=1;
-+ share->uniques= 1;
-+ }
-+ if (!(key_part_info= (KEY_PART_INFO*)
-+ alloc_root(&table->mem_root,
-+ keyinfo->key_parts * sizeof(KEY_PART_INFO))))
-+ goto err;
-+ bzero((void*) key_part_info, keyinfo->key_parts * sizeof(KEY_PART_INFO));
-+ table->key_info=keyinfo;
-+ keyinfo->key_part=key_part_info;
-+ keyinfo->flags=HA_NOSAME | HA_NULL_ARE_EQUAL;
-+ keyinfo->key_length=(uint16) reclength;
-+ keyinfo->name= (char*) "distinct_key";
-+ keyinfo->algorithm= HA_KEY_ALG_UNDEF;
-+ keyinfo->rec_per_key=0;
-+ if (null_pack_length)
-+ {
-+ key_part_info->null_bit=0;
-+ key_part_info->offset=hidden_null_pack_length;
-+ key_part_info->length=null_pack_length;
-+ key_part_info->field= new Field_string(table->record[0],
-+ (uint32) key_part_info->length,
-+ (uchar*) 0,
-+ (uint) 0,
-+ Field::NONE,
-+ NullS, &my_charset_bin);
-+ if (!key_part_info->field)
-+ goto err;
-+ key_part_info->field->init(table);
-+ key_part_info->key_type=FIELDFLAG_BINARY;
-+ key_part_info->type= HA_KEYTYPE_BINARY;
-+ key_part_info++;
-+ }
-+ /* Create a distinct key over the columns we are going to return */
-+ for (i=param->hidden_field_count, reg_field=table->field + i ;
-+ i < field_count;
-+ i++, reg_field++, key_part_info++)
-+ {
-+ key_part_info->null_bit=0;
-+ key_part_info->field= *reg_field;
-+ key_part_info->offset= (*reg_field)->offset(table->record[0]);
-+ key_part_info->length= (uint16) (*reg_field)->pack_length();
-+ key_part_info->type= (uint8) (*reg_field)->key_type();
-+ key_part_info->key_type =
-+ ((ha_base_keytype) key_part_info->type == HA_KEYTYPE_TEXT ||
-+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT1 ||
-+ (ha_base_keytype) key_part_info->type == HA_KEYTYPE_VARTEXT2) ?
-+ 0 : FIELDFLAG_BINARY;
-+ }
-+ }
-+
-+ if (thd->is_fatal_error) // If end of memory
-+ goto err; /* purecov: inspected */
-+ share->db_record_offset= 1;
-+ if (share->db_type() == myisam_hton)
-+ {
-+ if (create_myisam_tmp_table(table,param,select_options))
-+ goto err;
-+ }
-+ if (open_tmp_table(table))
-+ goto err;
-+
-+ thd->mem_root= mem_root_save;
-+
-+ DBUG_RETURN(table);
-+
-+err:
-+ thd->mem_root= mem_root_save;
-+ free_tmp_table(thd,table); /* purecov: inspected */
-+ if (temp_pool_slot != MY_BIT_NONE)
-+ bitmap_lock_clear_bit(&temp_pool, temp_pool_slot);
-+ DBUG_RETURN(NULL); /* purecov: inspected */
-+}
-+
-+
-+/****************************************************************************/
-+
-+/**
-+ Create a reduced TABLE object with properly set up Field list from a
-+ list of field definitions.
-+
-+ The created table doesn't have a table handler associated with
-+ it, has no keys, no group/distinct, no copy_funcs array.
-+ The sole purpose of this TABLE object is to use the power of Field
-+ class to read/write data to/from table->record[0]. Then one can store
-+ the record in any container (RB tree, hash, etc).
-+ The table is created in THD mem_root, so are the table's fields.
-+ Consequently, if you don't BLOB fields, you don't need to free it.
-+
-+ @param thd connection handle
-+ @param field_list list of column definitions
-+
-+ @return
-+ 0 if out of memory, TABLE object in case of success
-+*/
-+
-+TABLE *create_virtual_tmp_table(THD *thd, List<Create_field> &field_list)
-+{
-+ uint field_count= field_list.elements;
-+ uint blob_count= 0;
-+ Field **field;
-+ Create_field *cdef; /* column definition */
-+ uint record_length= 0;
-+ uint null_count= 0; /* number of columns which may be null */
-+ uint null_pack_length; /* NULL representation array length */
-+ uint *blob_field;
-+ uchar *bitmaps;
-+ TABLE *table;
-+ TABLE_SHARE *share;
-+
-+ if (!multi_alloc_root(thd->mem_root,
-+ &table, sizeof(*table),
-+ &share, sizeof(*share),
-+ &field, (field_count + 1) * sizeof(Field*),
-+ &blob_field, (field_count+1) *sizeof(uint),
-+ &bitmaps, bitmap_buffer_size(field_count)*2,
-+ NullS))
-+ return 0;
-+
-+ bzero(table, sizeof(*table));
-+ bzero(share, sizeof(*share));
-+ table->field= field;
-+ table->s= share;
-+ share->blob_field= blob_field;
-+ share->fields= field_count;
-+ share->blob_ptr_size= portable_sizeof_char_ptr;
-+ setup_tmp_table_column_bitmaps(table, bitmaps);
-+
-+ /* Create all fields and calculate the total length of record */
-+ List_iterator_fast<Create_field> it(field_list);
-+ while ((cdef= it++))
-+ {
-+ *field= make_field(share, 0, cdef->length,
-+ (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0),
-+ f_maybe_null(cdef->pack_flag) ? 1 : 0,
-+ cdef->pack_flag, cdef->sql_type, cdef->charset,
-+ cdef->geom_type, cdef->unireg_check,
-+ cdef->interval, cdef->field_name);
-+ if (!*field)
-+ goto error;
-+ (*field)->init(table);
-+ record_length+= (*field)->pack_length();
-+ if (! ((*field)->flags & NOT_NULL_FLAG))
-+ null_count++;
-+
-+ if ((*field)->flags & BLOB_FLAG)
-+ share->blob_field[blob_count++]= (uint) (field - table->field);
-+
-+ field++;
-+ }
-+ *field= NULL; /* mark the end of the list */
-+ share->blob_field[blob_count]= 0; /* mark the end of the list */
-+ share->blob_fields= blob_count;
-+
-+ null_pack_length= (null_count + 7)/8;
-+ share->reclength= record_length + null_pack_length;
-+ share->rec_buff_length= ALIGN_SIZE(share->reclength + 1);
-+ table->record[0]= (uchar*) thd->alloc(share->rec_buff_length);
-+ if (!table->record[0])
-+ goto error;
-+
-+ if (null_pack_length)
-+ {
-+ table->null_flags= (uchar*) table->record[0];
-+ share->null_fields= null_count;
-+ share->null_bytes= null_pack_length;
-+ }
-+
-+ table->in_use= thd; /* field->reset() may access table->in_use */
-+ {
-+ /* Set up field pointers */
-+ uchar *null_pos= table->record[0];
-+ uchar *field_pos= null_pos + share->null_bytes;
-+ uint null_bit= 1;
-+
-+ for (field= table->field; *field; ++field)
-+ {
-+ Field *cur_field= *field;
-+ if ((cur_field->flags & NOT_NULL_FLAG))
-+ cur_field->move_field(field_pos);
-+ else
-+ {
-+ cur_field->move_field(field_pos, (uchar*) null_pos, null_bit);
-+ null_bit<<= 1;
-+ if (null_bit == (1 << 8))
-+ {
-+ ++null_pos;
-+ null_bit= 1;
-+ }
-+ }
-+ cur_field->reset();
-+
-+ field_pos+= cur_field->pack_length();
-+ }
-+ }
-+ return table;
-+error:
-+ for (field= table->field; *field; ++field)
-+ delete *field; /* just invokes field destructor */
-+ return 0;
-+}
-+
-+
-+static bool open_tmp_table(TABLE *table)
-+{
-+ int error;
-+ if ((error=table->file->ha_open(table, table->s->table_name.str,O_RDWR,
-+ HA_OPEN_TMP_TABLE | HA_OPEN_INTERNAL_TABLE)))
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ table->db_stat=0;
-+ return(1);
-+ }
-+ (void) table->file->extra(HA_EXTRA_QUICK); /* Faster */
-+ return(0);
-+}
-+
-+
-+static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
-+ ulonglong options)
-+{
-+ int error;
-+ MI_KEYDEF keydef;
-+ MI_UNIQUEDEF uniquedef;
-+ KEY *keyinfo=param->keyinfo;
-+ TABLE_SHARE *share= table->s;
-+ DBUG_ENTER("create_myisam_tmp_table");
-+
-+ if (share->keys)
-+ { // Get keys for ni_create
-+ bool using_unique_constraint=0;
-+ HA_KEYSEG *seg= (HA_KEYSEG*) alloc_root(&table->mem_root,
-+ sizeof(*seg) * keyinfo->key_parts);
-+ if (!seg)
-+ goto err;
-+
-+ bzero(seg, sizeof(*seg) * keyinfo->key_parts);
-+ if (keyinfo->key_length >= table->file->max_key_length() ||
-+ keyinfo->key_parts > table->file->max_key_parts() ||
-+ share->uniques)
-+ {
-+ /* Can't create a key; Make a unique constraint instead of a key */
-+ share->keys= 0;
-+ share->uniques= 1;
-+ using_unique_constraint=1;
-+ bzero((char*) &uniquedef,sizeof(uniquedef));
-+ uniquedef.keysegs=keyinfo->key_parts;
-+ uniquedef.seg=seg;
-+ uniquedef.null_are_equal=1;
-+
-+ /* Create extra column for hash value */
-+ bzero((uchar*) param->recinfo,sizeof(*param->recinfo));
-+ param->recinfo->type= FIELD_CHECK;
-+ param->recinfo->length=MI_UNIQUE_HASH_LENGTH;
-+ param->recinfo++;
-+ share->reclength+=MI_UNIQUE_HASH_LENGTH;
-+ }
-+ else
-+ {
-+ /* Create an unique key */
-+ bzero((char*) &keydef,sizeof(keydef));
-+ keydef.flag=HA_NOSAME | HA_BINARY_PACK_KEY | HA_PACK_KEY;
-+ keydef.keysegs= keyinfo->key_parts;
-+ keydef.seg= seg;
-+ }
-+ for (uint i=0; i < keyinfo->key_parts ; i++,seg++)
-+ {
-+ Field *field=keyinfo->key_part[i].field;
-+ seg->flag= 0;
-+ seg->language= field->charset()->number;
-+ seg->length= keyinfo->key_part[i].length;
-+ seg->start= keyinfo->key_part[i].offset;
-+ if (field->flags & BLOB_FLAG)
-+ {
-+ seg->type=
-+ ((keyinfo->key_part[i].key_type & FIELDFLAG_BINARY) ?
-+ HA_KEYTYPE_VARBINARY2 : HA_KEYTYPE_VARTEXT2);
-+ seg->bit_start= (uint8)(field->pack_length() - share->blob_ptr_size);
-+ seg->flag= HA_BLOB_PART;
-+ seg->length=0; // Whole blob in unique constraint
-+ }
-+ else
-+ {
-+ seg->type= keyinfo->key_part[i].type;
-+ /* Tell handler if it can do suffic space compression */
-+ if (field->real_type() == MYSQL_TYPE_STRING &&
-+ keyinfo->key_part[i].length > 4)
-+ seg->flag|= HA_SPACE_PACK;
-+ }
-+ if (!(field->flags & NOT_NULL_FLAG))
-+ {
-+ seg->null_bit= field->null_bit;
-+ seg->null_pos= (uint) (field->null_ptr - (uchar*) table->record[0]);
-+ /*
-+ We are using a GROUP BY on something that contains NULL
-+ In this case we have to tell MyISAM that two NULL should
-+ on INSERT be regarded at the same value
-+ */
-+ if (!using_unique_constraint)
-+ keydef.flag|= HA_NULL_ARE_EQUAL;
-+ }
-+ }
-+ }
-+ MI_CREATE_INFO create_info;
-+ bzero((char*) &create_info,sizeof(create_info));
-+
-+ if ((options & (OPTION_BIG_TABLES | SELECT_SMALL_RESULT)) ==
-+ OPTION_BIG_TABLES)
-+ create_info.data_file_length= ~(ulonglong) 0;
-+
-+ if ((error=mi_create(share->table_name.str, share->keys, &keydef,
-+ (uint) (param->recinfo-param->start_recinfo),
-+ param->start_recinfo,
-+ share->uniques, &uniquedef,
-+ &create_info,
-+ HA_CREATE_TMP_TABLE)))
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ table->db_stat=0;
-+ goto err;
-+ }
-+ status_var_increment(table->in_use->status_var.created_tmp_disk_tables);
-+ share->db_record_offset= 1;
-+ DBUG_RETURN(0);
-+ err:
-+ DBUG_RETURN(1);
-+}
-+
-+
-+void
-+free_tmp_table(THD *thd, TABLE *entry)
-+{
-+ MEM_ROOT own_root= entry->mem_root;
-+ const char *save_proc_info;
-+ DBUG_ENTER("free_tmp_table");
-+ DBUG_PRINT("enter",("table: %s",entry->alias));
-+
-+ save_proc_info=thd->proc_info;
-+ thd_proc_info(thd, "removing tmp table");
-+
-+ // Release latches since this can take a long time
-+ ha_release_temporary_latches(thd);
-+
-+ if (entry->file)
-+ {
-+ if (entry->db_stat)
-+ entry->file->ha_drop_table(entry->s->table_name.str);
-+ else
-+ entry->file->ha_delete_table(entry->s->table_name.str);
-+ delete entry->file;
-+ }
-+
-+ /* free blobs */
-+ for (Field **ptr=entry->field ; *ptr ; ptr++)
-+ (*ptr)->free();
-+ free_io_cache(entry);
-+
-+ if (entry->temp_pool_slot != MY_BIT_NONE)
-+ bitmap_lock_clear_bit(&temp_pool, entry->temp_pool_slot);
-+
-+ plugin_unlock(0, entry->s->db_plugin);
-+
-+ free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
-+ thd_proc_info(thd, save_proc_info);
-+
-+ DBUG_VOID_RETURN;
-+}
-+
-+/**
-+ If a HEAP table gets full, create a MyISAM table and copy all rows
-+ to this.
-+*/
-+
-+bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
-+ int error, bool ignore_last_dupp_key_error)
-+{
-+ TABLE new_table;
-+ TABLE_SHARE share;
-+ const char *save_proc_info;
-+ int write_err;
-+ DBUG_ENTER("create_myisam_from_heap");
-+
-+ if (table->s->db_type() != heap_hton ||
-+ error != HA_ERR_RECORD_FILE_FULL)
-+ {
-+ /*
-+ We don't want this error to be converted to a warning, e.g. in case of
-+ INSERT IGNORE ... SELECT.
-+ */
-+ thd->fatal_error();
-+ table->file->print_error(error,MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+
-+ // Release latches since this can take a long time
-+ ha_release_temporary_latches(thd);
-+
-+ new_table= *table;
-+ share= *table->s;
-+ new_table.s= &share;
-+ new_table.s->db_plugin= ha_lock_engine(thd, myisam_hton);
-+ if (!(new_table.file= get_new_handler(&share, &new_table.mem_root,
-+ new_table.s->db_type())))
-+ DBUG_RETURN(1); // End of memory
-+
-+ save_proc_info=thd->proc_info;
-+ thd_proc_info(thd, "converting HEAP to MyISAM");
-+
-+ if (create_myisam_tmp_table(&new_table, param,
-+ thd->lex->select_lex.options | thd->options))
-+ goto err2;
-+ if (open_tmp_table(&new_table))
-+ goto err1;
-+ if (table->file->indexes_are_disabled())
-+ new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL);
-+ table->file->ha_index_or_rnd_end();
-+ table->file->ha_rnd_init(1);
-+ if (table->no_rows)
-+ {
-+ new_table.file->extra(HA_EXTRA_NO_ROWS);
-+ new_table.no_rows=1;
-+ }
-+
-+#ifdef TO_BE_DONE_LATER_IN_4_1
-+ /*
-+ To use start_bulk_insert() (which is new in 4.1) we need to find
-+ all places where a corresponding end_bulk_insert() should be put.
-+ */
-+ table->file->info(HA_STATUS_VARIABLE); /* update table->file->stats.records */
-+ new_table.file->ha_start_bulk_insert(table->file->stats.records);
-+#else
-+ /* HA_EXTRA_WRITE_CACHE can stay until close, no need to disable it */
-+ new_table.file->extra(HA_EXTRA_WRITE_CACHE);
-+#endif
-+
-+ /*
-+ copy all old rows from heap table to MyISAM table
-+ This is the only code that uses record[1] to read/write but this
-+ is safe as this is a temporary MyISAM table without timestamp/autoincrement
-+ or partitioning.
-+ */
-+ while (!table->file->rnd_next(new_table.record[1]))
-+ {
-+ write_err= new_table.file->ha_write_row(new_table.record[1]);
-+ DBUG_EXECUTE_IF("raise_error", write_err= HA_ERR_FOUND_DUPP_KEY ;);
-+ if (write_err)
-+ goto err;
-+ }
-+ /* copy row that filled HEAP table */
-+ if ((write_err=new_table.file->ha_write_row(table->record[0])))
-+ {
-+ if (new_table.file->is_fatal_error(write_err, HA_CHECK_DUP) ||
-+ !ignore_last_dupp_key_error)
-+ goto err;
-+ }
-+
-+ /* remove heap table and change to use myisam table */
-+ (void) table->file->ha_rnd_end();
-+ (void) table->file->close(); // This deletes the table !
-+ delete table->file;
-+ table->file=0;
-+ plugin_unlock(0, table->s->db_plugin);
-+ share.db_plugin= my_plugin_lock(0, &share.db_plugin);
-+ new_table.s= table->s; // Keep old share
-+ *table= new_table;
-+ *table->s= share;
-+
-+ table->file->change_table_ptr(table, table->s);
-+ table->use_all_columns();
-+ if (save_proc_info)
-+ thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
-+ "Copying to tmp table on disk" : save_proc_info));
-+ DBUG_RETURN(0);
-+
-+ err:
-+ DBUG_PRINT("error",("Got error: %d",write_err));
-+ table->file->print_error(write_err, MYF(0));
-+ (void) table->file->ha_rnd_end();
-+ (void) new_table.file->close();
-+ err1:
-+ new_table.file->ha_delete_table(new_table.s->table_name.str);
-+ err2:
-+ delete new_table.file;
-+ thd_proc_info(thd, save_proc_info);
-+ table->mem_root= new_table.mem_root;
-+ DBUG_RETURN(1);
-+}
-+
-+
-+/**
-+ @details
-+ Rows produced by a join sweep may end up in a temporary table or be sent
-+ to a client. Setup the function of the nested loop join algorithm which
-+ handles final fully constructed and matched records.
-+
-+ @param join join to setup the function for.
-+
-+ @return
-+ end_select function to use. This function can't fail.
-+*/
-+
-+Next_select_func setup_end_select_func(JOIN *join)
-+{
-+ TABLE *table= join->tmp_table;
-+ TMP_TABLE_PARAM *tmp_tbl= &join->tmp_table_param;
-+ Next_select_func end_select;
-+
-+ /* Set up select_end */
-+ if (table)
-+ {
-+ if (table->group && tmp_tbl->sum_func_count &&
-+ !tmp_tbl->precomputed_group_by)
-+ {
-+ if (table->s->keys)
-+ {
-+ DBUG_PRINT("info",("Using end_update"));
-+ end_select=end_update;
-+ }
-+ else
-+ {
-+ DBUG_PRINT("info",("Using end_unique_update"));
-+ end_select=end_unique_update;
-+ }
-+ }
-+ else if (join->sort_and_group && !tmp_tbl->precomputed_group_by)
-+ {
-+ DBUG_PRINT("info",("Using end_write_group"));
-+ end_select=end_write_group;
-+ }
-+ else
-+ {
-+ DBUG_PRINT("info",("Using end_write"));
-+ end_select=end_write;
-+ if (tmp_tbl->precomputed_group_by)
-+ {
-+ /*
-+ A preceding call to create_tmp_table in the case when loose
-+ index scan is used guarantees that
-+ TMP_TABLE_PARAM::items_to_copy has enough space for the group
-+ by functions. It is OK here to use memcpy since we copy
-+ Item_sum pointers into an array of Item pointers.
-+ */
-+ memcpy(tmp_tbl->items_to_copy + tmp_tbl->func_count,
-+ join->sum_funcs,
-+ sizeof(Item*)*tmp_tbl->sum_func_count);
-+ tmp_tbl->items_to_copy[tmp_tbl->func_count+tmp_tbl->sum_func_count]= 0;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ Choose method for presenting result to user. Use end_send_group
-+ if the query requires grouping (has a GROUP BY clause and/or one or
-+ more aggregate functions). Use end_send if the query should not
-+ be grouped.
-+ */
-+ if ((join->sort_and_group ||
-+ (join->procedure && join->procedure->flags & PROC_GROUP)) &&
-+ !tmp_tbl->precomputed_group_by)
-+ end_select= end_send_group;
-+ else
-+ end_select= end_send;
-+ }
-+ return end_select;
-+}
-+
-+
-+/**
-+ Make a join of all tables and write it on socket or to table.
-+
-+ @retval
-+ 0 if ok
-+ @retval
-+ 1 if error is sent
-+ @retval
-+ -1 if error should be sent
-+*/
-+
-+static int
-+do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure)
-+{
-+ int rc= 0;
-+ enum_nested_loop_state error= NESTED_LOOP_OK;
-+ JOIN_TAB *join_tab= NULL;
-+ DBUG_ENTER("do_select");
-+
-+ join->procedure=procedure;
-+ join->tmp_table= table; /* Save for easy recursion */
-+ join->fields= fields;
-+
-+ if (table)
-+ {
-+ VOID(table->file->extra(HA_EXTRA_WRITE_CACHE));
-+ empty_record(table);
-+ if (table->group && join->tmp_table_param.sum_func_count &&
-+ table->s->keys && !table->file->inited)
-+ table->file->ha_index_init(0, 0);
-+ }
-+ /* Set up select_end */
-+ Next_select_func end_select= setup_end_select_func(join);
-+ if (join->tables)
-+ {
-+ join->join_tab[join->tables-1].next_select= end_select;
-+
-+ join_tab=join->join_tab+join->const_tables;
-+ }
-+ join->send_records=0;
-+ if (join->tables == join->const_tables)
-+ {
-+ /*
-+ HAVING will be checked after processing aggregate functions,
-+ But WHERE should checkd here (we alredy have read tables)
-+ */
-+ if (!join->conds || join->conds->val_int())
-+ {
-+ error= (*end_select)(join, 0, 0);
-+ if (error == NESTED_LOOP_OK || error == NESTED_LOOP_QUERY_LIMIT)
-+ error= (*end_select)(join, 0, 1);
-+
-+ /*
-+ If we don't go through evaluate_join_record(), do the counting
-+ here. join->send_records is increased on success in end_send(),
-+ so we don't touch it here.
-+ */
-+ join->examined_rows++;
-+ join->thd->row_count++;
-+ DBUG_ASSERT(join->examined_rows <= 1);
-+ }
-+ else if (join->send_row_on_empty_set())
-+ {
-+ List<Item> *columns_list= (procedure ? &join->procedure_fields_list :
-+ fields);
-+ rc= join->result->send_data(*columns_list);
-+ }
-+ }
-+ else
-+ {
-+ DBUG_ASSERT(join->tables);
-+ error= sub_select(join,join_tab,0);
-+ if (error == NESTED_LOOP_OK || error == NESTED_LOOP_NO_MORE_ROWS)
-+ error= sub_select(join,join_tab,1);
-+ if (error == NESTED_LOOP_QUERY_LIMIT)
-+ error= NESTED_LOOP_OK; /* select_limit used */
-+ }
-+ if (error == NESTED_LOOP_NO_MORE_ROWS)
-+ error= NESTED_LOOP_OK;
-+
-+ if (table == NULL) // If sending data to client
-+ /*
-+ The following will unlock all cursors if the command wasn't an
-+ update command
-+ */
-+ join->join_free(); // Unlock all cursors
-+ if (error == NESTED_LOOP_OK)
-+ {
-+ /*
-+ Sic: this branch works even if rc != 0, e.g. when
-+ send_data above returns an error.
-+ */
-+ if (table == NULL && join->result->send_eof()) // If sending data to client
-+ rc= 1; // Don't send error
-+ DBUG_PRINT("info",("%ld records output", (long) join->send_records));
-+ }
-+ else
-+ rc= -1;
-+ if (table)
-+ {
-+ int tmp, new_errno= 0;
-+ if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
-+ {
-+ DBUG_PRINT("error",("extra(HA_EXTRA_NO_CACHE) failed"));
-+ new_errno= tmp;
-+ }
-+ if ((tmp=table->file->ha_index_or_rnd_end()))
-+ {
-+ DBUG_PRINT("error",("ha_index_or_rnd_end() failed"));
-+ new_errno= tmp;
-+ }
-+ if (new_errno)
-+ table->file->print_error(new_errno,MYF(0));
-+ }
-+#ifndef DBUG_OFF
-+ if (rc)
-+ {
-+ DBUG_PRINT("error",("Error: do_select() failed"));
-+ }
-+#endif
-+ DBUG_RETURN(join->thd->is_error() ? -1 : rc);
-+}
-+
-+
-+enum_nested_loop_state
-+sub_select_cache(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
-+{
-+ enum_nested_loop_state rc;
-+
-+ if (end_of_records)
-+ {
-+ rc= flush_cached_records(join,join_tab,FALSE);
-+ if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
-+ rc= sub_select(join,join_tab,end_of_records);
-+ return rc;
-+ }
-+ if (join->thd->killed) // If aborted by user
-+ {
-+ join->thd->send_kill_message();
-+ return NESTED_LOOP_KILLED; /* purecov: inspected */
-+ }
-+ if (join_tab->use_quick != 2 || test_if_quick_select(join_tab) <= 0)
-+ {
-+ if (!store_record_in_cache(&join_tab->cache))
-+ return NESTED_LOOP_OK; // There is more room in cache
-+ return flush_cached_records(join,join_tab,FALSE);
-+ }
-+ rc= flush_cached_records(join, join_tab, TRUE);
-+ if (rc == NESTED_LOOP_OK || rc == NESTED_LOOP_NO_MORE_ROWS)
-+ rc= sub_select(join, join_tab, end_of_records);
-+ return rc;
-+}
-+
-+/**
-+ Retrieve records ends with a given beginning from the result of a join.
-+
-+ For a given partial join record consisting of records from the tables
-+ preceding the table join_tab in the execution plan, the function
-+ retrieves all matching full records from the result set and
-+ send them to the result set stream.
-+
-+ @note
-+ The function effectively implements the final (n-k) nested loops
-+ of nested loops join algorithm, where k is the ordinal number of
-+ the join_tab table and n is the total number of tables in the join query.
-+ It performs nested loops joins with all conjunctive predicates from
-+ the where condition pushed as low to the tables as possible.
-+ E.g. for the query
-+ @code
-+ SELECT * FROM t1,t2,t3
-+ WHERE t1.a=t2.a AND t2.b=t3.b AND t1.a BETWEEN 5 AND 9
-+ @endcode
-+ the predicate (t1.a BETWEEN 5 AND 9) will be pushed to table t1,
-+ given the selected plan prescribes to nest retrievals of the
-+ joined tables in the following order: t1,t2,t3.
-+ A pushed down predicate are attached to the table which it pushed to,
-+ at the field join_tab->select_cond.
-+ When executing a nested loop of level k the function runs through
-+ the rows of 'join_tab' and for each row checks the pushed condition
-+ attached to the table.
-+ If it is false the function moves to the next row of the
-+ table. If the condition is true the function recursively executes (n-k-1)
-+ remaining embedded nested loops.
-+ The situation becomes more complicated if outer joins are involved in
-+ the execution plan. In this case the pushed down predicates can be
-+ checked only at certain conditions.
-+ Suppose for the query
-+ @code
-+ SELECT * FROM t1 LEFT JOIN (t2,t3) ON t3.a=t1.a
-+ WHERE t1>2 AND (t2.b>5 OR t2.b IS NULL)
-+ @endcode
-+ the optimizer has chosen a plan with the table order t1,t2,t3.
-+ The predicate P1=t1>2 will be pushed down to the table t1, while the
-+ predicate P2=(t2.b>5 OR t2.b IS NULL) will be attached to the table
-+ t2. But the second predicate can not be unconditionally tested right
-+ after a row from t2 has been read. This can be done only after the
-+ first row with t3.a=t1.a has been encountered.
-+ Thus, the second predicate P2 is supplied with a guarded value that are
-+ stored in the field 'found' of the first inner table for the outer join
-+ (table t2). When the first row with t3.a=t1.a for the current row
-+ of table t1 appears, the value becomes true. For now on the predicate
-+ is evaluated immediately after the row of table t2 has been read.
-+ When the first row with t3.a=t1.a has been encountered all
-+ conditions attached to the inner tables t2,t3 must be evaluated.
-+ Only when all of them are true the row is sent to the output stream.
-+ If not, the function returns to the lowest nest level that has a false
-+ attached condition.
-+ The predicates from on expressions are also pushed down. If in the
-+ the above example the on expression were (t3.a=t1.a AND t2.a=t1.a),
-+ then t1.a=t2.a would be pushed down to table t2, and without any
-+ guard.
-+ If after the run through all rows of table t2, the first inner table
-+ for the outer join operation, it turns out that no matches are
-+ found for the current row of t1, then current row from table t1
-+ is complemented by nulls for t2 and t3. Then the pushed down predicates
-+ are checked for the composed row almost in the same way as it had
-+ been done for the first row with a match. The only difference is
-+ the predicates from on expressions are not checked.
-+
-+ @par
-+ @b IMPLEMENTATION
-+ @par
-+ The function forms output rows for a current partial join of k
-+ tables tables recursively.
-+ For each partial join record ending with a certain row from
-+ join_tab it calls sub_select that builds all possible matching
-+ tails from the result set.
-+ To be able check predicates conditionally items of the class
-+ Item_func_trig_cond are employed.
-+ An object of this class is constructed from an item of class COND
-+ and a pointer to a guarding boolean variable.
-+ When the value of the guard variable is true the value of the object
-+ is the same as the value of the predicate, otherwise it's just returns
-+ true.
-+ To carry out a return to a nested loop level of join table t the pointer
-+ to t is remembered in the field 'return_tab' of the join structure.
-+ Consider the following query:
-+ @code
-+ SELECT * FROM t1,
-+ LEFT JOIN
-+ (t2, t3 LEFT JOIN (t4,t5) ON t5.a=t3.a)
-+ ON t4.a=t2.a
-+ WHERE (t2.b=5 OR t2.b IS NULL) AND (t4.b=2 OR t4.b IS NULL)
-+ @endcode
-+ Suppose the chosen execution plan dictates the order t1,t2,t3,t4,t5
-+ and suppose for a given joined rows from tables t1,t2,t3 there are
-+ no rows in the result set yet.
-+ When first row from t5 that satisfies the on condition
-+ t5.a=t3.a is found, the pushed down predicate t4.b=2 OR t4.b IS NULL
-+ becomes 'activated', as well the predicate t4.a=t2.a. But
-+ the predicate (t2.b=5 OR t2.b IS NULL) can not be checked until
-+ t4.a=t2.a becomes true.
-+ In order not to re-evaluate the predicates that were already evaluated
-+ as attached pushed down predicates, a pointer to the the first
-+ most inner unmatched table is maintained in join_tab->first_unmatched.
-+ Thus, when the first row from t5 with t5.a=t3.a is found
-+ this pointer for t5 is changed from t4 to t2.
-+
-+ @par
-+ @b STRUCTURE @b NOTES
-+ @par
-+ join_tab->first_unmatched points always backwards to the first inner
-+ table of the embedding nested join, if any.
-+
-+ @param join pointer to the structure providing all context info for
-+ the query
-+ @param join_tab the first next table of the execution plan to be retrieved
-+ @param end_records true when we need to perform final steps of retrival
-+
-+ @return
-+ return one of enum_nested_loop_state, except NESTED_LOOP_NO_MORE_ROWS.
-+*/
-+
-+enum_nested_loop_state
-+sub_select(JOIN *join,JOIN_TAB *join_tab,bool end_of_records)
-+{
-+ join_tab->table->null_row=0;
-+ if (end_of_records)
-+ return (*join_tab->next_select)(join,join_tab+1,end_of_records);
-+
-+ int error;
-+ enum_nested_loop_state rc;
-+ READ_RECORD *info= &join_tab->read_record;
-+
-+ if (join->resume_nested_loop)
-+ {
-+ /* If not the last table, plunge down the nested loop */
-+ if (join_tab < join->join_tab + join->tables - 1)
-+ rc= (*join_tab->next_select)(join, join_tab + 1, 0);
-+ else
-+ {
-+ join->resume_nested_loop= FALSE;
-+ rc= NESTED_LOOP_OK;
-+ }
-+ }
-+ else
-+ {
-+ join->return_tab= join_tab;
-+
-+ if (join_tab->last_inner)
-+ {
-+ /* join_tab is the first inner table for an outer join operation. */
-+
-+ /* Set initial state of guard variables for this table.*/
-+ join_tab->found=0;
-+ join_tab->not_null_compl= 1;
-+
-+ /* Set first_unmatched for the last inner table of this group */
-+ join_tab->last_inner->first_unmatched= join_tab;
-+ }
-+ join->thd->row_count= 0;
-+
-+ error= (*join_tab->read_first_record)(join_tab);
-+ rc= evaluate_join_record(join, join_tab, error);
-+ }
-+
-+ while (rc == NESTED_LOOP_OK)
-+ {
-+ error= info->read_record(info);
-+ rc= evaluate_join_record(join, join_tab, error);
-+ }
-+
-+ if (rc == NESTED_LOOP_NO_MORE_ROWS &&
-+ join_tab->last_inner && !join_tab->found)
-+ rc= evaluate_null_complemented_join_record(join, join_tab);
-+
-+ if (rc == NESTED_LOOP_NO_MORE_ROWS)
-+ rc= NESTED_LOOP_OK;
-+ return rc;
-+}
-+
-+
-+/**
-+ Process one record of the nested loop join.
-+
-+ This function will evaluate parts of WHERE/ON clauses that are
-+ applicable to the partial record on hand and in case of success
-+ submit this record to the next level of the nested loop.
-+*/
-+
-+static enum_nested_loop_state
-+evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
-+ int error)
-+{
-+ bool not_used_in_distinct=join_tab->not_used_in_distinct;
-+ ha_rows found_records=join->found_records;
-+ COND *select_cond= join_tab->select_cond;
-+ bool select_cond_result= TRUE;
-+
-+ if (error > 0 || (join->thd->is_error())) // Fatal error
-+ return NESTED_LOOP_ERROR;
-+ if (error < 0)
-+ return NESTED_LOOP_NO_MORE_ROWS;
-+ if (join->thd->killed) // Aborted by user
-+ {
-+ join->thd->send_kill_message();
-+ return NESTED_LOOP_KILLED; /* purecov: inspected */
-+ }
-+ DBUG_PRINT("info", ("select cond 0x%lx", (ulong)select_cond));
-+
-+ if (select_cond)
-+ {
-+ select_cond_result= test(select_cond->val_int());
-+
-+ /* check for errors evaluating the condition */
-+ if (join->thd->is_error())
-+ return NESTED_LOOP_ERROR;
-+ }
-+
-+ if (!select_cond || select_cond_result)
-+ {
-+ /*
-+ There is no select condition or the attached pushed down
-+ condition is true => a match is found.
-+ */
-+ bool found= 1;
-+ while (join_tab->first_unmatched && found)
-+ {
-+ /*
-+ The while condition is always false if join_tab is not
-+ the last inner join table of an outer join operation.
-+ */
-+ JOIN_TAB *first_unmatched= join_tab->first_unmatched;
-+ /*
-+ Mark that a match for current outer table is found.
-+ This activates push down conditional predicates attached
-+ to the all inner tables of the outer join.
-+ */
-+ first_unmatched->found= 1;
-+ for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
-+ {
-+ if (tab->table->reginfo.not_exists_optimize)
-+ return NESTED_LOOP_NO_MORE_ROWS;
-+ /* Check all predicates that has just been activated. */
-+ /*
-+ Actually all predicates non-guarded by first_unmatched->found
-+ will be re-evaluated again. It could be fixed, but, probably,
-+ it's not worth doing now.
-+ */
-+ if (tab->select_cond && !tab->select_cond->val_int())
-+ {
-+ /* The condition attached to table tab is false */
-+ if (tab == join_tab)
-+ found= 0;
-+ else
-+ {
-+ /*
-+ Set a return point if rejected predicate is attached
-+ not to the last table of the current nest level.
-+ */
-+ join->return_tab= tab;
-+ return NESTED_LOOP_OK;
-+ }
-+ }
-+ }
-+ /*
-+ Check whether join_tab is not the last inner table
-+ for another embedding outer join.
-+ */
-+ if ((first_unmatched= first_unmatched->first_upper) &&
-+ first_unmatched->last_inner != join_tab)
-+ first_unmatched= 0;
-+ join_tab->first_unmatched= first_unmatched;
-+ }
-+
-+ /*
-+ It was not just a return to lower loop level when one
-+ of the newly activated predicates is evaluated as false
-+ (See above join->return_tab= tab).
-+ */
-+ join->examined_rows++;
-+ join->thd->row_count++;
-+ DBUG_PRINT("counts", ("join->examined_rows++: %lu",
-+ (ulong) join->examined_rows));
-+
-+ if (found)
-+ {
-+ enum enum_nested_loop_state rc;
-+ /* A match from join_tab is found for the current partial join. */
-+ rc= (*join_tab->next_select)(join, join_tab+1, 0);
-+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
-+ return rc;
-+ if (join->return_tab < join_tab)
-+ return NESTED_LOOP_OK;
-+ /*
-+ Test if this was a SELECT DISTINCT query on a table that
-+ was not in the field list; In this case we can abort if
-+ we found a row, as no new rows can be added to the result.
-+ */
-+ if (not_used_in_distinct && found_records != join->found_records)
-+ return NESTED_LOOP_NO_MORE_ROWS;
-+ }
-+ else
-+ join_tab->read_record.unlock_row(join_tab);
-+ }
-+ else
-+ {
-+ /*
-+ The condition pushed down to the table join_tab rejects all rows
-+ with the beginning coinciding with the current partial join.
-+ */
-+ join->examined_rows++;
-+ join->thd->row_count++;
-+ join_tab->read_record.unlock_row(join_tab);
-+ }
-+ return NESTED_LOOP_OK;
-+}
-+
-+
-+/**
-+
-+ @details
-+ Construct a NULL complimented partial join record and feed it to the next
-+ level of the nested loop. This function is used in case we have
-+ an OUTER join and no matching record was found.
-+*/
-+
-+static enum_nested_loop_state
-+evaluate_null_complemented_join_record(JOIN *join, JOIN_TAB *join_tab)
-+{
-+ /*
-+ The table join_tab is the first inner table of a outer join operation
-+ and no matches has been found for the current outer row.
-+ */
-+ JOIN_TAB *last_inner_tab= join_tab->last_inner;
-+ /* Cache variables for faster loop */
-+ COND *select_cond;
-+ for ( ; join_tab <= last_inner_tab ; join_tab++)
-+ {
-+ /* Change the the values of guard predicate variables. */
-+ join_tab->found= 1;
-+ join_tab->not_null_compl= 0;
-+ /* The outer row is complemented by nulls for each inner tables */
-+ restore_record(join_tab->table,s->default_values); // Make empty record
-+ mark_as_null_row(join_tab->table); // For group by without error
-+ select_cond= join_tab->select_cond;
-+ /* Check all attached conditions for inner table rows. */
-+ if (select_cond && !select_cond->val_int())
-+ return NESTED_LOOP_OK;
-+ }
-+ join_tab--;
-+ /*
-+ The row complemented by nulls might be the first row
-+ of embedding outer joins.
-+ If so, perform the same actions as in the code
-+ for the first regular outer join row above.
-+ */
-+ for ( ; ; )
-+ {
-+ JOIN_TAB *first_unmatched= join_tab->first_unmatched;
-+ if ((first_unmatched= first_unmatched->first_upper) &&
-+ first_unmatched->last_inner != join_tab)
-+ first_unmatched= 0;
-+ join_tab->first_unmatched= first_unmatched;
-+ if (!first_unmatched)
-+ break;
-+ first_unmatched->found= 1;
-+ for (JOIN_TAB *tab= first_unmatched; tab <= join_tab; tab++)
-+ {
-+ if (tab->select_cond && !tab->select_cond->val_int())
-+ {
-+ join->return_tab= tab;
-+ return NESTED_LOOP_OK;
-+ }
-+ }
-+ }
-+ /*
-+ The row complemented by nulls satisfies all conditions
-+ attached to inner tables.
-+ Send the row complemented by nulls to be joined with the
-+ remaining tables.
-+ */
-+ return (*join_tab->next_select)(join, join_tab+1, 0);
-+}
-+
-+
-+static enum_nested_loop_state
-+flush_cached_records(JOIN *join,JOIN_TAB *join_tab,bool skip_last)
-+{
-+ enum_nested_loop_state rc= NESTED_LOOP_OK;
-+ int error;
-+ READ_RECORD *info;
-+
-+ join_tab->table->null_row= 0;
-+ if (!join_tab->cache.records)
-+ return NESTED_LOOP_OK; /* Nothing to do */
-+ if (skip_last)
-+ (void) store_record_in_cache(&join_tab->cache); // Must save this for later
-+ if (join_tab->use_quick == 2)
-+ {
-+ if (join_tab->select->quick)
-+ { /* Used quick select last. reset it */
-+ delete join_tab->select->quick;
-+ join_tab->select->quick=0;
-+ }
-+ }
-+ /* read through all records */
-+ if ((error=join_init_read_record(join_tab)))
-+ {
-+ reset_cache_write(&join_tab->cache);
-+ return error < 0 ? NESTED_LOOP_NO_MORE_ROWS: NESTED_LOOP_ERROR;
-+ }
-+
-+ for (JOIN_TAB *tmp=join->join_tab; tmp != join_tab ; tmp++)
-+ {
-+ tmp->status=tmp->table->status;
-+ tmp->table->status=0;
-+ }
-+
-+ info= &join_tab->read_record;
-+ do
-+ {
-+ if (join->thd->killed)
-+ {
-+ join->thd->send_kill_message();
-+ return NESTED_LOOP_KILLED; // Aborted by user /* purecov: inspected */
-+ }
-+ SQL_SELECT *select=join_tab->select;
-+ if (rc == NESTED_LOOP_OK)
-+ {
-+ bool skip_record= FALSE;
-+ if (join_tab->cache.select &&
-+ join_tab->cache.select->skip_record(join->thd, &skip_record))
-+ {
-+ reset_cache_write(&join_tab->cache);
-+ return NESTED_LOOP_ERROR;
-+ }
-+
-+ if (!skip_record)
-+ {
-+ uint i;
-+ reset_cache_read(&join_tab->cache);
-+ for (i=(join_tab->cache.records- (skip_last ? 1 : 0)) ; i-- > 0 ;)
-+ {
-+ read_cached_record(join_tab);
-+ skip_record= FALSE;
-+ if (select && select->skip_record(join->thd, &skip_record))
-+ {
-+ reset_cache_write(&join_tab->cache);
-+ return NESTED_LOOP_ERROR;
-+ }
-+ if (!skip_record)
-+ {
-+ rc= (join_tab->next_select)(join,join_tab+1,0);
-+ if (rc != NESTED_LOOP_OK && rc != NESTED_LOOP_NO_MORE_ROWS)
-+ {
-+ reset_cache_write(&join_tab->cache);
-+ return rc;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ } while (!(error=info->read_record(info)));
-+
-+ if (skip_last)
-+ read_cached_record(join_tab); // Restore current record
-+ reset_cache_write(&join_tab->cache);
-+ if (error > 0) // Fatal error
-+ return NESTED_LOOP_ERROR; /* purecov: inspected */
-+ for (JOIN_TAB *tmp2=join->join_tab; tmp2 != join_tab ; tmp2++)
-+ tmp2->table->status=tmp2->status;
-+ return NESTED_LOOP_OK;
-+}
-+
-+
-+/*****************************************************************************
-+ The different ways to read a record
-+ Returns -1 if row was not found, 0 if row was found and 1 on errors
-+*****************************************************************************/
-+
-+/** Help function when we get some an error from the table handler. */
-+
-+int report_error(TABLE *table, int error)
-+{
-+ if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND)
-+ {
-+ table->status= STATUS_GARBAGE;
-+ return -1; // key not found; ok
-+ }
-+ /*
-+ Locking reads can legally return also these errors, do not
-+ print them to the .err log
-+ */
-+ if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT)
-+ sql_print_error("Got error %d when reading table '%s'",
-+ error, table->s->path.str);
-+ table->file->print_error(error,MYF(0));
-+ return 1;
-+}
-+
-+
-+int safe_index_read(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+ if ((error=table->file->index_read_map(table->record[0],
-+ tab->ref.key_buff,
-+ make_prev_keypart_map(tab->ref.key_parts),
-+ HA_READ_KEY_EXACT)))
-+ return report_error(table, error);
-+ return 0;
-+}
-+
-+
-+static int
-+join_read_const_table(JOIN_TAB *tab, POSITION *pos)
-+{
-+ int error;
-+ DBUG_ENTER("join_read_const_table");
-+ TABLE *table=tab->table;
-+ table->const_table=1;
-+ table->null_row=0;
-+ table->status=STATUS_NO_RECORD;
-+
-+ if (tab->type == JT_SYSTEM)
-+ {
-+ if ((error=join_read_system(tab)))
-+ { // Info for DESCRIBE
-+ tab->info="const row not found";
-+ /* Mark for EXPLAIN that the row was not found */
-+ pos->records_read=0.0;
-+ pos->ref_depend_map= 0;
-+ if (!table->maybe_null || error > 0)
-+ DBUG_RETURN(error);
-+ }
-+ }
-+ else
-+ {
-+ if (!table->key_read && table->covering_keys.is_set(tab->ref.key) &&
-+ !table->no_keyread &&
-+ (int) table->reginfo.lock_type <= (int) TL_READ_HIGH_PRIORITY)
-+ {
-+ table->set_keyread(TRUE);
-+ tab->index= tab->ref.key;
-+ }
-+ error=join_read_const(tab);
-+ table->set_keyread(FALSE);
-+ if (error)
-+ {
-+ tab->info="unique row not found";
-+ /* Mark for EXPLAIN that the row was not found */
-+ pos->records_read=0.0;
-+ pos->ref_depend_map= 0;
-+ if (!table->maybe_null || error > 0)
-+ DBUG_RETURN(error);
-+ }
-+ }
-+ if (*tab->on_expr_ref && !table->null_row)
-+ {
-+ if ((table->null_row= test((*tab->on_expr_ref)->val_int() == 0)))
-+ mark_as_null_row(table);
-+ }
-+ if (!table->null_row)
-+ table->maybe_null=0;
-+
-+ /* Check appearance of new constant items in Item_equal objects */
-+ JOIN *join= tab->join;
-+ if (join->conds)
-+ update_const_equal_items(join->conds, tab);
-+ TABLE_LIST *tbl;
-+ for (tbl= join->select_lex->leaf_tables; tbl; tbl= tbl->next_leaf)
-+ {
-+ TABLE_LIST *embedded;
-+ TABLE_LIST *embedding= tbl;
-+ do
-+ {
-+ embedded= embedding;
-+ if (embedded->on_expr)
-+ update_const_equal_items(embedded->on_expr, tab);
-+ embedding= embedded->embedding;
-+ }
-+ while (embedding &&
-+ embedding->nested_join->join_list.head() == embedded);
-+ }
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static int
-+join_read_system(JOIN_TAB *tab)
-+{
-+ TABLE *table= tab->table;
-+ int error;
-+ if (table->status & STATUS_GARBAGE) // If first read
-+ {
-+ if ((error=table->file->read_first_row(table->record[0],
-+ table->s->primary_key)))
-+ {
-+ if (error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+ mark_as_null_row(tab->table);
-+ empty_record(table); // Make empty record
-+ return -1;
-+ }
-+ store_record(table,record[1]);
-+ }
-+ else if (!table->status) // Only happens with left join
-+ restore_record(table,record[1]); // restore old record
-+ table->null_row=0;
-+ return table->status ? -1 : 0;
-+}
-+
-+
-+/**
-+ Read a table when there is at most one matching row.
-+
-+ @param tab Table to read
-+
-+ @retval
-+ 0 Row was found
-+ @retval
-+ -1 Row was not found
-+ @retval
-+ 1 Got an error (other than row not found) during read
-+*/
-+
-+static int
-+join_read_const(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+ if (table->status & STATUS_GARBAGE) // If first read
-+ {
-+ table->status= 0;
-+ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
-+ error=HA_ERR_KEY_NOT_FOUND;
-+ else
-+ {
-+ error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
-+ (uchar*) tab->ref.key_buff,
-+ make_prev_keypart_map(tab->ref.key_parts),
-+ HA_READ_KEY_EXACT);
-+ }
-+ if (error)
-+ {
-+ table->status= STATUS_NOT_FOUND;
-+ mark_as_null_row(tab->table);
-+ empty_record(table);
-+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+ return -1;
-+ }
-+ store_record(table,record[1]);
-+ }
-+ else if (!(table->status & ~STATUS_NULL_ROW)) // Only happens with left join
-+ {
-+ table->status=0;
-+ restore_record(table,record[1]); // restore old record
-+ }
-+ table->null_row=0;
-+ return table->status ? -1 : 0;
-+}
-+
-+
-+static int
-+join_read_key(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+
-+ if (!table->file->inited)
-+ {
-+ table->file->ha_index_init(tab->ref.key, tab->sorted);
-+ }
-+ if (cmp_buffer_with_ref(tab) ||
-+ (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW)))
-+ {
-+ if (tab->ref.key_err)
-+ {
-+ table->status=STATUS_NOT_FOUND;
-+ return -1;
-+ }
-+ /*
-+ Moving away from the current record. Unlock the row
-+ in the handler if it did not match the partial WHERE.
-+ */
-+ if (tab->ref.has_record && tab->ref.use_count == 0)
-+ {
-+ tab->read_record.file->unlock_row();
-+ tab->ref.has_record= FALSE;
-+ }
-+ error=table->file->index_read_map(table->record[0],
-+ tab->ref.key_buff,
-+ make_prev_keypart_map(tab->ref.key_parts),
-+ HA_READ_KEY_EXACT);
-+ if (error && error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+
-+ if (! error)
-+ {
-+ tab->ref.has_record= TRUE;
-+ tab->ref.use_count= 1;
-+ }
-+ }
-+ else if (table->status == 0)
-+ {
-+ DBUG_ASSERT(tab->ref.has_record);
-+ tab->ref.use_count++;
-+ }
-+ table->null_row=0;
-+ return table->status ? -1 : 0;
-+}
-+
-+
-+/**
-+ Since join_read_key may buffer a record, do not unlock
-+ it if it was not used in this invocation of join_read_key().
-+ Only count locks, thus remembering if the record was left unused,
-+ and unlock already when pruning the current value of
-+ TABLE_REF buffer.
-+ @sa join_read_key()
-+*/
-+
-+static void
-+join_read_key_unlock_row(st_join_table *tab)
-+{
-+ DBUG_ASSERT(tab->ref.use_count);
-+ if (tab->ref.use_count)
-+ tab->ref.use_count--;
-+}
-+
-+/*
-+ ref access method implementation: "read_first" function
-+
-+ SYNOPSIS
-+ join_read_always_key()
-+ tab JOIN_TAB of the accessed table
-+
-+ DESCRIPTION
-+ This is "read_fist" function for the "ref" access method.
-+
-+ The functon must leave the index initialized when it returns.
-+ ref_or_null access implementation depends on that.
-+
-+ RETURN
-+ 0 - Ok
-+ -1 - Row not found
-+ 1 - Error
-+*/
-+
-+static int
-+join_read_always_key(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+
-+ /* Initialize the index first */
-+ if (!table->file->inited)
-+ table->file->ha_index_init(tab->ref.key, tab->sorted);
-+
-+ /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
-+ for (uint i= 0 ; i < tab->ref.key_parts ; i++)
-+ {
-+ if ((tab->ref.null_rejecting & 1 << i) && tab->ref.items[i]->is_null())
-+ return -1;
-+ }
-+
-+ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
-+ return -1;
-+ if ((error=table->file->index_read_map(table->record[0],
-+ tab->ref.key_buff,
-+ make_prev_keypart_map(tab->ref.key_parts),
-+ HA_READ_KEY_EXACT)))
-+ {
-+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+ return -1; /* purecov: inspected */
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ This function is used when optimizing away ORDER BY in
-+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC.
-+*/
-+
-+static int
-+join_read_last_key(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+
-+ if (!table->file->inited)
-+ table->file->ha_index_init(tab->ref.key, tab->sorted);
-+ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
-+ return -1;
-+ if ((error=table->file->index_read_last_map(table->record[0],
-+ tab->ref.key_buff,
-+ make_prev_keypart_map(tab->ref.key_parts))))
-+ {
-+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+ return -1; /* purecov: inspected */
-+ }
-+ return 0;
-+}
-+
-+
-+ /* ARGSUSED */
-+static int
-+join_no_more_records(READ_RECORD *info __attribute__((unused)))
-+{
-+ return -1;
-+}
-+
-+
-+static int
-+join_read_next_same(READ_RECORD *info)
-+{
-+ int error;
-+ TABLE *table= info->table;
-+ JOIN_TAB *tab=table->reginfo.join_tab;
-+
-+ if ((error=table->file->index_next_same(table->record[0],
-+ tab->ref.key_buff,
-+ tab->ref.key_length)))
-+ {
-+ if (error != HA_ERR_END_OF_FILE)
-+ return report_error(table, error);
-+ table->status= STATUS_GARBAGE;
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+
-+static int
-+join_read_prev_same(READ_RECORD *info)
-+{
-+ int error;
-+ TABLE *table= info->table;
-+ JOIN_TAB *tab=table->reginfo.join_tab;
-+
-+ if ((error=table->file->index_prev(table->record[0])))
-+ return report_error(table, error);
-+ if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
-+ tab->ref.key_length))
-+ {
-+ table->status=STATUS_NOT_FOUND;
-+ error= -1;
-+ }
-+ return error;
-+}
-+
-+
-+static int
-+join_init_quick_read_record(JOIN_TAB *tab)
-+{
-+ if (test_if_quick_select(tab) == -1)
-+ return -1; /* No possible records */
-+ return join_init_read_record(tab);
-+}
-+
-+
-+int rr_sequential(READ_RECORD *info);
-+int init_read_record_seq(JOIN_TAB *tab)
-+{
-+ tab->read_record.read_record= rr_sequential;
-+ if (tab->read_record.file->ha_rnd_init(1))
-+ return 1;
-+ return (*tab->read_record.read_record)(&tab->read_record);
-+}
-+
-+static int
-+test_if_quick_select(JOIN_TAB *tab)
-+{
-+ delete tab->select->quick;
-+ tab->select->quick=0;
-+ return tab->select->test_quick_select(tab->join->thd, tab->keys,
-+ (table_map) 0, HA_POS_ERROR, 0);
-+}
-+
-+
-+static int
-+join_init_read_record(JOIN_TAB *tab)
-+{
-+ if (tab->select && tab->select->quick && tab->select->quick->reset())
-+ return 1;
-+ init_read_record(&tab->read_record, tab->join->thd, tab->table,
-+ tab->select,1,1, FALSE);
-+ return (*tab->read_record.read_record)(&tab->read_record);
-+}
-+
-+
-+static int
-+join_read_first(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table=tab->table;
-+ if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
-+ table->set_keyread(TRUE);
-+ tab->table->status=0;
-+ tab->read_record.read_record=join_read_next;
-+ tab->read_record.table=table;
-+ tab->read_record.file=table->file;
-+ tab->read_record.index=tab->index;
-+ tab->read_record.record=table->record[0];
-+ if (!table->file->inited)
-+ table->file->ha_index_init(tab->index, tab->sorted);
-+ if ((error=tab->table->file->index_first(tab->table->record[0])))
-+ {
-+ if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
-+ report_error(table, error);
-+ return -1;
-+ }
-+ return 0;
-+}
-+
-+
-+static int
-+join_read_next(READ_RECORD *info)
-+{
-+ int error;
-+ if ((error=info->file->index_next(info->record)))
-+ return report_error(info->table, error);
-+ return 0;
-+}
-+
-+
-+static int
-+join_read_last(JOIN_TAB *tab)
-+{
-+ TABLE *table=tab->table;
-+ int error;
-+ if (table->covering_keys.is_set(tab->index) && !table->no_keyread)
-+ table->set_keyread(TRUE);
-+ tab->table->status=0;
-+ tab->read_record.read_record=join_read_prev;
-+ tab->read_record.table=table;
-+ tab->read_record.file=table->file;
-+ tab->read_record.index=tab->index;
-+ tab->read_record.record=table->record[0];
-+ if (!table->file->inited)
-+ table->file->ha_index_init(tab->index, 1);
-+ if ((error= tab->table->file->index_last(tab->table->record[0])))
-+ return report_error(table, error);
-+ return 0;
-+}
-+
-+
-+static int
-+join_read_prev(READ_RECORD *info)
-+{
-+ int error;
-+ if ((error= info->file->index_prev(info->record)))
-+ return report_error(info->table, error);
-+ return 0;
-+}
-+
-+
-+static int
-+join_ft_read_first(JOIN_TAB *tab)
-+{
-+ int error;
-+ TABLE *table= tab->table;
-+
-+ if (!table->file->inited)
-+ table->file->ha_index_init(tab->ref.key, 1);
-+#if NOT_USED_YET
-+ /* as ft-key doesn't use store_key's, see also FT_SELECT::init() */
-+ if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref))
-+ return -1;
-+#endif
-+ table->file->ft_init();
-+
-+ if ((error= table->file->ft_read(table->record[0])))
-+ return report_error(table, error);
-+ return 0;
-+}
-+
-+static int
-+join_ft_read_next(READ_RECORD *info)
-+{
-+ int error;
-+ if ((error= info->file->ft_read(info->table->record[0])))
-+ return report_error(info->table, error);
-+ return 0;
-+}
-+
-+
-+/**
-+ Reading of key with key reference and one part that may be NULL.
-+*/
-+
-+int
-+join_read_always_key_or_null(JOIN_TAB *tab)
-+{
-+ int res;
-+
-+ /* First read according to key which is NOT NULL */
-+ *tab->ref.null_ref_key= 0; // Clear null byte
-+ if ((res= join_read_always_key(tab)) >= 0)
-+ return res;
-+
-+ /* Then read key with null value */
-+ *tab->ref.null_ref_key= 1; // Set null byte
-+ return safe_index_read(tab);
-+}
-+
-+
-+int
-+join_read_next_same_or_null(READ_RECORD *info)
-+{
-+ int error;
-+ if ((error= join_read_next_same(info)) >= 0)
-+ return error;
-+ JOIN_TAB *tab= info->table->reginfo.join_tab;
-+
-+ /* Test if we have already done a read after null key */
-+ if (*tab->ref.null_ref_key)
-+ return -1; // All keys read
-+ *tab->ref.null_ref_key= 1; // Set null byte
-+ return safe_index_read(tab); // then read null keys
-+}
-+
-+
-+/*****************************************************************************
-+ DESCRIPTION
-+ Functions that end one nested loop iteration. Different functions
-+ are used to support GROUP BY clause and to redirect records
-+ to a table (e.g. in case of SELECT into a temporary table) or to the
-+ network client.
-+
-+ RETURN VALUES
-+ NESTED_LOOP_OK - the record has been successfully handled
-+ NESTED_LOOP_ERROR - a fatal error (like table corruption)
-+ was detected
-+ NESTED_LOOP_KILLED - thread shutdown was requested while processing
-+ the record
-+ NESTED_LOOP_QUERY_LIMIT - the record has been successfully handled;
-+ additionally, the nested loop produced the
-+ number of rows specified in the LIMIT clause
-+ for the query
-+ NESTED_LOOP_CURSOR_LIMIT - the record has been successfully handled;
-+ additionally, there is a cursor and the nested
-+ loop algorithm produced the number of rows
-+ that is specified for current cursor fetch
-+ operation.
-+ All return values except NESTED_LOOP_OK abort the nested loop.
-+*****************************************************************************/
-+
-+/* ARGSUSED */
-+static enum_nested_loop_state
-+end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ DBUG_ENTER("end_send");
-+ if (!end_of_records)
-+ {
-+ int error;
-+ if (join->having && join->having->val_int() == 0)
-+ DBUG_RETURN(NESTED_LOOP_OK); // Didn't match having
-+ error=0;
-+ if (join->procedure)
-+ error=join->procedure->send_row(join->procedure_fields_list);
-+ else if (join->do_send_rows)
-+ error=join->result->send_data(*join->fields);
-+ if (error)
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ if (++join->send_records >= join->unit->select_limit_cnt &&
-+ join->do_send_rows)
-+ {
-+ if (join->select_options & OPTION_FOUND_ROWS)
-+ {
-+ JOIN_TAB *jt=join->join_tab;
-+ if ((join->tables == 1) && !join->tmp_table && !join->sort_and_group
-+ && !join->send_group_parts && !join->having && !jt->select_cond &&
-+ !(jt->select && jt->select->quick) &&
-+ (jt->table->file->ha_table_flags() & HA_STATS_RECORDS_IS_EXACT) &&
-+ (jt->ref.key < 0))
-+ {
-+ /* Join over all rows in table; Return number of found rows */
-+ TABLE *table=jt->table;
-+
-+ join->select_options ^= OPTION_FOUND_ROWS;
-+ if (table->sort.record_pointers ||
-+ (table->sort.io_cache && my_b_inited(table->sort.io_cache)))
-+ {
-+ /* Using filesort */
-+ join->send_records= table->sort.found_records;
-+ }
-+ else
-+ {
-+ table->file->info(HA_STATUS_VARIABLE);
-+ join->send_records= table->file->stats.records;
-+ }
-+ }
-+ else
-+ {
-+ join->do_send_rows= 0;
-+ if (join->unit->fake_select_lex)
-+ join->unit->fake_select_lex->select_limit= 0;
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ }
-+ }
-+ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
-+ }
-+ else if (join->send_records >= join->fetch_limit)
-+ {
-+ /*
-+ There is a server side cursor and all rows for
-+ this fetch request are sent.
-+ */
-+ DBUG_RETURN(NESTED_LOOP_CURSOR_LIMIT);
-+ }
-+ }
-+ else
-+ {
-+ if (join->procedure && join->procedure->end_of_records())
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ }
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+
-+ /* ARGSUSED */
-+static enum_nested_loop_state
-+end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ int idx= -1;
-+ enum_nested_loop_state ok_code= NESTED_LOOP_OK;
-+ DBUG_ENTER("end_send_group");
-+
-+ if (!join->first_record || end_of_records ||
-+ (idx=test_if_group_changed(join->group_fields)) >= 0)
-+ {
-+ if (join->first_record ||
-+ (end_of_records && !join->group && !join->group_optimized_away))
-+ {
-+ if (join->procedure)
-+ join->procedure->end_group();
-+ if (idx < (int) join->send_group_parts)
-+ {
-+ int error=0;
-+ if (join->procedure)
-+ {
-+ if (join->having && join->having->val_int() == 0)
-+ error= -1; // Didn't satisfy having
-+ else
-+ {
-+ if (join->do_send_rows)
-+ error=join->procedure->send_row(*join->fields) ? 1 : 0;
-+ join->send_records++;
-+ }
-+ if (end_of_records && join->procedure->end_of_records())
-+ error= 1; // Fatal error
-+ }
-+ else
-+ {
-+ if (!join->first_record)
-+ {
-+ List_iterator_fast<Item> it(*join->fields);
-+ Item *item;
-+ /* No matching rows for group function */
-+ join->clear();
-+
-+ while ((item= it++))
-+ item->no_rows_in_result();
-+ }
-+ if (join->having && join->having->val_int() == 0)
-+ error= -1; // Didn't satisfy having
-+ else
-+ {
-+ if (join->do_send_rows)
-+ error=join->result->send_data(*join->fields) ? 1 : 0;
-+ join->send_records++;
-+ }
-+ if (join->rollup.state != ROLLUP::STATE_NONE && error <= 0)
-+ {
-+ if (join->rollup_send_data((uint) (idx+1)))
-+ error= 1;
-+ }
-+ }
-+ if (error > 0)
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ if (join->send_records >= join->unit->select_limit_cnt &&
-+ join->do_send_rows)
-+ {
-+ if (!(join->select_options & OPTION_FOUND_ROWS))
-+ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT); // Abort nicely
-+ join->do_send_rows=0;
-+ join->unit->select_limit_cnt = HA_POS_ERROR;
-+ }
-+ else if (join->send_records >= join->fetch_limit)
-+ {
-+ /*
-+ There is a server side cursor and all rows
-+ for this fetch request are sent.
-+ */
-+ /*
-+ Preventing code duplication. When finished with the group reset
-+ the group functions and copy_fields. We fall through. bug #11904
-+ */
-+ ok_code= NESTED_LOOP_CURSOR_LIMIT;
-+ }
-+ }
-+ }
-+ else
-+ {
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ join->first_record=1;
-+ VOID(test_if_group_changed(join->group_fields));
-+ }
-+ if (idx < (int) join->send_group_parts)
-+ {
-+ /*
-+ This branch is executed also for cursors which have finished their
-+ fetch limit - the reason for ok_code.
-+ */
-+ copy_fields(&join->tmp_table_param);
-+ if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ if (join->procedure)
-+ join->procedure->add();
-+ DBUG_RETURN(ok_code);
-+ }
-+ }
-+ if (update_sum_func(join->sum_funcs))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ if (join->procedure)
-+ join->procedure->add();
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+
-+ /* ARGSUSED */
-+static enum_nested_loop_state
-+end_write(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ TABLE *table=join->tmp_table;
-+ DBUG_ENTER("end_write");
-+
-+ if (join->thd->killed) // Aborted by user
-+ {
-+ join->thd->send_kill_message();
-+ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
-+ }
-+ if (!end_of_records)
-+ {
-+ copy_fields(&join->tmp_table_param);
-+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+
-+#ifdef TO_BE_DELETED
-+ if (!table->uniques) // If not unique handling
-+ {
-+ /* Copy null values from group to row */
-+ ORDER *group;
-+ for (group=table->group ; group ; group=group->next)
-+ {
-+ Item *item= *group->item;
-+ if (item->maybe_null)
-+ {
-+ Field *field=item->get_tmp_table_field();
-+ field->ptr[-1]= (uchar) (field->is_null() ? 1 : 0);
-+ }
-+ }
-+ }
-+#endif
-+ if (!join->having || join->having->val_int())
-+ {
-+ int error;
-+ join->found_records++;
-+ if ((error=table->file->ha_write_row(table->record[0])))
-+ {
-+ if (!table->file->is_fatal_error(error, HA_CHECK_DUP))
-+ goto end;
-+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
-+ error,1))
-+ DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
-+ table->s->uniques=0; // To ensure rows are the same
-+ }
-+ if (++join->send_records >= join->tmp_table_param.end_write_records &&
-+ join->do_send_rows)
-+ {
-+ if (!(join->select_options & OPTION_FOUND_ROWS))
-+ DBUG_RETURN(NESTED_LOOP_QUERY_LIMIT);
-+ join->do_send_rows=0;
-+ join->unit->select_limit_cnt = HA_POS_ERROR;
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ }
-+ }
-+ }
-+end:
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+/* ARGSUSED */
-+/** Group by searching after group record and updating it if possible. */
-+
-+static enum_nested_loop_state
-+end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ TABLE *table=join->tmp_table;
-+ ORDER *group;
-+ int error;
-+ DBUG_ENTER("end_update");
-+
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ if (join->thd->killed) // Aborted by user
-+ {
-+ join->thd->send_kill_message();
-+ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
-+ }
-+
-+ join->found_records++;
-+ copy_fields(&join->tmp_table_param); // Groups are copied twice.
-+ /* Make a key of group index */
-+ for (group=table->group ; group ; group=group->next)
-+ {
-+ Item *item= *group->item;
-+ item->save_org_in_field(group->field);
-+ /* Store in the used key if the field was 0 */
-+ if (item->maybe_null)
-+ group->buff[-1]= (char) group->field->is_null();
-+ }
-+ if (!table->file->index_read_map(table->record[1],
-+ join->tmp_table_param.group_buff,
-+ HA_WHOLE_KEY,
-+ HA_READ_KEY_EXACT))
-+ { /* Update old record */
-+ restore_record(table,record[1]);
-+ update_tmptable_sum_func(join->sum_funcs,table);
-+ if ((error=table->file->ha_update_row(table->record[1],
-+ table->record[0])))
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ }
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ }
-+
-+ /*
-+ Copy null bits from group key to table
-+ We can't copy all data as the key may have different format
-+ as the row data (for example as with VARCHAR keys)
-+ */
-+ KEY_PART_INFO *key_part;
-+ for (group=table->group,key_part=table->key_info[0].key_part;
-+ group ;
-+ group=group->next,key_part++)
-+ {
-+ if (key_part->null_bit)
-+ memcpy(table->record[0]+key_part->offset, group->buff, 1);
-+ }
-+ init_tmptable_sum_functions(join->sum_funcs);
-+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ if ((error=table->file->ha_write_row(table->record[0])))
-+ {
-+ if (create_myisam_from_heap(join->thd, table, &join->tmp_table_param,
-+ error, 0))
-+ DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error
-+ /* Change method to update rows */
-+ table->file->ha_index_init(0, 0);
-+ join->join_tab[join->tables-1].next_select=end_unique_update;
-+ }
-+ join->send_records++;
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+
-+/** Like end_update, but this is done with unique constraints instead of keys. */
-+
-+static enum_nested_loop_state
-+end_unique_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ TABLE *table=join->tmp_table;
-+ int error;
-+ DBUG_ENTER("end_unique_update");
-+
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ if (join->thd->killed) // Aborted by user
-+ {
-+ join->thd->send_kill_message();
-+ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
-+ }
-+
-+ init_tmptable_sum_functions(join->sum_funcs);
-+ copy_fields(&join->tmp_table_param); // Groups are copied twice.
-+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+
-+ if (!(error=table->file->ha_write_row(table->record[0])))
-+ join->send_records++; // New group
-+ else
-+ {
-+ if ((int) table->file->get_dup_key(error) < 0)
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ }
-+ if (table->file->rnd_pos(table->record[1],table->file->dup_ref))
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ }
-+ restore_record(table,record[1]);
-+ update_tmptable_sum_func(join->sum_funcs,table);
-+ if ((error=table->file->ha_update_row(table->record[1],
-+ table->record[0])))
-+ {
-+ table->file->print_error(error,MYF(0)); /* purecov: inspected */
-+ DBUG_RETURN(NESTED_LOOP_ERROR); /* purecov: inspected */
-+ }
-+ }
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+
-+ /* ARGSUSED */
-+static enum_nested_loop_state
-+end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
-+ bool end_of_records)
-+{
-+ TABLE *table=join->tmp_table;
-+ int idx= -1;
-+ DBUG_ENTER("end_write_group");
-+
-+ if (join->thd->killed)
-+ { // Aborted by user
-+ join->thd->send_kill_message();
-+ DBUG_RETURN(NESTED_LOOP_KILLED); /* purecov: inspected */
-+ }
-+ if (!join->first_record || end_of_records ||
-+ (idx=test_if_group_changed(join->group_fields)) >= 0)
-+ {
-+ if (join->first_record || (end_of_records && !join->group))
-+ {
-+ if (join->procedure)
-+ join->procedure->end_group();
-+ int send_group_parts= join->send_group_parts;
-+ if (idx < send_group_parts)
-+ {
-+ if (!join->first_record)
-+ {
-+ /* No matching rows for group function */
-+ join->clear();
-+ }
-+ copy_sum_funcs(join->sum_funcs,
-+ join->sum_funcs_end[send_group_parts]);
-+ if (!join->having || join->having->val_int())
-+ {
-+ int error= table->file->ha_write_row(table->record[0]);
-+ if (error && create_myisam_from_heap(join->thd, table,
-+ &join->tmp_table_param,
-+ error, 0))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ }
-+ if (join->rollup.state != ROLLUP::STATE_NONE)
-+ {
-+ if (join->rollup_write_data((uint) (idx+1), table))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ }
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ }
-+ }
-+ else
-+ {
-+ if (end_of_records)
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ join->first_record=1;
-+ VOID(test_if_group_changed(join->group_fields));
-+ }
-+ if (idx < (int) join->send_group_parts)
-+ {
-+ copy_fields(&join->tmp_table_param);
-+ if (copy_funcs(join->tmp_table_param.items_to_copy, join->thd))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ if (init_sum_functions(join->sum_funcs, join->sum_funcs_end[idx+1]))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ if (join->procedure)
-+ join->procedure->add();
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+ }
-+ }
-+ if (update_sum_func(join->sum_funcs))
-+ DBUG_RETURN(NESTED_LOOP_ERROR);
-+ if (join->procedure)
-+ join->procedure->add();
-+ DBUG_RETURN(NESTED_LOOP_OK);
-+}
-+
-+
-+/*****************************************************************************
-+ Remove calculation with tables that aren't yet read. Remove also tests
-+ against fields that are read through key where the table is not a
-+ outer join table.
-+ We can't remove tests that are made against columns which are stored
-+ in sorted order.
-+*****************************************************************************/
-+
-+/**
-+ @return
-+ 1 if right_item is used removable reference key on left_item
-+*/
-+
-+static bool test_if_ref(Item_field *left_item,Item *right_item)
-+{
-+ Field *field=left_item->field;
-+ // No need to change const test. We also have to keep tests on LEFT JOIN
-+ if (!field->table->const_table && !field->table->maybe_null)
-+ {
-+ Item *ref_item=part_of_refkey(field->table,field);
-+ if (ref_item && ref_item->eq(right_item,1))
-+ {
-+ right_item= right_item->real_item();
-+ if (right_item->type() == Item::FIELD_ITEM)
-+ return (field->eq_def(((Item_field *) right_item)->field));
-+ /* remove equalities injected by IN->EXISTS transformation */
-+ else if (right_item->type() == Item::CACHE_ITEM)
-+ return ((Item_cache *)right_item)->eq_def (field);
-+ if (right_item->const_item() && !(right_item->is_null()))
-+ {
-+ /*
-+ We can remove binary fields and numerical fields except float,
-+ as float comparison isn't 100 % secure
-+ We have to keep normal strings to be able to check for end spaces
-+ */
-+ if (field->binary() &&
-+ field->real_type() != MYSQL_TYPE_STRING &&
-+ field->real_type() != MYSQL_TYPE_VARCHAR &&
-+ (field->type() != MYSQL_TYPE_FLOAT || field->decimals() == 0))
-+ {
-+ return !store_val_in_field(field, right_item, CHECK_FIELD_WARN);
-+ }
-+ }
-+ }
-+ }
-+ return 0; // keep test
-+}
-+
-+
-+static COND *
-+make_cond_for_table(COND *cond, table_map tables, table_map used_table)
-+{
-+ if (used_table && !(cond->used_tables() & used_table))
-+ return (COND*) 0; // Already checked
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ {
-+ /* Create new top level AND item */
-+ Item_cond_and *new_cond=new Item_cond_and;
-+ if (!new_cond)
-+ return (COND*) 0; // OOM /* purecov: inspected */
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ Item *fix=make_cond_for_table(item,tables,used_table);
-+ if (fix)
-+ new_cond->argument_list()->push_back(fix);
-+ }
-+ switch (new_cond->argument_list()->elements) {
-+ case 0:
-+ return (COND*) 0; // Always true
-+ case 1:
-+ return new_cond->argument_list()->head();
-+ default:
-+ /*
-+ Item_cond_and do not need fix_fields for execution, its parameters
-+ are fixed or do not need fix_fields, too
-+ */
-+ new_cond->quick_fix_field();
-+ new_cond->used_tables_cache=
-+ ((Item_cond_and*) cond)->used_tables_cache &
-+ tables;
-+ return new_cond;
-+ }
-+ }
-+ else
-+ { // Or list
-+ Item_cond_or *new_cond=new Item_cond_or;
-+ if (!new_cond)
-+ return (COND*) 0; // OOM /* purecov: inspected */
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ Item *fix=make_cond_for_table(item,tables,0L);
-+ if (!fix)
-+ return (COND*) 0; // Always true
-+ new_cond->argument_list()->push_back(fix);
-+ }
-+ /*
-+ Item_cond_and do not need fix_fields for execution, its parameters
-+ are fixed or do not need fix_fields, too
-+ */
-+ new_cond->quick_fix_field();
-+ new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
-+ new_cond->top_level_item();
-+ return new_cond;
-+ }
-+ }
-+
-+ /*
-+ Because the following test takes a while and it can be done
-+ table_count times, we mark each item that we have examined with the result
-+ of the test
-+ */
-+
-+ if (cond->marker == 3 || (cond->used_tables() & ~tables))
-+ return (COND*) 0; // Can't check this yet
-+ if (cond->marker == 2 || cond->eq_cmp_result() == Item::COND_OK)
-+ return cond; // Not boolean op
-+
-+ if (((Item_func*) cond)->functype() == Item_func::EQ_FUNC)
-+ {
-+ Item *left_item= ((Item_func*) cond)->arguments()[0];
-+ Item *right_item= ((Item_func*) cond)->arguments()[1];
-+ if (left_item->type() == Item::FIELD_ITEM &&
-+ test_if_ref((Item_field*) left_item,right_item))
-+ {
-+ cond->marker=3; // Checked when read
-+ return (COND*) 0;
-+ }
-+ if (right_item->type() == Item::FIELD_ITEM &&
-+ test_if_ref((Item_field*) right_item,left_item))
-+ {
-+ cond->marker=3; // Checked when read
-+ return (COND*) 0;
-+ }
-+ }
-+ cond->marker=2;
-+ return cond;
-+}
-+
-+static Item *
-+part_of_refkey(TABLE *table,Field *field)
-+{
-+ if (!table->reginfo.join_tab)
-+ return (Item*) 0; // field from outer non-select (UPDATE,...)
-+
-+ uint ref_parts=table->reginfo.join_tab->ref.key_parts;
-+ if (ref_parts)
-+ {
-+ KEY_PART_INFO *key_part=
-+ table->key_info[table->reginfo.join_tab->ref.key].key_part;
-+
-+ for (uint part=0 ; part < ref_parts ; part++,key_part++)
-+ if (field->eq(key_part->field) &&
-+ !(key_part->key_part_flag & (HA_PART_KEY_SEG | HA_NULL_PART)))
-+ return table->reginfo.join_tab->ref.items[part];
-+ }
-+ return (Item*) 0;
-+}
-+
-+
-+/**
-+ Test if one can use the key to resolve ORDER BY.
-+
-+ @param order Sort order
-+ @param table Table to sort
-+ @param idx Index to check
-+ @param used_key_parts Return value for used key parts.
-+
-+
-+ @note
-+ used_key_parts is set to correct key parts used if return value != 0
-+ (On other cases, used_key_part may be changed)
-+ Note that the value may actually be greater than the number of index
-+ key parts. This can happen for storage engines that have the primary
-+ key parts as a suffix for every secondary key.
-+
-+ @retval
-+ 1 key is ok.
-+ @retval
-+ 0 Key can't be used
-+ @retval
-+ -1 Reverse key can be used
-+*/
-+
-+static int test_if_order_by_key(ORDER *order, TABLE *table, uint idx,
-+ uint *used_key_parts)
-+{
-+ KEY_PART_INFO *key_part,*key_part_end;
-+ key_part=table->key_info[idx].key_part;
-+ key_part_end=key_part+table->key_info[idx].key_parts;
-+ key_part_map const_key_parts=table->const_key_parts[idx];
-+ int reverse=0;
-+ my_bool on_pk_suffix= FALSE;
-+ DBUG_ENTER("test_if_order_by_key");
-+
-+ for (; order ; order=order->next, const_key_parts>>=1)
-+ {
-+ Field *field=((Item_field*) (*order->item)->real_item())->field;
-+ int flag;
-+
-+ /*
-+ Skip key parts that are constants in the WHERE clause.
-+ These are already skipped in the ORDER BY by const_expression_in_where()
-+ */
-+ for (; const_key_parts & 1 ; const_key_parts>>= 1)
-+ key_part++;
-+
-+ if (key_part == key_part_end)
-+ {
-+ /*
-+ We are at the end of the key. Check if the engine has the primary
-+ key as a suffix to the secondary keys. If it has continue to check
-+ the primary key as a suffix.
-+ */
-+ if (!on_pk_suffix &&
-+ (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
-+ table->s->primary_key != MAX_KEY &&
-+ table->s->primary_key != idx)
-+ {
-+ on_pk_suffix= TRUE;
-+ key_part= table->key_info[table->s->primary_key].key_part;
-+ key_part_end=key_part+table->key_info[table->s->primary_key].key_parts;
-+ const_key_parts=table->const_key_parts[table->s->primary_key];
-+
-+ for (; const_key_parts & 1 ; const_key_parts>>= 1)
-+ key_part++;
-+ /*
-+ The primary and secondary key parts were all const (i.e. there's
-+ one row). The sorting doesn't matter.
-+ */
-+ if (key_part == key_part_end && reverse == 0)
-+ {
-+ *used_key_parts= 0;
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ else
-+ DBUG_RETURN(0);
-+ }
-+
-+ if (key_part->field != field)
-+ DBUG_RETURN(0);
-+
-+ /* set flag to 1 if we can use read-next on key, else to -1 */
-+ flag= ((order->asc == !(key_part->key_part_flag & HA_REVERSE_SORT)) ?
-+ 1 : -1);
-+ if (reverse && flag != reverse)
-+ DBUG_RETURN(0);
-+ reverse=flag; // Remember if reverse
-+ key_part++;
-+ }
-+ if (on_pk_suffix)
-+ {
-+ uint used_key_parts_secondary= table->key_info[idx].key_parts;
-+ uint used_key_parts_pk=
-+ (uint) (key_part - table->key_info[table->s->primary_key].key_part);
-+ *used_key_parts= used_key_parts_pk + used_key_parts_secondary;
-+
-+ if (reverse == -1 &&
-+ (!(table->file->index_flags(idx, used_key_parts_secondary - 1, 1) &
-+ HA_READ_PREV) ||
-+ !(table->file->index_flags(table->s->primary_key,
-+ used_key_parts_pk - 1, 1) & HA_READ_PREV)))
-+ reverse= 0; // Index can't be used
-+ }
-+ else
-+ {
-+ *used_key_parts= (uint) (key_part - table->key_info[idx].key_part);
-+ if (reverse == -1 &&
-+ !(table->file->index_flags(idx, *used_key_parts-1, 1) & HA_READ_PREV))
-+ reverse= 0; // Index can't be used
-+ }
-+ DBUG_RETURN(reverse);
-+}
-+
-+
-+/**
-+ Find shortest key suitable for full table scan.
-+
-+ @param table Table to scan
-+ @param usable_keys Allowed keys
-+
-+ @note
-+ As far as
-+ 1) clustered primary key entry data set is a set of all record
-+ fields (key fields and not key fields) and
-+ 2) secondary index entry data is a union of its key fields and
-+ primary key fields (at least InnoDB and its derivatives don't
-+ duplicate primary key fields there, even if the primary and
-+ the secondary keys have a common subset of key fields),
-+ then secondary index entry data is always a subset of primary key entry.
-+ Unfortunately, key_info[nr].key_length doesn't show the length
-+ of key/pointer pair but a sum of key field lengths only, thus
-+ we can't estimate index IO volume comparing only this key_length
-+ value of secondary keys and clustered PK.
-+ So, try secondary keys first, and choose PK only if there are no
-+ usable secondary covering keys or found best secondary key include
-+ all table fields (i.e. same as PK):
-+
-+ @return
-+ MAX_KEY no suitable key found
-+ key index otherwise
-+*/
-+
-+uint find_shortest_key(TABLE *table, const key_map *usable_keys)
-+{
-+ uint best= MAX_KEY;
-+ uint usable_clustered_pk= (table->file->primary_key_is_clustered() &&
-+ table->s->primary_key != MAX_KEY &&
-+ usable_keys->is_set(table->s->primary_key)) ?
-+ table->s->primary_key : MAX_KEY;
-+ if (!usable_keys->is_clear_all())
-+ {
-+ uint min_length= (uint) ~0;
-+ for (uint nr=0; nr < table->s->keys ; nr++)
-+ {
-+ if (nr == usable_clustered_pk)
-+ continue;
-+ if (usable_keys->is_set(nr))
-+ {
-+ if (table->key_info[nr].key_length < min_length)
-+ {
-+ min_length=table->key_info[nr].key_length;
-+ best=nr;
-+ }
-+ }
-+ }
-+ }
-+ if (usable_clustered_pk != MAX_KEY)
-+ {
-+ /*
-+ If the primary key is clustered and found shorter key covers all table
-+ fields then primary key scan normally would be faster because amount of
-+ data to scan is the same but PK is clustered.
-+ It's safe to compare key parts with table fields since duplicate key
-+ parts aren't allowed.
-+ */
-+ if (best == MAX_KEY ||
-+ table->key_info[best].key_parts >= table->s->fields)
-+ best= usable_clustered_pk;
-+ }
-+ return best;
-+}
-+
-+/**
-+ Test if a second key is the subkey of the first one.
-+
-+ @param key_part First key parts
-+ @param ref_key_part Second key parts
-+ @param ref_key_part_end Last+1 part of the second key
-+
-+ @note
-+ Second key MUST be shorter than the first one.
-+
-+ @retval
-+ 1 is a subkey
-+ @retval
-+ 0 no sub key
-+*/
-+
-+inline bool
-+is_subkey(KEY_PART_INFO *key_part, KEY_PART_INFO *ref_key_part,
-+ KEY_PART_INFO *ref_key_part_end)
-+{
-+ for (; ref_key_part < ref_key_part_end; key_part++, ref_key_part++)
-+ if (!key_part->field->eq(ref_key_part->field))
-+ return 0;
-+ return 1;
-+}
-+
-+/**
-+ Test if we can use one of the 'usable_keys' instead of 'ref' key
-+ for sorting.
-+
-+ @param ref Number of key, used for WHERE clause
-+ @param usable_keys Keys for testing
-+
-+ @return
-+ - MAX_KEY If we can't use other key
-+ - the number of found key Otherwise
-+*/
-+
-+static uint
-+test_if_subkey(ORDER *order, TABLE *table, uint ref, uint ref_key_parts,
-+ const key_map *usable_keys)
-+{
-+ uint nr;
-+ uint min_length= (uint) ~0;
-+ uint best= MAX_KEY;
-+ uint not_used;
-+ KEY_PART_INFO *ref_key_part= table->key_info[ref].key_part;
-+ KEY_PART_INFO *ref_key_part_end= ref_key_part + ref_key_parts;
-+
-+ for (nr= 0 ; nr < table->s->keys ; nr++)
-+ {
-+ if (usable_keys->is_set(nr) &&
-+ table->key_info[nr].key_length < min_length &&
-+ table->key_info[nr].key_parts >= ref_key_parts &&
-+ is_subkey(table->key_info[nr].key_part, ref_key_part,
-+ ref_key_part_end) &&
-+ test_if_order_by_key(order, table, nr, ¬_used))
-+ {
-+ min_length= table->key_info[nr].key_length;
-+ best= nr;
-+ }
-+ }
-+ return best;
-+}
-+
-+
-+/**
-+ Check if GROUP BY/DISTINCT can be optimized away because the set is
-+ already known to be distinct.
-+
-+ Used in removing the GROUP BY/DISTINCT of the following types of
-+ statements:
-+ @code
-+ SELECT [DISTINCT] <unique_key_cols>... FROM <single_table_ref>
-+ [GROUP BY <unique_key_cols>,...]
-+ @endcode
-+
-+ If (a,b,c is distinct)
-+ then <any combination of a,b,c>,{whatever} is also distinct
-+
-+ This function checks if all the key parts of any of the unique keys
-+ of the table are referenced by a list : either the select list
-+ through find_field_in_item_list or GROUP BY list through
-+ find_field_in_order_list.
-+ If the above holds and the key parts cannot contain NULLs then we
-+ can safely remove the GROUP BY/DISTINCT,
-+ as no result set can be more distinct than an unique key.
-+
-+ @param table The table to operate on.
-+ @param find_func function to iterate over the list and search
-+ for a field
-+
-+ @retval
-+ 1 found
-+ @retval
-+ 0 not found.
-+*/
-+
-+static bool
-+list_contains_unique_index(TABLE *table,
-+ bool (*find_func) (Field *, void *), void *data)
-+{
-+ if (table->pos_in_table_list->outer_join)
-+ return 0;
-+ for (uint keynr= 0; keynr < table->s->keys; keynr++)
-+ {
-+ if (keynr == table->s->primary_key ||
-+ (table->key_info[keynr].flags & HA_NOSAME))
-+ {
-+ KEY *keyinfo= table->key_info + keynr;
-+ KEY_PART_INFO *key_part, *key_part_end;
-+
-+ for (key_part=keyinfo->key_part,
-+ key_part_end=key_part+ keyinfo->key_parts;
-+ key_part < key_part_end;
-+ key_part++)
-+ {
-+ if (key_part->field->real_maybe_null() ||
-+ !find_func(key_part->field, data))
-+ break;
-+ }
-+ if (key_part == key_part_end)
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Helper function for list_contains_unique_index.
-+ Find a field reference in a list of ORDER structures.
-+ Finds a direct reference of the Field in the list.
-+
-+ @param field The field to search for.
-+ @param data ORDER *.The list to search in
-+
-+ @retval
-+ 1 found
-+ @retval
-+ 0 not found.
-+*/
-+
-+static bool
-+find_field_in_order_list (Field *field, void *data)
-+{
-+ ORDER *group= (ORDER *) data;
-+ bool part_found= 0;
-+ for (ORDER *tmp_group= group; tmp_group; tmp_group=tmp_group->next)
-+ {
-+ Item *item= (*tmp_group->item)->real_item();
-+ if (item->type() == Item::FIELD_ITEM &&
-+ ((Item_field*) item)->field->eq(field))
-+ {
-+ part_found= 1;
-+ break;
-+ }
-+ }
-+ return part_found;
-+}
-+
-+
-+/**
-+ Helper function for list_contains_unique_index.
-+ Find a field reference in a dynamic list of Items.
-+ Finds a direct reference of the Field in the list.
-+
-+ @param[in] field The field to search for.
-+ @param[in] data List<Item> *.The list to search in
-+
-+ @retval
-+ 1 found
-+ @retval
-+ 0 not found.
-+*/
-+
-+static bool
-+find_field_in_item_list (Field *field, void *data)
-+{
-+ List<Item> *fields= (List<Item> *) data;
-+ bool part_found= 0;
-+ List_iterator<Item> li(*fields);
-+ Item *item;
-+
-+ while ((item= li++))
-+ {
-+ if (item->type() == Item::FIELD_ITEM &&
-+ ((Item_field*) item)->field->eq(field))
-+ {
-+ part_found= 1;
-+ break;
-+ }
-+ }
-+ return part_found;
-+}
-+
-+
-+/**
-+ Test if we can skip the ORDER BY by using an index.
-+
-+ If we can use an index, the JOIN_TAB / tab->select struct
-+ is changed to use the index.
-+
-+ The index must cover all fields in <order>, or it will not be considered.
-+
-+ @param no_changes No changes will be made to the query plan.
-+
-+ @todo
-+ - sergeyp: Results of all index merge selects actually are ordered
-+ by clustered PK values.
-+
-+ @retval
-+ 0 We have to use filesort to do the sorting
-+ @retval
-+ 1 We can use an index.
-+*/
-+
-+static bool
-+test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
-+ bool no_changes, key_map *map)
-+{
-+ int ref_key;
-+ uint ref_key_parts;
-+ int order_direction= 0;
-+ uint used_key_parts;
-+ TABLE *table=tab->table;
-+ SQL_SELECT *select=tab->select;
-+ key_map usable_keys;
-+ QUICK_SELECT_I *save_quick= 0;
-+ int best_key= -1;
-+
-+ DBUG_ENTER("test_if_skip_sort_order");
-+ LINT_INIT(ref_key_parts);
-+
-+ /*
-+ Keys disabled by ALTER TABLE ... DISABLE KEYS should have already
-+ been taken into account.
-+ */
-+ usable_keys= *map;
-+
-+ for (ORDER *tmp_order=order; tmp_order ; tmp_order=tmp_order->next)
-+ {
-+ Item *item= (*tmp_order->item)->real_item();
-+ if (item->type() != Item::FIELD_ITEM)
-+ {
-+ usable_keys.clear_all();
-+ DBUG_RETURN(0);
-+ }
-+ usable_keys.intersect(((Item_field*) item)->field->part_of_sortkey);
-+ if (usable_keys.is_clear_all())
-+ DBUG_RETURN(0); // No usable keys
-+ }
-+
-+ ref_key= -1;
-+ /* Test if constant range in WHERE */
-+ if (tab->ref.key >= 0 && tab->ref.key_parts)
-+ {
-+ ref_key= tab->ref.key;
-+ ref_key_parts= tab->ref.key_parts;
-+ if (tab->type == JT_REF_OR_NULL || tab->type == JT_FT)
-+ DBUG_RETURN(0);
-+ }
-+ else if (select && select->quick) // Range found by opt_range
-+ {
-+ int quick_type= select->quick->get_type();
-+ save_quick= select->quick;
-+ /*
-+ assume results are not ordered when index merge is used
-+ TODO: sergeyp: Results of all index merge selects actually are ordered
-+ by clustered PK values.
-+ */
-+
-+ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
-+ DBUG_RETURN(0);
-+ ref_key= select->quick->index;
-+ ref_key_parts= select->quick->used_key_parts;
-+ }
-+
-+ if (ref_key >= 0)
-+ {
-+ /*
-+ We come here when there is a REF key.
-+ */
-+ if (!usable_keys.is_set(ref_key))
-+ {
-+ /*
-+ We come here when ref_key is not among usable_keys
-+ */
-+ uint new_ref_key;
-+ /*
-+ If using index only read, only consider other possible index only
-+ keys
-+ */
-+ if (table->covering_keys.is_set(ref_key))
-+ usable_keys.intersect(table->covering_keys);
-+ if ((new_ref_key= test_if_subkey(order, table, ref_key, ref_key_parts,
-+ &usable_keys)) < MAX_KEY)
-+ {
-+ /* Found key that can be used to retrieve data in sorted order */
-+ if (tab->ref.key >= 0)
-+ {
-+ /*
-+ We'll use ref access method on key new_ref_key. In general case
-+ the index search tuple for new_ref_key will be different (e.g.
-+ when one index is defined as (part1, part2, ...) and another as
-+ (part1, part2(N), ...) and the WHERE clause contains
-+ "part1 = const1 AND part2=const2".
-+ So we build tab->ref from scratch here.
-+ */
-+ KEYUSE *keyuse= tab->keyuse;
-+ while (keyuse->key != new_ref_key && keyuse->table == tab->table)
-+ keyuse++;
-+ if (create_ref_for_key(tab->join, tab, keyuse,
-+ tab->join->const_table_map))
-+ DBUG_RETURN(0);
-+
-+ pick_table_access_method(tab);
-+ }
-+ else
-+ {
-+ /*
-+ The range optimizer constructed QUICK_RANGE for ref_key, and
-+ we want to use instead new_ref_key as the index. We can't
-+ just change the index of the quick select, because this may
-+ result in an incosistent QUICK_SELECT object. Below we
-+ create a new QUICK_SELECT from scratch so that all its
-+ parameres are set correctly by the range optimizer.
-+ */
-+ key_map new_ref_key_map;
-+ new_ref_key_map.clear_all(); // Force the creation of quick select
-+ new_ref_key_map.set_bit(new_ref_key); // only for new_ref_key.
-+
-+ select->quick= 0;
-+ if (select->test_quick_select(tab->join->thd, new_ref_key_map, 0,
-+ (tab->join->select_options &
-+ OPTION_FOUND_ROWS) ?
-+ HA_POS_ERROR :
-+ tab->join->unit->select_limit_cnt,0) <=
-+ 0)
-+ goto use_filesort;
-+ }
-+ ref_key= new_ref_key;
-+ }
-+ }
-+ /* Check if we get the rows in requested sorted order by using the key */
-+ if (usable_keys.is_set(ref_key) &&
-+ (order_direction= test_if_order_by_key(order,table,ref_key,
-+ &used_key_parts)))
-+ goto check_reverse_order;
-+ }
-+ {
-+ /*
-+ Check whether there is an index compatible with the given order
-+ usage of which is cheaper than usage of the ref_key index (ref_key>=0)
-+ or a table scan.
-+ It may be the case if ORDER/GROUP BY is used with LIMIT.
-+ */
-+ uint nr;
-+ key_map keys;
-+ uint best_key_parts= 0;
-+ uint saved_best_key_parts= 0;
-+ int best_key_direction= 0;
-+ ha_rows best_records= 0;
-+ double read_time;
-+ bool is_best_covering= FALSE;
-+ double fanout= 1;
-+ JOIN *join= tab->join;
-+ uint tablenr= tab - join->join_tab;
-+ ha_rows table_records= table->file->stats.records;
-+ bool group= join->group && order == join->group_list;
-+ ha_rows ref_key_quick_rows= HA_POS_ERROR;
-+
-+ /*
-+ If not used with LIMIT, only use keys if the whole query can be
-+ resolved with a key; This is because filesort() is usually faster than
-+ retrieving all rows through an index.
-+ */
-+ if (select_limit >= table_records)
-+ {
-+ keys= *table->file->keys_to_use_for_scanning();
-+ keys.merge(table->covering_keys);
-+
-+ /*
-+ We are adding here also the index specified in FORCE INDEX clause,
-+ if any.
-+ This is to allow users to use index in ORDER BY.
-+ */
-+ if (table->force_index)
-+ keys.merge(group ? table->keys_in_use_for_group_by :
-+ table->keys_in_use_for_order_by);
-+ keys.intersect(usable_keys);
-+ }
-+ else
-+ keys= usable_keys;
-+
-+ if (ref_key >= 0 && table->covering_keys.is_set(ref_key))
-+ ref_key_quick_rows= table->quick_rows[ref_key];
-+
-+ read_time= join->best_positions[tablenr].read_time;
-+ for (uint i= tablenr+1; i < join->tables; i++)
-+ fanout*= join->best_positions[i].records_read; // fanout is always >= 1
-+
-+ for (nr=0; nr < table->s->keys ; nr++)
-+ {
-+ int direction;
-+
-+ if (keys.is_set(nr) &&
-+ (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
-+ {
-+ /*
-+ At this point we are sure that ref_key is a non-ordering
-+ key (where "ordering key" is a key that will return rows
-+ in the order required by ORDER BY).
-+ */
-+ DBUG_ASSERT (ref_key != (int) nr);
-+
-+ bool is_covering= table->covering_keys.is_set(nr) ||
-+ (nr == table->s->primary_key &&
-+ table->file->primary_key_is_clustered());
-+
-+ /*
-+ Don't use an index scan with ORDER BY without limit.
-+ For GROUP BY without limit always use index scan
-+ if there is a suitable index.
-+ Why we hold to this asymmetry hardly can be explained
-+ rationally. It's easy to demonstrate that using
-+ temporary table + filesort could be cheaper for grouping
-+ queries too.
-+ */
-+ if (is_covering ||
-+ select_limit != HA_POS_ERROR ||
-+ (ref_key < 0 && (group || table->force_index)))
-+ {
-+ double rec_per_key;
-+ double index_scan_time;
-+ KEY *keyinfo= tab->table->key_info+nr;
-+ if (select_limit == HA_POS_ERROR)
-+ select_limit= table_records;
-+ if (group)
-+ {
-+ /*
-+ Used_key_parts can be larger than keyinfo->key_parts
-+ when using a secondary index clustered with a primary
-+ key (e.g. as in Innodb).
-+ See Bug #28591 for details.
-+ */
-+ rec_per_key= used_key_parts &&
-+ used_key_parts <= keyinfo->key_parts ?
-+ keyinfo->rec_per_key[used_key_parts-1] : 1;
-+ set_if_bigger(rec_per_key, 1);
-+ /*
-+ With a grouping query each group containing on average
-+ rec_per_key records produces only one row that will
-+ be included into the result set.
-+ */
-+ if (select_limit > table_records/rec_per_key)
-+ select_limit= table_records;
-+ else
-+ select_limit= (ha_rows) (select_limit*rec_per_key);
-+ }
-+ /*
-+ If tab=tk is not the last joined table tn then to get first
-+ L records from the result set we can expect to retrieve
-+ only L/fanout(tk,tn) where fanout(tk,tn) says how many
-+ rows in the record set on average will match each row tk.
-+ Usually our estimates for fanouts are too pessimistic.
-+ So the estimate for L/fanout(tk,tn) will be too optimistic
-+ and as result we'll choose an index scan when using ref/range
-+ access + filesort will be cheaper.
-+ */
-+ select_limit= (ha_rows) (select_limit < fanout ?
-+ 1 : select_limit/fanout);
-+ /*
-+ We assume that each of the tested indexes is not correlated
-+ with ref_key. Thus, to select first N records we have to scan
-+ N/selectivity(ref_key) index entries.
-+ selectivity(ref_key) = #scanned_records/#table_records =
-+ table->quick_condition_rows/table_records.
-+ In any case we can't select more than #table_records.
-+ N/(table->quick_condition_rows/table_records) > table_records
-+ <=> N > table->quick_condition_rows.
-+ */
-+ if (select_limit > table->quick_condition_rows)
-+ select_limit= table_records;
-+ else
-+ select_limit= (ha_rows) (select_limit *
-+ (double) table_records /
-+ table->quick_condition_rows);
-+ rec_per_key= keyinfo->rec_per_key[keyinfo->key_parts-1];
-+ set_if_bigger(rec_per_key, 1);
-+ /*
-+ Here we take into account the fact that rows are
-+ accessed in sequences rec_per_key records in each.
-+ Rows in such a sequence are supposed to be ordered
-+ by rowid/primary key. When reading the data
-+ in a sequence we'll touch not more pages than the
-+ table file contains.
-+ TODO. Use the formula for a disk sweep sequential access
-+ to calculate the cost of accessing data rows for one
-+ index entry.
-+ */
-+ index_scan_time= select_limit/rec_per_key *
-+ min(rec_per_key, table->file->scan_time());
-+ if ((ref_key < 0 && is_covering) ||
-+ (ref_key < 0 && (group || table->force_index)) ||
-+ index_scan_time < read_time)
-+ {
-+ ha_rows quick_records= table_records;
-+ if ((is_best_covering && !is_covering) ||
-+ (is_covering && ref_key_quick_rows < select_limit))
-+ continue;
-+ if (table->quick_keys.is_set(nr))
-+ quick_records= table->quick_rows[nr];
-+ if (best_key < 0 ||
-+ (select_limit <= min(quick_records,best_records) ?
-+ keyinfo->key_parts < best_key_parts :
-+ quick_records < best_records))
-+ {
-+ best_key= nr;
-+ best_key_parts= keyinfo->key_parts;
-+ saved_best_key_parts= used_key_parts;
-+ best_records= quick_records;
-+ is_best_covering= is_covering;
-+ best_key_direction= direction;
-+ }
-+ }
-+ }
-+ }
-+ }
-+
-+ /*
-+ filesort() and join cache are usually faster than reading in
-+ index order and not using join cache, except in case that chosen
-+ index is clustered primary key.
-+ */
-+ if ((select_limit >= table_records) &&
-+ (tab->type == JT_ALL &&
-+ tab->join->tables > tab->join->const_tables + 1) &&
-+ ((unsigned) best_key != table->s->primary_key ||
-+ !table->file->primary_key_is_clustered()))
-+ goto use_filesort;
-+
-+ if (best_key >= 0)
-+ {
-+ if (table->quick_keys.is_set(best_key) && best_key != ref_key)
-+ {
-+ key_map map;
-+ map.clear_all(); // Force the creation of quick select
-+ map.set_bit(best_key); // only best_key.
-+ select->quick= 0;
-+ select->test_quick_select(join->thd, map, 0,
-+ join->select_options & OPTION_FOUND_ROWS ?
-+ HA_POS_ERROR :
-+ join->unit->select_limit_cnt,
-+ 0);
-+ }
-+ order_direction= best_key_direction;
-+ /*
-+ saved_best_key_parts is actual number of used keyparts found by the
-+ test_if_order_by_key function. It could differ from keyinfo->key_parts,
-+ thus we have to restore it in case of desc order as it affects
-+ QUICK_SELECT_DESC behaviour.
-+ */
-+ used_key_parts= (order_direction == -1) ?
-+ saved_best_key_parts : best_key_parts;
-+ }
-+ else
-+ goto use_filesort;
-+ }
-+
-+check_reverse_order:
-+ DBUG_ASSERT(order_direction != 0);
-+
-+ if (order_direction == -1) // If ORDER BY ... DESC
-+ {
-+ if (select && select->quick)
-+ {
-+ /*
-+ Don't reverse the sort order, if it's already done.
-+ (In some cases test_if_order_by_key() can be called multiple times
-+ */
-+ if (select->quick->reverse_sorted())
-+ goto skipped_filesort;
-+ else
-+ {
-+ int quick_type= select->quick->get_type();
-+ if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
-+ {
-+ tab->limit= 0;
-+ goto use_filesort; // Use filesort
-+ }
-+ }
-+ }
-+ }
-+
-+ /*
-+ Update query plan with access pattern for doing
-+ ordered access according to what we have decided
-+ above.
-+ */
-+ if (!no_changes) // We are allowed to update QEP
-+ {
-+ if (best_key >= 0)
-+ {
-+ bool quick_created=
-+ (select && select->quick && select->quick!=save_quick);
-+
-+ /*
-+ If ref_key used index tree reading only ('Using index' in EXPLAIN),
-+ and best_key doesn't, then revert the decision.
-+ */
-+ if (!table->covering_keys.is_set(best_key))
-+ table->set_keyread(FALSE);
-+ if (!quick_created)
-+ {
-+ if (select) // Throw any existing quick select
-+ select->quick= 0; // Cleanup either reset to save_quick,
-+ // or 'delete save_quick'
-+ tab->index= best_key;
-+ tab->read_first_record= order_direction > 0 ?
-+ join_read_first:join_read_last;
-+ tab->type=JT_NEXT; // Read with index_first(), index_next()
-+
-+ if (table->covering_keys.is_set(best_key))
-+ table->set_keyread(TRUE);
-+ table->file->ha_index_or_rnd_end();
-+ if (tab->join->select_options & SELECT_DESCRIBE)
-+ {
-+ tab->ref.key= -1;
-+ tab->ref.key_parts= 0;
-+ if (select_limit < table->file->stats.records)
-+ tab->limit= select_limit;
-+ }
-+ }
-+ else if (tab->type != JT_ALL)
-+ {
-+ /*
-+ We're about to use a quick access to the table.
-+ We need to change the access method so as the quick access
-+ method is actually used.
-+ */
-+ DBUG_ASSERT(tab->select->quick);
-+ tab->type=JT_ALL;
-+ tab->use_quick=1;
-+ tab->ref.key= -1;
-+ tab->ref.key_parts=0; // Don't use ref key.
-+ tab->read_first_record= join_init_read_record;
-+ if (tab->is_using_loose_index_scan())
-+ tab->join->tmp_table_param.precomputed_group_by= TRUE;
-+ /*
-+ TODO: update the number of records in join->best_positions[tablenr]
-+ */
-+ }
-+ } // best_key >= 0
-+
-+ if (order_direction == -1) // If ORDER BY ... DESC
-+ {
-+ if (select && select->quick)
-+ {
-+ QUICK_SELECT_DESC *tmp;
-+ /* ORDER BY range_key DESC */
-+ tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
-+ used_key_parts);
-+ if (tmp && select->quick == save_quick)
-+ save_quick= 0; // ::QUICK_SELECT_DESC consumed it
-+
-+ if (!tmp || tmp->error)
-+ {
-+ delete tmp;
-+ tab->limit= 0;
-+ goto use_filesort; // Reverse sort failed -> filesort
-+ }
-+ select->quick= tmp;
-+ }
-+ else if (tab->type != JT_NEXT && tab->type != JT_REF_OR_NULL &&
-+ tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
-+ {
-+ /*
-+ SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
-+
-+ Use a traversal function that starts by reading the last row
-+ with key part (A) and then traverse the index backwards.
-+ */
-+ tab->read_first_record= join_read_last_key;
-+ tab->read_record.read_record= join_read_prev_same;
-+ }
-+ }
-+ else if (select && select->quick)
-+ select->quick->sorted= 1;
-+
-+ } // QEP has been modified
-+
-+ /*
-+ Cleanup:
-+ We may have both a 'select->quick' and 'save_quick' (original)
-+ at this point. Delete the one that we wan't use.
-+ */
-+
-+skipped_filesort:
-+ // Keep current (ordered) select->quick
-+ if (select && save_quick != select->quick)
-+ {
-+ delete save_quick;
-+ save_quick= NULL;
-+ }
-+ DBUG_RETURN(1);
-+
-+use_filesort:
-+ // Restore original save_quick
-+ if (select && select->quick != save_quick)
-+ {
-+ delete select->quick;
-+ select->quick= save_quick;
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ If not selecting by given key, create an index how records should be read
-+
-+ SYNOPSIS
-+ create_sort_index()
-+ thd Thread handler
-+ tab Table to sort (in join structure)
-+ order How table should be sorted
-+ filesort_limit Max number of rows that needs to be sorted
-+ select_limit Max number of rows in final output
-+ Used to decide if we should use index or not
-+ is_order_by true if we are sorting on ORDER BY, false if GROUP BY
-+ Used to decide if we should use index or not
-+
-+
-+ IMPLEMENTATION
-+ - If there is an index that can be used, 'tab' is modified to use
-+ this index.
-+ - If no index, create with filesort() an index file that can be used to
-+ retrieve rows in order (should be done with 'read_record').
-+ The sorted data is stored in tab->table and will be freed when calling
-+ free_io_cache(tab->table).
-+
-+ RETURN VALUES
-+ 0 ok
-+ -1 Some fatal error
-+ 1 No records
-+*/
-+
-+static int
-+create_sort_index(THD *thd, JOIN *join, ORDER *order,
-+ ha_rows filesort_limit, ha_rows select_limit,
-+ bool is_order_by)
-+{
-+ uint length= 0;
-+ ha_rows examined_rows;
-+ TABLE *table;
-+ SQL_SELECT *select;
-+ JOIN_TAB *tab;
-+ DBUG_ENTER("create_sort_index");
-+
-+ if (join->tables == join->const_tables)
-+ DBUG_RETURN(0); // One row, no need to sort
-+ tab= join->join_tab + join->const_tables;
-+ table= tab->table;
-+ select= tab->select;
-+
-+ /*
-+ When there is SQL_BIG_RESULT do not sort using index for GROUP BY,
-+ and thus force sorting on disk unless a group min-max optimization
-+ is going to be used as it is applied now only for one table queries
-+ with covering indexes.
-+ */
-+ if ((order != join->group_list ||
-+ !(join->select_options & SELECT_BIG_RESULT) ||
-+ (select && select->quick &&
-+ select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)) &&
-+ test_if_skip_sort_order(tab,order,select_limit,0,
-+ is_order_by ? &table->keys_in_use_for_order_by :
-+ &table->keys_in_use_for_group_by))
-+ DBUG_RETURN(0);
-+ for (ORDER *ord= join->order; ord; ord= ord->next)
-+ length++;
-+ if (!(join->sortorder=
-+ make_unireg_sortorder(order, &length, join->sortorder)))
-+ goto err; /* purecov: inspected */
-+
-+ table->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
-+ MYF(MY_WME | MY_ZEROFILL));
-+ table->status=0; // May be wrong if quick_select
-+
-+ // If table has a range, move it to select
-+ if (select && !select->quick && tab->ref.key >= 0)
-+ {
-+ if (tab->quick)
-+ {
-+ select->quick=tab->quick;
-+ tab->quick=0;
-+ /*
-+ We can only use 'Only index' if quick key is same as ref_key
-+ and in index_merge 'Only index' cannot be used
-+ */
-+ if (((uint) tab->ref.key != select->quick->index))
-+ table->set_keyread(FALSE);
-+ }
-+ else
-+ {
-+ /*
-+ We have a ref on a const; Change this to a range that filesort
-+ can use.
-+ For impossible ranges (like when doing a lookup on NULL on a NOT NULL
-+ field, quick will contain an empty record set.
-+ */
-+ if (!(select->quick= (tab->type == JT_FT ?
-+ new FT_SELECT(thd, table, tab->ref.key) :
-+ get_quick_select_for_ref(thd, table, &tab->ref,
-+ tab->found_records))))
-+ goto err;
-+ }
-+ }
-+
-+ /* Fill schema tables with data before filesort if it's necessary */
-+ if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
-+ get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
-+ goto err;
-+
-+ if (table->s->tmp_table)
-+ table->file->info(HA_STATUS_VARIABLE); // Get record count
-+ table->sort.found_records=filesort(thd, table,join->sortorder, length,
-+ select, filesort_limit, 0,
-+ &examined_rows);
-+ tab->records= table->sort.found_records; // For SQL_CALC_ROWS
-+ if (select)
-+ {
-+ /*
-+ We need to preserve tablesort's output resultset here, because
-+ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT (called by
-+ SQL_SELECT::cleanup()) may free it assuming it's the result of the quick
-+ select operation that we no longer need. Note that all the other parts of
-+ this data structure are cleaned up when
-+ QUICK_INDEX_MERGE_SELECT::get_next encounters end of data, so the next
-+ SQL_SELECT::cleanup() call changes sort.io_cache alone.
-+ */
-+ IO_CACHE *tablesort_result_cache;
-+
-+ tablesort_result_cache= table->sort.io_cache;
-+ table->sort.io_cache= NULL;
-+
-+ select->cleanup(); // filesort did select
-+ tab->select= 0;
-+ table->quick_keys.clear_all(); // as far as we cleanup select->quick
-+ table->sort.io_cache= tablesort_result_cache;
-+ }
-+ tab->select_cond=0;
-+ tab->last_inner= 0;
-+ tab->first_unmatched= 0;
-+ tab->type=JT_ALL; // Read with normal read_record
-+ tab->read_first_record= join_init_read_record;
-+ tab->join->examined_rows+=examined_rows;
-+ table->set_keyread(FALSE); // Restore if we used indexes
-+ DBUG_RETURN(table->sort.found_records == HA_POS_ERROR);
-+err:
-+ DBUG_RETURN(-1);
-+}
-+
-+#ifdef NOT_YET
-+/**
-+ Add the HAVING criteria to table->select.
-+*/
-+
-+static bool fix_having(JOIN *join, Item **having)
-+{
-+ (*having)->update_used_tables(); // Some tables may have been const
-+ JOIN_TAB *table=&join->join_tab[join->const_tables];
-+ table_map used_tables= join->const_table_map | table->table->map;
-+
-+ DBUG_EXECUTE("where",print_where(*having,"having", QT_ORDINARY););
-+ Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables);
-+ if (sort_table_cond)
-+ {
-+ if (!table->select)
-+ if (!(table->select=new SQL_SELECT))
-+ return 1;
-+ if (!table->select->cond)
-+ table->select->cond=sort_table_cond;
-+ else // This should never happen
-+ if (!(table->select->cond= new Item_cond_and(table->select->cond,
-+ sort_table_cond)) ||
-+ table->select->cond->fix_fields(join->thd, &table->select->cond))
-+ return 1;
-+ table->select_cond=table->select->cond;
-+ table->select_cond->top_level_item();
-+ DBUG_EXECUTE("where",print_where(table->select_cond,
-+ "select and having",
-+ QT_ORDINARY););
-+ *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables);
-+ DBUG_EXECUTE("where",
-+ print_where(*having,"having after make_cond", QT_ORDINARY););
-+ }
-+ return 0;
-+}
-+#endif
-+
-+
-+/*****************************************************************************
-+ Remove duplicates from tmp table
-+ This should be recoded to add a unique index to the table and remove
-+ duplicates
-+ Table is a locked single thread table
-+ fields is the number of fields to check (from the end)
-+*****************************************************************************/
-+
-+static bool compare_record(TABLE *table, Field **ptr)
-+{
-+ for (; *ptr ; ptr++)
-+ {
-+ if ((*ptr)->cmp_offset(table->s->rec_buff_length))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+static bool copy_blobs(Field **ptr)
-+{
-+ for (; *ptr ; ptr++)
-+ {
-+ if ((*ptr)->flags & BLOB_FLAG)
-+ if (((Field_blob *) (*ptr))->copy())
-+ return 1; // Error
-+ }
-+ return 0;
-+}
-+
-+static void free_blobs(Field **ptr)
-+{
-+ for (; *ptr ; ptr++)
-+ {
-+ if ((*ptr)->flags & BLOB_FLAG)
-+ ((Field_blob *) (*ptr))->free();
-+ }
-+}
-+
-+
-+static int
-+remove_duplicates(JOIN *join, TABLE *entry,List<Item> &fields, Item *having)
-+{
-+ int error;
-+ ulong reclength,offset;
-+ uint field_count;
-+ THD *thd= join->thd;
-+ DBUG_ENTER("remove_duplicates");
-+
-+ entry->reginfo.lock_type=TL_WRITE;
-+
-+ /* Calculate how many saved fields there is in list */
-+ field_count=0;
-+ List_iterator<Item> it(fields);
-+ Item *item;
-+ while ((item=it++))
-+ {
-+ if (item->get_tmp_table_field() && ! item->const_item())
-+ field_count++;
-+ }
-+
-+ if (!field_count && !(join->select_options & OPTION_FOUND_ROWS) && !having)
-+ { // only const items with no OPTION_FOUND_ROWS
-+ join->unit->select_limit_cnt= 1; // Only send first row
-+ DBUG_RETURN(0);
-+ }
-+ Field **first_field=entry->field+entry->s->fields - field_count;
-+ offset= (field_count ?
-+ entry->field[entry->s->fields - field_count]->
-+ offset(entry->record[0]) : 0);
-+ reclength=entry->s->reclength-offset;
-+
-+ free_io_cache(entry); // Safety
-+ entry->file->info(HA_STATUS_VARIABLE);
-+ if (entry->s->db_type() == heap_hton ||
-+ (!entry->s->blob_fields &&
-+ ((ALIGN_SIZE(reclength) + HASH_OVERHEAD) * entry->file->stats.records <
-+ thd->variables.sortbuff_size)))
-+ error=remove_dup_with_hash_index(join->thd, entry,
-+ field_count, first_field,
-+ reclength, having);
-+ else
-+ error=remove_dup_with_compare(join->thd, entry, first_field, offset,
-+ having);
-+
-+ free_blobs(first_field);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field,
-+ ulong offset, Item *having)
-+{
-+ handler *file=table->file;
-+ char *org_record,*new_record;
-+ uchar *record;
-+ int error;
-+ ulong reclength= table->s->reclength-offset;
-+ DBUG_ENTER("remove_dup_with_compare");
-+
-+ org_record=(char*) (record=table->record[0])+offset;
-+ new_record=(char*) table->record[1]+offset;
-+
-+ file->ha_rnd_init(1);
-+ error=file->rnd_next(record);
-+ for (;;)
-+ {
-+ if (thd->killed)
-+ {
-+ thd->send_kill_message();
-+ error=0;
-+ goto err;
-+ }
-+ if (error)
-+ {
-+ if (error == HA_ERR_RECORD_DELETED)
-+ {
-+ error= file->rnd_next(record);
-+ continue;
-+ }
-+ if (error == HA_ERR_END_OF_FILE)
-+ break;
-+ goto err;
-+ }
-+ if (having && !having->val_int())
-+ {
-+ if ((error=file->ha_delete_row(record)))
-+ goto err;
-+ error=file->rnd_next(record);
-+ continue;
-+ }
-+ if (copy_blobs(first_field))
-+ {
-+ my_message(ER_OUTOFMEMORY, ER(ER_OUTOFMEMORY), MYF(0));
-+ error=0;
-+ goto err;
-+ }
-+ memcpy(new_record,org_record,reclength);
-+
-+ /* Read through rest of file and mark duplicated rows deleted */
-+ bool found=0;
-+ for (;;)
-+ {
-+ if ((error=file->rnd_next(record)))
-+ {
-+ if (error == HA_ERR_RECORD_DELETED)
-+ continue;
-+ if (error == HA_ERR_END_OF_FILE)
-+ break;
-+ goto err;
-+ }
-+ if (compare_record(table, first_field) == 0)
-+ {
-+ if ((error=file->ha_delete_row(record)))
-+ goto err;
-+ }
-+ else if (!found)
-+ {
-+ found=1;
-+ file->position(record); // Remember position
-+ }
-+ }
-+ if (!found)
-+ break; // End of file
-+ /* Restart search on next row */
-+ error=file->restart_rnd_next(record,file->ref);
-+ }
-+
-+ file->extra(HA_EXTRA_NO_CACHE);
-+ DBUG_RETURN(0);
-+err:
-+ file->extra(HA_EXTRA_NO_CACHE);
-+ if (error)
-+ file->print_error(error,MYF(0));
-+ DBUG_RETURN(1);
-+}
-+
-+
-+/**
-+ Generate a hash index for each row to quickly find duplicate rows.
-+
-+ @note
-+ Note that this will not work on tables with blobs!
-+*/
-+
-+static int remove_dup_with_hash_index(THD *thd, TABLE *table,
-+ uint field_count,
-+ Field **first_field,
-+ ulong key_length,
-+ Item *having)
-+{
-+ uchar *key_buffer, *key_pos, *record=table->record[0];
-+ int error;
-+ handler *file= table->file;
-+ ulong extra_length= ALIGN_SIZE(key_length)-key_length;
-+ uint *field_lengths,*field_length;
-+ HASH hash;
-+ DBUG_ENTER("remove_dup_with_hash_index");
-+
-+ if (!my_multi_malloc(MYF(MY_WME),
-+ &key_buffer,
-+ (uint) ((key_length + extra_length) *
-+ (long) file->stats.records),
-+ &field_lengths,
-+ (uint) (field_count*sizeof(*field_lengths)),
-+ NullS))
-+ DBUG_RETURN(1);
-+
-+ {
-+ Field **ptr;
-+ ulong total_length= 0;
-+ for (ptr= first_field, field_length=field_lengths ; *ptr ; ptr++)
-+ {
-+ uint length= (*ptr)->sort_length();
-+ (*field_length++)= length;
-+ total_length+= length;
-+ }
-+ DBUG_PRINT("info",("field_count: %u key_length: %lu total_length: %lu",
-+ field_count, key_length, total_length));
-+ DBUG_ASSERT(total_length <= key_length);
-+ key_length= total_length;
-+ extra_length= ALIGN_SIZE(key_length)-key_length;
-+ }
-+
-+ if (hash_init(&hash, &my_charset_bin, (uint) file->stats.records, 0,
-+ key_length, (hash_get_key) 0, 0, 0))
-+ {
-+ my_free((char*) key_buffer,MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+
-+ file->ha_rnd_init(1);
-+ key_pos=key_buffer;
-+ for (;;)
-+ {
-+ uchar *org_key_pos;
-+ if (thd->killed)
-+ {
-+ thd->send_kill_message();
-+ error=0;
-+ goto err;
-+ }
-+ if ((error=file->rnd_next(record)))
-+ {
-+ if (error == HA_ERR_RECORD_DELETED)
-+ continue;
-+ if (error == HA_ERR_END_OF_FILE)
-+ break;
-+ goto err;
-+ }
-+ if (having && !having->val_int())
-+ {
-+ if ((error=file->ha_delete_row(record)))
-+ goto err;
-+ continue;
-+ }
-+
-+ /* copy fields to key buffer */
-+ org_key_pos= key_pos;
-+ field_length=field_lengths;
-+ for (Field **ptr= first_field ; *ptr ; ptr++)
-+ {
-+ (*ptr)->sort_string(key_pos,*field_length);
-+ key_pos+= *field_length++;
-+ }
-+ /* Check if it exists before */
-+ if (hash_search(&hash, org_key_pos, key_length))
-+ {
-+ /* Duplicated found ; Remove the row */
-+ if ((error=file->ha_delete_row(record)))
-+ goto err;
-+ }
-+ else
-+ {
-+ if (my_hash_insert(&hash, org_key_pos))
-+ goto err;
-+ }
-+ key_pos+=extra_length;
-+ }
-+ my_free((char*) key_buffer,MYF(0));
-+ hash_free(&hash);
-+ file->extra(HA_EXTRA_NO_CACHE);
-+ (void) file->ha_rnd_end();
-+ DBUG_RETURN(0);
-+
-+err:
-+ my_free((char*) key_buffer,MYF(0));
-+ hash_free(&hash);
-+ file->extra(HA_EXTRA_NO_CACHE);
-+ (void) file->ha_rnd_end();
-+ if (error)
-+ file->print_error(error,MYF(0));
-+ DBUG_RETURN(1);
-+}
-+
-+
-+SORT_FIELD *make_unireg_sortorder(ORDER *order, uint *length,
-+ SORT_FIELD *sortorder)
-+{
-+ uint count;
-+ SORT_FIELD *sort,*pos;
-+ DBUG_ENTER("make_unireg_sortorder");
-+
-+ count=0;
-+ for (ORDER *tmp = order; tmp; tmp=tmp->next)
-+ count++;
-+ if (!sortorder)
-+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
-+ (max(count, *length) + 1));
-+ pos= sort= sortorder;
-+
-+ if (!pos)
-+ return 0;
-+
-+ for (;order;order=order->next,pos++)
-+ {
-+ Item *item= order->item[0]->real_item();
-+ pos->field= 0; pos->item= 0;
-+ if (item->type() == Item::FIELD_ITEM)
-+ pos->field= ((Item_field*) item)->field;
-+ else if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
-+ pos->field= ((Item_sum*) item)->get_tmp_table_field();
-+ else if (item->type() == Item::COPY_STR_ITEM)
-+ { // Blob patch
-+ pos->item= ((Item_copy*) item)->get_item();
-+ }
-+ else
-+ pos->item= *order->item;
-+ pos->reverse=! order->asc;
-+ }
-+ *length=count;
-+ DBUG_RETURN(sort);
-+}
-+
-+
-+/*****************************************************************************
-+ Fill join cache with packed records
-+ Records are stored in tab->cache.buffer and last record in
-+ last record is stored with pointers to blobs to support very big
-+ records
-+******************************************************************************/
-+
-+static int
-+join_init_cache(THD *thd,JOIN_TAB *tables,uint table_count)
-+{
-+ reg1 uint i;
-+ uint length, blobs;
-+ size_t size;
-+ CACHE_FIELD *copy,**blob_ptr;
-+ JOIN_CACHE *cache;
-+ JOIN_TAB *join_tab;
-+ DBUG_ENTER("join_init_cache");
-+
-+ cache= &tables[table_count].cache;
-+ cache->fields=blobs=0;
-+
-+ join_tab=tables;
-+ for (i=0 ; i < table_count ; i++,join_tab++)
-+ {
-+ if (!join_tab->used_fieldlength) /* Not calced yet */
-+ calc_used_field_length(thd, join_tab);
-+ cache->fields+=join_tab->used_fields;
-+ blobs+=join_tab->used_blobs;
-+ }
-+ if (!(cache->field=(CACHE_FIELD*)
-+ sql_alloc(sizeof(CACHE_FIELD)*(cache->fields+table_count*2)+(blobs+1)*
-+
-+ sizeof(CACHE_FIELD*))))
-+ {
-+ my_free((uchar*) cache->buff,MYF(0)); /* purecov: inspected */
-+ cache->buff=0; /* purecov: inspected */
-+ DBUG_RETURN(1); /* purecov: inspected */
-+ }
-+ copy=cache->field;
-+ blob_ptr=cache->blob_ptr=(CACHE_FIELD**)
-+ (cache->field+cache->fields+table_count*2);
-+
-+ length=0;
-+ for (i=0 ; i < table_count ; i++)
-+ {
-+ bool have_bit_fields= FALSE;
-+ uint null_fields=0,used_fields;
-+ Field **f_ptr,*field;
-+ MY_BITMAP *read_set= tables[i].table->read_set;
-+ for (f_ptr=tables[i].table->field,used_fields=tables[i].used_fields ;
-+ used_fields ;
-+ f_ptr++)
-+ {
-+ field= *f_ptr;
-+ if (bitmap_is_set(read_set, field->field_index))
-+ {
-+ used_fields--;
-+ length+=field->fill_cache_field(copy);
-+ if (copy->type == CACHE_BLOB)
-+ (*blob_ptr++)=copy;
-+ if (field->real_maybe_null())
-+ null_fields++;
-+ if (field->type() == MYSQL_TYPE_BIT &&
-+ ((Field_bit*)field)->bit_len)
-+ have_bit_fields= TRUE;
-+ copy++;
-+ }
-+ }
-+ /* Copy null bits from table */
-+ if (null_fields || have_bit_fields)
-+ { /* must copy null bits */
-+ copy->str= tables[i].table->null_flags;
-+ copy->length= tables[i].table->s->null_bytes;
-+ copy->type=0;
-+ copy->field=0;
-+ length+=copy->length;
-+ copy++;
-+ cache->fields++;
-+ }
-+ /* If outer join table, copy null_row flag */
-+ if (tables[i].table->maybe_null)
-+ {
-+ copy->str= (uchar*) &tables[i].table->null_row;
-+ copy->length=sizeof(tables[i].table->null_row);
-+ copy->type=0;
-+ copy->field=0;
-+ length+=copy->length;
-+ copy++;
-+ cache->fields++;
-+ }
-+ }
-+
-+ cache->length=length+blobs*sizeof(char*);
-+ cache->blobs=blobs;
-+ *blob_ptr=0; /* End sequentel */
-+ size=max(thd->variables.join_buff_size, cache->length);
-+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
-+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
-+ cache->end=cache->buff+size;
-+ reset_cache_write(cache);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static ulong
-+used_blob_length(CACHE_FIELD **ptr)
-+{
-+ uint length,blob_length;
-+ for (length=0 ; *ptr ; ptr++)
-+ {
-+ Field_blob *field_blob= (Field_blob *) (*ptr)->field;
-+ (*ptr)->blob_length=blob_length= field_blob->get_length();
-+ length+=blob_length;
-+ field_blob->get_ptr(&(*ptr)->str);
-+ }
-+ return length;
-+}
-+
-+
-+static bool
-+store_record_in_cache(JOIN_CACHE *cache)
-+{
-+ uint length;
-+ uchar *pos;
-+ CACHE_FIELD *copy,*end_field;
-+ bool last_record;
-+
-+ pos=cache->pos;
-+ end_field=cache->field+cache->fields;
-+
-+ length=cache->length;
-+ if (cache->blobs)
-+ length+=used_blob_length(cache->blob_ptr);
-+ if ((last_record= (length + cache->length > (size_t) (cache->end - pos))))
-+ cache->ptr_record=cache->records;
-+
-+ /*
-+ There is room in cache. Put record there
-+ */
-+ cache->records++;
-+ for (copy=cache->field ; copy < end_field; copy++)
-+ {
-+ if (copy->type == CACHE_BLOB)
-+ {
-+ Field_blob *blob_field= (Field_blob *) copy->field;
-+ if (last_record)
-+ {
-+ blob_field->get_image(pos, copy->length+sizeof(char*),
-+ blob_field->charset());
-+ pos+=copy->length+sizeof(char*);
-+ }
-+ else
-+ {
-+ blob_field->get_image(pos, copy->length, // blob length
-+ blob_field->charset());
-+ memcpy(pos+copy->length,copy->str,copy->blob_length); // Blob data
-+ pos+=copy->length+copy->blob_length;
-+ }
-+ }
-+ else
-+ {
-+ if (copy->type == CACHE_STRIPPED)
-+ {
-+ uchar *str,*end;
-+ Field *field= copy->field;
-+ if (field && field->maybe_null() && field->is_null())
-+ end= str= copy->str;
-+ else
-+ for (str=copy->str,end= str+copy->length;
-+ end > str && end[-1] == ' ' ;
-+ end--) ;
-+ length=(uint) (end-str);
-+ memcpy(pos+2, str, length);
-+ int2store(pos, length);
-+ pos+= length+2;
-+ }
-+ else
-+ {
-+ memcpy(pos,copy->str,copy->length);
-+ pos+=copy->length;
-+ }
-+ }
-+ }
-+ cache->pos=pos;
-+ return last_record || (size_t) (cache->end - pos) < cache->length;
-+}
-+
-+
-+static void
-+reset_cache_read(JOIN_CACHE *cache)
-+{
-+ cache->record_nr=0;
-+ cache->pos=cache->buff;
-+}
-+
-+
-+static void reset_cache_write(JOIN_CACHE *cache)
-+{
-+ reset_cache_read(cache);
-+ cache->records= 0;
-+ cache->ptr_record= (uint) ~0;
-+}
-+
-+
-+static void
-+read_cached_record(JOIN_TAB *tab)
-+{
-+ uchar *pos;
-+ uint length;
-+ bool last_record;
-+ CACHE_FIELD *copy,*end_field;
-+
-+ last_record=tab->cache.record_nr++ == tab->cache.ptr_record;
-+ pos=tab->cache.pos;
-+
-+ for (copy=tab->cache.field,end_field=copy+tab->cache.fields ;
-+ copy < end_field;
-+ copy++)
-+ {
-+ if (copy->type == CACHE_BLOB)
-+ {
-+ Field_blob *blob_field= (Field_blob *) copy->field;
-+ if (last_record)
-+ {
-+ blob_field->set_image(pos, copy->length+sizeof(char*),
-+ blob_field->charset());
-+ pos+=copy->length+sizeof(char*);
-+ }
-+ else
-+ {
-+ blob_field->set_ptr(pos, pos+copy->length);
-+ pos+=copy->length + blob_field->get_length();
-+ }
-+ }
-+ else
-+ {
-+ if (copy->type == CACHE_STRIPPED)
-+ {
-+ length= uint2korr(pos);
-+ memcpy(copy->str, pos+2, length);
-+ memset(copy->str+length, ' ', copy->length-length);
-+ pos+= 2 + length;
-+ }
-+ else
-+ {
-+ memcpy(copy->str,pos,copy->length);
-+ pos+=copy->length;
-+ }
-+ }
-+ }
-+ tab->cache.pos=pos;
-+ return;
-+}
-+
-+
-+static bool
-+cmp_buffer_with_ref(JOIN_TAB *tab)
-+{
-+ bool diff;
-+ if (!(diff=tab->ref.key_err))
-+ {
-+ memcpy(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length);
-+ }
-+ if ((tab->ref.key_err= cp_buffer_from_ref(tab->join->thd, tab->table,
-+ &tab->ref)) ||
-+ diff)
-+ return 1;
-+ return memcmp(tab->ref.key_buff2, tab->ref.key_buff, tab->ref.key_length)
-+ != 0;
-+}
-+
-+
-+bool
-+cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref)
-+{
-+ enum enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
-+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-+ my_bitmap_map *old_map= dbug_tmp_use_all_columns(table, table->write_set);
-+ bool result= 0;
-+
-+ for (store_key **copy=ref->key_copy ; *copy ; copy++)
-+ {
-+ if ((*copy)->copy() & 1)
-+ {
-+ result= 1;
-+ break;
-+ }
-+ }
-+ thd->count_cuted_fields= save_count_cuted_fields;
-+ dbug_tmp_restore_column_map(table->write_set, old_map);
-+ return result;
-+}
-+
-+
-+/*****************************************************************************
-+ Group and order functions
-+*****************************************************************************/
-+
-+/**
-+ Resolve an ORDER BY or GROUP BY column reference.
-+
-+ Given a column reference (represented by 'order') from a GROUP BY or ORDER
-+ BY clause, find the actual column it represents. If the column being
-+ resolved is from the GROUP BY clause, the procedure searches the SELECT
-+ list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
-+ the ORDER BY clause, only the SELECT list is being searched.
-+
-+ If 'order' is resolved to an Item, then order->item is set to the found
-+ Item. If there is no item for the found column (that is, it was resolved
-+ into a table field), order->item is 'fixed' and is added to all_fields and
-+ ref_pointer_array.
-+
-+ ref_pointer_array and all_fields are updated.
-+
-+ @param[in] thd Pointer to current thread structure
-+ @param[in,out] ref_pointer_array All select, group and order by fields
-+ @param[in] tables List of tables to search in (usually
-+ FROM clause)
-+ @param[in] order Column reference to be resolved
-+ @param[in] fields List of fields to search in (usually
-+ SELECT list)
-+ @param[in,out] all_fields All select, group and order by fields
-+ @param[in] is_group_field True if order is a GROUP field, false if
-+ ORDER by field
-+
-+ @retval
-+ FALSE if OK
-+ @retval
-+ TRUE if error occurred
-+*/
-+
-+static bool
-+find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
-+ ORDER *order, List<Item> &fields, List<Item> &all_fields,
-+ bool is_group_field)
-+{
-+ Item *order_item= *order->item; /* The item from the GROUP/ORDER caluse. */
-+ Item::Type order_item_type;
-+ Item **select_item; /* The corresponding item from the SELECT clause. */
-+ Field *from_field; /* The corresponding field from the FROM clause. */
-+ uint counter;
-+ enum_resolution_type resolution;
-+
-+ /*
-+ Local SP variables may be int but are expressions, not positions.
-+ (And they can't be used before fix_fields is called for them).
-+ */
-+ if (order_item->type() == Item::INT_ITEM && order_item->basic_const_item())
-+ { /* Order by position */
-+ uint count= (uint) order_item->val_int();
-+ if (!count || count > fields.elements)
-+ {
-+ my_error(ER_BAD_FIELD_ERROR, MYF(0),
-+ order_item->full_name(), thd->where);
-+ return TRUE;
-+ }
-+ order->item= ref_pointer_array + count - 1;
-+ order->in_field_list= 1;
-+ order->counter= count;
-+ order->counter_used= 1;
-+ return FALSE;
-+ }
-+ /* Lookup the current GROUP/ORDER field in the SELECT clause. */
-+ select_item= find_item_in_list(order_item, fields, &counter,
-+ REPORT_EXCEPT_NOT_FOUND, &resolution);
-+ if (!select_item)
-+ return TRUE; /* The item is not unique, or some other error occured. */
-+
-+
-+ /* Check whether the resolved field is not ambiguos. */
-+ if (select_item != not_found_item)
-+ {
-+ Item *view_ref= NULL;
-+ /*
-+ If we have found field not by its alias in select list but by its
-+ original field name, we should additionaly check if we have conflict
-+ for this name (in case if we would perform lookup in all tables).
-+ */
-+ if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
-+ order_item->fix_fields(thd, order->item))
-+ return TRUE;
-+
-+ /* Lookup the current GROUP field in the FROM clause. */
-+ order_item_type= order_item->type();
-+ from_field= (Field*) not_found_field;
-+ if ((is_group_field &&
-+ order_item_type == Item::FIELD_ITEM) ||
-+ order_item_type == Item::REF_ITEM)
-+ {
-+ from_field= find_field_in_tables(thd, (Item_ident*) order_item, tables,
-+ NULL, &view_ref, IGNORE_ERRORS, TRUE,
-+ FALSE);
-+ if (!from_field)
-+ from_field= (Field*) not_found_field;
-+ }
-+
-+ if (from_field == not_found_field ||
-+ (from_field != view_ref_found ?
-+ /* it is field of base table => check that fields are same */
-+ ((*select_item)->type() == Item::FIELD_ITEM &&
-+ ((Item_field*) (*select_item))->field->eq(from_field)) :
-+ /*
-+ in is field of view table => check that references on translation
-+ table are same
-+ */
-+ ((*select_item)->type() == Item::REF_ITEM &&
-+ view_ref->type() == Item::REF_ITEM &&
-+ ((Item_ref *) (*select_item))->ref ==
-+ ((Item_ref *) view_ref)->ref)))
-+ {
-+ /*
-+ If there is no such field in the FROM clause, or it is the same field
-+ as the one found in the SELECT clause, then use the Item created for
-+ the SELECT field. As a result if there was a derived field that
-+ 'shadowed' a table field with the same name, the table field will be
-+ chosen over the derived field.
-+ */
-+ order->item= ref_pointer_array + counter;
-+ order->in_field_list=1;
-+ return FALSE;
-+ }
-+ else
-+ {
-+ /*
-+ There is a field with the same name in the FROM clause. This
-+ is the field that will be chosen. In this case we issue a
-+ warning so the user knows that the field from the FROM clause
-+ overshadows the column reference from the SELECT list.
-+ */
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NON_UNIQ_ERROR,
-+ ER(ER_NON_UNIQ_ERROR),
-+ ((Item_ident*) order_item)->field_name,
-+ current_thd->where);
-+ }
-+ }
-+
-+ order->in_field_list=0;
-+ /*
-+ The call to order_item->fix_fields() means that here we resolve
-+ 'order_item' to a column from a table in the list 'tables', or to
-+ a column in some outer query. Exactly because of the second case
-+ we come to this point even if (select_item == not_found_item),
-+ inspite of that fix_fields() calls find_item_in_list() one more
-+ time.
-+
-+ We check order_item->fixed because Item_func_group_concat can put
-+ arguments for which fix_fields already was called.
-+
-+ group_fix_field= TRUE is to resolve aliases from the SELECT list
-+ without creating of Item_ref-s: JOIN::exec() wraps aliased items
-+ in SELECT list with Item_copy items. To re-evaluate such a tree
-+ that includes Item_copy items we have to refresh Item_copy caches,
-+ but:
-+ - filesort() never refresh Item_copy items,
-+ - end_send_group() checks every record for group boundary by the
-+ test_if_group_changed function that obtain data from these
-+ Item_copy items, but the copy_fields function that
-+ refreshes Item copy items is called after group boundaries only -
-+ that is a vicious circle.
-+ So we prevent inclusion of Item_copy items.
-+ */
-+ bool save_group_fix_field= thd->lex->current_select->group_fix_field;
-+ if (is_group_field)
-+ thd->lex->current_select->group_fix_field= TRUE;
-+ bool ret= (!order_item->fixed &&
-+ (order_item->fix_fields(thd, order->item) ||
-+ (order_item= *order->item)->check_cols(1) ||
-+ thd->is_fatal_error));
-+ thd->lex->current_select->group_fix_field= save_group_fix_field;
-+ if (ret)
-+ return TRUE; /* Wrong field. */
-+
-+ uint el= all_fields.elements;
-+ all_fields.push_front(order_item); /* Add new field to field list. */
-+ ref_pointer_array[el]= order_item;
-+ order->item= ref_pointer_array + el;
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Change order to point at item in select list.
-+
-+ If item isn't a number and doesn't exits in the select list, add it the
-+ the field list.
-+*/
-+
-+int setup_order(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
-+ List<Item> &fields, List<Item> &all_fields, ORDER *order)
-+{
-+ thd->where="order clause";
-+ for (; order; order=order->next)
-+ {
-+ if (find_order_in_list(thd, ref_pointer_array, tables, order, fields,
-+ all_fields, FALSE))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Intitialize the GROUP BY list.
-+
-+ @param thd Thread handler
-+ @param ref_pointer_array We store references to all fields that was
-+ not in 'fields' here.
-+ @param fields All fields in the select part. Any item in
-+ 'order' that is part of these list is replaced
-+ by a pointer to this fields.
-+ @param all_fields Total list of all unique fields used by the
-+ select. All items in 'order' that was not part
-+ of fields will be added first to this list.
-+ @param order The fields we should do GROUP BY on.
-+ @param hidden_group_fields Pointer to flag that is set to 1 if we added
-+ any fields to all_fields.
-+
-+ @todo
-+ change ER_WRONG_FIELD_WITH_GROUP to more detailed
-+ ER_NON_GROUPING_FIELD_USED
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error (probably out of memory)
-+*/
-+
-+int
-+setup_group(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,
-+ List<Item> &fields, List<Item> &all_fields, ORDER *order,
-+ bool *hidden_group_fields)
-+{
-+ *hidden_group_fields=0;
-+ ORDER *ord;
-+
-+ if (!order)
-+ return 0; /* Everything is ok */
-+
-+ uint org_fields=all_fields.elements;
-+
-+ thd->where="group statement";
-+ for (ord= order; ord; ord= ord->next)
-+ {
-+ if (find_order_in_list(thd, ref_pointer_array, tables, ord, fields,
-+ all_fields, TRUE))
-+ return 1;
-+ (*ord->item)->marker= UNDEF_POS; /* Mark found */
-+ if ((*ord->item)->with_sum_func)
-+ {
-+ my_error(ER_WRONG_GROUP_FIELD, MYF(0), (*ord->item)->full_name());
-+ return 1;
-+ }
-+ }
-+ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY)
-+ {
-+ /*
-+ Don't allow one to use fields that is not used in GROUP BY
-+ For each select a list of field references that aren't under an
-+ aggregate function is created. Each field in this list keeps the
-+ position of the select list expression which it belongs to.
-+
-+ First we check an expression from the select list against the GROUP BY
-+ list. If it's found there then it's ok. It's also ok if this expression
-+ is a constant or an aggregate function. Otherwise we scan the list
-+ of non-aggregated fields and if we'll find at least one field reference
-+ that belongs to this expression and doesn't occur in the GROUP BY list
-+ we throw an error. If there are no fields in the created list for a
-+ select list expression this means that all fields in it are used under
-+ aggregate functions.
-+ */
-+ Item *item;
-+ Item_field *field;
-+ int cur_pos_in_select_list= 0;
-+ List_iterator<Item> li(fields);
-+ List_iterator<Item_field> naf_it(thd->lex->current_select->non_agg_fields);
-+
-+ field= naf_it++;
-+ while (field && (item=li++))
-+ {
-+ if (item->type() != Item::SUM_FUNC_ITEM && item->marker >= 0 &&
-+ !item->const_item() &&
-+ !(item->real_item()->type() == Item::FIELD_ITEM &&
-+ item->used_tables() & OUTER_REF_TABLE_BIT))
-+ {
-+ while (field)
-+ {
-+ /* Skip fields from previous expressions. */
-+ if (field->marker < cur_pos_in_select_list)
-+ goto next_field;
-+ /* Found a field from the next expression. */
-+ if (field->marker > cur_pos_in_select_list)
-+ break;
-+ /*
-+ Check whether the field occur in the GROUP BY list.
-+ Throw the error later if the field isn't found.
-+ */
-+ for (ord= order; ord; ord= ord->next)
-+ if ((*ord->item)->eq((Item*)field, 0))
-+ goto next_field;
-+ /*
-+ TODO: change ER_WRONG_FIELD_WITH_GROUP to more detailed
-+ ER_NON_GROUPING_FIELD_USED
-+ */
-+ my_error(ER_WRONG_FIELD_WITH_GROUP, MYF(0), field->full_name());
-+ return 1;
-+next_field:
-+ field= naf_it++;
-+ }
-+ }
-+ cur_pos_in_select_list++;
-+ }
-+ }
-+ if (org_fields != all_fields.elements)
-+ *hidden_group_fields=1; // group fields is not used
-+ return 0;
-+}
-+
-+/**
-+ Add fields with aren't used at start of field list.
-+
-+ @return
-+ FALSE if ok
-+*/
-+
-+static bool
-+setup_new_fields(THD *thd, List<Item> &fields,
-+ List<Item> &all_fields, ORDER *new_field)
-+{
-+ Item **item;
-+ uint counter;
-+ enum_resolution_type not_used;
-+ DBUG_ENTER("setup_new_fields");
-+
-+ thd->mark_used_columns= MARK_COLUMNS_READ; // Not really needed, but...
-+ for (; new_field ; new_field= new_field->next)
-+ {
-+ if ((item= find_item_in_list(*new_field->item, fields, &counter,
-+ IGNORE_ERRORS, ¬_used)))
-+ new_field->item=item; /* Change to shared Item */
-+ else
-+ {
-+ thd->where="procedure list";
-+ if ((*new_field->item)->fix_fields(thd, new_field->item))
-+ DBUG_RETURN(1); /* purecov: inspected */
-+ all_fields.push_front(*new_field->item);
-+ new_field->item=all_fields.head_ref();
-+ }
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+/**
-+ Create a group by that consist of all non const fields.
-+
-+ Try to use the fields in the order given by 'order' to allow one to
-+ optimize away 'order by'.
-+*/
-+
-+static ORDER *
-+create_distinct_group(THD *thd, Item **ref_pointer_array,
-+ ORDER *order_list, List<Item> &fields,
-+ List<Item> &all_fields,
-+ bool *all_order_by_fields_used)
-+{
-+ List_iterator<Item> li(fields);
-+ Item *item, **orig_ref_pointer_array= ref_pointer_array;
-+ ORDER *order,*group,**prev;
-+
-+ *all_order_by_fields_used= 1;
-+ while ((item=li++))
-+ item->marker=0; /* Marker that field is not used */
-+
-+ prev= &group; group=0;
-+ for (order=order_list ; order; order=order->next)
-+ {
-+ if (order->in_field_list)
-+ {
-+ ORDER *ord=(ORDER*) thd->memdup((char*) order,sizeof(ORDER));
-+ if (!ord)
-+ return 0;
-+ *prev=ord;
-+ prev= &ord->next;
-+ (*ord->item)->marker=1;
-+ }
-+ else
-+ *all_order_by_fields_used= 0;
-+ }
-+
-+ li.rewind();
-+ while ((item=li++))
-+ {
-+ if (!item->const_item() && !item->with_sum_func && !item->marker)
-+ {
-+ /*
-+ Don't put duplicate columns from the SELECT list into the
-+ GROUP BY list.
-+ */
-+ ORDER *ord_iter;
-+ for (ord_iter= group; ord_iter; ord_iter= ord_iter->next)
-+ if ((*ord_iter->item)->eq(item, 1))
-+ goto next_item;
-+
-+ ORDER *ord=(ORDER*) thd->calloc(sizeof(ORDER));
-+ if (!ord)
-+ return 0;
-+
-+ if (item->type() == Item::FIELD_ITEM &&
-+ item->field_type() == MYSQL_TYPE_BIT)
-+ {
-+ /*
-+ Because HEAP tables can't index BIT fields we need to use an
-+ additional hidden field for grouping because later it will be
-+ converted to a LONG field. Original field will remain of the
-+ BIT type and will be returned to a client.
-+ */
-+ Item_field *new_item= new Item_field(thd, (Item_field*)item);
-+ int el= all_fields.elements;
-+ orig_ref_pointer_array[el]= new_item;
-+ all_fields.push_front(new_item);
-+ ord->item= orig_ref_pointer_array + el;
-+ }
-+ else
-+ {
-+ /*
-+ We have here only field_list (not all_field_list), so we can use
-+ simple indexing of ref_pointer_array (order in the array and in the
-+ list are same)
-+ */
-+ ord->item= ref_pointer_array;
-+ }
-+ ord->asc=1;
-+ *prev=ord;
-+ prev= &ord->next;
-+ }
-+next_item:
-+ ref_pointer_array++;
-+ }
-+ *prev=0;
-+ return group;
-+}
-+
-+
-+/**
-+ Update join with count of the different type of fields.
-+*/
-+
-+void
-+count_field_types(SELECT_LEX *select_lex, TMP_TABLE_PARAM *param,
-+ List<Item> &fields, bool reset_with_sum_func)
-+{
-+ List_iterator<Item> li(fields);
-+ Item *field;
-+
-+ param->field_count=param->sum_func_count=param->func_count=
-+ param->hidden_field_count=0;
-+ param->quick_group=1;
-+ while ((field=li++))
-+ {
-+ Item::Type real_type= field->real_item()->type();
-+ if (real_type == Item::FIELD_ITEM)
-+ param->field_count++;
-+ else if (real_type == Item::SUM_FUNC_ITEM)
-+ {
-+ if (! field->const_item())
-+ {
-+ Item_sum *sum_item=(Item_sum*) field->real_item();
-+ if (!sum_item->depended_from() ||
-+ sum_item->depended_from() == select_lex)
-+ {
-+ if (!sum_item->quick_group)
-+ param->quick_group=0; // UDF SUM function
-+ param->sum_func_count++;
-+
-+ for (uint i=0 ; i < sum_item->get_arg_count() ; i++)
-+ {
-+ if (sum_item->get_arg(i)->real_item()->type() == Item::FIELD_ITEM)
-+ param->field_count++;
-+ else
-+ param->func_count++;
-+ }
-+ }
-+ param->func_count++;
-+ }
-+ }
-+ else
-+ {
-+ param->func_count++;
-+ if (reset_with_sum_func)
-+ field->with_sum_func=0;
-+ }
-+ }
-+}
-+
-+
-+/**
-+ Return 1 if second is a subpart of first argument.
-+
-+ If first parts has different direction, change it to second part
-+ (group is sorted like order)
-+*/
-+
-+static bool
-+test_if_subpart(ORDER *a,ORDER *b)
-+{
-+ for (; a && b; a=a->next,b=b->next)
-+ {
-+ if ((*a->item)->eq(*b->item,1))
-+ a->asc=b->asc;
-+ else
-+ return 0;
-+ }
-+ return test(!b);
-+}
-+
-+/**
-+ Return table number if there is only one table in sort order
-+ and group and order is compatible, else return 0.
-+*/
-+
-+static TABLE *
-+get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables)
-+{
-+ table_map map= (table_map) 0;
-+ DBUG_ENTER("get_sort_by_table");
-+
-+ if (!a)
-+ a=b; // Only one need to be given
-+ else if (!b)
-+ b=a;
-+
-+ for (; a && b; a=a->next,b=b->next)
-+ {
-+ if (!(*a->item)->eq(*b->item,1))
-+ DBUG_RETURN(0);
-+ map|=a->item[0]->used_tables();
-+ }
-+ if (!map || (map & (RAND_TABLE_BIT | OUTER_REF_TABLE_BIT)))
-+ DBUG_RETURN(0);
-+
-+ for (; !(map & tables->table->map); tables= tables->next_leaf) ;
-+ if (map != tables->table->map)
-+ DBUG_RETURN(0); // More than one table
-+ DBUG_PRINT("exit",("sort by table: %d",tables->table->tablenr));
-+ DBUG_RETURN(tables->table);
-+}
-+
-+
-+/**
-+ calc how big buffer we need for comparing group entries.
-+*/
-+
-+static void
-+calc_group_buffer(JOIN *join,ORDER *group)
-+{
-+ uint key_length=0, parts=0, null_parts=0;
-+
-+ if (group)
-+ join->group= 1;
-+ for (; group ; group=group->next)
-+ {
-+ Item *group_item= *group->item;
-+ Field *field= group_item->get_tmp_table_field();
-+ if (field)
-+ {
-+ enum_field_types type;
-+ if ((type= field->type()) == MYSQL_TYPE_BLOB)
-+ key_length+=MAX_BLOB_WIDTH; // Can't be used as a key
-+ else if (type == MYSQL_TYPE_VARCHAR || type == MYSQL_TYPE_VAR_STRING)
-+ key_length+= field->field_length + HA_KEY_BLOB_LENGTH;
-+ else if (type == MYSQL_TYPE_BIT)
-+ {
-+ /* Bit is usually stored as a longlong key for group fields */
-+ key_length+= 8; // Big enough
-+ }
-+ else
-+ key_length+= field->pack_length();
-+ }
-+ else
-+ {
-+ switch (group_item->result_type()) {
-+ case REAL_RESULT:
-+ key_length+= sizeof(double);
-+ break;
-+ case INT_RESULT:
-+ key_length+= sizeof(longlong);
-+ break;
-+ case DECIMAL_RESULT:
-+ key_length+= my_decimal_get_binary_size(group_item->max_length -
-+ (group_item->decimals ? 1 : 0),
-+ group_item->decimals);
-+ break;
-+ case STRING_RESULT:
-+ {
-+ enum enum_field_types type= group_item->field_type();
-+ /*
-+ As items represented as DATE/TIME fields in the group buffer
-+ have STRING_RESULT result type, we increase the length
-+ by 8 as maximum pack length of such fields.
-+ */
-+ if (type == MYSQL_TYPE_TIME ||
-+ type == MYSQL_TYPE_DATE ||
-+ type == MYSQL_TYPE_DATETIME ||
-+ type == MYSQL_TYPE_TIMESTAMP)
-+ {
-+ key_length+= 8;
-+ }
-+ else if (type == MYSQL_TYPE_BLOB)
-+ key_length+= MAX_BLOB_WIDTH; // Can't be used as a key
-+ else
-+ {
-+ /*
-+ Group strings are taken as varstrings and require an length field.
-+ A field is not yet created by create_tmp_field()
-+ and the sizes should match up.
-+ */
-+ key_length+= group_item->max_length + HA_KEY_BLOB_LENGTH;
-+ }
-+ break;
-+ }
-+ default:
-+ /* This case should never be choosen */
-+ DBUG_ASSERT(0);
-+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
-+ join->thd->fatal_error();
-+ }
-+ }
-+ parts++;
-+ if (group_item->maybe_null)
-+ null_parts++;
-+ }
-+ join->tmp_table_param.group_length=key_length+null_parts;
-+ join->tmp_table_param.group_parts=parts;
-+ join->tmp_table_param.group_null_parts=null_parts;
-+}
-+
-+
-+/**
-+ allocate group fields or take prepared (cached).
-+
-+ @param main_join join of current select
-+ @param curr_join current join (join of current select or temporary copy
-+ of it)
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 failed
-+*/
-+
-+static bool
-+make_group_fields(JOIN *main_join, JOIN *curr_join)
-+{
-+ if (main_join->group_fields_cache.elements)
-+ {
-+ curr_join->group_fields= main_join->group_fields_cache;
-+ curr_join->sort_and_group= 1;
-+ }
-+ else
-+ {
-+ if (alloc_group_fields(curr_join, curr_join->group_list))
-+ return (1);
-+ main_join->group_fields_cache= curr_join->group_fields;
-+ }
-+ return (0);
-+}
-+
-+
-+/**
-+ Get a list of buffers for saveing last group.
-+
-+ Groups are saved in reverse order for easyer check loop.
-+*/
-+
-+static bool
-+alloc_group_fields(JOIN *join,ORDER *group)
-+{
-+ if (group)
-+ {
-+ for (; group ; group=group->next)
-+ {
-+ Cached_item *tmp=new_Cached_item(join->thd, *group->item);
-+ if (!tmp || join->group_fields.push_front(tmp))
-+ return TRUE;
-+ }
-+ }
-+ join->sort_and_group=1; /* Mark for do_select */
-+ return FALSE;
-+}
-+
-+
-+static int
-+test_if_group_changed(List<Cached_item> &list)
-+{
-+ DBUG_ENTER("test_if_group_changed");
-+ List_iterator<Cached_item> li(list);
-+ int idx= -1,i;
-+ Cached_item *buff;
-+
-+ for (i=(int) list.elements-1 ; (buff=li++) ; i--)
-+ {
-+ if (buff->cmp())
-+ idx=i;
-+ }
-+ DBUG_PRINT("info", ("idx: %d", idx));
-+ DBUG_RETURN(idx);
-+}
-+
-+
-+/**
-+ Setup copy_fields to save fields at start of new group.
-+
-+ Setup copy_fields to save fields at start of new group
-+
-+ Only FIELD_ITEM:s and FUNC_ITEM:s needs to be saved between groups.
-+ Change old item_field to use a new field with points at saved fieldvalue
-+ This function is only called before use of send_fields.
-+
-+ @param thd THD pointer
-+ @param param temporary table parameters
-+ @param ref_pointer_array array of pointers to top elements of filed list
-+ @param res_selected_fields new list of items of select item list
-+ @param res_all_fields new list of all items
-+ @param elements number of elements in select item list
-+ @param all_fields all fields list
-+
-+ @todo
-+ In most cases this result will be sent to the user.
-+ This should be changed to use copy_int or copy_real depending
-+ on how the value is to be used: In some cases this may be an
-+ argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ !=0 error
-+*/
-+
-+bool
-+setup_copy_fields(THD *thd, TMP_TABLE_PARAM *param,
-+ Item **ref_pointer_array,
-+ List<Item> &res_selected_fields, List<Item> &res_all_fields,
-+ uint elements, List<Item> &all_fields)
-+{
-+ Item *pos;
-+ List_iterator_fast<Item> li(all_fields);
-+ Copy_field *copy= NULL;
-+ IF_DBUG(Copy_field *copy_start);
-+ res_selected_fields.empty();
-+ res_all_fields.empty();
-+ List_iterator_fast<Item> itr(res_all_fields);
-+ List<Item> extra_funcs;
-+ uint i, border= all_fields.elements - elements;
-+ DBUG_ENTER("setup_copy_fields");
-+
-+ if (param->field_count &&
-+ !(copy=param->copy_field= new Copy_field[param->field_count]))
-+ goto err2;
-+
-+ param->copy_funcs.empty();
-+ IF_DBUG(copy_start= copy);
-+ for (i= 0; (pos= li++); i++)
-+ {
-+ Field *field;
-+ uchar *tmp;
-+ Item *real_pos= pos->real_item();
-+ /*
-+ Aggregate functions can be substituted for fields (by e.g. temp tables).
-+ We need to filter those substituted fields out.
-+ */
-+ if (real_pos->type() == Item::FIELD_ITEM &&
-+ !(real_pos != pos &&
-+ ((Item_ref *)pos)->ref_type() == Item_ref::AGGREGATE_REF))
-+ {
-+ Item_field *item;
-+ if (!(item= new Item_field(thd, ((Item_field*) real_pos))))
-+ goto err;
-+ if (pos->type() == Item::REF_ITEM)
-+ {
-+ /* preserve the names of the ref when dereferncing */
-+ Item_ref *ref= (Item_ref *) pos;
-+ item->db_name= ref->db_name;
-+ item->table_name= ref->table_name;
-+ item->name= ref->name;
-+ }
-+ pos= item;
-+ if (item->field->flags & BLOB_FLAG)
-+ {
-+ if (!(pos= Item_copy::create(pos)))
-+ goto err;
-+ /*
-+ Item_copy_string::copy for function can call
-+ Item_copy_string::val_int for blob via Item_ref.
-+ But if Item_copy_string::copy for blob isn't called before,
-+ it's value will be wrong
-+ so let's insert Item_copy_string for blobs in the beginning of
-+ copy_funcs
-+ (to see full test case look at having.test, BUG #4358)
-+ */
-+ if (param->copy_funcs.push_front(pos))
-+ goto err;
-+ }
-+ else
-+ {
-+ /*
-+ set up save buffer and change result_field to point at
-+ saved value
-+ */
-+ field= item->field;
-+ item->result_field=field->new_field(thd->mem_root,field->table, 1);
-+ /*
-+ We need to allocate one extra byte for null handling and
-+ another extra byte to not get warnings from purify in
-+ Field_string::val_int
-+ */
-+ if (!(tmp= (uchar*) sql_alloc(field->pack_length()+2)))
-+ goto err;
-+ if (copy)
-+ {
-+ DBUG_ASSERT (param->field_count > (uint) (copy - copy_start));
-+ copy->set(tmp, item->result_field);
-+ item->result_field->move_field(copy->to_ptr,copy->to_null_ptr,1);
-+#ifdef HAVE_purify
-+ copy->to_ptr[copy->from_length]= 0;
-+#endif
-+ copy++;
-+ }
-+ }
-+ }
-+ else if ((real_pos->type() == Item::FUNC_ITEM ||
-+ real_pos->type() == Item::SUBSELECT_ITEM ||
-+ real_pos->type() == Item::CACHE_ITEM ||
-+ real_pos->type() == Item::COND_ITEM) &&
-+ !real_pos->with_sum_func)
-+ { // Save for send fields
-+ pos= real_pos;
-+ /* TODO:
-+ In most cases this result will be sent to the user.
-+ This should be changed to use copy_int or copy_real depending
-+ on how the value is to be used: In some cases this may be an
-+ argument in a group function, like: IF(ISNULL(col),0,COUNT(*))
-+ */
-+ if (!(pos= Item_copy::create(pos)))
-+ goto err;
-+ if (i < border) // HAVING, ORDER and GROUP BY
-+ {
-+ if (extra_funcs.push_back(pos))
-+ goto err;
-+ }
-+ else if (param->copy_funcs.push_back(pos))
-+ goto err;
-+ }
-+ res_all_fields.push_back(pos);
-+ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
-+ pos;
-+ }
-+ param->copy_field_end= copy;
-+
-+ for (i= 0; i < border; i++)
-+ itr++;
-+ itr.sublist(res_selected_fields, elements);
-+ /*
-+ Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
-+ reference used in these will resolve to a item that is already calculated
-+ */
-+ param->copy_funcs.concat(&extra_funcs);
-+
-+ DBUG_RETURN(0);
-+
-+ err:
-+ if (copy)
-+ delete [] param->copy_field; // This is never 0
-+ param->copy_field=0;
-+err2:
-+ DBUG_RETURN(TRUE);
-+}
-+
-+
-+/**
-+ Make a copy of all simple SELECT'ed items.
-+
-+ This is done at the start of a new group so that we can retrieve
-+ these later when the group changes.
-+*/
-+
-+void
-+copy_fields(TMP_TABLE_PARAM *param)
-+{
-+ Copy_field *ptr=param->copy_field;
-+ Copy_field *end=param->copy_field_end;
-+
-+ for (; ptr != end; ptr++)
-+ (*ptr->do_copy)(ptr);
-+
-+ List_iterator_fast<Item> it(param->copy_funcs);
-+ Item_copy *item;
-+ while ((item = (Item_copy*) it++))
-+ item->copy();
-+}
-+
-+
-+/**
-+ Make an array of pointers to sum_functions to speed up
-+ sum_func calculation.
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 Error
-+*/
-+
-+bool JOIN::alloc_func_list()
-+{
-+ uint func_count, group_parts;
-+ DBUG_ENTER("alloc_func_list");
-+
-+ func_count= tmp_table_param.sum_func_count;
-+ /*
-+ If we are using rollup, we need a copy of the summary functions for
-+ each level
-+ */
-+ if (rollup.state != ROLLUP::STATE_NONE)
-+ func_count*= (send_group_parts+1);
-+
-+ group_parts= send_group_parts;
-+ /*
-+ If distinct, reserve memory for possible
-+ disctinct->group_by optimization
-+ */
-+ if (select_distinct)
-+ {
-+ group_parts+= fields_list.elements;
-+ /*
-+ If the ORDER clause is specified then it's possible that
-+ it also will be optimized, so reserve space for it too
-+ */
-+ if (order)
-+ {
-+ ORDER *ord;
-+ for (ord= order; ord; ord= ord->next)
-+ group_parts++;
-+ }
-+ }
-+
-+ /* This must use calloc() as rollup_make_fields depends on this */
-+ sum_funcs= (Item_sum**) thd->calloc(sizeof(Item_sum**) * (func_count+1) +
-+ sizeof(Item_sum***) * (group_parts+1));
-+ sum_funcs_end= (Item_sum***) (sum_funcs+func_count+1);
-+ DBUG_RETURN(sum_funcs == 0);
-+}
-+
-+
-+/**
-+ Initialize 'sum_funcs' array with all Item_sum objects.
-+
-+ @param field_list All items
-+ @param send_fields Items in select list
-+ @param before_group_by Set to 1 if this is called before GROUP BY handling
-+ @param recompute Set to TRUE if sum_funcs must be recomputed
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error
-+*/
-+
-+bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
-+ bool before_group_by, bool recompute)
-+{
-+ List_iterator_fast<Item> it(field_list);
-+ Item_sum **func;
-+ Item *item;
-+ DBUG_ENTER("make_sum_func_list");
-+
-+ if (*sum_funcs && !recompute)
-+ DBUG_RETURN(FALSE); /* We have already initialized sum_funcs. */
-+
-+ func= sum_funcs;
-+ while ((item=it++))
-+ {
-+ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
-+ (!((Item_sum*) item)->depended_from() ||
-+ ((Item_sum *)item)->depended_from() == select_lex))
-+ *func++= (Item_sum*) item;
-+ }
-+ if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
-+ {
-+ rollup.state= ROLLUP::STATE_READY;
-+ if (rollup_make_fields(field_list, send_fields, &func))
-+ DBUG_RETURN(TRUE); // Should never happen
-+ }
-+ else if (rollup.state == ROLLUP::STATE_NONE)
-+ {
-+ for (uint i=0 ; i <= send_group_parts ;i++)
-+ sum_funcs_end[i]= func;
-+ }
-+ else if (rollup.state == ROLLUP::STATE_READY)
-+ DBUG_RETURN(FALSE); // Don't put end marker
-+ *func=0; // End marker
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Change all funcs and sum_funcs to fields in tmp table, and create
-+ new list of all items.
-+
-+ @param thd THD pointer
-+ @param ref_pointer_array array of pointers to top elements of filed list
-+ @param res_selected_fields new list of items of select item list
-+ @param res_all_fields new list of all items
-+ @param elements number of elements in select item list
-+ @param all_fields all fields list
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ !=0 error
-+*/
-+
-+static bool
-+change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
-+ List<Item> &res_selected_fields,
-+ List<Item> &res_all_fields,
-+ uint elements, List<Item> &all_fields)
-+{
-+ List_iterator_fast<Item> it(all_fields);
-+ Item *item_field,*item;
-+ DBUG_ENTER("change_to_use_tmp_fields");
-+
-+ res_selected_fields.empty();
-+ res_all_fields.empty();
-+
-+ uint i, border= all_fields.elements - elements;
-+ for (i= 0; (item= it++); i++)
-+ {
-+ Field *field;
-+
-+ if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) ||
-+ (item->type() == Item::FUNC_ITEM &&
-+ ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC))
-+ item_field= item;
-+ else
-+ {
-+ if (item->type() == Item::FIELD_ITEM)
-+ {
-+ item_field= item->get_tmp_table_item(thd);
-+ }
-+ else if ((field= item->get_tmp_table_field()))
-+ {
-+ if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
-+ item_field= ((Item_sum*) item)->result_item(field);
-+ else
-+ item_field= (Item*) new Item_field(field);
-+ if (!item_field)
-+ DBUG_RETURN(TRUE); // Fatal error
-+
-+ if (item->real_item()->type() != Item::FIELD_ITEM)
-+ field->orig_table= 0;
-+ item_field->name= item->name;
-+ if (item->type() == Item::REF_ITEM)
-+ {
-+ Item_field *ifield= (Item_field *) item_field;
-+ Item_ref *iref= (Item_ref *) item;
-+ ifield->table_name= iref->table_name;
-+ ifield->db_name= iref->db_name;
-+ }
-+#ifndef DBUG_OFF
-+ if (!item_field->name)
-+ {
-+ char buff[256];
-+ String str(buff,sizeof(buff),&my_charset_bin);
-+ str.length(0);
-+ item->print(&str, QT_ORDINARY);
-+ item_field->name= sql_strmake(str.ptr(),str.length());
-+ }
-+#endif
-+ }
-+ else
-+ item_field= item;
-+ }
-+ res_all_fields.push_back(item_field);
-+ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
-+ item_field;
-+ }
-+
-+ List_iterator_fast<Item> itr(res_all_fields);
-+ for (i= 0; i < border; i++)
-+ itr++;
-+ itr.sublist(res_selected_fields, elements);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/**
-+ Change all sum_func refs to fields to point at fields in tmp table.
-+ Change all funcs to be fields in tmp table.
-+
-+ @param thd THD pointer
-+ @param ref_pointer_array array of pointers to top elements of filed list
-+ @param res_selected_fields new list of items of select item list
-+ @param res_all_fields new list of all items
-+ @param elements number of elements in select item list
-+ @param all_fields all fields list
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 error
-+*/
-+
-+static bool
-+change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
-+ List<Item> &res_selected_fields,
-+ List<Item> &res_all_fields, uint elements,
-+ List<Item> &all_fields)
-+{
-+ List_iterator_fast<Item> it(all_fields);
-+ Item *item, *new_item;
-+ res_selected_fields.empty();
-+ res_all_fields.empty();
-+
-+ uint i, border= all_fields.elements - elements;
-+ for (i= 0; (item= it++); i++)
-+ {
-+ res_all_fields.push_back(new_item= item->get_tmp_table_item(thd));
-+ ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
-+ new_item;
-+ }
-+
-+ List_iterator_fast<Item> itr(res_all_fields);
-+ for (i= 0; i < border; i++)
-+ itr++;
-+ itr.sublist(res_selected_fields, elements);
-+
-+ return thd->is_fatal_error;
-+}
-+
-+
-+
-+/******************************************************************************
-+ Code for calculating functions
-+******************************************************************************/
-+
-+
-+/**
-+ Call ::setup for all sum functions.
-+
-+ @param thd thread handler
-+ @param func_ptr sum function list
-+
-+ @retval
-+ FALSE ok
-+ @retval
-+ TRUE error
-+*/
-+
-+static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
-+{
-+ Item_sum *func;
-+ DBUG_ENTER("setup_sum_funcs");
-+ while ((func= *(func_ptr++)))
-+ {
-+ if (func->setup(thd))
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+static void
-+init_tmptable_sum_functions(Item_sum **func_ptr)
-+{
-+ Item_sum *func;
-+ while ((func= *(func_ptr++)))
-+ func->reset_field();
-+}
-+
-+
-+/** Update record 0 in tmp_table from record 1. */
-+
-+static void
-+update_tmptable_sum_func(Item_sum **func_ptr,
-+ TABLE *tmp_table __attribute__((unused)))
-+{
-+ Item_sum *func;
-+ while ((func= *(func_ptr++)))
-+ func->update_field();
-+}
-+
-+
-+/** Copy result of sum functions to record in tmp_table. */
-+
-+static void
-+copy_sum_funcs(Item_sum **func_ptr, Item_sum **end_ptr)
-+{
-+ for (; func_ptr != end_ptr ; func_ptr++)
-+ (void) (*func_ptr)->save_in_result_field(1);
-+ return;
-+}
-+
-+
-+static bool
-+init_sum_functions(Item_sum **func_ptr, Item_sum **end_ptr)
-+{
-+ for (; func_ptr != end_ptr ;func_ptr++)
-+ {
-+ if ((*func_ptr)->reset())
-+ return 1;
-+ }
-+ /* If rollup, calculate the upper sum levels */
-+ for ( ; *func_ptr ; func_ptr++)
-+ {
-+ if ((*func_ptr)->add())
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+static bool
-+update_sum_func(Item_sum **func_ptr)
-+{
-+ Item_sum *func;
-+ for (; (func= (Item_sum*) *func_ptr) ; func_ptr++)
-+ if (func->add())
-+ return 1;
-+ return 0;
-+}
-+
-+/**
-+ Copy result of functions to record in tmp_table.
-+
-+ Uses the thread pointer to check for errors in
-+ some of the val_xxx() methods called by the
-+ save_in_result_field() function.
-+ TODO: make the Item::val_xxx() return error code
-+
-+ @param func_ptr array of the function Items to copy to the tmp table
-+ @param thd pointer to the current thread for error checking
-+ @retval
-+ FALSE if OK
-+ @retval
-+ TRUE on error
-+*/
-+
-+bool
-+copy_funcs(Item **func_ptr, const THD *thd)
-+{
-+ Item *func;
-+ for (; (func = *func_ptr) ; func_ptr++)
-+ {
-+ func->save_in_result_field(1);
-+ /*
-+ Need to check the THD error state because Item::val_xxx() don't
-+ return error code, but can generate errors
-+ TODO: change it for a real status check when Item::val_xxx()
-+ are extended to return status code.
-+ */
-+ if (thd->is_error())
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+
-+/**
-+ Create a condition for a const reference and add this to the
-+ currenct select for the table.
-+*/
-+
-+static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
-+{
-+ DBUG_ENTER("add_ref_to_table_cond");
-+ if (!join_tab->ref.key_parts)
-+ DBUG_RETURN(FALSE);
-+
-+ Item_cond_and *cond=new Item_cond_and();
-+ TABLE *table=join_tab->table;
-+ int error= 0;
-+ if (!cond)
-+ DBUG_RETURN(TRUE);
-+
-+ for (uint i=0 ; i < join_tab->ref.key_parts ; i++)
-+ {
-+ Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
-+ fieldnr-1];
-+ Item *value=join_tab->ref.items[i];
-+ cond->add(new Item_func_equal(new Item_field(field), value));
-+ }
-+ if (thd->is_fatal_error)
-+ DBUG_RETURN(TRUE);
-+
-+ if (!cond->fixed)
-+ cond->fix_fields(thd, (Item**)&cond);
-+ if (join_tab->select)
-+ {
-+ if (join_tab->select->cond)
-+ error=(int) cond->add(join_tab->select->cond);
-+ join_tab->select_cond=join_tab->select->cond=cond;
-+ }
-+ else if ((join_tab->select= make_select(join_tab->table, 0, 0, cond, 0,
-+ &error)))
-+ join_tab->select_cond=cond;
-+
-+ DBUG_RETURN(error ? TRUE : FALSE);
-+}
-+
-+
-+/**
-+ Free joins of subselect of this select.
-+
-+ @param thd THD pointer
-+ @param select pointer to st_select_lex which subselects joins we will free
-+*/
-+
-+void free_underlaid_joins(THD *thd, SELECT_LEX *select)
-+{
-+ for (SELECT_LEX_UNIT *unit= select->first_inner_unit();
-+ unit;
-+ unit= unit->next_unit())
-+ unit->cleanup();
-+}
-+
-+/****************************************************************************
-+ ROLLUP handling
-+****************************************************************************/
-+
-+/**
-+ Replace occurences of group by fields in an expression by ref items.
-+
-+ The function replaces occurrences of group by fields in expr
-+ by ref objects for these fields unless they are under aggregate
-+ functions.
-+ The function also corrects value of the the maybe_null attribute
-+ for the items of all subexpressions containing group by fields.
-+
-+ @b EXAMPLES
-+ @code
-+ SELECT a+1 FROM t1 GROUP BY a WITH ROLLUP
-+ SELECT SUM(a)+a FROM t1 GROUP BY a WITH ROLLUP
-+ @endcode
-+
-+ @b IMPLEMENTATION
-+
-+ The function recursively traverses the tree of the expr expression,
-+ looks for occurrences of the group by fields that are not under
-+ aggregate functions and replaces them for the corresponding ref items.
-+
-+ @note
-+ This substitution is needed GROUP BY queries with ROLLUP if
-+ SELECT list contains expressions over group by attributes.
-+
-+ @param thd reference to the context
-+ @param expr expression to make replacement
-+ @param group_list list of references to group by items
-+ @param changed out: returns 1 if item contains a replaced field item
-+
-+ @todo
-+ - TODO: Some functions are not null-preserving. For those functions
-+ updating of the maybe_null attribute is an overkill.
-+
-+ @retval
-+ 0 if ok
-+ @retval
-+ 1 on error
-+*/
-+
-+static bool change_group_ref(THD *thd, Item_func *expr, ORDER *group_list,
-+ bool *changed)
-+{
-+ if (expr->arg_count)
-+ {
-+ Name_resolution_context *context= &thd->lex->current_select->context;
-+ Item **arg,**arg_end;
-+ bool arg_changed= FALSE;
-+ for (arg= expr->arguments(),
-+ arg_end= expr->arguments()+expr->arg_count;
-+ arg != arg_end; arg++)
-+ {
-+ Item *item= *arg;
-+ if (item->type() == Item::FIELD_ITEM || item->type() == Item::REF_ITEM)
-+ {
-+ ORDER *group_tmp;
-+ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
-+ {
-+ if (item->eq(*group_tmp->item,0))
-+ {
-+ Item *new_item;
-+ if (!(new_item= new Item_ref(context, group_tmp->item, 0,
-+ item->name)))
-+ return 1; // fatal_error is set
-+ thd->change_item_tree(arg, new_item);
-+ arg_changed= TRUE;
-+ }
-+ }
-+ }
-+ else if (item->type() == Item::FUNC_ITEM)
-+ {
-+ if (change_group_ref(thd, (Item_func *) item, group_list, &arg_changed))
-+ return 1;
-+ }
-+ }
-+ if (arg_changed)
-+ {
-+ expr->maybe_null= 1;
-+ *changed= TRUE;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/** Allocate memory needed for other rollup functions. */
-+
-+bool JOIN::rollup_init()
-+{
-+ uint i,j;
-+ Item **ref_array;
-+
-+ tmp_table_param.quick_group= 0; // Can't create groups in tmp table
-+ rollup.state= ROLLUP::STATE_INITED;
-+
-+ /*
-+ Create pointers to the different sum function groups
-+ These are updated by rollup_make_fields()
-+ */
-+ tmp_table_param.group_parts= send_group_parts;
-+
-+ if (!(rollup.null_items= (Item_null_result**) thd->alloc((sizeof(Item*) +
-+ sizeof(Item**) +
-+ sizeof(List<Item>) +
-+ ref_pointer_array_size)
-+ * send_group_parts )))
-+ return 1;
-+
-+ rollup.fields= (List<Item>*) (rollup.null_items + send_group_parts);
-+ rollup.ref_pointer_arrays= (Item***) (rollup.fields + send_group_parts);
-+ ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts);
-+
-+ /*
-+ Prepare space for field list for the different levels
-+ These will be filled up in rollup_make_fields()
-+ */
-+ for (i= 0 ; i < send_group_parts ; i++)
-+ {
-+ rollup.null_items[i]= new (thd->mem_root) Item_null_result();
-+ List<Item> *rollup_fields= &rollup.fields[i];
-+ rollup_fields->empty();
-+ rollup.ref_pointer_arrays[i]= ref_array;
-+ ref_array+= all_fields.elements;
-+ }
-+ for (i= 0 ; i < send_group_parts; i++)
-+ {
-+ for (j=0 ; j < fields_list.elements ; j++)
-+ rollup.fields[i].push_back(rollup.null_items[i]);
-+ }
-+ List_iterator<Item> it(all_fields);
-+ Item *item;
-+ while ((item= it++))
-+ {
-+ ORDER *group_tmp;
-+ bool found_in_group= 0;
-+
-+ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
-+ {
-+ if (*group_tmp->item == item)
-+ {
-+ item->maybe_null= 1;
-+ found_in_group= 1;
-+ break;
-+ }
-+ }
-+ if (item->type() == Item::FUNC_ITEM && !found_in_group)
-+ {
-+ bool changed= FALSE;
-+ if (change_group_ref(thd, (Item_func *) item, group_list, &changed))
-+ return 1;
-+ /*
-+ We have to prevent creation of a field in a temporary table for
-+ an expression that contains GROUP BY attributes.
-+ Marking the expression item as 'with_sum_func' will ensure this.
-+ */
-+ if (changed)
-+ item->with_sum_func= 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/**
-+ Wrap all constant Items in GROUP BY list.
-+
-+ For ROLLUP queries each constant item referenced in GROUP BY list
-+ is wrapped up into an Item_func object yielding the same value
-+ as the constant item. The objects of the wrapper class are never
-+ considered as constant items and besides they inherit all
-+ properties of the Item_result_field class.
-+ This wrapping allows us to ensure writing constant items
-+ into temporary tables whenever the result of the ROLLUP
-+ operation has to be written into a temporary table, e.g. when
-+ ROLLUP is used together with DISTINCT in the SELECT list.
-+ Usually when creating temporary tables for a intermidiate
-+ result we do not include fields for constant expressions.
-+
-+ @retval
-+ 0 if ok
-+ @retval
-+ 1 on error
-+*/
-+
-+bool JOIN::rollup_process_const_fields()
-+{
-+ ORDER *group_tmp;
-+ Item *item;
-+ List_iterator<Item> it(all_fields);
-+
-+ for (group_tmp= group_list; group_tmp; group_tmp= group_tmp->next)
-+ {
-+ if (!(*group_tmp->item)->const_item())
-+ continue;
-+ while ((item= it++))
-+ {
-+ if (*group_tmp->item == item)
-+ {
-+ Item* new_item= new Item_func_rollup_const(item);
-+ if (!new_item)
-+ return 1;
-+ new_item->fix_fields(thd, (Item **) 0);
-+ thd->change_item_tree(it.ref(), new_item);
-+ for (ORDER *tmp= group_tmp; tmp; tmp= tmp->next)
-+ {
-+ if (*tmp->item == item)
-+ thd->change_item_tree(tmp->item, new_item);
-+ }
-+ break;
-+ }
-+ }
-+ it.rewind();
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ Fill up rollup structures with pointers to fields to use.
-+
-+ Creates copies of item_sum items for each sum level.
-+
-+ @param fields_arg List of all fields (hidden and real ones)
-+ @param sel_fields Pointer to selected fields
-+ @param func Store here a pointer to all fields
-+
-+ @retval
-+ 0 if ok;
-+ In this case func is pointing to next not used element.
-+ @retval
-+ 1 on error
-+*/
-+
-+bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields,
-+ Item_sum ***func)
-+{
-+ List_iterator_fast<Item> it(fields_arg);
-+ Item *first_field= sel_fields.head();
-+ uint level;
-+
-+ /*
-+ Create field lists for the different levels
-+
-+ The idea here is to have a separate field list for each rollup level to
-+ avoid all runtime checks of which columns should be NULL.
-+
-+ The list is stored in reverse order to get sum function in such an order
-+ in func that it makes it easy to reset them with init_sum_functions()
-+
-+ Assuming: SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
-+
-+ rollup.fields[0] will contain list where a,b,c is NULL
-+ rollup.fields[1] will contain list where b,c is NULL
-+ ...
-+ rollup.ref_pointer_array[#] points to fields for rollup.fields[#]
-+ ...
-+ sum_funcs_end[0] points to all sum functions
-+ sum_funcs_end[1] points to all sum functions, except grand totals
-+ ...
-+ */
-+
-+ for (level=0 ; level < send_group_parts ; level++)
-+ {
-+ uint i;
-+ uint pos= send_group_parts - level -1;
-+ bool real_fields= 0;
-+ Item *item;
-+ List_iterator<Item> new_it(rollup.fields[pos]);
-+ Item **ref_array_start= rollup.ref_pointer_arrays[pos];
-+ ORDER *start_group;
-+
-+ /* Point to first hidden field */
-+ Item **ref_array= ref_array_start + fields_arg.elements-1;
-+
-+ /* Remember where the sum functions ends for the previous level */
-+ sum_funcs_end[pos+1]= *func;
-+
-+ /* Find the start of the group for this level */
-+ for (i= 0, start_group= group_list ;
-+ i++ < pos ;
-+ start_group= start_group->next)
-+ ;
-+
-+ it.rewind();
-+ while ((item= it++))
-+ {
-+ if (item == first_field)
-+ {
-+ real_fields= 1; // End of hidden fields
-+ ref_array= ref_array_start;
-+ }
-+
-+ if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item() &&
-+ (!((Item_sum*) item)->depended_from() ||
-+ ((Item_sum *)item)->depended_from() == select_lex))
-+
-+ {
-+ /*
-+ This is a top level summary function that must be replaced with
-+ a sum function that is reset for this level.
-+
-+ NOTE: This code creates an object which is not that nice in a
-+ sub select. Fortunately it's not common to have rollup in
-+ sub selects.
-+ */
-+ item= item->copy_or_same(thd);
-+ ((Item_sum*) item)->make_unique();
-+ *(*func)= (Item_sum*) item;
-+ (*func)++;
-+ }
-+ else
-+ {
-+ /* Check if this is something that is part of this group by */
-+ ORDER *group_tmp;
-+ for (group_tmp= start_group, i= pos ;
-+ group_tmp ; group_tmp= group_tmp->next, i++)
-+ {
-+ if (*group_tmp->item == item)
-+ {
-+ /*
-+ This is an element that is used by the GROUP BY and should be
-+ set to NULL in this level
-+ */
-+ Item_null_result *null_item= new (thd->mem_root) Item_null_result();
-+ if (!null_item)
-+ return 1;
-+ item->maybe_null= 1; // Value will be null sometimes
-+ null_item->result_field= item->get_tmp_table_field();
-+ item= null_item;
-+ break;
-+ }
-+ }
-+ }
-+ *ref_array= item;
-+ if (real_fields)
-+ {
-+ (void) new_it++; // Point to next item
-+ new_it.replace(item); // Replace previous
-+ ref_array++;
-+ }
-+ else
-+ ref_array--;
-+ }
-+ }
-+ sum_funcs_end[0]= *func; // Point to last function
-+ return 0;
-+}
-+
-+/**
-+ Send all rollup levels higher than the current one to the client.
-+
-+ @b SAMPLE
-+ @code
-+ SELECT a, b, c SUM(b) FROM t1 GROUP BY a,b WITH ROLLUP
-+ @endcode
-+
-+ @param idx Level we are on:
-+ - 0 = Total sum level
-+ - 1 = First group changed (a)
-+ - 2 = Second group changed (a,b)
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 If send_data_failed()
-+*/
-+
-+int JOIN::rollup_send_data(uint idx)
-+{
-+ uint i;
-+ for (i= send_group_parts ; i-- > idx ; )
-+ {
-+ /* Get reference pointers to sum functions in place */
-+ memcpy((char*) ref_pointer_array,
-+ (char*) rollup.ref_pointer_arrays[i],
-+ ref_pointer_array_size);
-+ if ((!having || having->val_int()))
-+ {
-+ if (send_records < unit->select_limit_cnt && do_send_rows &&
-+ result->send_data(rollup.fields[i]))
-+ return 1;
-+ send_records++;
-+ }
-+ }
-+ /* Restore ref_pointer_array */
-+ set_items_ref_array(current_ref_pointer_array);
-+ return 0;
-+}
-+
-+/**
-+ Write all rollup levels higher than the current one to a temp table.
-+
-+ @b SAMPLE
-+ @code
-+ SELECT a, b, SUM(c) FROM t1 GROUP BY a,b WITH ROLLUP
-+ @endcode
-+
-+ @param idx Level we are on:
-+ - 0 = Total sum level
-+ - 1 = First group changed (a)
-+ - 2 = Second group changed (a,b)
-+ @param table reference to temp table
-+
-+ @retval
-+ 0 ok
-+ @retval
-+ 1 if write_data_failed()
-+*/
-+
-+int JOIN::rollup_write_data(uint idx, TABLE *table_arg)
-+{
-+ uint i;
-+ for (i= send_group_parts ; i-- > idx ; )
-+ {
-+ /* Get reference pointers to sum functions in place */
-+ memcpy((char*) ref_pointer_array,
-+ (char*) rollup.ref_pointer_arrays[i],
-+ ref_pointer_array_size);
-+ if ((!having || having->val_int()))
-+ {
-+ int write_error;
-+ Item *item;
-+ List_iterator_fast<Item> it(rollup.fields[i]);
-+ while ((item= it++))
-+ {
-+ if (item->type() == Item::NULL_ITEM && item->is_result_field())
-+ item->save_in_result_field(1);
-+ }
-+ copy_sum_funcs(sum_funcs_end[i+1], sum_funcs_end[i]);
-+ if ((write_error= table_arg->file->ha_write_row(table_arg->record[0])))
-+ {
-+ if (create_myisam_from_heap(thd, table_arg, &tmp_table_param,
-+ write_error, 0))
-+ return 1;
-+ }
-+ }
-+ }
-+ /* Restore ref_pointer_array */
-+ set_items_ref_array(current_ref_pointer_array);
-+ return 0;
-+}
-+
-+/**
-+ clear results if there are not rows found for group
-+ (end_send_group/end_write_group)
-+*/
-+
-+void JOIN::clear()
-+{
-+ clear_tables(this);
-+ copy_fields(&tmp_table_param);
-+
-+ if (sum_funcs)
-+ {
-+ Item_sum *func, **func_ptr= sum_funcs;
-+ while ((func= *(func_ptr++)))
-+ func->clear();
-+ }
-+}
-+
-+/**
-+ EXPLAIN handling.
-+
-+ Send a description about what how the select will be done to stdout.
-+*/
-+
-+static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
-+ bool distinct,const char *message)
-+{
-+ List<Item> field_list;
-+ List<Item> item_list;
-+ THD *thd=join->thd;
-+ select_result *result=join->result;
-+ Item *item_null= new Item_null();
-+ CHARSET_INFO *cs= system_charset_info;
-+ int quick_type;
-+ DBUG_ENTER("select_describe");
-+ DBUG_PRINT("info", ("Select 0x%lx, type %s, message %s",
-+ (ulong)join->select_lex, join->select_lex->type,
-+ message ? message : "NULL"));
-+ /* Don't log this into the slow query log */
-+ thd->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
-+ join->unit->offset_limit_cnt= 0;
-+
-+ /*
-+ NOTE: the number/types of items pushed into item_list must be in sync with
-+ EXPLAIN column types as they're "defined" in THD::send_explain_fields()
-+ */
-+ if (message)
-+ {
-+ item_list.push_back(new Item_int((int32)
-+ join->select_lex->select_number));
-+ item_list.push_back(new Item_string(join->select_lex->type,
-+ strlen(join->select_lex->type), cs));
-+ for (uint i=0 ; i < 7; i++)
-+ item_list.push_back(item_null);
-+ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
-+ item_list.push_back(item_null);
-+ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
-+ item_list.push_back(item_null);
-+
-+ item_list.push_back(new Item_string(message,strlen(message),cs));
-+ if (result->send_data(item_list))
-+ join->error= 1;
-+ }
-+ else if (join->select_lex == join->unit->fake_select_lex)
-+ {
-+ /*
-+ here we assume that the query will return at least two rows, so we
-+ show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
-+ and no filesort will be actually done, but executing all selects in
-+ the UNION to provide precise EXPLAIN information will hardly be
-+ appreciated :)
-+ */
-+ char table_name_buffer[NAME_LEN];
-+ item_list.empty();
-+ /* id */
-+ item_list.push_back(new Item_null);
-+ /* select_type */
-+ item_list.push_back(new Item_string(join->select_lex->type,
-+ strlen(join->select_lex->type),
-+ cs));
-+ /* table */
-+ {
-+ SELECT_LEX *sl= join->unit->first_select();
-+ uint len= 6, lastop= 0;
-+ memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
-+ for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
-+ {
-+ len+= lastop;
-+ lastop= my_snprintf(table_name_buffer + len, NAME_LEN - len,
-+ "%u,", sl->select_number);
-+ }
-+ if (sl || len + lastop >= NAME_LEN)
-+ {
-+ memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
-+ len+= 4;
-+ }
-+ else
-+ {
-+ len+= lastop;
-+ table_name_buffer[len - 1]= '>'; // change ',' to '>'
-+ }
-+ item_list.push_back(new Item_string(table_name_buffer, len, cs));
-+ }
-+ /* partitions */
-+ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
-+ item_list.push_back(item_null);
-+ /* type */
-+ item_list.push_back(new Item_string(join_type_str[JT_ALL],
-+ strlen(join_type_str[JT_ALL]),
-+ cs));
-+ /* possible_keys */
-+ item_list.push_back(item_null);
-+ /* key*/
-+ item_list.push_back(item_null);
-+ /* key_len */
-+ item_list.push_back(item_null);
-+ /* ref */
-+ item_list.push_back(item_null);
-+ /* in_rows */
-+ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
-+ item_list.push_back(item_null);
-+ /* rows */
-+ item_list.push_back(item_null);
-+ /* extra */
-+ if (join->unit->global_parameters->order_list.first)
-+ item_list.push_back(new Item_string("Using filesort",
-+ 14, cs));
-+ else
-+ item_list.push_back(new Item_string("", 0, cs));
-+
-+ if (result->send_data(item_list))
-+ join->error= 1;
-+ }
-+ else
-+ {
-+ table_map used_tables=0;
-+ for (uint i=0 ; i < join->tables ; i++)
-+ {
-+ JOIN_TAB *tab=join->join_tab+i;
-+ TABLE *table=tab->table;
-+ TABLE_LIST *table_list= tab->table->pos_in_table_list;
-+ char buff[512];
-+ char buff1[512], buff2[512], buff3[512];
-+ char keylen_str_buf[64];
-+ String extra(buff, sizeof(buff),cs);
-+ char table_name_buffer[NAME_LEN];
-+ String tmp1(buff1,sizeof(buff1),cs);
-+ String tmp2(buff2,sizeof(buff2),cs);
-+ String tmp3(buff3,sizeof(buff3),cs);
-+ extra.length(0);
-+ tmp1.length(0);
-+ tmp2.length(0);
-+ tmp3.length(0);
-+
-+ quick_type= -1;
-+ item_list.empty();
-+ /* id */
-+ item_list.push_back(new Item_uint((uint32)
-+ join->select_lex->select_number));
-+ /* select_type */
-+ item_list.push_back(new Item_string(join->select_lex->type,
-+ strlen(join->select_lex->type),
-+ cs));
-+ if (tab->type == JT_ALL && tab->select && tab->select->quick)
-+ {
-+ quick_type= tab->select->quick->get_type();
-+ if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
-+ (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
-+ (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
-+ tab->type = JT_INDEX_MERGE;
-+ else
-+ tab->type = JT_RANGE;
-+ }
-+ /* table */
-+ if (table->derived_select_number)
-+ {
-+ /* Derived table name generation */
-+ int len= my_snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
-+ "<derived%u>",
-+ table->derived_select_number);
-+ item_list.push_back(new Item_string(table_name_buffer, len, cs));
-+ }
-+ else
-+ {
-+ TABLE_LIST *real_table= table->pos_in_table_list;
-+ item_list.push_back(new Item_string(real_table->alias,
-+ strlen(real_table->alias),
-+ cs));
-+ }
-+ /* "partitions" column */
-+ if (join->thd->lex->describe & DESCRIBE_PARTITIONS)
-+ {
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ partition_info *part_info;
-+ if (!table->derived_select_number &&
-+ (part_info= table->part_info))
-+ {
-+ Item_string *item_str= new Item_string(cs);
-+ make_used_partitions_str(part_info, &item_str->str_value);
-+ item_list.push_back(item_str);
-+ }
-+ else
-+ item_list.push_back(item_null);
-+#else
-+ /* just produce empty column if partitioning is not compiled in */
-+ item_list.push_back(item_null);
-+#endif
-+ }
-+ /* "type" column */
-+ item_list.push_back(new Item_string(join_type_str[tab->type],
-+ strlen(join_type_str[tab->type]),
-+ cs));
-+ /* Build "possible_keys" value and add it to item_list */
-+ if (!tab->keys.is_clear_all())
-+ {
-+ uint j;
-+ for (j=0 ; j < table->s->keys ; j++)
-+ {
-+ if (tab->keys.is_set(j))
-+ {
-+ if (tmp1.length())
-+ tmp1.append(',');
-+ tmp1.append(table->key_info[j].name,
-+ strlen(table->key_info[j].name),
-+ system_charset_info);
-+ }
-+ }
-+ }
-+ if (tmp1.length())
-+ item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
-+ else
-+ item_list.push_back(item_null);
-+
-+ /* Build "key", "key_len", and "ref" values and add them to item_list */
-+ if (tab->ref.key_parts)
-+ {
-+ KEY *key_info=table->key_info+ tab->ref.key;
-+ register uint length;
-+ item_list.push_back(new Item_string(key_info->name,
-+ strlen(key_info->name),
-+ system_charset_info));
-+ length= longlong2str(tab->ref.key_length, keylen_str_buf, 10) -
-+ keylen_str_buf;
-+ item_list.push_back(new Item_string(keylen_str_buf, length,
-+ system_charset_info));
-+ for (store_key **ref=tab->ref.key_copy ; *ref ; ref++)
-+ {
-+ if (tmp2.length())
-+ tmp2.append(',');
-+ tmp2.append((*ref)->name(), strlen((*ref)->name()),
-+ system_charset_info);
-+ }
-+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
-+ }
-+ else if (tab->type == JT_NEXT)
-+ {
-+ KEY *key_info=table->key_info+ tab->index;
-+ register uint length;
-+ item_list.push_back(new Item_string(key_info->name,
-+ strlen(key_info->name),cs));
-+ length= longlong2str(key_info->key_length, keylen_str_buf, 10) -
-+ keylen_str_buf;
-+ item_list.push_back(new Item_string(keylen_str_buf,
-+ length,
-+ system_charset_info));
-+ item_list.push_back(item_null);
-+ }
-+ else if (tab->select && tab->select->quick)
-+ {
-+ tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
-+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
-+ item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
-+ item_list.push_back(item_null);
-+ }
-+ else
-+ {
-+ if (table_list->schema_table &&
-+ table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
-+ {
-+ const char *tmp_buff;
-+ int f_idx;
-+ if (table_list->has_db_lookup_value)
-+ {
-+ f_idx= table_list->schema_table->idx_field1;
-+ tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
-+ tmp2.append(tmp_buff, strlen(tmp_buff), cs);
-+ }
-+ if (table_list->has_table_lookup_value)
-+ {
-+ if (table_list->has_db_lookup_value)
-+ tmp2.append(',');
-+ f_idx= table_list->schema_table->idx_field2;
-+ tmp_buff= table_list->schema_table->fields_info[f_idx].field_name;
-+ tmp2.append(tmp_buff, strlen(tmp_buff), cs);
-+ }
-+ if (tmp2.length())
-+ item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
-+ else
-+ item_list.push_back(item_null);
-+ }
-+ else
-+ item_list.push_back(item_null);
-+ item_list.push_back(item_null);
-+ item_list.push_back(item_null);
-+ }
-+
-+ /* Add "rows" field to item_list. */
-+ if (table_list->schema_table)
-+ {
-+ /* in_rows */
-+ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
-+ item_list.push_back(item_null);
-+ /* rows */
-+ item_list.push_back(item_null);
-+ }
-+ else
-+ {
-+ ha_rows examined_rows;
-+ if (tab->select && tab->select->quick)
-+ examined_rows= tab->select->quick->records;
-+ else if (tab->type == JT_NEXT || tab->type == JT_ALL)
-+ {
-+ if (tab->limit)
-+ examined_rows= tab->limit;
-+ else
-+ {
-+ tab->table->file->info(HA_STATUS_VARIABLE);
-+ examined_rows= tab->table->file->stats.records;
-+ }
-+ }
-+ else
-+ examined_rows=(ha_rows)join->best_positions[i].records_read;
-+
-+ item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows,
-+ MY_INT64_NUM_DECIMAL_DIGITS));
-+
-+ /* Add "filtered" field to item_list. */
-+ if (join->thd->lex->describe & DESCRIBE_EXTENDED)
-+ {
-+ float f= 0.0;
-+ if (examined_rows)
-+ f= (float) (100.0 * join->best_positions[i].records_read /
-+ examined_rows);
-+ item_list.push_back(new Item_float(f, 2));
-+ }
-+ }
-+
-+ /* Build "Extra" field and add it to item_list. */
-+ my_bool key_read=table->key_read;
-+ if ((tab->type == JT_NEXT || tab->type == JT_CONST) &&
-+ table->covering_keys.is_set(tab->index))
-+ key_read=1;
-+ if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
-+ !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
-+ key_read=1;
-+
-+ if (tab->info)
-+ item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
-+ else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
-+ {
-+ if (tab->packed_info & TAB_INFO_USING_INDEX)
-+ extra.append(STRING_WITH_LEN("; Using index"));
-+ if (tab->packed_info & TAB_INFO_USING_WHERE)
-+ extra.append(STRING_WITH_LEN("; Using where"));
-+ if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
-+ extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
-+ /* Skip initial "; "*/
-+ const char *str= extra.ptr();
-+ uint32 len= extra.length();
-+ if (len)
-+ {
-+ str += 2;
-+ len -= 2;
-+ }
-+ item_list.push_back(new Item_string(str, len, cs));
-+ }
-+ else
-+ {
-+ if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
-+ quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
-+ {
-+ extra.append(STRING_WITH_LEN("; Using "));
-+ tab->select->quick->add_info_string(&extra);
-+ }
-+ if (tab->select)
-+ {
-+ if (tab->use_quick == 2)
-+ {
-+ /* 4 bits per 1 hex digit + terminating '\0' */
-+ char buf[MAX_KEY / 4 + 1];
-+ extra.append(STRING_WITH_LEN("; Range checked for each "
-+ "record (index map: 0x"));
-+ extra.append(tab->keys.print(buf));
-+ extra.append(')');
-+ }
-+ else if (tab->select->cond)
-+ {
-+ const COND *pushed_cond= tab->table->file->pushed_cond;
-+
-+ if (thd->variables.engine_condition_pushdown && pushed_cond)
-+ {
-+ extra.append(STRING_WITH_LEN("; Using where with pushed "
-+ "condition"));
-+ if (thd->lex->describe & DESCRIBE_EXTENDED)
-+ {
-+ extra.append(STRING_WITH_LEN(": "));
-+ ((COND *)pushed_cond)->print(&extra, QT_ORDINARY);
-+ }
-+ }
-+ else
-+ extra.append(STRING_WITH_LEN("; Using where"));
-+ }
-+ }
-+ if (table_list->schema_table &&
-+ table_list->schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
-+ {
-+ if (!table_list->table_open_method)
-+ extra.append(STRING_WITH_LEN("; Skip_open_table"));
-+ else if (table_list->table_open_method == OPEN_FRM_ONLY)
-+ extra.append(STRING_WITH_LEN("; Open_frm_only"));
-+ else
-+ extra.append(STRING_WITH_LEN("; Open_full_table"));
-+ if (table_list->has_db_lookup_value &&
-+ table_list->has_table_lookup_value)
-+ extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
-+ else if (table_list->has_db_lookup_value ||
-+ table_list->has_table_lookup_value)
-+ extra.append(STRING_WITH_LEN("; Scanned 1 database"));
-+ else
-+ extra.append(STRING_WITH_LEN("; Scanned all databases"));
-+ }
-+ if (key_read)
-+ {
-+ if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
-+ extra.append(STRING_WITH_LEN("; Using index for group-by"));
-+ else
-+ extra.append(STRING_WITH_LEN("; Using index"));
-+ }
-+ if (table->reginfo.not_exists_optimize)
-+ extra.append(STRING_WITH_LEN("; Not exists"));
-+ if (need_tmp_table)
-+ {
-+ need_tmp_table=0;
-+ extra.append(STRING_WITH_LEN("; Using temporary"));
-+ }
-+ if (need_order)
-+ {
-+ need_order=0;
-+ extra.append(STRING_WITH_LEN("; Using filesort"));
-+ }
-+ if (distinct & test_all_bits(used_tables,thd->used_tables))
-+ extra.append(STRING_WITH_LEN("; Distinct"));
-+
-+ for (uint part= 0; part < tab->ref.key_parts; part++)
-+ {
-+ if (tab->ref.cond_guards[part])
-+ {
-+ extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
-+ break;
-+ }
-+ }
-+ if (i > 0 && tab[-1].next_select == sub_select_cache)
-+ extra.append(STRING_WITH_LEN("; Using join buffer"));
-+
-+ /* Skip initial "; "*/
-+ const char *str= extra.ptr();
-+ uint32 len= extra.length();
-+ if (len)
-+ {
-+ str += 2;
-+ len -= 2;
-+ }
-+ item_list.push_back(new Item_string(str, len, cs));
-+ }
-+ // For next iteration
-+ used_tables|=table->map;
-+ if (result->send_data(item_list))
-+ join->error= 1;
-+ }
-+ }
-+ for (SELECT_LEX_UNIT *unit= join->select_lex->first_inner_unit();
-+ unit;
-+ unit= unit->next_unit())
-+ {
-+ if (mysql_explain_union(thd, unit, result))
-+ DBUG_VOID_RETURN;
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+bool mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
-+{
-+ DBUG_ENTER("mysql_explain_union");
-+ bool res= 0;
-+ SELECT_LEX *first= unit->first_select();
-+
-+ for (SELECT_LEX *sl= first;
-+ sl;
-+ sl= sl->next_select())
-+ {
-+ // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
-+ uint8 uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
-+ sl->type= (((&thd->lex->select_lex)==sl)?
-+ (sl->first_inner_unit() || sl->next_select() ?
-+ "PRIMARY" : "SIMPLE"):
-+ ((sl == first)?
-+ ((sl->linkage == DERIVED_TABLE_TYPE) ?
-+ "DERIVED":
-+ ((uncacheable & UNCACHEABLE_DEPENDENT) ?
-+ "DEPENDENT SUBQUERY":
-+ (uncacheable?"UNCACHEABLE SUBQUERY":
-+ "SUBQUERY"))):
-+ ((uncacheable & UNCACHEABLE_DEPENDENT) ?
-+ "DEPENDENT UNION":
-+ uncacheable?"UNCACHEABLE UNION":
-+ "UNION")));
-+ sl->options|= SELECT_DESCRIBE;
-+ }
-+ if (unit->is_union())
-+ {
-+ unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
-+ unit->fake_select_lex->type= "UNION RESULT";
-+ unit->fake_select_lex->options|= SELECT_DESCRIBE;
-+ if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
-+ res= unit->exec();
-+ res|= unit->cleanup();
-+ }
-+ else
-+ {
-+ thd->lex->current_select= first;
-+ unit->set_limit(unit->global_parameters);
-+ res= mysql_select(thd, &first->ref_pointer_array,
-+ first->table_list.first,
-+ first->with_wild, first->item_list,
-+ first->where,
-+ first->order_list.elements +
-+ first->group_list.elements,
-+ first->order_list.first,
-+ first->group_list.first,
-+ first->having,
-+ thd->lex->proc_list.first,
-+ first->options | thd->options | SELECT_DESCRIBE,
-+ result, unit, first);
-+ }
-+ DBUG_RETURN(res || thd->is_error());
-+}
-+
-+
-+/**
-+ Print joins from the FROM clause.
-+
-+ @param thd thread handler
-+ @param str string where table should be printed
-+ @param tables list of tables in join
-+ @query_type type of the query is being generated
-+*/
-+
-+static void print_join(THD *thd,
-+ String *str,
-+ List<TABLE_LIST> *tables,
-+ enum_query_type query_type)
-+{
-+ /* List is reversed => we should reverse it before using */
-+ List_iterator_fast<TABLE_LIST> ti(*tables);
-+ TABLE_LIST **table= (TABLE_LIST **)thd->alloc(sizeof(TABLE_LIST*) *
-+ tables->elements);
-+ if (table == 0)
-+ return; // out of memory
-+
-+ for (TABLE_LIST **t= table + (tables->elements - 1); t >= table; t--)
-+ *t= ti++;
-+
-+ DBUG_ASSERT(tables->elements >= 1);
-+ (*table)->print(thd, str, query_type);
-+
-+ TABLE_LIST **end= table + tables->elements;
-+ for (TABLE_LIST **tbl= table + 1; tbl < end; tbl++)
-+ {
-+ TABLE_LIST *curr= *tbl;
-+ if (curr->outer_join)
-+ {
-+ /* MySQL converts right to left joins */
-+ str->append(STRING_WITH_LEN(" left join "));
-+ }
-+ else if (curr->straight)
-+ str->append(STRING_WITH_LEN(" straight_join "));
-+ else
-+ str->append(STRING_WITH_LEN(" join "));
-+ curr->print(thd, str, query_type);
-+ if (curr->on_expr)
-+ {
-+ str->append(STRING_WITH_LEN(" on("));
-+ curr->on_expr->print(str, query_type);
-+ str->append(')');
-+ }
-+ }
-+}
-+
-+
-+/**
-+ @brief Print an index hint
-+
-+ @details Prints out the USE|FORCE|IGNORE index hint.
-+
-+ @param thd the current thread
-+ @param[out] str appends the index hint here
-+ @param hint what the hint is (as string : "USE INDEX"|
-+ "FORCE INDEX"|"IGNORE INDEX")
-+ @param hint_length the length of the string in 'hint'
-+ @param indexes a list of index names for the hint
-+*/
-+
-+void
-+Index_hint::print(THD *thd, String *str)
-+{
-+ switch (type)
-+ {
-+ case INDEX_HINT_IGNORE: str->append(STRING_WITH_LEN("IGNORE INDEX")); break;
-+ case INDEX_HINT_USE: str->append(STRING_WITH_LEN("USE INDEX")); break;
-+ case INDEX_HINT_FORCE: str->append(STRING_WITH_LEN("FORCE INDEX")); break;
-+ }
-+ str->append (STRING_WITH_LEN(" ("));
-+ if (key_name.length)
-+ {
-+ if (thd && !my_strnncoll(system_charset_info,
-+ (const uchar *)key_name.str, key_name.length,
-+ (const uchar *)primary_key_name,
-+ strlen(primary_key_name)))
-+ str->append(primary_key_name);
-+ else
-+ append_identifier(thd, str, key_name.str, key_name.length);
-+ }
-+ str->append(')');
-+}
-+
-+
-+/**
-+ Print table as it should be in join list.
-+
-+ @param str string where table should be printed
-+*/
-+
-+void TABLE_LIST::print(THD *thd, String *str, enum_query_type query_type)
-+{
-+ if (nested_join)
-+ {
-+ str->append('(');
-+ print_join(thd, str, &nested_join->join_list, query_type);
-+ str->append(')');
-+ }
-+ else
-+ {
-+ const char *cmp_name; // Name to compare with alias
-+ if (view_name.str)
-+ {
-+ // A view
-+
-+ if (!(belong_to_view &&
-+ belong_to_view->compact_view_format))
-+ {
-+ append_identifier(thd, str, view_db.str, view_db.length);
-+ str->append('.');
-+ }
-+ append_identifier(thd, str, view_name.str, view_name.length);
-+ cmp_name= view_name.str;
-+ }
-+ else if (derived)
-+ {
-+ // A derived table
-+ str->append('(');
-+ derived->print(str, query_type);
-+ str->append(')');
-+ cmp_name= ""; // Force printing of alias
-+ }
-+ else
-+ {
-+ // A normal table
-+
-+ if (!(belong_to_view &&
-+ belong_to_view->compact_view_format))
-+ {
-+ append_identifier(thd, str, db, db_length);
-+ str->append('.');
-+ }
-+ if (schema_table)
-+ {
-+ append_identifier(thd, str, schema_table_name,
-+ strlen(schema_table_name));
-+ cmp_name= schema_table_name;
-+ }
-+ else
-+ {
-+ append_identifier(thd, str, table_name, table_name_length);
-+ cmp_name= table_name;
-+ }
-+ }
-+ if (my_strcasecmp(table_alias_charset, cmp_name, alias))
-+ {
-+ char t_alias_buff[MAX_ALIAS_NAME];
-+ const char *t_alias= alias;
-+
-+ str->append(' ');
-+ if (lower_case_table_names== 1)
-+ {
-+ if (alias && alias[0])
-+ {
-+ strmov(t_alias_buff, alias);
-+ my_casedn_str(files_charset_info, t_alias_buff);
-+ t_alias= t_alias_buff;
-+ }
-+ }
-+
-+ append_identifier(thd, str, t_alias, strlen(t_alias));
-+ }
-+
-+ if (index_hints)
-+ {
-+ List_iterator<Index_hint> it(*index_hints);
-+ Index_hint *hint;
-+
-+ while ((hint= it++))
-+ {
-+ str->append (STRING_WITH_LEN(" "));
-+ hint->print (thd, str);
-+ }
-+ }
-+ }
-+}
-+
-+
-+void st_select_lex::print(THD *thd, String *str, enum_query_type query_type)
-+{
-+ /* QQ: thd may not be set for sub queries, but this should be fixed */
-+ if (!thd)
-+ thd= current_thd;
-+
-+ str->append(STRING_WITH_LEN("select "));
-+
-+ /* First add options */
-+ if (options & SELECT_STRAIGHT_JOIN)
-+ str->append(STRING_WITH_LEN("straight_join "));
-+ if ((thd->lex->lock_option == TL_READ_HIGH_PRIORITY) &&
-+ (this == &thd->lex->select_lex))
-+ str->append(STRING_WITH_LEN("high_priority "));
-+ if (options & SELECT_DISTINCT)
-+ str->append(STRING_WITH_LEN("distinct "));
-+ if (options & SELECT_SMALL_RESULT)
-+ str->append(STRING_WITH_LEN("sql_small_result "));
-+ if (options & SELECT_BIG_RESULT)
-+ str->append(STRING_WITH_LEN("sql_big_result "));
-+ if (options & OPTION_BUFFER_RESULT)
-+ str->append(STRING_WITH_LEN("sql_buffer_result "));
-+ if (options & OPTION_FOUND_ROWS)
-+ str->append(STRING_WITH_LEN("sql_calc_found_rows "));
-+ switch (sql_cache)
-+ {
-+ case SQL_NO_CACHE:
-+ str->append(STRING_WITH_LEN("sql_no_cache "));
-+ break;
-+ case SQL_CACHE:
-+ str->append(STRING_WITH_LEN("sql_cache "));
-+ break;
-+ case SQL_CACHE_UNSPECIFIED:
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+
-+ //Item List
-+ bool first= 1;
-+ List_iterator_fast<Item> it(item_list);
-+ Item *item;
-+ while ((item= it++))
-+ {
-+ if (first)
-+ first= 0;
-+ else
-+ str->append(',');
-+
-+ if (master_unit()->item && item->is_autogenerated_name)
-+ {
-+ /*
-+ Do not print auto-generated aliases in subqueries. It has no purpose
-+ in a view definition or other contexts where the query is printed.
-+ */
-+ item->print(str, query_type);
-+ }
-+ else
-+ item->print_item_w_name(str, query_type);
-+ }
-+
-+ /*
-+ from clause
-+ TODO: support USING/FORCE/IGNORE index
-+ */
-+ if (table_list.elements)
-+ {
-+ str->append(STRING_WITH_LEN(" from "));
-+ /* go through join tree */
-+ print_join(thd, str, &top_join_list, query_type);
-+ }
-+ else if (where)
-+ {
-+ /*
-+ "SELECT 1 FROM DUAL WHERE 2" should not be printed as
-+ "SELECT 1 WHERE 2": the 1st syntax is valid, but the 2nd is not.
-+ */
-+ str->append(STRING_WITH_LEN(" from DUAL "));
-+ }
-+
-+ // Where
-+ Item *cur_where= where;
-+ if (join)
-+ cur_where= join->conds;
-+ if (cur_where || cond_value != Item::COND_UNDEF)
-+ {
-+ str->append(STRING_WITH_LEN(" where "));
-+ if (cur_where)
-+ cur_where->print(str, query_type);
-+ else
-+ str->append(cond_value != Item::COND_FALSE ? "1" : "0");
-+ }
-+
-+ // group by & olap
-+ if (group_list.elements)
-+ {
-+ str->append(STRING_WITH_LEN(" group by "));
-+ print_order(str, group_list.first, query_type);
-+ switch (olap)
-+ {
-+ case CUBE_TYPE:
-+ str->append(STRING_WITH_LEN(" with cube"));
-+ break;
-+ case ROLLUP_TYPE:
-+ str->append(STRING_WITH_LEN(" with rollup"));
-+ break;
-+ default:
-+ ; //satisfy compiler
-+ }
-+ }
-+
-+ // having
-+ Item *cur_having= having;
-+ if (join)
-+ cur_having= join->having;
-+
-+ if (cur_having || having_value != Item::COND_UNDEF)
-+ {
-+ str->append(STRING_WITH_LEN(" having "));
-+ if (cur_having)
-+ cur_having->print(str, query_type);
-+ else
-+ str->append(having_value != Item::COND_FALSE ? "1" : "0");
-+ }
-+
-+ if (order_list.elements)
-+ {
-+ str->append(STRING_WITH_LEN(" order by "));
-+ print_order(str, order_list.first, query_type);
-+ }
-+
-+ // limit
-+ print_limit(thd, str, query_type);
-+
-+ // PROCEDURE unsupported here
-+}
-+
-+
-+/**
-+ change select_result object of JOIN.
-+
-+ @param res new select_result object
-+
-+ @retval
-+ FALSE OK
-+ @retval
-+ TRUE error
-+*/
-+
-+bool JOIN::change_result(select_result *res)
-+{
-+ DBUG_ENTER("JOIN::change_result");
-+ result= res;
-+ if (!procedure && (result->prepare(fields_list, select_lex->master_unit()) ||
-+ result->prepare2()))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+/**
-+ @} (end of group Query_Optimizer)
-+*/
diff -urN mysql-old/sql/sql_show.cc mysql/sql/sql_show.cc
--- mysql-old/sql/sql_show.cc 2011-05-10 17:45:45.626682377 +0000
+++ mysql/sql/sql_show.cc 2011-05-10 17:56:01.596682375 +0000
@@ -53517,7285 +2492,6 @@ diff -urN mysql-old/sql/sql_show.cc mysql/sql/sql_show.cc
stmt_fld->maybe_null= TRUE;
-diff -urN mysql-old/sql/sql_show.cc.orig mysql/sql/sql_show.cc.orig
---- mysql-old/sql/sql_show.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/sql_show.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,7275 @@
-+/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License along
-+ with this program; if not, write to the Free Software Foundation, Inc.,
-+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
-+
-+
-+/* Function with list databases, tables or fields */
-+
-+#include "mysql_priv.h"
-+#include "sql_select.h" // For select_describe
-+#include "sql_show.h"
-+#include "repl_failsafe.h"
-+#include "sp.h"
-+#include "sp_head.h"
-+#include "sql_trigger.h"
-+#include "authors.h"
-+#include "contributors.h"
-+#ifdef HAVE_EVENT_SCHEDULER
-+#include "events.h"
-+#include "event_data_objects.h"
-+#endif
-+#include <my_dir.h>
-+#include "debug_sync.h"
-+
-+#define STR_OR_NIL(S) ((S) ? (S) : "<nil>")
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+#include "ha_partition.h"
-+#endif
-+enum enum_i_s_events_fields
-+{
-+ ISE_EVENT_CATALOG= 0,
-+ ISE_EVENT_SCHEMA,
-+ ISE_EVENT_NAME,
-+ ISE_DEFINER,
-+ ISE_TIME_ZONE,
-+ ISE_EVENT_BODY,
-+ ISE_EVENT_DEFINITION,
-+ ISE_EVENT_TYPE,
-+ ISE_EXECUTE_AT,
-+ ISE_INTERVAL_VALUE,
-+ ISE_INTERVAL_FIELD,
-+ ISE_SQL_MODE,
-+ ISE_STARTS,
-+ ISE_ENDS,
-+ ISE_STATUS,
-+ ISE_ON_COMPLETION,
-+ ISE_CREATED,
-+ ISE_LAST_ALTERED,
-+ ISE_LAST_EXECUTED,
-+ ISE_EVENT_COMMENT,
-+ ISE_ORIGINATOR,
-+ ISE_CLIENT_CS,
-+ ISE_CONNECTION_CL,
-+ ISE_DB_CL
-+};
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+static const char *grant_names[]={
-+ "select","insert","update","delete","create","drop","reload","shutdown",
-+ "process","file","grant","references","index","alter"};
-+
-+static TYPELIB grant_types = { sizeof(grant_names)/sizeof(char **),
-+ "grant_types",
-+ grant_names, NULL};
-+#endif
-+
-+static void store_key_options(THD *thd, String *packet, TABLE *table,
-+ KEY *key_info);
-+
-+static void
-+append_algorithm(TABLE_LIST *table, String *buff);
-+
-+static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);
-+
-+/***************************************************************************
-+** List all table types supported
-+***************************************************************************/
-+
-+static int make_version_string(char *buf, int buf_length, uint version)
-+{
-+ return my_snprintf(buf, buf_length, "%d.%d", version>>8,version&0xff);
-+}
-+
-+static my_bool show_plugins(THD *thd, plugin_ref plugin,
-+ void *arg)
-+{
-+ TABLE *table= (TABLE*) arg;
-+ struct st_mysql_plugin *plug= plugin_decl(plugin);
-+ struct st_plugin_dl *plugin_dl= plugin_dlib(plugin);
-+ CHARSET_INFO *cs= system_charset_info;
-+ char version_buf[20];
-+
-+ restore_record(table, s->default_values);
-+
-+ table->field[0]->store(plugin_name(plugin)->str,
-+ plugin_name(plugin)->length, cs);
-+
-+ table->field[1]->store(version_buf,
-+ make_version_string(version_buf, sizeof(version_buf), plug->version),
-+ cs);
-+
-+
-+ switch (plugin_state(plugin)) {
-+ /* case PLUGIN_IS_FREED: does not happen */
-+ case PLUGIN_IS_DELETED:
-+ table->field[2]->store(STRING_WITH_LEN("DELETED"), cs);
-+ break;
-+ case PLUGIN_IS_UNINITIALIZED:
-+ table->field[2]->store(STRING_WITH_LEN("INACTIVE"), cs);
-+ break;
-+ case PLUGIN_IS_READY:
-+ table->field[2]->store(STRING_WITH_LEN("ACTIVE"), cs);
-+ break;
-+ case PLUGIN_IS_DISABLED:
-+ table->field[2]->store(STRING_WITH_LEN("DISABLED"), cs);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+
-+ table->field[3]->store(plugin_type_names[plug->type].str,
-+ plugin_type_names[plug->type].length,
-+ cs);
-+ table->field[4]->store(version_buf,
-+ make_version_string(version_buf, sizeof(version_buf),
-+ *(uint *)plug->info), cs);
-+
-+ if (plugin_dl)
-+ {
-+ table->field[5]->store(plugin_dl->dl.str, plugin_dl->dl.length, cs);
-+ table->field[5]->set_notnull();
-+ table->field[6]->store(version_buf,
-+ make_version_string(version_buf, sizeof(version_buf),
-+ plugin_dl->version),
-+ cs);
-+ table->field[6]->set_notnull();
-+ }
-+ else
-+ {
-+ table->field[5]->set_null();
-+ table->field[6]->set_null();
-+ }
-+
-+
-+ if (plug->author)
-+ {
-+ table->field[7]->store(plug->author, strlen(plug->author), cs);
-+ table->field[7]->set_notnull();
-+ }
-+ else
-+ table->field[7]->set_null();
-+
-+ if (plug->descr)
-+ {
-+ table->field[8]->store(plug->descr, strlen(plug->descr), cs);
-+ table->field[8]->set_notnull();
-+ }
-+ else
-+ table->field[8]->set_null();
-+
-+ switch (plug->license) {
-+ case PLUGIN_LICENSE_GPL:
-+ table->field[9]->store(PLUGIN_LICENSE_GPL_STRING,
-+ strlen(PLUGIN_LICENSE_GPL_STRING), cs);
-+ break;
-+ case PLUGIN_LICENSE_BSD:
-+ table->field[9]->store(PLUGIN_LICENSE_BSD_STRING,
-+ strlen(PLUGIN_LICENSE_BSD_STRING), cs);
-+ break;
-+ default:
-+ table->field[9]->store(PLUGIN_LICENSE_PROPRIETARY_STRING,
-+ strlen(PLUGIN_LICENSE_PROPRIETARY_STRING), cs);
-+ break;
-+ }
-+ table->field[9]->set_notnull();
-+
-+ return schema_table_store_record(thd, table);
-+}
-+
-+
-+int fill_plugins(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_plugins");
-+ TABLE *table= tables->table;
-+
-+ if (plugin_foreach_with_mask(thd, show_plugins, MYSQL_ANY_PLUGIN,
-+ ~PLUGIN_IS_FREED, table))
-+ DBUG_RETURN(1);
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/***************************************************************************
-+** List all Authors.
-+** If you can update it, you get to be in it :)
-+***************************************************************************/
-+
-+bool mysqld_show_authors(THD *thd)
-+{
-+ List<Item> field_list;
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysqld_show_authors");
-+
-+ field_list.push_back(new Item_empty_string("Name",40));
-+ field_list.push_back(new Item_empty_string("Location",40));
-+ field_list.push_back(new Item_empty_string("Comment",80));
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ show_table_authors_st *authors;
-+ for (authors= show_table_authors; authors->name; authors++)
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store(authors->name, system_charset_info);
-+ protocol->store(authors->location, system_charset_info);
-+ protocol->store(authors->comment, system_charset_info);
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+ }
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/***************************************************************************
-+** List all Contributors.
-+** Please get permission before updating
-+***************************************************************************/
-+
-+bool mysqld_show_contributors(THD *thd)
-+{
-+ List<Item> field_list;
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysqld_show_contributors");
-+
-+ field_list.push_back(new Item_empty_string("Name",40));
-+ field_list.push_back(new Item_empty_string("Location",40));
-+ field_list.push_back(new Item_empty_string("Comment",80));
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ show_table_contributors_st *contributors;
-+ for (contributors= show_table_contributors; contributors->name; contributors++)
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store(contributors->name, system_charset_info);
-+ protocol->store(contributors->location, system_charset_info);
-+ protocol->store(contributors->comment, system_charset_info);
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+ }
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/***************************************************************************
-+ List all privileges supported
-+***************************************************************************/
-+
-+struct show_privileges_st {
-+ const char *privilege;
-+ const char *context;
-+ const char *comment;
-+};
-+
-+static struct show_privileges_st sys_privileges[]=
-+{
-+ {"Alter", "Tables", "To alter the table"},
-+ {"Alter routine", "Functions,Procedures", "To alter or drop stored functions/procedures"},
-+ {"Create", "Databases,Tables,Indexes", "To create new databases and tables"},
-+ {"Create routine","Databases","To use CREATE FUNCTION/PROCEDURE"},
-+ {"Create temporary tables","Databases","To use CREATE TEMPORARY TABLE"},
-+ {"Create view", "Tables", "To create new views"},
-+ {"Create user", "Server Admin", "To create new users"},
-+ {"Delete", "Tables", "To delete existing rows"},
-+ {"Drop", "Databases,Tables", "To drop databases, tables, and views"},
-+#ifdef HAVE_EVENT_SCHEDULER
-+ {"Event","Server Admin","To create, alter, drop and execute events"},
-+#endif
-+ {"Execute", "Functions,Procedures", "To execute stored routines"},
-+ {"File", "File access on server", "To read and write files on the server"},
-+ {"Grant option", "Databases,Tables,Functions,Procedures", "To give to other users those privileges you possess"},
-+ {"Index", "Tables", "To create or drop indexes"},
-+ {"Insert", "Tables", "To insert data into tables"},
-+ {"Lock tables","Databases","To use LOCK TABLES (together with SELECT privilege)"},
-+ {"Process", "Server Admin", "To view the plain text of currently executing queries"},
-+ {"References", "Databases,Tables", "To have references on tables"},
-+ {"Reload", "Server Admin", "To reload or refresh tables, logs and privileges"},
-+ {"Replication client","Server Admin","To ask where the slave or master servers are"},
-+ {"Replication slave","Server Admin","To read binary log events from the master"},
-+ {"Select", "Tables", "To retrieve rows from table"},
-+ {"Show databases","Server Admin","To see all databases with SHOW DATABASES"},
-+ {"Show view","Tables","To see views with SHOW CREATE VIEW"},
-+ {"Shutdown","Server Admin", "To shut down the server"},
-+ {"Super","Server Admin","To use KILL thread, SET GLOBAL, CHANGE MASTER, etc."},
-+ {"Trigger","Tables", "To use triggers"},
-+ {"Update", "Tables", "To update existing rows"},
-+ {"Usage","Server Admin","No privileges - allow connect only"},
-+ {NullS, NullS, NullS}
-+};
-+
-+bool mysqld_show_privileges(THD *thd)
-+{
-+ List<Item> field_list;
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysqld_show_privileges");
-+
-+ field_list.push_back(new Item_empty_string("Privilege",10));
-+ field_list.push_back(new Item_empty_string("Context",15));
-+ field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ show_privileges_st *privilege= sys_privileges;
-+ for (privilege= sys_privileges; privilege->privilege ; privilege++)
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store(privilege->privilege, system_charset_info);
-+ protocol->store(privilege->context, system_charset_info);
-+ protocol->store(privilege->comment, system_charset_info);
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+ }
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/***************************************************************************
-+ List all column types
-+***************************************************************************/
-+
-+struct show_column_type_st
-+{
-+ const char *type;
-+ uint size;
-+ const char *min_value;
-+ const char *max_value;
-+ uint precision;
-+ uint scale;
-+ const char *nullable;
-+ const char *auto_increment;
-+ const char *unsigned_attr;
-+ const char *zerofill;
-+ const char *searchable;
-+ const char *case_sensitivity;
-+ const char *default_value;
-+ const char *comment;
-+};
-+
-+/* TODO: Add remaning types */
-+
-+static struct show_column_type_st sys_column_types[]=
-+{
-+ {"tinyint",
-+ 1, "-128", "127", 0, 0, "YES", "YES",
-+ "NO", "YES", "YES", "NO", "NULL,0",
-+ "A very small integer"},
-+ {"tinyint unsigned",
-+ 1, "0" , "255", 0, 0, "YES", "YES",
-+ "YES", "YES", "YES", "NO", "NULL,0",
-+ "A very small integer"},
-+};
-+
-+bool mysqld_show_column_types(THD *thd)
-+{
-+ List<Item> field_list;
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysqld_show_column_types");
-+
-+ field_list.push_back(new Item_empty_string("Type",30));
-+ field_list.push_back(new Item_int("Size",(longlong) 1,
-+ MY_INT64_NUM_DECIMAL_DIGITS));
-+ field_list.push_back(new Item_empty_string("Min_Value",20));
-+ field_list.push_back(new Item_empty_string("Max_Value",20));
-+ field_list.push_back(new Item_return_int("Prec", 4, MYSQL_TYPE_SHORT));
-+ field_list.push_back(new Item_return_int("Scale", 4, MYSQL_TYPE_SHORT));
-+ field_list.push_back(new Item_empty_string("Nullable",4));
-+ field_list.push_back(new Item_empty_string("Auto_Increment",4));
-+ field_list.push_back(new Item_empty_string("Unsigned",4));
-+ field_list.push_back(new Item_empty_string("Zerofill",4));
-+ field_list.push_back(new Item_empty_string("Searchable",4));
-+ field_list.push_back(new Item_empty_string("Case_Sensitive",4));
-+ field_list.push_back(new Item_empty_string("Default",NAME_CHAR_LEN));
-+ field_list.push_back(new Item_empty_string("Comment",NAME_CHAR_LEN));
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ /* TODO: Change the loop to not use 'i' */
-+ for (uint i=0; i < sizeof(sys_column_types)/sizeof(sys_column_types[0]); i++)
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store(sys_column_types[i].type, system_charset_info);
-+ protocol->store((ulonglong) sys_column_types[i].size);
-+ protocol->store(sys_column_types[i].min_value, system_charset_info);
-+ protocol->store(sys_column_types[i].max_value, system_charset_info);
-+ protocol->store_short((longlong) sys_column_types[i].precision);
-+ protocol->store_short((longlong) sys_column_types[i].scale);
-+ protocol->store(sys_column_types[i].nullable, system_charset_info);
-+ protocol->store(sys_column_types[i].auto_increment, system_charset_info);
-+ protocol->store(sys_column_types[i].unsigned_attr, system_charset_info);
-+ protocol->store(sys_column_types[i].zerofill, system_charset_info);
-+ protocol->store(sys_column_types[i].searchable, system_charset_info);
-+ protocol->store(sys_column_types[i].case_sensitivity, system_charset_info);
-+ protocol->store(sys_column_types[i].default_value, system_charset_info);
-+ protocol->store(sys_column_types[i].comment, system_charset_info);
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+ }
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ find_files() - find files in a given directory.
-+
-+ SYNOPSIS
-+ find_files()
-+ thd thread handler
-+ files put found files in this list
-+ db database name to set in TABLE_LIST structure
-+ path path to database
-+ wild filter for found files
-+ dir read databases in path if TRUE, read .frm files in
-+ database otherwise
-+
-+ RETURN
-+ FIND_FILES_OK success
-+ FIND_FILES_OOM out of memory error
-+ FIND_FILES_DIR no such directory, or directory can't be read
-+*/
-+
-+
-+find_files_result
-+find_files(THD *thd, List<LEX_STRING> *files, const char *db,
-+ const char *path, const char *wild, bool dir)
-+{
-+ uint i;
-+ char *ext;
-+ MY_DIR *dirp;
-+ FILEINFO *file;
-+ LEX_STRING *file_name= 0;
-+ uint file_name_len;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ uint col_access=thd->col_access;
-+#endif
-+ uint wild_length= 0;
-+ TABLE_LIST table_list;
-+ DBUG_ENTER("find_files");
-+
-+ if (wild)
-+ {
-+ if (!wild[0])
-+ wild= 0;
-+ else
-+ wild_length= strlen(wild);
-+ }
-+
-+
-+
-+ bzero((char*) &table_list,sizeof(table_list));
-+
-+ if (!(dirp = my_dir(path,MYF(dir ? MY_WANT_STAT : 0))))
-+ {
-+ if (my_errno == ENOENT)
-+ my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db);
-+ else
-+ my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno);
-+ DBUG_RETURN(FIND_FILES_DIR);
-+ }
-+
-+ for (i=0 ; i < (uint) dirp->number_off_files ; i++)
-+ {
-+ char uname[NAME_LEN + 1]; /* Unencoded name */
-+ file=dirp->dir_entry+i;
-+ if (dir)
-+ { /* Return databases */
-+ if ((file->name[0] == '.' &&
-+ ((file->name[1] == '.' && file->name[2] == '\0') ||
-+ file->name[1] == '\0')))
-+ continue; /* . or .. */
-+#ifdef USE_SYMDIR
-+ char *ext;
-+ char buff[FN_REFLEN];
-+ if (my_use_symdir && !strcmp(ext=fn_ext(file->name), ".sym"))
-+ {
-+ /* Only show the sym file if it points to a directory */
-+ char *end;
-+ *ext=0; /* Remove extension */
-+ unpack_dirname(buff, file->name);
-+ end= strend(buff);
-+ if (end != buff && end[-1] == FN_LIBCHAR)
-+ end[-1]= 0; // Remove end FN_LIBCHAR
-+ if (!my_stat(buff, file->mystat, MYF(0)))
-+ continue;
-+ }
-+#endif
-+ if (!MY_S_ISDIR(file->mystat->st_mode))
-+ continue;
-+
-+ file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
-+ if (wild)
-+ {
-+ if (lower_case_table_names)
-+ {
-+ if (my_wildcmp(files_charset_info,
-+ uname, uname + file_name_len,
-+ wild, wild + wild_length,
-+ wild_prefix, wild_one,wild_many))
-+ continue;
-+ }
-+ else if (wild_compare(uname, wild, 0))
-+ continue;
-+ }
-+ }
-+ else
-+ {
-+ // Return only .frm files which aren't temp files.
-+ if (my_strcasecmp(system_charset_info, ext=fn_rext(file->name),reg_ext) ||
-+ is_prefix(file->name, tmp_file_prefix))
-+ continue;
-+ *ext=0;
-+ file_name_len= filename_to_tablename(file->name, uname, sizeof(uname));
-+ if (wild)
-+ {
-+ if (lower_case_table_names)
-+ {
-+ if (my_wildcmp(files_charset_info,
-+ uname, uname + file_name_len,
-+ wild, wild + wild_length,
-+ wild_prefix, wild_one,wild_many))
-+ continue;
-+ }
-+ else if (wild_compare(uname, wild, 0))
-+ continue;
-+ }
-+ }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ /* Don't show tables where we don't have any privileges */
-+ if (db && !(col_access & TABLE_ACLS))
-+ {
-+ table_list.db= (char*) db;
-+ table_list.db_length= strlen(db);
-+ table_list.table_name= uname;
-+ table_list.table_name_length= file_name_len;
-+ table_list.grant.privilege=col_access;
-+ if (check_grant(thd, TABLE_ACLS, &table_list, 1, 1, 1))
-+ continue;
-+ }
-+#endif
-+ if (!(file_name=
-+ thd->make_lex_string(file_name, uname, file_name_len, TRUE)) ||
-+ files->push_back(file_name))
-+ {
-+ my_dirend(dirp);
-+ DBUG_RETURN(FIND_FILES_OOM);
-+ }
-+ }
-+ DBUG_PRINT("info",("found: %d files", files->elements));
-+ my_dirend(dirp);
-+
-+ VOID(ha_find_files(thd, db, path, wild, dir, files));
-+
-+ DBUG_RETURN(FIND_FILES_OK);
-+}
-+
-+
-+/**
-+ An Internal_error_handler that suppresses errors regarding views'
-+ underlying tables that occur during privilege checking within SHOW CREATE
-+ VIEW commands. This happens in the cases when
-+
-+ - A view's underlying table (e.g. referenced in its SELECT list) does not
-+ exist. There should not be an error as no attempt was made to access it
-+ per se.
-+
-+ - Access is denied for some table, column, function or stored procedure
-+ such as mentioned above. This error gets raised automatically, since we
-+ can't untangle its access checking from that of the view itself.
-+ */
-+class Show_create_error_handler : public Internal_error_handler {
-+
-+ TABLE_LIST *m_top_view;
-+ bool m_handling;
-+ Security_context *m_sctx;
-+
-+ char m_view_access_denied_message[MYSQL_ERRMSG_SIZE];
-+ char *m_view_access_denied_message_ptr;
-+
-+public:
-+
-+ /**
-+ Creates a new Show_create_error_handler for the particular security
-+ context and view.
-+
-+ @thd Thread context, used for security context information if needed.
-+ @top_view The view. We do not verify at this point that top_view is in
-+ fact a view since, alas, these things do not stay constant.
-+ */
-+ explicit Show_create_error_handler(THD *thd, TABLE_LIST *top_view) :
-+ m_top_view(top_view), m_handling(FALSE),
-+ m_view_access_denied_message_ptr(NULL)
-+ {
-+
-+ m_sctx = test(m_top_view->security_ctx) ?
-+ m_top_view->security_ctx : thd->security_ctx;
-+ }
-+
-+ /**
-+ Lazy instantiation of 'view access denied' message. The purpose of the
-+ Show_create_error_handler is to hide details of underlying tables for
-+ which we have no privileges behind ER_VIEW_INVALID messages. But this
-+ obviously does not apply if we lack privileges on the view itself.
-+ Unfortunately the information about for which table privilege checking
-+ failed is not available at this point. The only way for us to check is by
-+ reconstructing the actual error message and see if it's the same.
-+ */
-+ char* get_view_access_denied_message()
-+ {
-+ if (!m_view_access_denied_message_ptr)
-+ {
-+ m_view_access_denied_message_ptr= m_view_access_denied_message;
-+ my_snprintf(m_view_access_denied_message, MYSQL_ERRMSG_SIZE,
-+ ER(ER_TABLEACCESS_DENIED_ERROR), "SHOW VIEW",
-+ m_sctx->priv_user,
-+ m_sctx->host_or_ip, m_top_view->get_table_name());
-+ }
-+ return m_view_access_denied_message_ptr;
-+ }
-+
-+ bool handle_error(uint sql_errno, const char *message,
-+ MYSQL_ERROR::enum_warning_level level, THD *thd) {
-+ /*
-+ The handler does not handle the errors raised by itself.
-+ At this point we know if top_view is really a view.
-+ */
-+ if (m_handling || !m_top_view->view)
-+ return FALSE;
-+
-+ m_handling= TRUE;
-+
-+ bool is_handled;
-+
-+ switch (sql_errno)
-+ {
-+ case ER_TABLEACCESS_DENIED_ERROR:
-+ if (!strcmp(get_view_access_denied_message(), message))
-+ {
-+ /* Access to top view is not granted, don't interfere. */
-+ is_handled= FALSE;
-+ break;
-+ }
-+ case ER_COLUMNACCESS_DENIED_ERROR:
-+ case ER_VIEW_NO_EXPLAIN: /* Error was anonymized, ignore all the same. */
-+ case ER_PROCACCESS_DENIED_ERROR:
-+ is_handled= TRUE;
-+ break;
-+
-+ case ER_NO_SUCH_TABLE:
-+ /* Established behavior: warn if underlying tables are missing. */
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_VIEW_INVALID,
-+ ER(ER_VIEW_INVALID),
-+ m_top_view->get_db_name(),
-+ m_top_view->get_table_name());
-+ is_handled= TRUE;
-+ break;
-+
-+ case ER_SP_DOES_NOT_EXIST:
-+ /* Established behavior: warn if underlying functions are missing. */
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_VIEW_INVALID,
-+ ER(ER_VIEW_INVALID),
-+ m_top_view->get_db_name(),
-+ m_top_view->get_table_name());
-+ is_handled= TRUE;
-+ break;
-+ default:
-+ is_handled= FALSE;
-+ }
-+
-+ m_handling= FALSE;
-+ return is_handled;
-+ }
-+};
-+
-+
-+bool
-+mysqld_show_create(THD *thd, TABLE_LIST *table_list)
-+{
-+ Protocol *protocol= thd->protocol;
-+ char buff[2048];
-+ String buffer(buff, sizeof(buff), system_charset_info);
-+ DBUG_ENTER("mysqld_show_create");
-+ DBUG_PRINT("enter",("db: %s table: %s",table_list->db,
-+ table_list->table_name));
-+
-+ /* We want to preserve the tree for views. */
-+ thd->lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
-+
-+ {
-+ Show_create_error_handler view_error_suppressor(thd, table_list);
-+ thd->push_internal_handler(&view_error_suppressor);
-+ bool error= open_normal_and_derived_tables(thd, table_list, 0);
-+ thd->pop_internal_handler();
-+ if (error && (thd->killed || thd->main_da.is_error()))
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* TODO: add environment variables show when it become possible */
-+ if (thd->lex->only_view && !table_list->view)
-+ {
-+ my_error(ER_WRONG_OBJECT, MYF(0),
-+ table_list->db, table_list->table_name, "VIEW");
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ buffer.length(0);
-+
-+ if (table_list->view)
-+ buffer.set_charset(table_list->view_creation_ctx->get_client_cs());
-+
-+ if ((table_list->view ?
-+ view_store_create_info(thd, table_list, &buffer) :
-+ store_create_info(thd, table_list, &buffer, NULL,
-+ FALSE /* show_database */)))
-+ DBUG_RETURN(TRUE);
-+
-+ List<Item> field_list;
-+ if (table_list->view)
-+ {
-+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
-+ field_list.push_back(new Item_empty_string("Create View",
-+ max(buffer.length(),1024)));
-+ field_list.push_back(new Item_empty_string("character_set_client",
-+ MY_CS_NAME_SIZE));
-+ field_list.push_back(new Item_empty_string("collation_connection",
-+ MY_CS_NAME_SIZE));
-+ }
-+ else
-+ {
-+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
-+ // 1024 is for not to confuse old clients
-+ field_list.push_back(new Item_empty_string("Create Table",
-+ max(buffer.length(),1024)));
-+ }
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+ protocol->prepare_for_resend();
-+ if (table_list->view)
-+ protocol->store(table_list->view_name.str, system_charset_info);
-+ else
-+ {
-+ if (table_list->schema_table)
-+ protocol->store(table_list->schema_table->table_name,
-+ system_charset_info);
-+ else
-+ protocol->store(table_list->table->alias, system_charset_info);
-+ }
-+
-+ if (table_list->view)
-+ {
-+ protocol->store(buffer.ptr(), buffer.length(),
-+ table_list->view_creation_ctx->get_client_cs());
-+
-+ protocol->store(table_list->view_creation_ctx->get_client_cs()->csname,
-+ system_charset_info);
-+
-+ protocol->store(table_list->view_creation_ctx->get_connection_cl()->name,
-+ system_charset_info);
-+ }
-+ else
-+ protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
-+
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+bool mysqld_show_create_db(THD *thd, char *dbname,
-+ HA_CREATE_INFO *create_info)
-+{
-+ char buff[2048];
-+ String buffer(buff, sizeof(buff), system_charset_info);
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ Security_context *sctx= thd->security_ctx;
-+ uint db_access;
-+#endif
-+ HA_CREATE_INFO create;
-+ uint create_options = create_info ? create_info->options : 0;
-+ Protocol *protocol=thd->protocol;
-+ DBUG_ENTER("mysql_show_create_db");
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (test_all_bits(sctx->master_access, DB_ACLS))
-+ db_access=DB_ACLS;
-+ else
-+ db_access= (acl_get(sctx->host, sctx->ip, sctx->priv_user, dbname, 0) |
-+ sctx->master_access);
-+ if (!(db_access & DB_ACLS) && check_grant_db(thd,dbname))
-+ {
-+ my_error(ER_DBACCESS_DENIED_ERROR, MYF(0),
-+ sctx->priv_user, sctx->host_or_ip, dbname);
-+ general_log_print(thd,COM_INIT_DB,ER(ER_DBACCESS_DENIED_ERROR),
-+ sctx->priv_user, sctx->host_or_ip, dbname);
-+ DBUG_RETURN(TRUE);
-+ }
-+#endif
-+ if (is_schema_db(dbname))
-+ {
-+ dbname= INFORMATION_SCHEMA_NAME.str;
-+ create.default_table_charset= system_charset_info;
-+ }
-+ else
-+ {
-+ if (check_db_dir_existence(dbname))
-+ {
-+ my_error(ER_BAD_DB_ERROR, MYF(0), dbname);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ load_db_opt_by_name(thd, dbname, &create);
-+ }
-+ List<Item> field_list;
-+ field_list.push_back(new Item_empty_string("Database",NAME_CHAR_LEN));
-+ field_list.push_back(new Item_empty_string("Create Database",1024));
-+
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ protocol->prepare_for_resend();
-+ protocol->store(dbname, strlen(dbname), system_charset_info);
-+ buffer.length(0);
-+ buffer.append(STRING_WITH_LEN("CREATE DATABASE "));
-+ if (create_options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ buffer.append(STRING_WITH_LEN("/*!32312 IF NOT EXISTS*/ "));
-+ append_identifier(thd, &buffer, dbname, strlen(dbname));
-+
-+ if (create.default_table_charset)
-+ {
-+ buffer.append(STRING_WITH_LEN(" /*!40100"));
-+ buffer.append(STRING_WITH_LEN(" DEFAULT CHARACTER SET "));
-+ buffer.append(create.default_table_charset->csname);
-+ if (!(create.default_table_charset->state & MY_CS_PRIMARY))
-+ {
-+ buffer.append(STRING_WITH_LEN(" COLLATE "));
-+ buffer.append(create.default_table_charset->name);
-+ }
-+ buffer.append(STRING_WITH_LEN(" */"));
-+ }
-+ protocol->store(buffer.ptr(), buffer.length(), buffer.charset());
-+
-+ if (protocol->write())
-+ DBUG_RETURN(TRUE);
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+
-+/****************************************************************************
-+ Return only fields for API mysql_list_fields
-+ Use "show table wildcard" in mysql instead of this
-+****************************************************************************/
-+
-+void
-+mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
-+{
-+ TABLE *table;
-+ DBUG_ENTER("mysqld_list_fields");
-+ DBUG_PRINT("enter",("table: %s",table_list->table_name));
-+
-+ if (open_normal_and_derived_tables(thd, table_list, 0))
-+ DBUG_VOID_RETURN;
-+ table= table_list->table;
-+
-+ List<Item> field_list;
-+
-+ Field **ptr,*field;
-+ for (ptr=table->field ; (field= *ptr); ptr++)
-+ {
-+ if (!wild || !wild[0] ||
-+ !wild_case_compare(system_charset_info, field->field_name,wild))
-+ {
-+ if (table_list->view)
-+ field_list.push_back(new Item_ident_for_show(field,
-+ table_list->view_db.str,
-+ table_list->view_name.str));
-+ else
-+ field_list.push_back(new Item_field(field));
-+ }
-+ }
-+ restore_record(table, s->default_values); // Get empty record
-+ table->use_all_columns();
-+ if (thd->protocol->send_fields(&field_list, Protocol::SEND_DEFAULTS))
-+ DBUG_VOID_RETURN;
-+ my_eof(thd);
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+int
-+mysqld_dump_create_info(THD *thd, TABLE_LIST *table_list, int fd)
-+{
-+ Protocol *protocol= thd->protocol;
-+ String *packet= protocol->storage_packet();
-+ DBUG_ENTER("mysqld_dump_create_info");
-+ DBUG_PRINT("enter",("table: %s",table_list->table->s->table_name.str));
-+
-+ protocol->prepare_for_resend();
-+ if (store_create_info(thd, table_list, packet, NULL,
-+ FALSE /* show_database */))
-+ DBUG_RETURN(-1);
-+
-+ if (fd < 0)
-+ {
-+ if (protocol->write())
-+ DBUG_RETURN(-1);
-+ protocol->flush();
-+ }
-+ else
-+ {
-+ if (my_write(fd, (const uchar*) packet->ptr(), packet->length(),
-+ MYF(MY_WME)))
-+ DBUG_RETURN(-1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+/*
-+ Go through all character combinations and ensure that sql_lex.cc can
-+ parse it as an identifier.
-+
-+ SYNOPSIS
-+ require_quotes()
-+ name attribute name
-+ name_length length of name
-+
-+ RETURN
-+ # Pointer to conflicting character
-+ 0 No conflicting character
-+*/
-+
-+static const char *require_quotes(const char *name, uint name_length)
-+{
-+ uint length;
-+ bool pure_digit= TRUE;
-+ const char *end= name + name_length;
-+
-+ for (; name < end ; name++)
-+ {
-+ uchar chr= (uchar) *name;
-+ length= my_mbcharlen(system_charset_info, chr);
-+ if (length == 1 && !system_charset_info->ident_map[chr])
-+ return name;
-+ if (length == 1 && (chr < '0' || chr > '9'))
-+ pure_digit= FALSE;
-+ }
-+ if (pure_digit)
-+ return name;
-+ return 0;
-+}
-+
-+
-+/*
-+ Quote the given identifier if needed and append it to the target string.
-+ If the given identifier is empty, it will be quoted.
-+
-+ SYNOPSIS
-+ append_identifier()
-+ thd thread handler
-+ packet target string
-+ name the identifier to be appended
-+ name_length length of the appending identifier
-+*/
-+
-+void
-+append_identifier(THD *thd, String *packet, const char *name, uint length)
-+{
-+ const char *name_end;
-+ char quote_char;
-+ int q= get_quote_char_for_identifier(thd, name, length);
-+
-+ if (q == EOF)
-+ {
-+ packet->append(name, length, packet->charset());
-+ return;
-+ }
-+
-+ /*
-+ The identifier must be quoted as it includes a quote character or
-+ it's a keyword
-+ */
-+
-+ VOID(packet->reserve(length*2 + 2));
-+ quote_char= (char) q;
-+ packet->append("e_char, 1, system_charset_info);
-+
-+ for (name_end= name+length ; name < name_end ; name+= length)
-+ {
-+ uchar chr= (uchar) *name;
-+ length= my_mbcharlen(system_charset_info, chr);
-+ /*
-+ my_mbcharlen can return 0 on a wrong multibyte
-+ sequence. It is possible when upgrading from 4.0,
-+ and identifier contains some accented characters.
-+ The manual says it does not work. So we'll just
-+ change length to 1 not to hang in the endless loop.
-+ */
-+ if (!length)
-+ length= 1;
-+ if (length == 1 && chr == (uchar) quote_char)
-+ packet->append("e_char, 1, system_charset_info);
-+ packet->append(name, length, system_charset_info);
-+ }
-+ packet->append("e_char, 1, system_charset_info);
-+}
-+
-+
-+/*
-+ Get the quote character for displaying an identifier.
-+
-+ SYNOPSIS
-+ get_quote_char_for_identifier()
-+ thd Thread handler
-+ name name to quote
-+ length length of name
-+
-+ IMPLEMENTATION
-+ Force quoting in the following cases:
-+ - name is empty (for one, it is possible when we use this function for
-+ quoting user and host names for DEFINER clause);
-+ - name is a keyword;
-+ - name includes a special character;
-+ Otherwise identifier is quoted only if the option OPTION_QUOTE_SHOW_CREATE
-+ is set.
-+
-+ RETURN
-+ EOF No quote character is needed
-+ # Quote character
-+*/
-+
-+int get_quote_char_for_identifier(THD *thd, const char *name, uint length)
-+{
-+ if (length &&
-+ !is_keyword(name,length) &&
-+ !require_quotes(name, length) &&
-+ !(thd->options & OPTION_QUOTE_SHOW_CREATE))
-+ return EOF;
-+ if (thd->variables.sql_mode & MODE_ANSI_QUOTES)
-+ return '"';
-+ return '`';
-+}
-+
-+
-+/* Append directory name (if exists) to CREATE INFO */
-+
-+static void append_directory(THD *thd, String *packet, const char *dir_type,
-+ const char *filename)
-+{
-+ if (filename && !(thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
-+ {
-+ uint length= dirname_length(filename);
-+ packet->append(' ');
-+ packet->append(dir_type);
-+ packet->append(STRING_WITH_LEN(" DIRECTORY='"));
-+#ifdef __WIN__
-+ /* Convert \ to / to be able to create table on unix */
-+ char *winfilename= (char*) thd->memdup(filename, length);
-+ char *pos, *end;
-+ for (pos= winfilename, end= pos+length ; pos < end ; pos++)
-+ {
-+ if (*pos == '\\')
-+ *pos = '/';
-+ }
-+ filename= winfilename;
-+#endif
-+ packet->append(filename, length);
-+ packet->append('\'');
-+ }
-+}
-+
-+
-+#define LIST_PROCESS_HOST_LEN 64
-+
-+static bool get_field_default_value(THD *thd, TABLE *table,
-+ Field *field, String *def_value,
-+ bool quoted)
-+{
-+ bool has_default;
-+ bool has_now_default;
-+ enum enum_field_types field_type= field->type();
-+ /*
-+ We are using CURRENT_TIMESTAMP instead of NOW because it is
-+ more standard
-+ */
-+ has_now_default= table->timestamp_field == field &&
-+ field->unireg_check != Field::TIMESTAMP_UN_FIELD;
-+
-+ has_default= (field_type != FIELD_TYPE_BLOB &&
-+ !(field->flags & NO_DEFAULT_VALUE_FLAG) &&
-+ field->unireg_check != Field::NEXT_NUMBER &&
-+ !((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
-+ && has_now_default));
-+
-+ def_value->length(0);
-+ if (has_default)
-+ {
-+ if (has_now_default)
-+ def_value->append(STRING_WITH_LEN("CURRENT_TIMESTAMP"));
-+ else if (!field->is_null())
-+ { // Not null by default
-+ char tmp[MAX_FIELD_WIDTH];
-+ String type(tmp, sizeof(tmp), field->charset());
-+ if (field_type == MYSQL_TYPE_BIT)
-+ {
-+ longlong dec= field->val_int();
-+ char *ptr= longlong2str(dec, tmp + 2, 2);
-+ uint32 length= (uint32) (ptr - tmp);
-+ tmp[0]= 'b';
-+ tmp[1]= '\'';
-+ tmp[length]= '\'';
-+ type.length(length + 1);
-+ quoted= 0;
-+ }
-+ else
-+ field->val_str(&type);
-+ if (type.length())
-+ {
-+ String def_val;
-+ uint dummy_errors;
-+ /* convert to system_charset_info == utf8 */
-+ def_val.copy(type.ptr(), type.length(), field->charset(),
-+ system_charset_info, &dummy_errors);
-+ if (quoted)
-+ append_unescaped(def_value, def_val.ptr(), def_val.length());
-+ else
-+ def_value->append(def_val.ptr(), def_val.length());
-+ }
-+ else if (quoted)
-+ def_value->append(STRING_WITH_LEN("''"));
-+ }
-+ else if (field->maybe_null() && quoted)
-+ def_value->append(STRING_WITH_LEN("NULL")); // Null as default
-+ else
-+ return 0;
-+
-+ }
-+ return has_default;
-+}
-+
-+/*
-+ Build a CREATE TABLE statement for a table.
-+
-+ SYNOPSIS
-+ store_create_info()
-+ thd The thread
-+ table_list A list containing one table to write statement
-+ for.
-+ packet Pointer to a string where statement will be
-+ written.
-+ create_info_arg Pointer to create information that can be used
-+ to tailor the format of the statement. Can be
-+ NULL, in which case only SQL_MODE is considered
-+ when building the statement.
-+
-+ NOTE
-+ Currently always return 0, but might return error code in the
-+ future.
-+
-+ RETURN
-+ 0 OK
-+ */
-+
-+int store_create_info(THD *thd, TABLE_LIST *table_list, String *packet,
-+ HA_CREATE_INFO *create_info_arg, bool show_database)
-+{
-+ List<Item> field_list;
-+ char tmp[MAX_FIELD_WIDTH], *for_str, buff[128], def_value_buf[MAX_FIELD_WIDTH];
-+ const char *alias;
-+ String type(tmp, sizeof(tmp), system_charset_info);
-+ String def_value(def_value_buf, sizeof(def_value_buf), system_charset_info);
-+ Field **ptr,*field;
-+ uint primary_key;
-+ KEY *key_info;
-+ TABLE *table= table_list->table;
-+ handler *file= table->file;
-+ TABLE_SHARE *share= table->s;
-+ HA_CREATE_INFO create_info;
-+ bool show_table_options= FALSE;
-+ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
-+ MODE_ORACLE |
-+ MODE_MSSQL |
-+ MODE_DB2 |
-+ MODE_MAXDB |
-+ MODE_ANSI)) != 0;
-+ bool limited_mysql_mode= (thd->variables.sql_mode & (MODE_NO_FIELD_OPTIONS |
-+ MODE_MYSQL323 |
-+ MODE_MYSQL40)) != 0;
-+ my_bitmap_map *old_map;
-+ DBUG_ENTER("store_create_info");
-+ DBUG_PRINT("enter",("table: %s", table->s->table_name.str));
-+
-+ restore_record(table, s->default_values); // Get empty record
-+
-+ if (share->tmp_table)
-+ packet->append(STRING_WITH_LEN("CREATE TEMPORARY TABLE "));
-+ else
-+ packet->append(STRING_WITH_LEN("CREATE TABLE "));
-+ if (create_info_arg &&
-+ (create_info_arg->options & HA_LEX_CREATE_IF_NOT_EXISTS))
-+ packet->append(STRING_WITH_LEN("IF NOT EXISTS "));
-+ if (table_list->schema_table)
-+ alias= table_list->schema_table->table_name;
-+ else
-+ {
-+ if (lower_case_table_names == 2)
-+ alias= table->alias;
-+ else
-+ {
-+ alias= share->table_name.str;
-+ }
-+ }
-+
-+ /*
-+ Print the database before the table name if told to do that. The
-+ database name is only printed in the event that it is different
-+ from the current database. The main reason for doing this is to
-+ avoid having to update gazillions of tests and result files, but
-+ it also saves a few bytes of the binary log.
-+ */
-+ if (show_database)
-+ {
-+ const LEX_STRING *const db=
-+ table_list->schema_table ? &INFORMATION_SCHEMA_NAME : &table->s->db;
-+ if (!thd->db || strcmp(db->str, thd->db))
-+ {
-+ append_identifier(thd, packet, db->str, db->length);
-+ packet->append(STRING_WITH_LEN("."));
-+ }
-+ }
-+
-+ append_identifier(thd, packet, alias, strlen(alias));
-+ packet->append(STRING_WITH_LEN(" (\n"));
-+ /*
-+ We need this to get default values from the table
-+ We have to restore the read_set if we are called from insert in case
-+ of row based replication.
-+ */
-+ old_map= tmp_use_all_columns(table, table->read_set);
-+
-+ for (ptr=table->field ; (field= *ptr); ptr++)
-+ {
-+ uint flags = field->flags;
-+
-+ if (ptr != table->field)
-+ packet->append(STRING_WITH_LEN(",\n"));
-+
-+ packet->append(STRING_WITH_LEN(" "));
-+ append_identifier(thd,packet,field->field_name, strlen(field->field_name));
-+ packet->append(' ');
-+ // check for surprises from the previous call to Field::sql_type()
-+ if (type.ptr() != tmp)
-+ type.set(tmp, sizeof(tmp), system_charset_info);
-+ else
-+ type.set_charset(system_charset_info);
-+
-+ field->sql_type(type);
-+ packet->append(type.ptr(), type.length(), system_charset_info);
-+
-+ if (field->has_charset() &&
-+ !(thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)))
-+ {
-+ if (field->charset() != share->table_charset)
-+ {
-+ packet->append(STRING_WITH_LEN(" CHARACTER SET "));
-+ packet->append(field->charset()->csname);
-+ }
-+ /*
-+ For string types dump collation name only if
-+ collation is not primary for the given charset
-+ */
-+ if (!(field->charset()->state & MY_CS_PRIMARY))
-+ {
-+ packet->append(STRING_WITH_LEN(" COLLATE "));
-+ packet->append(field->charset()->name);
-+ }
-+ }
-+
-+ if (flags & NOT_NULL_FLAG)
-+ packet->append(STRING_WITH_LEN(" NOT NULL"));
-+ else if (field->type() == MYSQL_TYPE_TIMESTAMP)
-+ {
-+ /*
-+ TIMESTAMP field require explicit NULL flag, because unlike
-+ all other fields they are treated as NOT NULL by default.
-+ */
-+ packet->append(STRING_WITH_LEN(" NULL"));
-+ }
-+
-+ if (get_field_default_value(thd, table, field, &def_value, 1))
-+ {
-+ packet->append(STRING_WITH_LEN(" DEFAULT "));
-+ packet->append(def_value.ptr(), def_value.length(), system_charset_info);
-+ }
-+
-+ if (!limited_mysql_mode && table->timestamp_field == field &&
-+ field->unireg_check != Field::TIMESTAMP_DN_FIELD)
-+ packet->append(STRING_WITH_LEN(" ON UPDATE CURRENT_TIMESTAMP"));
-+
-+ if (field->unireg_check == Field::NEXT_NUMBER &&
-+ !(thd->variables.sql_mode & MODE_NO_FIELD_OPTIONS))
-+ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT"));
-+
-+ if (field->comment.length)
-+ {
-+ packet->append(STRING_WITH_LEN(" COMMENT "));
-+ append_unescaped(packet, field->comment.str, field->comment.length);
-+ }
-+ }
-+
-+ key_info= table->key_info;
-+ bzero((char*) &create_info, sizeof(create_info));
-+ /* Allow update_create_info to update row type */
-+ create_info.row_type= share->row_type;
-+ file->update_create_info(&create_info);
-+ primary_key= share->primary_key;
-+
-+ for (uint i=0 ; i < share->keys ; i++,key_info++)
-+ {
-+ KEY_PART_INFO *key_part= key_info->key_part;
-+ bool found_primary=0;
-+ packet->append(STRING_WITH_LEN(",\n "));
-+
-+ if (i == primary_key && !strcmp(key_info->name, primary_key_name))
-+ {
-+ found_primary=1;
-+ /*
-+ No space at end, because a space will be added after where the
-+ identifier would go, but that is not added for primary key.
-+ */
-+ packet->append(STRING_WITH_LEN("PRIMARY KEY"));
-+ }
-+ else if (key_info->flags & HA_NOSAME)
-+ packet->append(STRING_WITH_LEN("UNIQUE KEY "));
-+ else if (key_info->flags & HA_FULLTEXT)
-+ packet->append(STRING_WITH_LEN("FULLTEXT KEY "));
-+ else if (key_info->flags & HA_SPATIAL)
-+ packet->append(STRING_WITH_LEN("SPATIAL KEY "));
-+ else
-+ packet->append(STRING_WITH_LEN("KEY "));
-+
-+ if (!found_primary)
-+ append_identifier(thd, packet, key_info->name, strlen(key_info->name));
-+
-+ packet->append(STRING_WITH_LEN(" ("));
-+
-+ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+ {
-+ if (j)
-+ packet->append(',');
-+
-+ if (key_part->field)
-+ append_identifier(thd,packet,key_part->field->field_name,
-+ strlen(key_part->field->field_name));
-+ if (key_part->field &&
-+ (key_part->length !=
-+ table->field[key_part->fieldnr-1]->key_length() &&
-+ !(key_info->flags & (HA_FULLTEXT | HA_SPATIAL))))
-+ {
-+ char *end;
-+ buff[0] = '(';
-+ end= int10_to_str((long) key_part->length /
-+ key_part->field->charset()->mbmaxlen,
-+ buff + 1,10);
-+ *end++ = ')';
-+ packet->append(buff,(uint) (end-buff));
-+ }
-+ }
-+ packet->append(')');
-+ store_key_options(thd, packet, table, key_info);
-+ if (key_info->parser)
-+ {
-+ LEX_STRING *parser_name= plugin_name(key_info->parser);
-+ packet->append(STRING_WITH_LEN(" /*!50100 WITH PARSER "));
-+ append_identifier(thd, packet, parser_name->str, parser_name->length);
-+ packet->append(STRING_WITH_LEN(" */ "));
-+ }
-+ }
-+
-+ /*
-+ Get possible foreign key definitions stored in InnoDB and append them
-+ to the CREATE TABLE statement
-+ */
-+
-+ if ((for_str= file->get_foreign_key_create_info()))
-+ {
-+ packet->append(for_str, strlen(for_str));
-+ file->free_foreign_key_create_info(for_str);
-+ }
-+
-+ packet->append(STRING_WITH_LEN("\n)"));
-+ if (!(thd->variables.sql_mode & MODE_NO_TABLE_OPTIONS) && !foreign_db_mode)
-+ {
-+ show_table_options= TRUE;
-+ /*
-+ Get possible table space definitions and append them
-+ to the CREATE TABLE statement
-+ */
-+
-+ if ((for_str= file->get_tablespace_name(thd,0,0)))
-+ {
-+ packet->append(STRING_WITH_LEN(" /*!50100 TABLESPACE "));
-+ packet->append(for_str, strlen(for_str));
-+ packet->append(STRING_WITH_LEN(" STORAGE DISK */"));
-+ my_free(for_str, MYF(0));
-+ }
-+
-+ /*
-+ IF check_create_info
-+ THEN add ENGINE only if it was used when creating the table
-+ */
-+ if (!create_info_arg ||
-+ (create_info_arg->used_fields & HA_CREATE_USED_ENGINE))
-+ {
-+ if (thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40))
-+ packet->append(STRING_WITH_LEN(" TYPE="));
-+ else
-+ packet->append(STRING_WITH_LEN(" ENGINE="));
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (table->part_info)
-+ packet->append(ha_resolve_storage_engine_name(
-+ table->part_info->default_engine_type));
-+ else
-+ packet->append(file->table_type());
-+#else
-+ packet->append(file->table_type());
-+#endif
-+ }
-+
-+ /*
-+ Add AUTO_INCREMENT=... if there is an AUTO_INCREMENT column,
-+ and NEXT_ID > 1 (the default). We must not print the clause
-+ for engines that do not support this as it would break the
-+ import of dumps, but as of this writing, the test for whether
-+ AUTO_INCREMENT columns are allowed and wether AUTO_INCREMENT=...
-+ is supported is identical, !(file->table_flags() & HA_NO_AUTO_INCREMENT))
-+ Because of that, we do not explicitly test for the feature,
-+ but may extrapolate its existence from that of an AUTO_INCREMENT column.
-+ */
-+
-+ if (create_info.auto_increment_value > 1)
-+ {
-+ char *end;
-+ packet->append(STRING_WITH_LEN(" AUTO_INCREMENT="));
-+ end= longlong10_to_str(create_info.auto_increment_value, buff,10);
-+ packet->append(buff, (uint) (end - buff));
-+ }
-+
-+
-+ if (share->table_charset &&
-+ !(thd->variables.sql_mode & MODE_MYSQL323) &&
-+ !(thd->variables.sql_mode & MODE_MYSQL40))
-+ {
-+ /*
-+ IF check_create_info
-+ THEN add DEFAULT CHARSET only if it was used when creating the table
-+ */
-+ if (!create_info_arg ||
-+ (create_info_arg->used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
-+ {
-+ packet->append(STRING_WITH_LEN(" DEFAULT CHARSET="));
-+ packet->append(share->table_charset->csname);
-+ if (!(share->table_charset->state & MY_CS_PRIMARY))
-+ {
-+ packet->append(STRING_WITH_LEN(" COLLATE="));
-+ packet->append(table->s->table_charset->name);
-+ }
-+ }
-+ }
-+
-+ if (share->min_rows)
-+ {
-+ char *end;
-+ packet->append(STRING_WITH_LEN(" MIN_ROWS="));
-+ end= longlong10_to_str(share->min_rows, buff, 10);
-+ packet->append(buff, (uint) (end- buff));
-+ }
-+
-+ if (share->max_rows && !table_list->schema_table)
-+ {
-+ char *end;
-+ packet->append(STRING_WITH_LEN(" MAX_ROWS="));
-+ end= longlong10_to_str(share->max_rows, buff, 10);
-+ packet->append(buff, (uint) (end - buff));
-+ }
-+
-+ if (share->avg_row_length)
-+ {
-+ char *end;
-+ packet->append(STRING_WITH_LEN(" AVG_ROW_LENGTH="));
-+ end= longlong10_to_str(share->avg_row_length, buff,10);
-+ packet->append(buff, (uint) (end - buff));
-+ }
-+
-+ if (share->db_create_options & HA_OPTION_PACK_KEYS)
-+ packet->append(STRING_WITH_LEN(" PACK_KEYS=1"));
-+ if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
-+ packet->append(STRING_WITH_LEN(" PACK_KEYS=0"));
-+ /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
-+ if (share->db_create_options & HA_OPTION_CHECKSUM)
-+ packet->append(STRING_WITH_LEN(" CHECKSUM=1"));
-+ if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
-+ packet->append(STRING_WITH_LEN(" DELAY_KEY_WRITE=1"));
-+ if (create_info.row_type != ROW_TYPE_DEFAULT)
-+ {
-+ packet->append(STRING_WITH_LEN(" ROW_FORMAT="));
-+ packet->append(ha_row_type[(uint) create_info.row_type]);
-+ }
-+ if (table->s->key_block_size)
-+ {
-+ char *end;
-+ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
-+ end= longlong10_to_str(table->s->key_block_size, buff, 10);
-+ packet->append(buff, (uint) (end - buff));
-+ }
-+ table->file->append_create_info(packet);
-+ if (share->comment.length)
-+ {
-+ packet->append(STRING_WITH_LEN(" COMMENT="));
-+ append_unescaped(packet, share->comment.str, share->comment.length);
-+ }
-+ if (share->connect_string.length)
-+ {
-+ packet->append(STRING_WITH_LEN(" CONNECTION="));
-+ append_unescaped(packet, share->connect_string.str, share->connect_string.length);
-+ }
-+ append_directory(thd, packet, "DATA", create_info.data_file_name);
-+ append_directory(thd, packet, "INDEX", create_info.index_file_name);
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ {
-+ /*
-+ Partition syntax for CREATE TABLE is at the end of the syntax.
-+ */
-+ uint part_syntax_len;
-+ char *part_syntax;
-+ if (table->part_info &&
-+ (!table->part_info->is_auto_partitioned) &&
-+ ((part_syntax= generate_partition_syntax(table->part_info,
-+ &part_syntax_len,
-+ FALSE,
-+ show_table_options))))
-+ {
-+ packet->append(STRING_WITH_LEN("\n/*!50100"));
-+ packet->append(part_syntax, part_syntax_len);
-+ packet->append(STRING_WITH_LEN(" */"));
-+ my_free(part_syntax, MYF(0));
-+ }
-+ }
-+#endif
-+ tmp_restore_column_map(table->read_set, old_map);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static void store_key_options(THD *thd, String *packet, TABLE *table,
-+ KEY *key_info)
-+{
-+ bool limited_mysql_mode= (thd->variables.sql_mode &
-+ (MODE_NO_FIELD_OPTIONS | MODE_MYSQL323 |
-+ MODE_MYSQL40)) != 0;
-+ bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
-+ MODE_ORACLE |
-+ MODE_MSSQL |
-+ MODE_DB2 |
-+ MODE_MAXDB |
-+ MODE_ANSI)) != 0;
-+ char *end, buff[32];
-+
-+ if (!(thd->variables.sql_mode & MODE_NO_KEY_OPTIONS) &&
-+ !limited_mysql_mode && !foreign_db_mode)
-+ {
-+
-+ if (key_info->algorithm == HA_KEY_ALG_BTREE)
-+ packet->append(STRING_WITH_LEN(" USING BTREE"));
-+
-+ if (key_info->algorithm == HA_KEY_ALG_HASH)
-+ packet->append(STRING_WITH_LEN(" USING HASH"));
-+
-+ /* send USING only in non-default case: non-spatial rtree */
-+ if ((key_info->algorithm == HA_KEY_ALG_RTREE) &&
-+ !(key_info->flags & HA_SPATIAL))
-+ packet->append(STRING_WITH_LEN(" USING RTREE"));
-+
-+ if ((key_info->flags & HA_USES_BLOCK_SIZE) &&
-+ table->s->key_block_size != key_info->block_size)
-+ {
-+ packet->append(STRING_WITH_LEN(" KEY_BLOCK_SIZE="));
-+ end= longlong10_to_str(key_info->block_size, buff, 10);
-+ packet->append(buff, (uint) (end - buff));
-+ }
-+ }
-+}
-+
-+
-+void
-+view_store_options(THD *thd, TABLE_LIST *table, String *buff)
-+{
-+ append_algorithm(table, buff);
-+ append_definer(thd, buff, &table->definer.user, &table->definer.host);
-+ if (table->view_suid)
-+ buff->append(STRING_WITH_LEN("SQL SECURITY DEFINER "));
-+ else
-+ buff->append(STRING_WITH_LEN("SQL SECURITY INVOKER "));
-+}
-+
-+
-+/*
-+ Append DEFINER clause to the given buffer.
-+
-+ SYNOPSIS
-+ append_definer()
-+ thd [in] thread handle
-+ buffer [inout] buffer to hold DEFINER clause
-+ definer_user [in] user name part of definer
-+ definer_host [in] host name part of definer
-+*/
-+
-+static void append_algorithm(TABLE_LIST *table, String *buff)
-+{
-+ buff->append(STRING_WITH_LEN("ALGORITHM="));
-+ switch ((int8)table->algorithm) {
-+ case VIEW_ALGORITHM_UNDEFINED:
-+ buff->append(STRING_WITH_LEN("UNDEFINED "));
-+ break;
-+ case VIEW_ALGORITHM_TMPTABLE:
-+ buff->append(STRING_WITH_LEN("TEMPTABLE "));
-+ break;
-+ case VIEW_ALGORITHM_MERGE:
-+ buff->append(STRING_WITH_LEN("MERGE "));
-+ break;
-+ default:
-+ DBUG_ASSERT(0); // never should happen
-+ }
-+}
-+
-+/*
-+ Append DEFINER clause to the given buffer.
-+
-+ SYNOPSIS
-+ append_definer()
-+ thd [in] thread handle
-+ buffer [inout] buffer to hold DEFINER clause
-+ definer_user [in] user name part of definer
-+ definer_host [in] host name part of definer
-+*/
-+
-+void append_definer(THD *thd, String *buffer, const LEX_STRING *definer_user,
-+ const LEX_STRING *definer_host)
-+{
-+ buffer->append(STRING_WITH_LEN("DEFINER="));
-+ append_identifier(thd, buffer, definer_user->str, definer_user->length);
-+ buffer->append('@');
-+ append_identifier(thd, buffer, definer_host->str, definer_host->length);
-+ buffer->append(' ');
-+}
-+
-+
-+int
-+view_store_create_info(THD *thd, TABLE_LIST *table, String *buff)
-+{
-+ my_bool compact_view_name= TRUE;
-+ my_bool foreign_db_mode= (thd->variables.sql_mode & (MODE_POSTGRESQL |
-+ MODE_ORACLE |
-+ MODE_MSSQL |
-+ MODE_DB2 |
-+ MODE_MAXDB |
-+ MODE_ANSI)) != 0;
-+
-+ if (!thd->db || strcmp(thd->db, table->view_db.str))
-+ /*
-+ print compact view name if the view belongs to the current database
-+ */
-+ compact_view_name= table->compact_view_format= FALSE;
-+ else
-+ {
-+ /*
-+ Compact output format for view body can be used
-+ if this view only references table inside it's own db
-+ */
-+ TABLE_LIST *tbl;
-+ table->compact_view_format= TRUE;
-+ for (tbl= thd->lex->query_tables;
-+ tbl;
-+ tbl= tbl->next_global)
-+ {
-+ if (strcmp(table->view_db.str, tbl->view ? tbl->view_db.str :tbl->db)!= 0)
-+ {
-+ table->compact_view_format= FALSE;
-+ break;
-+ }
-+ }
-+ }
-+
-+ buff->append(STRING_WITH_LEN("CREATE "));
-+ if (!foreign_db_mode)
-+ {
-+ view_store_options(thd, table, buff);
-+ }
-+ buff->append(STRING_WITH_LEN("VIEW "));
-+ if (!compact_view_name)
-+ {
-+ append_identifier(thd, buff, table->view_db.str, table->view_db.length);
-+ buff->append('.');
-+ }
-+ append_identifier(thd, buff, table->view_name.str, table->view_name.length);
-+ buff->append(STRING_WITH_LEN(" AS "));
-+
-+ /*
-+ We can't just use table->query, because our SQL_MODE may trigger
-+ a different syntax, like when ANSI_QUOTES is defined.
-+ */
-+ table->view->unit.print(buff, QT_ORDINARY);
-+
-+ if (table->with_check != VIEW_CHECK_NONE)
-+ {
-+ if (table->with_check == VIEW_CHECK_LOCAL)
-+ buff->append(STRING_WITH_LEN(" WITH LOCAL CHECK OPTION"));
-+ else
-+ buff->append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
-+ }
-+ return 0;
-+}
-+
-+
-+/****************************************************************************
-+ Return info about all processes
-+ returns for each thread: thread id, user, host, db, command, info
-+****************************************************************************/
-+
-+class thread_info :public ilink {
-+public:
-+ static void *operator new(size_t size)
-+ {
-+ return (void*) sql_alloc((uint) size);
-+ }
-+ static void operator delete(void *ptr __attribute__((unused)),
-+ size_t size __attribute__((unused)))
-+ { TRASH(ptr, size); }
-+
-+ ulong thread_id;
-+ time_t start_time;
-+ uint command;
-+ const char *user,*host,*db,*proc_info,*state_info;
-+ char *query;
-+};
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class I_List<thread_info>;
-+#endif
-+
-+void mysqld_list_processes(THD *thd,const char *user, bool verbose)
-+{
-+ Item *field;
-+ List<Item> field_list;
-+ I_List<thread_info> thread_infos;
-+ ulong max_query_length= (verbose ? thd->variables.max_allowed_packet :
-+ PROCESS_LIST_WIDTH);
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysqld_list_processes");
-+
-+ field_list.push_back(new Item_int("Id", 0, MY_INT32_NUM_DECIMAL_DIGITS));
-+ field_list.push_back(new Item_empty_string("User",16));
-+ field_list.push_back(new Item_empty_string("Host",LIST_PROCESS_HOST_LEN));
-+ field_list.push_back(field=new Item_empty_string("db",NAME_CHAR_LEN));
-+ field->maybe_null=1;
-+ field_list.push_back(new Item_empty_string("Command",16));
-+ field_list.push_back(field= new Item_return_int("Time",7, MYSQL_TYPE_LONG));
-+ field->unsigned_flag= 0;
-+ field_list.push_back(field=new Item_empty_string("State",30));
-+ field->maybe_null=1;
-+ field_list.push_back(field=new Item_empty_string("Info",max_query_length));
-+ field->maybe_null=1;
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_VOID_RETURN;
-+
-+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+ if (!thd->killed)
-+ {
-+ I_List_iterator<THD> it(threads);
-+ THD *tmp;
-+ while ((tmp=it++))
-+ {
-+ Security_context *tmp_sctx= tmp->security_ctx;
-+ struct st_my_thread_var *mysys_var;
-+ if ((tmp->vio_ok() || tmp->system_thread) &&
-+ (!user || (tmp_sctx->user && !strcmp(tmp_sctx->user, user))))
-+ {
-+ thread_info *thd_info= new thread_info;
-+
-+ thd_info->thread_id=tmp->thread_id;
-+ thd_info->user= thd->strdup(tmp_sctx->user ? tmp_sctx->user :
-+ (tmp->system_thread ?
-+ "system user" : "unauthenticated user"));
-+ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
-+ thd->security_ctx->host_or_ip[0])
-+ {
-+ if ((thd_info->host= (char*) thd->alloc(LIST_PROCESS_HOST_LEN+1)))
-+ my_snprintf((char *) thd_info->host, LIST_PROCESS_HOST_LEN,
-+ "%s:%u", tmp_sctx->host_or_ip, tmp->peer_port);
-+ }
-+ else
-+ thd_info->host= thd->strdup(tmp_sctx->host_or_ip[0] ?
-+ tmp_sctx->host_or_ip :
-+ tmp_sctx->host ? tmp_sctx->host : "");
-+ if ((thd_info->db=tmp->db)) // Safe test
-+ thd_info->db=thd->strdup(thd_info->db);
-+ thd_info->command=(int) tmp->command;
-+ if ((mysys_var= tmp->mysys_var))
-+ pthread_mutex_lock(&mysys_var->mutex);
-+ thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0);
-+#ifndef EMBEDDED_LIBRARY
-+ thd_info->state_info= (char*) (tmp->locked ? "Locked" :
-+ tmp->net.reading_or_writing ?
-+ (tmp->net.reading_or_writing == 2 ?
-+ "Writing to net" :
-+ thd_info->command == COM_SLEEP ? "" :
-+ "Reading from net") :
-+ tmp->proc_info ? tmp->proc_info :
-+ tmp->mysys_var &&
-+ tmp->mysys_var->current_cond ?
-+ "Waiting on cond" : NullS);
-+#else
-+ thd_info->state_info= (char*)"Writing to net";
-+#endif
-+ if (mysys_var)
-+ pthread_mutex_unlock(&mysys_var->mutex);
-+
-+ thd_info->start_time= tmp->start_time;
-+ thd_info->query=0;
-+ /* Lock THD mutex that protects its data when looking at it. */
-+ pthread_mutex_lock(&tmp->LOCK_thd_data);
-+ if (tmp->query())
-+ {
-+ uint length= min(max_query_length, tmp->query_length());
-+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
-+ }
-+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
-+ thread_infos.append(thd_info);
-+ }
-+ }
-+ }
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+
-+ thread_info *thd_info;
-+ time_t now= my_time(0);
-+ while ((thd_info=thread_infos.get()))
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store((ulonglong) thd_info->thread_id);
-+ protocol->store(thd_info->user, system_charset_info);
-+ protocol->store(thd_info->host, system_charset_info);
-+ protocol->store(thd_info->db, system_charset_info);
-+ if (thd_info->proc_info)
-+ protocol->store(thd_info->proc_info, system_charset_info);
-+ else
-+ protocol->store(command_name[thd_info->command].str, system_charset_info);
-+ if (thd_info->start_time)
-+ protocol->store_long ((longlong) (now - thd_info->start_time));
-+ else
-+ protocol->store_null();
-+ protocol->store(thd_info->state_info, system_charset_info);
-+ protocol->store(thd_info->query, system_charset_info);
-+ if (protocol->write())
-+ break; /* purecov: inspected */
-+ }
-+ my_eof(thd);
-+ DBUG_VOID_RETURN;
-+}
-+
-+int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond)
-+{
-+ TABLE *table= tables->table;
-+ CHARSET_INFO *cs= system_charset_info;
-+ char *user;
-+ time_t now= my_time(0);
-+ DBUG_ENTER("fill_process_list");
-+
-+ user= thd->security_ctx->master_access & PROCESS_ACL ?
-+ NullS : thd->security_ctx->priv_user;
-+
-+ VOID(pthread_mutex_lock(&LOCK_thread_count));
-+
-+ if (!thd->killed)
-+ {
-+ I_List_iterator<THD> it(threads);
-+ THD* tmp;
-+
-+ while ((tmp= it++))
-+ {
-+ Security_context *tmp_sctx= tmp->security_ctx;
-+ struct st_my_thread_var *mysys_var;
-+ const char *val;
-+
-+ if ((!tmp->vio_ok() && !tmp->system_thread) ||
-+ (user && (!tmp_sctx->user || strcmp(tmp_sctx->user, user))))
-+ continue;
-+
-+ restore_record(table, s->default_values);
-+ /* ID */
-+ table->field[0]->store((longlong) tmp->thread_id, TRUE);
-+ /* USER */
-+ val= tmp_sctx->user ? tmp_sctx->user :
-+ (tmp->system_thread ? "system user" : "unauthenticated user");
-+ table->field[1]->store(val, strlen(val), cs);
-+ /* HOST */
-+ if (tmp->peer_port && (tmp_sctx->host || tmp_sctx->ip) &&
-+ thd->security_ctx->host_or_ip[0])
-+ {
-+ char host[LIST_PROCESS_HOST_LEN + 1];
-+ my_snprintf(host, LIST_PROCESS_HOST_LEN, "%s:%u",
-+ tmp_sctx->host_or_ip, tmp->peer_port);
-+ table->field[2]->store(host, strlen(host), cs);
-+ }
-+ else
-+ table->field[2]->store(tmp_sctx->host_or_ip,
-+ strlen(tmp_sctx->host_or_ip), cs);
-+ /* DB */
-+ if (tmp->db)
-+ {
-+ table->field[3]->store(tmp->db, strlen(tmp->db), cs);
-+ table->field[3]->set_notnull();
-+ }
-+
-+ if ((mysys_var= tmp->mysys_var))
-+ pthread_mutex_lock(&mysys_var->mutex);
-+ /* COMMAND */
-+ if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0)))
-+ table->field[4]->store(val, strlen(val), cs);
-+ else
-+ table->field[4]->store(command_name[tmp->command].str,
-+ command_name[tmp->command].length, cs);
-+ /* MYSQL_TIME */
-+ table->field[5]->store((longlong)(tmp->start_time ?
-+ now - tmp->start_time : 0), FALSE);
-+ /* STATE */
-+#ifndef EMBEDDED_LIBRARY
-+ val= (char*) (tmp->locked ? "Locked" :
-+ tmp->net.reading_or_writing ?
-+ (tmp->net.reading_or_writing == 2 ?
-+ "Writing to net" :
-+ tmp->command == COM_SLEEP ? "" :
-+ "Reading from net") :
-+ tmp->proc_info ? tmp->proc_info :
-+ tmp->mysys_var &&
-+ tmp->mysys_var->current_cond ?
-+ "Waiting on cond" : NullS);
-+#else
-+ val= (char *) (tmp->proc_info ? tmp->proc_info : NullS);
-+#endif
-+ if (val)
-+ {
-+ table->field[6]->store(val, strlen(val), cs);
-+ table->field[6]->set_notnull();
-+ }
-+
-+ if (mysys_var)
-+ pthread_mutex_unlock(&mysys_var->mutex);
-+
-+ /* INFO */
-+ /* Lock THD mutex that protects its data when looking at it. */
-+ pthread_mutex_lock(&tmp->LOCK_thd_data);
-+ if (tmp->query())
-+ {
-+ table->field[7]->store(tmp->query(),
-+ min(PROCESS_LIST_INFO_WIDTH,
-+ tmp->query_length()), cs);
-+ table->field[7]->set_notnull();
-+ }
-+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
-+
-+ if (schema_table_store_record(thd, table))
-+ {
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ }
-+
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ DBUG_RETURN(0);
-+}
-+
-+/*****************************************************************************
-+ Status functions
-+*****************************************************************************/
-+
-+static DYNAMIC_ARRAY all_status_vars;
-+static bool status_vars_inited= 0;
-+static int show_var_cmp(const void *var1, const void *var2)
-+{
-+ return strcmp(((SHOW_VAR*)var1)->name, ((SHOW_VAR*)var2)->name);
-+}
-+
-+/*
-+ deletes all the SHOW_UNDEF elements from the array and calls
-+ delete_dynamic() if it's completely empty.
-+*/
-+static void shrink_var_array(DYNAMIC_ARRAY *array)
-+{
-+ uint a,b;
-+ SHOW_VAR *all= dynamic_element(array, 0, SHOW_VAR *);
-+
-+ for (a= b= 0; b < array->elements; b++)
-+ if (all[b].type != SHOW_UNDEF)
-+ all[a++]= all[b];
-+ if (a)
-+ {
-+ bzero(all+a, sizeof(SHOW_VAR)); // writing NULL-element to the end
-+ array->elements= a;
-+ }
-+ else // array is completely empty - delete it
-+ delete_dynamic(array);
-+}
-+
-+/*
-+ Adds an array of SHOW_VAR entries to the output of SHOW STATUS
-+
-+ SYNOPSIS
-+ add_status_vars(SHOW_VAR *list)
-+ list - an array of SHOW_VAR entries to add to all_status_vars
-+ the last entry must be {0,0,SHOW_UNDEF}
-+
-+ NOTE
-+ The handling of all_status_vars[] is completely internal, it's allocated
-+ automatically when something is added to it, and deleted completely when
-+ the last entry is removed.
-+
-+ As a special optimization, if add_status_vars() is called before
-+ init_status_vars(), it assumes "startup mode" - neither concurrent access
-+ to the array nor SHOW STATUS are possible (thus it skips locks and qsort)
-+
-+ The last entry of the all_status_vars[] should always be {0,0,SHOW_UNDEF}
-+*/
-+int add_status_vars(SHOW_VAR *list)
-+{
-+ int res= 0;
-+ if (status_vars_inited)
-+ pthread_mutex_lock(&LOCK_status);
-+ if (!all_status_vars.buffer && // array is not allocated yet - do it now
-+ my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20))
-+ {
-+ res= 1;
-+ goto err;
-+ }
-+ while (list->name)
-+ res|= insert_dynamic(&all_status_vars, (uchar*)list++);
-+ res|= insert_dynamic(&all_status_vars, (uchar*)list); // appending NULL-element
-+ all_status_vars.elements--; // but next insert_dynamic should overwite it
-+ if (status_vars_inited)
-+ sort_dynamic(&all_status_vars, show_var_cmp);
-+err:
-+ if (status_vars_inited)
-+ pthread_mutex_unlock(&LOCK_status);
-+ return res;
-+}
-+
-+/*
-+ Make all_status_vars[] usable for SHOW STATUS
-+
-+ NOTE
-+ See add_status_vars(). Before init_status_vars() call, add_status_vars()
-+ works in a special fast "startup" mode. Thus init_status_vars()
-+ should be called as late as possible but before enabling multi-threading.
-+*/
-+void init_status_vars()
-+{
-+ status_vars_inited=1;
-+ sort_dynamic(&all_status_vars, show_var_cmp);
-+}
-+
-+void reset_status_vars()
-+{
-+ SHOW_VAR *ptr= (SHOW_VAR*) all_status_vars.buffer;
-+ SHOW_VAR *last= ptr + all_status_vars.elements;
-+ for (; ptr < last; ptr++)
-+ {
-+ /* Note that SHOW_LONG_NOFLUSH variables are not reset */
-+ if (ptr->type == SHOW_LONG)
-+ *(ulong*) ptr->value= 0;
-+ }
-+}
-+
-+/*
-+ catch-all cleanup function, cleans up everything no matter what
-+
-+ DESCRIPTION
-+ This function is not strictly required if all add_to_status/
-+ remove_status_vars are properly paired, but it's a safety measure that
-+ deletes everything from the all_status_vars[] even if some
-+ remove_status_vars were forgotten
-+*/
-+void free_status_vars()
-+{
-+ delete_dynamic(&all_status_vars);
-+}
-+
-+/*
-+ Removes an array of SHOW_VAR entries from the output of SHOW STATUS
-+
-+ SYNOPSIS
-+ remove_status_vars(SHOW_VAR *list)
-+ list - an array of SHOW_VAR entries to remove to all_status_vars
-+ the last entry must be {0,0,SHOW_UNDEF}
-+
-+ NOTE
-+ there's lots of room for optimizing this, especially in non-sorted mode,
-+ but nobody cares - it may be called only in case of failed plugin
-+ initialization in the mysqld startup.
-+*/
-+
-+void remove_status_vars(SHOW_VAR *list)
-+{
-+ if (status_vars_inited)
-+ {
-+ pthread_mutex_lock(&LOCK_status);
-+ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
-+ int a= 0, b= all_status_vars.elements, c= (a+b)/2;
-+
-+ for (; list->name; list++)
-+ {
-+ int res= 0;
-+ for (a= 0, b= all_status_vars.elements; b-a > 1; c= (a+b)/2)
-+ {
-+ res= show_var_cmp(list, all+c);
-+ if (res < 0)
-+ b= c;
-+ else if (res > 0)
-+ a= c;
-+ else
-+ break;
-+ }
-+ if (res == 0)
-+ all[c].type= SHOW_UNDEF;
-+ }
-+ shrink_var_array(&all_status_vars);
-+ pthread_mutex_unlock(&LOCK_status);
-+ }
-+ else
-+ {
-+ SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *);
-+ uint i;
-+ for (; list->name; list++)
-+ {
-+ for (i= 0; i < all_status_vars.elements; i++)
-+ {
-+ if (show_var_cmp(list, all+i))
-+ continue;
-+ all[i].type= SHOW_UNDEF;
-+ break;
-+ }
-+ }
-+ shrink_var_array(&all_status_vars);
-+ }
-+}
-+
-+inline void make_upper(char *buf)
-+{
-+ for (; *buf; buf++)
-+ *buf= my_toupper(system_charset_info, *buf);
-+}
-+
-+static bool show_status_array(THD *thd, const char *wild,
-+ SHOW_VAR *variables,
-+ enum enum_var_type value_type,
-+ struct system_status_var *status_var,
-+ const char *prefix, TABLE *table,
-+ bool ucase_names,
-+ COND *cond)
-+{
-+ my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer;
-+ char * const buff= buffer.data;
-+ char *prefix_end;
-+ /* the variable name should not be longer than 64 characters */
-+ char name_buffer[64];
-+ int len;
-+ LEX_STRING null_lex_str;
-+ SHOW_VAR tmp, *var;
-+ COND *partial_cond= 0;
-+ enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
-+ bool res= FALSE;
-+ CHARSET_INFO *charset= system_charset_info;
-+ DBUG_ENTER("show_status_array");
-+
-+ thd->count_cuted_fields= CHECK_FIELD_WARN;
-+ null_lex_str.str= 0; // For sys_var->value_ptr()
-+ null_lex_str.length= 0;
-+
-+ prefix_end=strnmov(name_buffer, prefix, sizeof(name_buffer)-1);
-+ if (*prefix)
-+ *prefix_end++= '_';
-+ len=name_buffer + sizeof(name_buffer) - prefix_end;
-+ partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list);
-+
-+ for (; variables->name; variables++)
-+ {
-+ strnmov(prefix_end, variables->name, len);
-+ name_buffer[sizeof(name_buffer)-1]=0; /* Safety */
-+ if (ucase_names)
-+ make_upper(name_buffer);
-+
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(name_buffer, strlen(name_buffer),
-+ system_charset_info);
-+ /*
-+ if var->type is SHOW_FUNC, call the function.
-+ Repeat as necessary, if new var is again SHOW_FUNC
-+ */
-+ for (var=variables; var->type == SHOW_FUNC; var= &tmp)
-+ ((mysql_show_var_func)(var->value))(thd, &tmp, buff);
-+
-+ SHOW_TYPE show_type=var->type;
-+ if (show_type == SHOW_ARRAY)
-+ {
-+ show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
-+ status_var, name_buffer, table, ucase_names, partial_cond);
-+ }
-+ else
-+ {
-+ if (!(wild && wild[0] && wild_case_compare(system_charset_info,
-+ name_buffer, wild)) &&
-+ (!partial_cond || partial_cond->val_int()))
-+ {
-+ char *value=var->value;
-+ const char *pos, *end; // We assign a lot of const's
-+
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+
-+ if (show_type == SHOW_SYS)
-+ {
-+ sys_var *var= ((sys_var *) value);
-+ show_type= var->show_type();
-+ value= (char*) var->value_ptr(thd, value_type, &null_lex_str);
-+ charset= var->charset(thd);
-+ }
-+
-+ pos= end= buff;
-+ /*
-+ note that value may be == buff. All SHOW_xxx code below
-+ should still work in this case
-+ */
-+ switch (show_type) {
-+ case SHOW_DOUBLE_STATUS:
-+ value= ((char *) status_var + (ulong) value);
-+ /* fall through */
-+ case SHOW_DOUBLE:
-+ end= buff + sprintf(buff, "%f", *(double*) value);
-+ break;
-+ case SHOW_LONG_STATUS:
-+ value= ((char *) status_var + (ulong) value);
-+ /* fall through */
-+ case SHOW_LONG:
-+ case SHOW_LONG_NOFLUSH: // the difference lies in refresh_status()
-+ end= int10_to_str(*(long*) value, buff, 10);
-+ break;
-+ case SHOW_LONGLONG_STATUS:
-+ value= ((char *) status_var + (ulonglong) value);
-+ /* fall through */
-+ case SHOW_LONGLONG:
-+ end= longlong10_to_str(*(longlong*) value, buff, 10);
-+ break;
-+ case SHOW_HA_ROWS:
-+ end= longlong10_to_str((longlong) *(ha_rows*) value, buff, 10);
-+ break;
-+ case SHOW_BOOL:
-+ end= strmov(buff, *(bool*) value ? "ON" : "OFF");
-+ break;
-+ case SHOW_MY_BOOL:
-+ end= strmov(buff, *(my_bool*) value ? "ON" : "OFF");
-+ break;
-+ case SHOW_INT:
-+ end= int10_to_str((long) *(uint32*) value, buff, 10);
-+ break;
-+ case SHOW_HAVE:
-+ {
-+ SHOW_COMP_OPTION tmp= *(SHOW_COMP_OPTION*) value;
-+ pos= show_comp_option_name[(int) tmp];
-+ end= strend(pos);
-+ break;
-+ }
-+ case SHOW_CHAR:
-+ {
-+ if (!(pos= value))
-+ pos= "";
-+ end= strend(pos);
-+ break;
-+ }
-+ case SHOW_CHAR_PTR:
-+ {
-+ if (!(pos= *(char**) value))
-+ pos= "";
-+ end= strend(pos);
-+ break;
-+ }
-+ case SHOW_KEY_CACHE_LONG:
-+ value= (char*) dflt_key_cache + (ulong)value;
-+ end= int10_to_str(*(long*) value, buff, 10);
-+ break;
-+ case SHOW_KEY_CACHE_LONGLONG:
-+ value= (char*) dflt_key_cache + (ulong)value;
-+ end= longlong10_to_str(*(longlong*) value, buff, 10);
-+ break;
-+ case SHOW_UNDEF:
-+ break; // Return empty string
-+ case SHOW_SYS: // Cannot happen
-+ default:
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ table->field[1]->store(pos, (uint32) (end - pos), charset);
-+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-+ table->field[1]->set_notnull();
-+
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+
-+ if (schema_table_store_record(thd, table))
-+ {
-+ res= TRUE;
-+ goto end;
-+ }
-+ }
-+ }
-+ }
-+end:
-+ thd->count_cuted_fields= save_count_cuted_fields;
-+ DBUG_RETURN(res);
-+}
-+
-+
-+/* collect status for all running threads */
-+
-+void calc_sum_of_all_status(STATUS_VAR *to)
-+{
-+ DBUG_ENTER("calc_sum_of_all_status");
-+
-+ /* Ensure that thread id not killed during loop */
-+ VOID(pthread_mutex_lock(&LOCK_thread_count)); // For unlink from list
-+
-+ I_List_iterator<THD> it(threads);
-+ THD *tmp;
-+
-+ /* Get global values as base */
-+ *to= global_status_var;
-+
-+ /* Add to this status from existing threads */
-+ while ((tmp= it++))
-+ add_to_status(to, &tmp->status_var);
-+
-+ VOID(pthread_mutex_unlock(&LOCK_thread_count));
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/* This is only used internally, but we need it here as a forward reference */
-+extern ST_SCHEMA_TABLE schema_tables[];
-+
-+typedef struct st_lookup_field_values
-+{
-+ LEX_STRING db_value, table_value;
-+ bool wild_db_value, wild_table_value;
-+} LOOKUP_FIELD_VALUES;
-+
-+
-+/*
-+ Store record to I_S table, convert HEAP table
-+ to MyISAM if necessary
-+
-+ SYNOPSIS
-+ schema_table_store_record()
-+ thd thread handler
-+ table Information schema table to be updated
-+
-+ RETURN
-+ 0 success
-+ 1 error
-+*/
-+
-+bool schema_table_store_record(THD *thd, TABLE *table)
-+{
-+ int error;
-+ if ((error= table->file->ha_write_row(table->record[0])))
-+ {
-+ if (create_myisam_from_heap(thd, table,
-+ table->pos_in_table_list->schema_table_param,
-+ error, 0))
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+int make_table_list(THD *thd, SELECT_LEX *sel,
-+ LEX_STRING *db_name, LEX_STRING *table_name)
-+{
-+ Table_ident *table_ident;
-+ table_ident= new Table_ident(thd, *db_name, *table_name, 1);
-+ sel->init_query();
-+ if (!sel->add_table_to_list(thd, table_ident, 0, 0, TL_READ))
-+ return 1;
-+ return 0;
-+}
-+
-+
-+/**
-+ @brief Get lookup value from the part of 'WHERE' condition
-+
-+ @details This function gets lookup value from
-+ the part of 'WHERE' condition if it's possible and
-+ fill appropriate lookup_field_vals struct field
-+ with this value.
-+
-+ @param[in] thd thread handler
-+ @param[in] item_func part of WHERE condition
-+ @param[in] table I_S table
-+ @param[in, out] lookup_field_vals Struct which holds lookup values
-+
-+ @return
-+ 0 success
-+ 1 error, there can be no matching records for the condition
-+*/
-+
-+bool get_lookup_value(THD *thd, Item_func *item_func,
-+ TABLE_LIST *table,
-+ LOOKUP_FIELD_VALUES *lookup_field_vals)
-+{
-+ ST_SCHEMA_TABLE *schema_table= table->schema_table;
-+ ST_FIELD_INFO *field_info= schema_table->fields_info;
-+ const char *field_name1= schema_table->idx_field1 >= 0 ?
-+ field_info[schema_table->idx_field1].field_name : "";
-+ const char *field_name2= schema_table->idx_field2 >= 0 ?
-+ field_info[schema_table->idx_field2].field_name : "";
-+
-+ if (item_func->functype() == Item_func::EQ_FUNC ||
-+ item_func->functype() == Item_func::EQUAL_FUNC)
-+ {
-+ int idx_field, idx_val;
-+ char tmp[MAX_FIELD_WIDTH];
-+ String *tmp_str, str_buff(tmp, sizeof(tmp), system_charset_info);
-+ Item_field *item_field;
-+ CHARSET_INFO *cs= system_charset_info;
-+
-+ if (item_func->arguments()[0]->type() == Item::FIELD_ITEM &&
-+ item_func->arguments()[1]->const_item())
-+ {
-+ idx_field= 0;
-+ idx_val= 1;
-+ }
-+ else if (item_func->arguments()[1]->type() == Item::FIELD_ITEM &&
-+ item_func->arguments()[0]->const_item())
-+ {
-+ idx_field= 1;
-+ idx_val= 0;
-+ }
-+ else
-+ return 0;
-+
-+ item_field= (Item_field*) item_func->arguments()[idx_field];
-+ if (table->table != item_field->field->table)
-+ return 0;
-+ tmp_str= item_func->arguments()[idx_val]->val_str(&str_buff);
-+
-+ /* impossible value */
-+ if (!tmp_str)
-+ return 1;
-+
-+ /* Lookup value is database name */
-+ if (!cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
-+ (uchar *) item_field->field_name,
-+ strlen(item_field->field_name), 0))
-+ {
-+ thd->make_lex_string(&lookup_field_vals->db_value, tmp_str->ptr(),
-+ tmp_str->length(), FALSE);
-+ }
-+ /* Lookup value is table name */
-+ else if (!cs->coll->strnncollsp(cs, (uchar *) field_name2,
-+ strlen(field_name2),
-+ (uchar *) item_field->field_name,
-+ strlen(item_field->field_name), 0))
-+ {
-+ thd->make_lex_string(&lookup_field_vals->table_value, tmp_str->ptr(),
-+ tmp_str->length(), FALSE);
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ @brief Calculates lookup values from 'WHERE' condition
-+
-+ @details This function calculates lookup value(database name, table name)
-+ from 'WHERE' condition if it's possible and
-+ fill lookup_field_vals struct fields with these values.
-+
-+ @param[in] thd thread handler
-+ @param[in] cond WHERE condition
-+ @param[in] table I_S table
-+ @param[in, out] lookup_field_vals Struct which holds lookup values
-+
-+ @return
-+ 0 success
-+ 1 error, there can be no matching records for the condition
-+*/
-+
-+bool calc_lookup_values_from_cond(THD *thd, COND *cond, TABLE_LIST *table,
-+ LOOKUP_FIELD_VALUES *lookup_field_vals)
-+{
-+ if (!cond)
-+ return 0;
-+
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ {
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item= li++))
-+ {
-+ if (item->type() == Item::FUNC_ITEM)
-+ {
-+ if (get_lookup_value(thd, (Item_func*)item, table, lookup_field_vals))
-+ return 1;
-+ }
-+ else
-+ {
-+ if (calc_lookup_values_from_cond(thd, item, table, lookup_field_vals))
-+ return 1;
-+ }
-+ }
-+ }
-+ return 0;
-+ }
-+ else if (cond->type() == Item::FUNC_ITEM &&
-+ get_lookup_value(thd, (Item_func*) cond, table, lookup_field_vals))
-+ return 1;
-+ return 0;
-+}
-+
-+
-+bool uses_only_table_name_fields(Item *item, TABLE_LIST *table)
-+{
-+ if (item->type() == Item::FUNC_ITEM)
-+ {
-+ Item_func *item_func= (Item_func*)item;
-+ for (uint i=0; i<item_func->argument_count(); i++)
-+ {
-+ if (!uses_only_table_name_fields(item_func->arguments()[i], table))
-+ return 0;
-+ }
-+ }
-+ else if (item->type() == Item::FIELD_ITEM)
-+ {
-+ Item_field *item_field= (Item_field*)item;
-+ CHARSET_INFO *cs= system_charset_info;
-+ ST_SCHEMA_TABLE *schema_table= table->schema_table;
-+ ST_FIELD_INFO *field_info= schema_table->fields_info;
-+ const char *field_name1= schema_table->idx_field1 >= 0 ?
-+ field_info[schema_table->idx_field1].field_name : "";
-+ const char *field_name2= schema_table->idx_field2 >= 0 ?
-+ field_info[schema_table->idx_field2].field_name : "";
-+ if (table->table != item_field->field->table ||
-+ (cs->coll->strnncollsp(cs, (uchar *) field_name1, strlen(field_name1),
-+ (uchar *) item_field->field_name,
-+ strlen(item_field->field_name), 0) &&
-+ cs->coll->strnncollsp(cs, (uchar *) field_name2, strlen(field_name2),
-+ (uchar *) item_field->field_name,
-+ strlen(item_field->field_name), 0)))
-+ return 0;
-+ }
-+ else if (item->type() == Item::REF_ITEM)
-+ return uses_only_table_name_fields(item->real_item(), table);
-+
-+ if (item->type() == Item::SUBSELECT_ITEM && !item->const_item())
-+ return 0;
-+
-+ return 1;
-+}
-+
-+
-+static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table)
-+{
-+ if (!cond)
-+ return (COND*) 0;
-+ if (cond->type() == Item::COND_ITEM)
-+ {
-+ if (((Item_cond*) cond)->functype() == Item_func::COND_AND_FUNC)
-+ {
-+ /* Create new top level AND item */
-+ Item_cond_and *new_cond=new Item_cond_and;
-+ if (!new_cond)
-+ return (COND*) 0;
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ Item *fix= make_cond_for_info_schema(item, table);
-+ if (fix)
-+ new_cond->argument_list()->push_back(fix);
-+ }
-+ switch (new_cond->argument_list()->elements) {
-+ case 0:
-+ return (COND*) 0;
-+ case 1:
-+ return new_cond->argument_list()->head();
-+ default:
-+ new_cond->quick_fix_field();
-+ return new_cond;
-+ }
-+ }
-+ else
-+ { // Or list
-+ Item_cond_or *new_cond=new Item_cond_or;
-+ if (!new_cond)
-+ return (COND*) 0;
-+ List_iterator<Item> li(*((Item_cond*) cond)->argument_list());
-+ Item *item;
-+ while ((item=li++))
-+ {
-+ Item *fix=make_cond_for_info_schema(item, table);
-+ if (!fix)
-+ return (COND*) 0;
-+ new_cond->argument_list()->push_back(fix);
-+ }
-+ new_cond->quick_fix_field();
-+ new_cond->top_level_item();
-+ return new_cond;
-+ }
-+ }
-+
-+ if (!uses_only_table_name_fields(cond, table))
-+ return (COND*) 0;
-+ return cond;
-+}
-+
-+
-+/**
-+ @brief Calculate lookup values(database name, table name)
-+
-+ @details This function calculates lookup values(database name, table name)
-+ from 'WHERE' condition or wild values (for 'SHOW' commands only)
-+ from LEX struct and fill lookup_field_vals struct field
-+ with these values.
-+
-+ @param[in] thd thread handler
-+ @param[in] cond WHERE condition
-+ @param[in] tables I_S table
-+ @param[in, out] lookup_field_values Struct which holds lookup values
-+
-+ @return
-+ 0 success
-+ 1 error, there can be no matching records for the condition
-+*/
-+
-+bool get_lookup_field_values(THD *thd, COND *cond, TABLE_LIST *tables,
-+ LOOKUP_FIELD_VALUES *lookup_field_values)
-+{
-+ LEX *lex= thd->lex;
-+ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-+ bool rc= 0;
-+
-+ bzero((char*) lookup_field_values, sizeof(LOOKUP_FIELD_VALUES));
-+ switch (lex->sql_command) {
-+ case SQLCOM_SHOW_DATABASES:
-+ if (wild)
-+ {
-+ thd->make_lex_string(&lookup_field_values->db_value,
-+ wild, strlen(wild), 0);
-+ lookup_field_values->wild_db_value= 1;
-+ }
-+ break;
-+ case SQLCOM_SHOW_TABLES:
-+ case SQLCOM_SHOW_TABLE_STATUS:
-+ case SQLCOM_SHOW_TRIGGERS:
-+ case SQLCOM_SHOW_EVENTS:
-+ thd->make_lex_string(&lookup_field_values->db_value,
-+ lex->select_lex.db, strlen(lex->select_lex.db), 0);
-+ if (wild)
-+ {
-+ thd->make_lex_string(&lookup_field_values->table_value,
-+ wild, strlen(wild), 0);
-+ lookup_field_values->wild_table_value= 1;
-+ }
-+ break;
-+ default:
-+ /*
-+ The "default" is for queries over I_S.
-+ All previous cases handle SHOW commands.
-+ */
-+ rc= calc_lookup_values_from_cond(thd, cond, tables, lookup_field_values);
-+ break;
-+ }
-+
-+ if (lower_case_table_names && !rc)
-+ {
-+ /*
-+ We can safely do in-place upgrades here since all of the above cases
-+ are allocating a new memory buffer for these strings.
-+ */
-+ if (lookup_field_values->db_value.str && lookup_field_values->db_value.str[0])
-+ my_casedn_str(system_charset_info, lookup_field_values->db_value.str);
-+ if (lookup_field_values->table_value.str &&
-+ lookup_field_values->table_value.str[0])
-+ my_casedn_str(system_charset_info, lookup_field_values->table_value.str);
-+ }
-+
-+ return rc;
-+}
-+
-+
-+enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table)
-+{
-+ return (enum enum_schema_tables) (schema_table - &schema_tables[0]);
-+}
-+
-+
-+/*
-+ Create db names list. Information schema name always is first in list
-+
-+ SYNOPSIS
-+ make_db_list()
-+ thd thread handler
-+ files list of db names
-+ wild wild string
-+ idx_field_vals idx_field_vals->db_name contains db name or
-+ wild string
-+ with_i_schema returns 1 if we added 'IS' name to list
-+ otherwise returns 0
-+
-+ RETURN
-+ zero success
-+ non-zero error
-+*/
-+
-+int make_db_list(THD *thd, List<LEX_STRING> *files,
-+ LOOKUP_FIELD_VALUES *lookup_field_vals,
-+ bool *with_i_schema)
-+{
-+ LEX_STRING *i_s_name_copy= 0;
-+ i_s_name_copy= thd->make_lex_string(i_s_name_copy,
-+ INFORMATION_SCHEMA_NAME.str,
-+ INFORMATION_SCHEMA_NAME.length, TRUE);
-+ *with_i_schema= 0;
-+ if (lookup_field_vals->wild_db_value)
-+ {
-+ /*
-+ This part of code is only for SHOW DATABASES command.
-+ idx_field_vals->db_value can be 0 when we don't use
-+ LIKE clause (see also get_index_field_values() function)
-+ */
-+ if (!lookup_field_vals->db_value.str ||
-+ !wild_case_compare(system_charset_info,
-+ INFORMATION_SCHEMA_NAME.str,
-+ lookup_field_vals->db_value.str))
-+ {
-+ *with_i_schema= 1;
-+ if (files->push_back(i_s_name_copy))
-+ return 1;
-+ }
-+ return (find_files(thd, files, NullS, mysql_data_home,
-+ lookup_field_vals->db_value.str, 1) != FIND_FILES_OK);
-+ }
-+
-+
-+ /*
-+ If we have db lookup vaule we just add it to list and
-+ exit from the function
-+ */
-+ if (lookup_field_vals->db_value.str)
-+ {
-+ if (is_schema_db(lookup_field_vals->db_value.str,
-+ lookup_field_vals->db_value.length))
-+ {
-+ *with_i_schema= 1;
-+ if (files->push_back(i_s_name_copy))
-+ return 1;
-+ return 0;
-+ }
-+ if (files->push_back(&lookup_field_vals->db_value))
-+ return 1;
-+ return 0;
-+ }
-+
-+ /*
-+ Create list of existing databases. It is used in case
-+ of select from information schema table
-+ */
-+ if (files->push_back(i_s_name_copy))
-+ return 1;
-+ *with_i_schema= 1;
-+ return (find_files(thd, files, NullS,
-+ mysql_data_home, NullS, 1) != FIND_FILES_OK);
-+}
-+
-+
-+struct st_add_schema_table
-+{
-+ List<LEX_STRING> *files;
-+ const char *wild;
-+};
-+
-+
-+static my_bool add_schema_table(THD *thd, plugin_ref plugin,
-+ void* p_data)
-+{
-+ LEX_STRING *file_name= 0;
-+ st_add_schema_table *data= (st_add_schema_table *)p_data;
-+ List<LEX_STRING> *file_list= data->files;
-+ const char *wild= data->wild;
-+ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
-+ DBUG_ENTER("add_schema_table");
-+
-+ if (schema_table->hidden)
-+ DBUG_RETURN(0);
-+ if (wild)
-+ {
-+ if (lower_case_table_names)
-+ {
-+ if (wild_case_compare(files_charset_info,
-+ schema_table->table_name,
-+ wild))
-+ DBUG_RETURN(0);
-+ }
-+ else if (wild_compare(schema_table->table_name, wild, 0))
-+ DBUG_RETURN(0);
-+ }
-+
-+ if ((file_name= thd->make_lex_string(file_name, schema_table->table_name,
-+ strlen(schema_table->table_name),
-+ TRUE)) &&
-+ !file_list->push_back(file_name))
-+ DBUG_RETURN(0);
-+ DBUG_RETURN(1);
-+}
-+
-+
-+int schema_tables_add(THD *thd, List<LEX_STRING> *files, const char *wild)
-+{
-+ LEX_STRING *file_name= 0;
-+ ST_SCHEMA_TABLE *tmp_schema_table= schema_tables;
-+ st_add_schema_table add_data;
-+ DBUG_ENTER("schema_tables_add");
-+
-+ for (; tmp_schema_table->table_name; tmp_schema_table++)
-+ {
-+ if (tmp_schema_table->hidden)
-+ continue;
-+ if (wild)
-+ {
-+ if (lower_case_table_names)
-+ {
-+ if (wild_case_compare(files_charset_info,
-+ tmp_schema_table->table_name,
-+ wild))
-+ continue;
-+ }
-+ else if (wild_compare(tmp_schema_table->table_name, wild, 0))
-+ continue;
-+ }
-+ if ((file_name=
-+ thd->make_lex_string(file_name, tmp_schema_table->table_name,
-+ strlen(tmp_schema_table->table_name), TRUE)) &&
-+ !files->push_back(file_name))
-+ continue;
-+ DBUG_RETURN(1);
-+ }
-+
-+ add_data.files= files;
-+ add_data.wild= wild;
-+ if (plugin_foreach(thd, add_schema_table,
-+ MYSQL_INFORMATION_SCHEMA_PLUGIN, &add_data))
-+ DBUG_RETURN(1);
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ @brief Create table names list
-+
-+ @details The function creates the list of table names in
-+ database
-+
-+ @param[in] thd thread handler
-+ @param[in] table_names List of table names in database
-+ @param[in] lex pointer to LEX struct
-+ @param[in] lookup_field_vals pointer to LOOKUP_FIELD_VALUE struct
-+ @param[in] with_i_schema TRUE means that we add I_S tables to list
-+ @param[in] db_name database name
-+
-+ @return Operation status
-+ @retval 0 ok
-+ @retval 1 fatal error
-+ @retval 2 Not fatal error; Safe to ignore this file list
-+*/
-+
-+static int
-+make_table_name_list(THD *thd, List<LEX_STRING> *table_names, LEX *lex,
-+ LOOKUP_FIELD_VALUES *lookup_field_vals,
-+ bool with_i_schema, LEX_STRING *db_name)
-+{
-+ char path[FN_REFLEN + 1];
-+ build_table_filename(path, sizeof(path) - 1, db_name->str, "", "", 0);
-+ if (!lookup_field_vals->wild_table_value &&
-+ lookup_field_vals->table_value.str)
-+ {
-+ if (with_i_schema)
-+ {
-+ LEX_STRING *name;
-+ ST_SCHEMA_TABLE *schema_table=
-+ find_schema_table(thd, lookup_field_vals->table_value.str);
-+ if (schema_table && !schema_table->hidden)
-+ {
-+ if (!(name=
-+ thd->make_lex_string(NULL, schema_table->table_name,
-+ strlen(schema_table->table_name), TRUE)) ||
-+ table_names->push_back(name))
-+ return 1;
-+ }
-+ }
-+ else
-+ {
-+ if (table_names->push_back(&lookup_field_vals->table_value))
-+ return 1;
-+ /*
-+ Check that table is relevant in current transaction.
-+ (used for ndb engine, see ndbcluster_find_files(), ha_ndbcluster.cc)
-+ */
-+ VOID(ha_find_files(thd, db_name->str, path,
-+ lookup_field_vals->table_value.str, 0,
-+ table_names));
-+ }
-+ return 0;
-+ }
-+
-+ /*
-+ This call will add all matching the wildcards (if specified) IS tables
-+ to the list
-+ */
-+ if (with_i_schema)
-+ return (schema_tables_add(thd, table_names,
-+ lookup_field_vals->table_value.str));
-+
-+ find_files_result res= find_files(thd, table_names, db_name->str, path,
-+ lookup_field_vals->table_value.str, 0);
-+ if (res != FIND_FILES_OK)
-+ {
-+ /*
-+ Downgrade errors about problems with database directory to
-+ warnings if this is not a 'SHOW' command. Another thread
-+ may have dropped database, and we may still have a name
-+ for that directory.
-+ */
-+ if (res == FIND_FILES_DIR)
-+ {
-+ if (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND)
-+ return 1;
-+ thd->clear_error();
-+ return 2;
-+ }
-+ return 1;
-+ }
-+ return 0;
-+}
-+
-+
-+/**
-+ @brief Fill I_S table for SHOW COLUMNS|INDEX commands
-+
-+ @param[in] thd thread handler
-+ @param[in] tables TABLE_LIST for I_S table
-+ @param[in] schema_table pointer to I_S structure
-+ @param[in] open_tables_state_backup pointer to Open_tables_state object
-+ which is used to save|restore original
-+ status of variables related to
-+ open tables state
-+
-+ @return Operation status
-+ @retval 0 success
-+ @retval 1 error
-+*/
-+
-+static int
-+fill_schema_show_cols_or_idxs(THD *thd, TABLE_LIST *tables,
-+ ST_SCHEMA_TABLE *schema_table,
-+ Open_tables_state *open_tables_state_backup)
-+{
-+ LEX *lex= thd->lex;
-+ bool res;
-+ LEX_STRING tmp_lex_string, tmp_lex_string1, *db_name, *table_name;
-+ enum_sql_command save_sql_command= lex->sql_command;
-+ TABLE_LIST *show_table_list= tables->schema_select_lex->table_list.first;
-+ TABLE *table= tables->table;
-+ int error= 1;
-+ DBUG_ENTER("fill_schema_show");
-+
-+ lex->all_selects_list= tables->schema_select_lex;
-+ /*
-+ Restore thd->temporary_tables to be able to process
-+ temporary tables(only for 'show index' & 'show columns').
-+ This should be changed when processing of temporary tables for
-+ I_S tables will be done.
-+ */
-+ thd->temporary_tables= open_tables_state_backup->temporary_tables;
-+ /*
-+ Let us set fake sql_command so views won't try to merge
-+ themselves into main statement. If we don't do this,
-+ SELECT * from information_schema.xxxx will cause problems.
-+ SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'
-+ */
-+ lex->sql_command= SQLCOM_SHOW_FIELDS;
-+ res= open_normal_and_derived_tables(thd, show_table_list,
-+ MYSQL_LOCK_IGNORE_FLUSH);
-+ lex->sql_command= save_sql_command;
-+ /*
-+ get_all_tables() returns 1 on failure and 0 on success thus
-+ return only these and not the result code of ::process_table()
-+
-+ We should use show_table_list->alias instead of
-+ show_table_list->table_name because table_name
-+ could be changed during opening of I_S tables. It's safe
-+ to use alias because alias contains original table name
-+ in this case(this part of code is used only for
-+ 'show columns' & 'show statistics' commands).
-+ */
-+ table_name= thd->make_lex_string(&tmp_lex_string1, show_table_list->alias,
-+ strlen(show_table_list->alias), FALSE);
-+ if (!show_table_list->view)
-+ db_name= thd->make_lex_string(&tmp_lex_string, show_table_list->db,
-+ show_table_list->db_length, FALSE);
-+ else
-+ db_name= &show_table_list->view_db;
-+
-+
-+ error= test(schema_table->process_table(thd, show_table_list,
-+ table, res, db_name,
-+ table_name));
-+ thd->temporary_tables= 0;
-+ close_tables_for_reopen(thd, &show_table_list);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/**
-+ @brief Fill I_S table for SHOW TABLE NAMES commands
-+
-+ @param[in] thd thread handler
-+ @param[in] table TABLE struct for I_S table
-+ @param[in] db_name database name
-+ @param[in] table_name table name
-+ @param[in] with_i_schema I_S table if TRUE
-+
-+ @return Operation status
-+ @retval 0 success
-+ @retval 1 error
-+*/
-+
-+static int fill_schema_table_names(THD *thd, TABLE *table,
-+ LEX_STRING *db_name, LEX_STRING *table_name,
-+ bool with_i_schema)
-+{
-+ if (with_i_schema)
-+ {
-+ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"),
-+ system_charset_info);
-+ }
-+ else
-+ {
-+ enum legacy_db_type not_used;
-+ char path[FN_REFLEN + 1];
-+ (void) build_table_filename(path, sizeof(path) - 1, db_name->str,
-+ table_name->str, reg_ext, 0);
-+ switch (mysql_frm_type(thd, path, ¬_used)) {
-+ case FRMTYPE_ERROR:
-+ table->field[3]->store(STRING_WITH_LEN("ERROR"),
-+ system_charset_info);
-+ break;
-+ case FRMTYPE_TABLE:
-+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"),
-+ system_charset_info);
-+ break;
-+ case FRMTYPE_VIEW:
-+ table->field[3]->store(STRING_WITH_LEN("VIEW"),
-+ system_charset_info);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ if (thd->is_error() && thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
-+ {
-+ thd->clear_error();
-+ return 0;
-+ }
-+ }
-+ if (schema_table_store_record(thd, table))
-+ return 1;
-+ return 0;
-+}
-+
-+
-+/**
-+ @brief Get open table method
-+
-+ @details The function calculates the method which will be used
-+ for table opening:
-+ SKIP_OPEN_TABLE - do not open table
-+ OPEN_FRM_ONLY - open FRM file only
-+ OPEN_FULL_TABLE - open FRM, data, index files
-+ @param[in] tables I_S table table_list
-+ @param[in] schema_table I_S table struct
-+ @param[in] schema_table_idx I_S table index
-+
-+ @return return a set of flags
-+ @retval SKIP_OPEN_TABLE | OPEN_FRM_ONLY | OPEN_FULL_TABLE
-+*/
-+
-+uint get_table_open_method(TABLE_LIST *tables,
-+ ST_SCHEMA_TABLE *schema_table,
-+ enum enum_schema_tables schema_table_idx)
-+{
-+ /*
-+ determine which method will be used for table opening
-+ */
-+ if (schema_table->i_s_requested_object & OPTIMIZE_I_S_TABLE)
-+ {
-+ Field **ptr, *field;
-+ int table_open_method= 0, field_indx= 0;
-+ uint star_table_open_method= OPEN_FULL_TABLE;
-+ bool used_star= true; // true if '*' is used in select
-+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
-+ {
-+ star_table_open_method=
-+ min(star_table_open_method,
-+ schema_table->fields_info[field_indx].open_method);
-+ if (bitmap_is_set(tables->table->read_set, field->field_index))
-+ {
-+ used_star= false;
-+ table_open_method|= schema_table->fields_info[field_indx].open_method;
-+ }
-+ field_indx++;
-+ }
-+ if (used_star)
-+ return star_table_open_method;
-+ return table_open_method;
-+ }
-+ /* I_S tables which use get_all_tables but can not be optimized */
-+ return (uint) OPEN_FULL_TABLE;
-+}
-+
-+
-+/**
-+ @brief Fill I_S table with data from FRM file only
-+
-+ @param[in] thd thread handler
-+ @param[in] table TABLE struct for I_S table
-+ @param[in] schema_table I_S table struct
-+ @param[in] db_name database name
-+ @param[in] table_name table name
-+ @param[in] schema_table_idx I_S table index
-+
-+ @return Operation status
-+ @retval 0 Table is processed and we can continue
-+ with new table
-+ @retval 1 It's view and we have to use
-+ open_tables function for this table
-+*/
-+
-+static int fill_schema_table_from_frm(THD *thd,TABLE *table,
-+ ST_SCHEMA_TABLE *schema_table,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name,
-+ enum enum_schema_tables schema_table_idx)
-+{
-+ TABLE_SHARE *share;
-+ TABLE tbl;
-+ TABLE_LIST table_list;
-+ uint res= 0;
-+ int error;
-+ char key[MAX_DBKEY_LENGTH];
-+ uint key_length;
-+
-+ bzero((char*) &table_list, sizeof(TABLE_LIST));
-+ bzero((char*) &tbl, sizeof(TABLE));
-+
-+ table_list.table_name= table_name->str;
-+ table_list.db= db_name->str;
-+ key_length= create_table_def_key(thd, key, &table_list, 0);
-+ pthread_mutex_lock(&LOCK_open);
-+ share= get_table_share(thd, &table_list, key,
-+ key_length, OPEN_VIEW, &error);
-+ if (!share)
-+ {
-+ res= 0;
-+ goto err;
-+ }
-+
-+ if (share->is_view)
-+ {
-+ if (schema_table->i_s_requested_object & OPEN_TABLE_ONLY)
-+ {
-+ /* skip view processing */
-+ res= 0;
-+ goto err1;
-+ }
-+ else if (schema_table->i_s_requested_object & OPEN_VIEW_FULL)
-+ {
-+ /*
-+ tell get_all_tables() to fall back to
-+ open_normal_and_derived_tables()
-+ */
-+ res= 1;
-+ goto err1;
-+ }
-+ }
-+
-+ if (share->is_view ||
-+ !open_table_from_share(thd, share, table_name->str, 0,
-+ (READ_KEYINFO | COMPUTE_TYPES |
-+ EXTRA_RECORD | OPEN_FRM_FILE_ONLY),
-+ thd->open_options, &tbl, FALSE))
-+ {
-+ tbl.s= share;
-+ table_list.table= &tbl;
-+ table_list.view= (st_lex*) share->is_view;
-+ res= schema_table->process_table(thd, &table_list, table,
-+ res, db_name, table_name);
-+ closefrm(&tbl, true);
-+ goto err;
-+ }
-+
-+err1:
-+ release_table_share(share, RELEASE_NORMAL);
-+
-+err:
-+ pthread_mutex_unlock(&LOCK_open);
-+ thd->clear_error();
-+ return res;
-+}
-+
-+
-+
-+/**
-+ @brief Fill I_S tables whose data are retrieved
-+ from frm files and storage engine
-+
-+ @details The information schema tables are internally represented as
-+ temporary tables that are filled at query execution time.
-+ Those I_S tables whose data are retrieved
-+ from frm files and storage engine are filled by the function
-+ get_all_tables().
-+
-+ @param[in] thd thread handler
-+ @param[in] tables I_S table
-+ @param[in] cond 'WHERE' condition
-+
-+ @return Operation status
-+ @retval 0 success
-+ @retval 1 error
-+*/
-+
-+int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ LEX *lex= thd->lex;
-+ TABLE *table= tables->table;
-+ SELECT_LEX *old_all_select_lex= lex->all_selects_list;
-+ enum_sql_command save_sql_command= lex->sql_command;
-+ SELECT_LEX *lsel= tables->schema_select_lex;
-+ ST_SCHEMA_TABLE *schema_table= tables->schema_table;
-+ SELECT_LEX sel;
-+ LOOKUP_FIELD_VALUES lookup_field_vals;
-+ LEX_STRING *db_name, *table_name;
-+ bool with_i_schema;
-+ enum enum_schema_tables schema_table_idx;
-+ List<LEX_STRING> db_names;
-+ List_iterator_fast<LEX_STRING> it(db_names);
-+ COND *partial_cond= 0;
-+ uint derived_tables= lex->derived_tables;
-+ int error= 1;
-+ Open_tables_state open_tables_state_backup;
-+ uint8 save_context_analysis_only= lex->context_analysis_only;
-+ Query_tables_list query_tables_list_backup;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ Security_context *sctx= thd->security_ctx;
-+#endif
-+ uint table_open_method;
-+ DBUG_ENTER("get_all_tables");
-+
-+ lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_VIEW;
-+ lex->reset_n_backup_query_tables_list(&query_tables_list_backup);
-+
-+ /*
-+ We should not introduce deadlocks even if we already have some
-+ tables open and locked, since we won't lock tables which we will
-+ open and will ignore possible name-locks for these tables.
-+ */
-+ thd->reset_n_backup_open_tables_state(&open_tables_state_backup);
-+
-+ /*
-+ this branch processes SHOW FIELDS, SHOW INDEXES commands.
-+ see sql_parse.cc, prepare_schema_table() function where
-+ this values are initialized
-+ */
-+ if (lsel && lsel->table_list.first)
-+ {
-+ error= fill_schema_show_cols_or_idxs(thd, tables, schema_table,
-+ &open_tables_state_backup);
-+ goto err;
-+ }
-+
-+ schema_table_idx= get_schema_table_idx(schema_table);
-+ if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
-+ {
-+ error= 0;
-+ goto err;
-+ }
-+
-+ DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
-+ STR_OR_NIL(lookup_field_vals.db_value.str),
-+ STR_OR_NIL(lookup_field_vals.table_value.str)));
-+
-+ if (!lookup_field_vals.wild_db_value && !lookup_field_vals.wild_table_value)
-+ {
-+ /*
-+ if lookup value is empty string then
-+ it's impossible table name or db name
-+ */
-+ if ((lookup_field_vals.db_value.str &&
-+ !lookup_field_vals.db_value.str[0]) ||
-+ (lookup_field_vals.table_value.str &&
-+ !lookup_field_vals.table_value.str[0]))
-+ {
-+ error= 0;
-+ goto err;
-+ }
-+ }
-+
-+ if (lookup_field_vals.db_value.length &&
-+ !lookup_field_vals.wild_db_value)
-+ tables->has_db_lookup_value= TRUE;
-+ if (lookup_field_vals.table_value.length &&
-+ !lookup_field_vals.wild_table_value)
-+ tables->has_table_lookup_value= TRUE;
-+
-+ if (tables->has_db_lookup_value && tables->has_table_lookup_value)
-+ partial_cond= 0;
-+ else
-+ partial_cond= make_cond_for_info_schema(cond, tables);
-+
-+ tables->table_open_method= table_open_method=
-+ get_table_open_method(tables, schema_table, schema_table_idx);
-+
-+ if (lex->describe)
-+ {
-+ /* EXPLAIN SELECT */
-+ error= 0;
-+ goto err;
-+ }
-+
-+ if (make_db_list(thd, &db_names, &lookup_field_vals, &with_i_schema))
-+ goto err;
-+ it.rewind(); /* To get access to new elements in basis list */
-+ while ((db_name= it++))
-+ {
-+ LEX_STRING orig_db_name;
-+
-+ /* db_name can be changed in make_table_list() func */
-+ if (!thd->make_lex_string(&orig_db_name, db_name->str,
-+ db_name->length, FALSE))
-+ goto err;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (!(check_access(thd,SELECT_ACL, db_name->str,
-+ &thd->col_access, 0, 1, with_i_schema) ||
-+ (!thd->col_access && check_grant_db(thd, db_name->str))) ||
-+ sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-+ acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0))
-+#endif
-+ {
-+ thd->no_warnings_for_error= 1;
-+ List<LEX_STRING> table_names;
-+ int res= make_table_name_list(thd, &table_names, lex,
-+ &lookup_field_vals,
-+ with_i_schema, db_name);
-+ if (res == 2) /* Not fatal error, continue */
-+ continue;
-+ if (res)
-+ goto err;
-+
-+ List_iterator_fast<LEX_STRING> it_files(table_names);
-+ while ((table_name= it_files++))
-+ {
-+ restore_record(table, s->default_values);
-+ table->field[schema_table->idx_field1]->
-+ store(db_name->str, db_name->length, system_charset_info);
-+ table->field[schema_table->idx_field2]->
-+ store(table_name->str, table_name->length, system_charset_info);
-+
-+ if (!partial_cond || partial_cond->val_int())
-+ {
-+ /*
-+ If table is I_S.tables and open_table_method is 0 (eg SKIP_OPEN)
-+ we can skip table opening and we don't have lookup value for
-+ table name or lookup value is wild string(table name list is
-+ already created by make_table_name_list() function).
-+ */
-+ if (!table_open_method && schema_table_idx == SCH_TABLES &&
-+ (!lookup_field_vals.table_value.length ||
-+ lookup_field_vals.wild_table_value))
-+ {
-+ if (schema_table_store_record(thd, table))
-+ goto err; /* Out of space in temporary table */
-+ continue;
-+ }
-+
-+ /* SHOW TABLE NAMES command */
-+ if (schema_table_idx == SCH_TABLE_NAMES)
-+ {
-+ if (fill_schema_table_names(thd, tables->table, db_name,
-+ table_name, with_i_schema))
-+ continue;
-+ }
-+ else
-+ {
-+ if (!(table_open_method & ~OPEN_FRM_ONLY) &&
-+ !with_i_schema)
-+ {
-+ if (!fill_schema_table_from_frm(thd, table, schema_table, db_name,
-+ table_name, schema_table_idx))
-+ continue;
-+ }
-+
-+ int res;
-+ LEX_STRING tmp_lex_string;
-+ /*
-+ Set the parent lex of 'sel' because it is needed by
-+ sel.init_query() which is called inside make_table_list.
-+ */
-+ thd->no_warnings_for_error= 1;
-+ sel.parent_lex= lex;
-+ if (make_table_list(thd, &sel, db_name, table_name))
-+ goto err;
-+ TABLE_LIST *show_table_list= sel.table_list.first;
-+ lex->all_selects_list= &sel;
-+ lex->derived_tables= 0;
-+ lex->sql_command= SQLCOM_SHOW_FIELDS;
-+ show_table_list->i_s_requested_object=
-+ schema_table->i_s_requested_object;
-+ DEBUG_SYNC(thd, "before_open_in_get_all_tables");
-+ res= open_normal_and_derived_tables(thd, show_table_list,
-+ MYSQL_LOCK_IGNORE_FLUSH);
-+ lex->sql_command= save_sql_command;
-+ /*
-+ XXX: show_table_list has a flag i_is_requested,
-+ and when it's set, open_normal_and_derived_tables()
-+ can return an error without setting an error message
-+ in THD, which is a hack. This is why we have to
-+ check for res, then for thd->is_error() only then
-+ for thd->main_da.sql_errno().
-+ */
-+ if (res && thd->is_error() &&
-+ thd->main_da.sql_errno() == ER_NO_SUCH_TABLE)
-+ {
-+ /*
-+ Hide error for not existing table.
-+ This error can occur for example when we use
-+ where condition with db name and table name and this
-+ table does not exist.
-+ */
-+ res= 0;
-+ thd->clear_error();
-+ }
-+ else
-+ {
-+ /*
-+ We should use show_table_list->alias instead of
-+ show_table_list->table_name because table_name
-+ could be changed during opening of I_S tables. It's safe
-+ to use alias because alias contains original table name
-+ in this case.
-+ */
-+ thd->make_lex_string(&tmp_lex_string, show_table_list->alias,
-+ strlen(show_table_list->alias), FALSE);
-+ res= schema_table->process_table(thd, show_table_list, table,
-+ res, &orig_db_name,
-+ &tmp_lex_string);
-+ close_tables_for_reopen(thd, &show_table_list);
-+ }
-+ DBUG_ASSERT(!lex->query_tables_own_last);
-+ if (res)
-+ goto err;
-+ }
-+ }
-+ }
-+ /*
-+ If we have information schema its always the first table and only
-+ the first table. Reset for other tables.
-+ */
-+ with_i_schema= 0;
-+ }
-+ }
-+
-+ error= 0;
-+err:
-+ thd->restore_backup_open_tables_state(&open_tables_state_backup);
-+ lex->restore_backup_query_tables_list(&query_tables_list_backup);
-+ lex->derived_tables= derived_tables;
-+ lex->all_selects_list= old_all_select_lex;
-+ lex->context_analysis_only= save_context_analysis_only;
-+ lex->sql_command= save_sql_command;
-+ DBUG_RETURN(error);
-+}
-+
-+
-+bool store_schema_shemata(THD* thd, TABLE *table, LEX_STRING *db_name,
-+ CHARSET_INFO *cs)
-+{
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, system_charset_info);
-+ table->field[2]->store(cs->csname, strlen(cs->csname), system_charset_info);
-+ table->field[3]->store(cs->name, strlen(cs->name), system_charset_info);
-+ return schema_table_store_record(thd, table);
-+}
-+
-+
-+int fill_schema_schemata(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ /*
-+ TODO: fill_schema_shemata() is called when new client is connected.
-+ Returning error status in this case leads to client hangup.
-+ */
-+
-+ LOOKUP_FIELD_VALUES lookup_field_vals;
-+ List<LEX_STRING> db_names;
-+ LEX_STRING *db_name;
-+ bool with_i_schema;
-+ HA_CREATE_INFO create;
-+ TABLE *table= tables->table;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ Security_context *sctx= thd->security_ctx;
-+#endif
-+ DBUG_ENTER("fill_schema_shemata");
-+
-+ if (get_lookup_field_values(thd, cond, tables, &lookup_field_vals))
-+ DBUG_RETURN(0);
-+ DBUG_PRINT("INDEX VALUES",("db_name='%s', table_name='%s'",
-+ lookup_field_vals.db_value.str,
-+ lookup_field_vals.table_value.str));
-+ if (make_db_list(thd, &db_names, &lookup_field_vals,
-+ &with_i_schema))
-+ DBUG_RETURN(1);
-+
-+ /*
-+ If we have lookup db value we should check that the database exists
-+ */
-+ if(lookup_field_vals.db_value.str && !lookup_field_vals.wild_db_value &&
-+ !with_i_schema)
-+ {
-+ char path[FN_REFLEN+16];
-+ uint path_len;
-+ MY_STAT stat_info;
-+ if (!lookup_field_vals.db_value.str[0])
-+ DBUG_RETURN(0);
-+ path_len= build_table_filename(path, sizeof(path) - 1,
-+ lookup_field_vals.db_value.str, "", "", 0);
-+ path[path_len-1]= 0;
-+ if (!my_stat(path,&stat_info,MYF(0)))
-+ DBUG_RETURN(0);
-+ }
-+
-+ List_iterator_fast<LEX_STRING> it(db_names);
-+ while ((db_name=it++))
-+ {
-+ if (with_i_schema) // information schema name is always first in list
-+ {
-+ if (store_schema_shemata(thd, table, db_name,
-+ system_charset_info))
-+ DBUG_RETURN(1);
-+ with_i_schema= 0;
-+ continue;
-+ }
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ if (sctx->master_access & (DB_ACLS | SHOW_DB_ACL) ||
-+ acl_get(sctx->host, sctx->ip, sctx->priv_user, db_name->str, 0) ||
-+ !check_grant_db(thd, db_name->str))
-+#endif
-+ {
-+ load_db_opt_by_name(thd, db_name->str, &create);
-+ if (store_schema_shemata(thd, table, db_name,
-+ create.default_table_charset))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static int get_schema_tables_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ const char *tmp_buff;
-+ MYSQL_TIME time;
-+ int info_error= 0;
-+ CHARSET_INFO *cs= system_charset_info;
-+ DBUG_ENTER("get_schema_tables_record");
-+
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(table_name->str, table_name->length, cs);
-+
-+ if (res)
-+ {
-+ /* There was a table open error, so set the table type and return */
-+ if (tables->view)
-+ table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
-+ else if (tables->schema_table)
-+ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
-+ else
-+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
-+
-+ goto err;
-+ }
-+
-+ if (tables->view)
-+ {
-+ table->field[3]->store(STRING_WITH_LEN("VIEW"), cs);
-+ table->field[20]->store(STRING_WITH_LEN("VIEW"), cs);
-+ }
-+ else
-+ {
-+ char option_buff[350],*ptr;
-+ TABLE *show_table= tables->table;
-+ TABLE_SHARE *share= show_table->s;
-+ handler *file= show_table->file;
-+ handlerton *tmp_db_type= share->db_type();
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ bool is_partitioned= FALSE;
-+#endif
-+ if (share->tmp_table == SYSTEM_TMP_TABLE)
-+ table->field[3]->store(STRING_WITH_LEN("SYSTEM VIEW"), cs);
-+ else if (share->tmp_table)
-+ table->field[3]->store(STRING_WITH_LEN("LOCAL TEMPORARY"), cs);
-+ else
-+ table->field[3]->store(STRING_WITH_LEN("BASE TABLE"), cs);
-+
-+ for (int i= 4; i < 20; i++)
-+ {
-+ if (i == 7 || (i > 12 && i < 17) || i == 18)
-+ continue;
-+ table->field[i]->set_notnull();
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (share->db_type() == partition_hton &&
-+ share->partition_info_len)
-+ {
-+ tmp_db_type= share->default_part_db_type;
-+ is_partitioned= TRUE;
-+ }
-+#endif
-+ tmp_buff= (char *) ha_resolve_storage_engine_name(tmp_db_type);
-+ table->field[4]->store(tmp_buff, strlen(tmp_buff), cs);
-+ table->field[5]->store((longlong) share->frm_version, TRUE);
-+
-+ ptr=option_buff;
-+ if (share->min_rows)
-+ {
-+ ptr=strmov(ptr," min_rows=");
-+ ptr=longlong10_to_str(share->min_rows,ptr,10);
-+ }
-+ if (share->max_rows)
-+ {
-+ ptr=strmov(ptr," max_rows=");
-+ ptr=longlong10_to_str(share->max_rows,ptr,10);
-+ }
-+ if (share->avg_row_length)
-+ {
-+ ptr=strmov(ptr," avg_row_length=");
-+ ptr=longlong10_to_str(share->avg_row_length,ptr,10);
-+ }
-+ if (share->db_create_options & HA_OPTION_PACK_KEYS)
-+ ptr=strmov(ptr," pack_keys=1");
-+ if (share->db_create_options & HA_OPTION_NO_PACK_KEYS)
-+ ptr=strmov(ptr," pack_keys=0");
-+ /* We use CHECKSUM, instead of TABLE_CHECKSUM, for backward compability */
-+ if (share->db_create_options & HA_OPTION_CHECKSUM)
-+ ptr=strmov(ptr," checksum=1");
-+ if (share->db_create_options & HA_OPTION_DELAY_KEY_WRITE)
-+ ptr=strmov(ptr," delay_key_write=1");
-+ if (share->row_type != ROW_TYPE_DEFAULT)
-+ ptr=strxmov(ptr, " row_format=",
-+ ha_row_type[(uint) share->row_type],
-+ NullS);
-+ if (share->key_block_size)
-+ {
-+ ptr= strmov(ptr, " KEY_BLOCK_SIZE=");
-+ ptr= longlong10_to_str(share->key_block_size, ptr, 10);
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (is_partitioned)
-+ ptr= strmov(ptr, " partitioned");
-+#endif
-+ table->field[19]->store(option_buff+1,
-+ (ptr == option_buff ? 0 :
-+ (uint) (ptr-option_buff)-1), cs);
-+
-+ tmp_buff= (share->table_charset ?
-+ share->table_charset->name : "default");
-+ table->field[17]->store(tmp_buff, strlen(tmp_buff), cs);
-+
-+ if (share->comment.str)
-+ table->field[20]->store(share->comment.str, share->comment.length, cs);
-+
-+ if (file)
-+ {
-+ /* If info() fails, then there's nothing else to do */
-+ if ((info_error= file->info(HA_STATUS_VARIABLE |
-+ HA_STATUS_TIME |
-+ HA_STATUS_AUTO)) != 0)
-+ goto err;
-+
-+ enum row_type row_type = file->get_row_type();
-+ switch (row_type) {
-+ case ROW_TYPE_NOT_USED:
-+ case ROW_TYPE_DEFAULT:
-+ tmp_buff= ((share->db_options_in_use &
-+ HA_OPTION_COMPRESS_RECORD) ? "Compressed" :
-+ (share->db_options_in_use & HA_OPTION_PACK_RECORD) ?
-+ "Dynamic" : "Fixed");
-+ break;
-+ case ROW_TYPE_FIXED:
-+ tmp_buff= "Fixed";
-+ break;
-+ case ROW_TYPE_DYNAMIC:
-+ tmp_buff= "Dynamic";
-+ break;
-+ case ROW_TYPE_COMPRESSED:
-+ tmp_buff= "Compressed";
-+ break;
-+ case ROW_TYPE_REDUNDANT:
-+ tmp_buff= "Redundant";
-+ break;
-+ case ROW_TYPE_COMPACT:
-+ tmp_buff= "Compact";
-+ break;
-+ case ROW_TYPE_PAGE:
-+ tmp_buff= "Paged";
-+ break;
-+ }
-+ table->field[6]->store(tmp_buff, strlen(tmp_buff), cs);
-+ if (!tables->schema_table)
-+ {
-+ table->field[7]->store((longlong) file->stats.records, TRUE);
-+ table->field[7]->set_notnull();
-+ }
-+ table->field[8]->store((longlong) file->stats.mean_rec_length, TRUE);
-+ table->field[9]->store((longlong) file->stats.data_file_length, TRUE);
-+ if (file->stats.max_data_file_length)
-+ {
-+ table->field[10]->store((longlong) file->stats.max_data_file_length,
-+ TRUE);
-+ }
-+ table->field[11]->store((longlong) file->stats.index_file_length, TRUE);
-+ table->field[12]->store((longlong) file->stats.delete_length, TRUE);
-+ if (show_table->found_next_number_field)
-+ {
-+ table->field[13]->store((longlong) file->stats.auto_increment_value,
-+ TRUE);
-+ table->field[13]->set_notnull();
-+ }
-+ if (file->stats.create_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t) file->stats.create_time);
-+ table->field[14]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[14]->set_notnull();
-+ }
-+ if (file->stats.update_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t) file->stats.update_time);
-+ table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[15]->set_notnull();
-+ }
-+ if (file->stats.check_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t) file->stats.check_time);
-+ table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[16]->set_notnull();
-+ }
-+ if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
-+ {
-+ table->field[18]->store((longlong) file->checksum(), TRUE);
-+ table->field[18]->set_notnull();
-+ }
-+ }
-+ }
-+
-+err:
-+ if (res || info_error)
-+ {
-+ /*
-+ If an error was encountered, push a warning, set the TABLE COMMENT
-+ column with the error text, and clear the error so that the operation
-+ can continue.
-+ */
-+ const char *error= thd->is_error() ? thd->main_da.message() : "";
-+ table->field[20]->store(error, strlen(error), cs);
-+
-+ if (thd->is_error())
-+ {
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ }
-+ }
-+
-+ DBUG_RETURN(schema_table_store_record(thd, table));
-+}
-+
-+
-+static int get_schema_column_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ LEX *lex= thd->lex;
-+ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-+ CHARSET_INFO *cs= system_charset_info;
-+ TABLE *show_table;
-+ Field **ptr,*field;
-+ int count;
-+ DBUG_ENTER("get_schema_column_record");
-+
-+ if (res)
-+ {
-+ if (lex->sql_command != SQLCOM_SHOW_FIELDS)
-+ {
-+ /*
-+ I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS
-+ rather than in SHOW COLUMNS
-+ */
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ res= 0;
-+ }
-+ DBUG_RETURN(res);
-+ }
-+
-+ show_table= tables->table;
-+ count= 0;
-+ restore_record(show_table, s->default_values);
-+ show_table->use_all_columns(); // Required for default
-+
-+ for (ptr= show_table->field; (field= *ptr) ; ptr++)
-+ {
-+ const char *tmp_buff;
-+ uchar *pos;
-+ bool is_blob;
-+ uint flags=field->flags;
-+ char tmp[MAX_FIELD_WIDTH];
-+ String type(tmp,sizeof(tmp), system_charset_info);
-+ int decimals, field_length;
-+
-+ if (wild && wild[0] &&
-+ wild_case_compare(system_charset_info, field->field_name,wild))
-+ continue;
-+
-+ flags= field->flags;
-+ count++;
-+ /* Get default row, with all NULL fields set to NULL */
-+ restore_record(table, s->default_values);
-+
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ uint col_access;
-+ check_access(thd,SELECT_ACL | EXTRA_ACL, db_name->str,
-+ &tables->grant.privilege, 0, 0, test(tables->schema_table));
-+ col_access= get_column_grant(thd, &tables->grant,
-+ db_name->str, table_name->str,
-+ field->field_name) & COL_ACLS;
-+ if (!tables->schema_table && !col_access)
-+ continue;
-+ char *end= tmp;
-+ for (uint bitnr=0; col_access ; col_access>>=1,bitnr++)
-+ {
-+ if (col_access & 1)
-+ {
-+ *end++=',';
-+ end=strmov(end,grant_types.type_names[bitnr]);
-+ }
-+ }
-+ table->field[17]->store(tmp+1,end == tmp ? 0 : (uint) (end-tmp-1), cs);
-+
-+#endif
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(table_name->str, table_name->length, cs);
-+ table->field[3]->store(field->field_name, strlen(field->field_name),
-+ cs);
-+ table->field[4]->store((longlong) count, TRUE);
-+ field->sql_type(type);
-+ table->field[14]->store(type.ptr(), type.length(), cs);
-+ /*
-+ MySQL column type has the following format:
-+ base_type [(dimension)] [unsigned] [zerofill].
-+ For DATA_TYPE column we extract only base type.
-+ */
-+ tmp_buff= strchr(type.ptr(), '(');
-+ if (!tmp_buff)
-+ /*
-+ if there is no dimention part then check the presence of
-+ [unsigned] [zerofill] attributes and cut them of if exist.
-+ */
-+ tmp_buff= strchr(type.ptr(), ' ');
-+ table->field[7]->store(type.ptr(),
-+ (tmp_buff ? tmp_buff - type.ptr() :
-+ type.length()), cs);
-+
-+ if (get_field_default_value(thd, show_table, field, &type, 0))
-+ {
-+ table->field[5]->store(type.ptr(), type.length(), cs);
-+ table->field[5]->set_notnull();
-+ }
-+ pos=(uchar*) ((flags & NOT_NULL_FLAG) ? "NO" : "YES");
-+ table->field[6]->store((const char*) pos,
-+ strlen((const char*) pos), cs);
-+ is_blob= (field->type() == MYSQL_TYPE_BLOB);
-+ if (field->has_charset() || is_blob ||
-+ field->real_type() == MYSQL_TYPE_VARCHAR || // For varbinary type
-+ field->real_type() == MYSQL_TYPE_STRING) // For binary type
-+ {
-+ uint32 octet_max_length= field->max_display_length();
-+ if (is_blob && octet_max_length != (uint32) 4294967295U)
-+ octet_max_length /= field->charset()->mbmaxlen;
-+ longlong char_max_len= is_blob ?
-+ (longlong) octet_max_length / field->charset()->mbminlen :
-+ (longlong) octet_max_length / field->charset()->mbmaxlen;
-+ table->field[8]->store(char_max_len, TRUE);
-+ table->field[8]->set_notnull();
-+ table->field[9]->store((longlong) octet_max_length, TRUE);
-+ table->field[9]->set_notnull();
-+ }
-+
-+ /*
-+ Calculate field_length and decimals.
-+ They are set to -1 if they should not be set (we should return NULL)
-+ */
-+
-+ decimals= field->decimals();
-+ switch (field->type()) {
-+ case MYSQL_TYPE_NEWDECIMAL:
-+ field_length= ((Field_new_decimal*) field)->precision;
-+ break;
-+ case MYSQL_TYPE_DECIMAL:
-+ field_length= field->field_length - (decimals ? 2 : 1);
-+ break;
-+ case MYSQL_TYPE_TINY:
-+ case MYSQL_TYPE_SHORT:
-+ case MYSQL_TYPE_LONG:
-+ case MYSQL_TYPE_INT24:
-+ field_length= field->max_display_length() - 1;
-+ break;
-+ case MYSQL_TYPE_LONGLONG:
-+ field_length= field->max_display_length() -
-+ ((field->flags & UNSIGNED_FLAG) ? 0 : 1);
-+ break;
-+ case MYSQL_TYPE_BIT:
-+ field_length= field->max_display_length();
-+ decimals= -1; // return NULL
-+ break;
-+ case MYSQL_TYPE_FLOAT:
-+ case MYSQL_TYPE_DOUBLE:
-+ field_length= field->field_length;
-+ if (decimals == NOT_FIXED_DEC)
-+ decimals= -1; // return NULL
-+ break;
-+ default:
-+ field_length= decimals= -1;
-+ break;
-+ }
-+
-+ if (field_length >= 0)
-+ {
-+ table->field[10]->store((longlong) field_length, TRUE);
-+ table->field[10]->set_notnull();
-+ }
-+ if (decimals >= 0)
-+ {
-+ table->field[11]->store((longlong) decimals, TRUE);
-+ table->field[11]->set_notnull();
-+ }
-+
-+ if (field->has_charset())
-+ {
-+ pos=(uchar*) field->charset()->csname;
-+ table->field[12]->store((const char*) pos,
-+ strlen((const char*) pos), cs);
-+ table->field[12]->set_notnull();
-+ pos=(uchar*) field->charset()->name;
-+ table->field[13]->store((const char*) pos,
-+ strlen((const char*) pos), cs);
-+ table->field[13]->set_notnull();
-+ }
-+ pos=(uchar*) ((field->flags & PRI_KEY_FLAG) ? "PRI" :
-+ (field->flags & UNIQUE_KEY_FLAG) ? "UNI" :
-+ (field->flags & MULTIPLE_KEY_FLAG) ? "MUL":"");
-+ table->field[15]->store((const char*) pos,
-+ strlen((const char*) pos), cs);
-+
-+ if (field->unireg_check == Field::NEXT_NUMBER)
-+ table->field[16]->store(STRING_WITH_LEN("auto_increment"), cs);
-+ if (show_table->timestamp_field == field &&
-+ field->unireg_check != Field::TIMESTAMP_DN_FIELD)
-+ table->field[16]->store(STRING_WITH_LEN("on update CURRENT_TIMESTAMP"),
-+ cs);
-+
-+ table->field[18]->store(field->comment.str, field->comment.length, cs);
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+
-+int fill_schema_charsets(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ CHARSET_INFO **cs;
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ TABLE *table= tables->table;
-+ CHARSET_INFO *scs= system_charset_info;
-+
-+ for (cs= all_charsets ; cs < all_charsets+255 ; cs++)
-+ {
-+ CHARSET_INFO *tmp_cs= cs[0];
-+ if (tmp_cs && (tmp_cs->state & MY_CS_PRIMARY) &&
-+ (tmp_cs->state & MY_CS_AVAILABLE) &&
-+ !(tmp_cs->state & MY_CS_HIDDEN) &&
-+ !(wild && wild[0] &&
-+ wild_case_compare(scs, tmp_cs->csname,wild)))
-+ {
-+ const char *comment;
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(tmp_cs->csname, strlen(tmp_cs->csname), scs);
-+ table->field[1]->store(tmp_cs->name, strlen(tmp_cs->name), scs);
-+ comment= tmp_cs->comment ? tmp_cs->comment : "";
-+ table->field[2]->store(comment, strlen(comment), scs);
-+ table->field[3]->store((longlong) tmp_cs->mbmaxlen, TRUE);
-+ if (schema_table_store_record(thd, table))
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+static my_bool iter_schema_engines(THD *thd, plugin_ref plugin,
-+ void *ptable)
-+{
-+ TABLE *table= (TABLE *) ptable;
-+ handlerton *hton= plugin_data(plugin, handlerton *);
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ CHARSET_INFO *scs= system_charset_info;
-+ handlerton *default_type= ha_default_handlerton(thd);
-+ DBUG_ENTER("iter_schema_engines");
-+
-+
-+ /* Disabled plugins */
-+ if (plugin_state(plugin) != PLUGIN_IS_READY)
-+ {
-+
-+ struct st_mysql_plugin *plug= plugin_decl(plugin);
-+ if (!(wild && wild[0] &&
-+ wild_case_compare(scs, plug->name,wild)))
-+ {
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(plug->name, strlen(plug->name), scs);
-+ table->field[1]->store(C_STRING_WITH_LEN("NO"), scs);
-+ table->field[2]->store(plug->descr, strlen(plug->descr), scs);
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+ }
-+
-+ if (!(hton->flags & HTON_HIDDEN))
-+ {
-+ LEX_STRING *name= plugin_name(plugin);
-+ if (!(wild && wild[0] &&
-+ wild_case_compare(scs, name->str,wild)))
-+ {
-+ LEX_STRING yesno[2]= {{ C_STRING_WITH_LEN("NO") },
-+ { C_STRING_WITH_LEN("YES") }};
-+ LEX_STRING *tmp;
-+ const char *option_name= show_comp_option_name[(int) hton->state];
-+ restore_record(table, s->default_values);
-+
-+ table->field[0]->store(name->str, name->length, scs);
-+ if (hton->state == SHOW_OPTION_YES && default_type == hton)
-+ option_name= "DEFAULT";
-+ table->field[1]->store(option_name, strlen(option_name), scs);
-+ table->field[2]->store(plugin_decl(plugin)->descr,
-+ strlen(plugin_decl(plugin)->descr), scs);
-+ tmp= &yesno[test(hton->commit)];
-+ table->field[3]->store(tmp->str, tmp->length, scs);
-+ table->field[3]->set_notnull();
-+ tmp= &yesno[test(hton->prepare)];
-+ table->field[4]->store(tmp->str, tmp->length, scs);
-+ table->field[4]->set_notnull();
-+ tmp= &yesno[test(hton->savepoint_set)];
-+ table->field[5]->store(tmp->str, tmp->length, scs);
-+ table->field[5]->set_notnull();
-+
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+int fill_schema_engines(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_schema_engines");
-+ if (plugin_foreach_with_mask(thd, iter_schema_engines,
-+ MYSQL_STORAGE_ENGINE_PLUGIN,
-+ ~PLUGIN_IS_FREED, tables->table))
-+ DBUG_RETURN(1);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+int fill_schema_collation(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ CHARSET_INFO **cs;
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ TABLE *table= tables->table;
-+ CHARSET_INFO *scs= system_charset_info;
-+ for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
-+ {
-+ CHARSET_INFO **cl;
-+ CHARSET_INFO *tmp_cs= cs[0];
-+ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
-+ (tmp_cs->state & MY_CS_HIDDEN) ||
-+ !(tmp_cs->state & MY_CS_PRIMARY))
-+ continue;
-+ for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
-+ {
-+ CHARSET_INFO *tmp_cl= cl[0];
-+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
-+ !my_charset_same(tmp_cs, tmp_cl))
-+ continue;
-+ if (!(wild && wild[0] &&
-+ wild_case_compare(scs, tmp_cl->name,wild)))
-+ {
-+ const char *tmp_buff;
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
-+ table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
-+ table->field[2]->store((longlong) tmp_cl->number, TRUE);
-+ tmp_buff= (tmp_cl->state & MY_CS_PRIMARY) ? "Yes" : "";
-+ table->field[3]->store(tmp_buff, strlen(tmp_buff), scs);
-+ tmp_buff= (tmp_cl->state & MY_CS_COMPILED)? "Yes" : "";
-+ table->field[4]->store(tmp_buff, strlen(tmp_buff), scs);
-+ table->field[5]->store((longlong) tmp_cl->strxfrm_multiply, TRUE);
-+ if (schema_table_store_record(thd, table))
-+ return 1;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+int fill_schema_coll_charset_app(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ CHARSET_INFO **cs;
-+ TABLE *table= tables->table;
-+ CHARSET_INFO *scs= system_charset_info;
-+ for (cs= all_charsets ; cs < all_charsets+255 ; cs++ )
-+ {
-+ CHARSET_INFO **cl;
-+ CHARSET_INFO *tmp_cs= cs[0];
-+ if (!tmp_cs || !(tmp_cs->state & MY_CS_AVAILABLE) ||
-+ !(tmp_cs->state & MY_CS_PRIMARY))
-+ continue;
-+ for (cl= all_charsets; cl < all_charsets+255 ;cl ++)
-+ {
-+ CHARSET_INFO *tmp_cl= cl[0];
-+ if (!tmp_cl || !(tmp_cl->state & MY_CS_AVAILABLE) ||
-+ !my_charset_same(tmp_cs,tmp_cl))
-+ continue;
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(tmp_cl->name, strlen(tmp_cl->name), scs);
-+ table->field[1]->store(tmp_cl->csname , strlen(tmp_cl->csname), scs);
-+ if (schema_table_store_record(thd, table))
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+static inline void copy_field_as_string(Field *to_field, Field *from_field)
-+{
-+ char buff[MAX_FIELD_WIDTH];
-+ String tmp_str(buff, sizeof(buff), system_charset_info);
-+ from_field->val_str(&tmp_str);
-+ to_field->store(tmp_str.ptr(), tmp_str.length(), system_charset_info);
-+}
-+
-+
-+bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
-+ const char *wild, bool full_access, const char *sp_user)
-+{
-+ MYSQL_TIME time;
-+ LEX *lex= thd->lex;
-+ CHARSET_INFO *cs= system_charset_info;
-+ char sp_db_buff[NAME_LEN + 1], sp_name_buff[NAME_LEN + 1],
-+ definer_buff[USERNAME_LENGTH + HOSTNAME_LENGTH + 2];
-+ String sp_db(sp_db_buff, sizeof(sp_db_buff), cs);
-+ String sp_name(sp_name_buff, sizeof(sp_name_buff), cs);
-+ String definer(definer_buff, sizeof(definer_buff), cs);
-+
-+ proc_table->field[0]->val_str(&sp_db);
-+ proc_table->field[1]->val_str(&sp_name);
-+ proc_table->field[11]->val_str(&definer);
-+
-+ if (!full_access)
-+ full_access= !strcmp(sp_user, definer.c_ptr_safe());
-+ if (!full_access &&
-+ check_some_routine_access(thd, sp_db.c_ptr_safe(), sp_name.c_ptr_safe(),
-+ proc_table->field[2]->val_int() ==
-+ TYPE_ENUM_PROCEDURE))
-+ return 0;
-+
-+ if ((lex->sql_command == SQLCOM_SHOW_STATUS_PROC &&
-+ proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE) ||
-+ (lex->sql_command == SQLCOM_SHOW_STATUS_FUNC &&
-+ proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION) ||
-+ (sql_command_flags[lex->sql_command] & CF_STATUS_COMMAND) == 0)
-+ {
-+ restore_record(table, s->default_values);
-+ if (!wild || !wild[0] || !wild_compare(sp_name.c_ptr_safe(), wild, 0))
-+ {
-+ int enum_idx= (int) proc_table->field[5]->val_int();
-+ table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
-+ copy_field_as_string(table->field[0], proc_table->field[3]);
-+ table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
-+ copy_field_as_string(table->field[4], proc_table->field[2]);
-+ if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
-+ {
-+ copy_field_as_string(table->field[5], proc_table->field[9]);
-+ table->field[5]->set_notnull();
-+ }
-+ if (full_access)
-+ {
-+ copy_field_as_string(table->field[7], proc_table->field[19]);
-+ table->field[7]->set_notnull();
-+ }
-+ table->field[6]->store(STRING_WITH_LEN("SQL"), cs);
-+ table->field[10]->store(STRING_WITH_LEN("SQL"), cs);
-+ copy_field_as_string(table->field[11], proc_table->field[6]);
-+ table->field[12]->store(sp_data_access_name[enum_idx].str,
-+ sp_data_access_name[enum_idx].length , cs);
-+ copy_field_as_string(table->field[14], proc_table->field[7]);
-+
-+ bzero((char *)&time, sizeof(time));
-+ ((Field_timestamp *) proc_table->field[12])->get_time(&time);
-+ table->field[15]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ bzero((char *)&time, sizeof(time));
-+ ((Field_timestamp *) proc_table->field[13])->get_time(&time);
-+ table->field[16]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ copy_field_as_string(table->field[17], proc_table->field[14]);
-+ copy_field_as_string(table->field[18], proc_table->field[15]);
-+ table->field[19]->store(definer.ptr(), definer.length(), cs);
-+ copy_field_as_string(table->field[20], proc_table->field[16]);
-+ copy_field_as_string(table->field[21], proc_table->field[17]);
-+ copy_field_as_string(table->field[22], proc_table->field[18]);
-+
-+ return schema_table_store_record(thd, table);
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ TABLE *proc_table;
-+ TABLE_LIST proc_tables;
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ int res= 0;
-+ TABLE *table= tables->table;
-+ bool full_access;
-+ char definer[USER_HOST_BUFF_SIZE];
-+ Open_tables_state open_tables_state_backup;
-+ DBUG_ENTER("fill_schema_proc");
-+
-+ strxmov(definer, thd->security_ctx->priv_user, "@",
-+ thd->security_ctx->priv_host, NullS);
-+ /* We use this TABLE_LIST instance only for checking of privileges. */
-+ bzero((char*) &proc_tables,sizeof(proc_tables));
-+ proc_tables.db= (char*) "mysql";
-+ proc_tables.db_length= 5;
-+ proc_tables.table_name= proc_tables.alias= (char*) "proc";
-+ proc_tables.table_name_length= 4;
-+ proc_tables.lock_type= TL_READ;
-+ full_access= !check_table_access(thd, SELECT_ACL, &proc_tables, 1, TRUE);
-+ if (!(proc_table= open_proc_table_for_read(thd, &open_tables_state_backup)))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ proc_table->file->ha_index_init(0, 1);
-+ if ((res= proc_table->file->index_first(proc_table->record[0])))
-+ {
-+ res= (res == HA_ERR_END_OF_FILE) ? 0 : 1;
-+ goto err;
-+ }
-+ if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
-+ {
-+ res= 1;
-+ goto err;
-+ }
-+ while (!proc_table->file->index_next(proc_table->record[0]))
-+ {
-+ if (store_schema_proc(thd, table, proc_table, wild, full_access, definer))
-+ {
-+ res= 1;
-+ goto err;
-+ }
-+ }
-+
-+err:
-+ proc_table->file->ha_index_end();
-+ close_system_tables(thd, &open_tables_state_backup);
-+ DBUG_RETURN(res);
-+}
-+
-+
-+static int get_schema_stat_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ DBUG_ENTER("get_schema_stat_record");
-+ if (res)
-+ {
-+ if (thd->lex->sql_command != SQLCOM_SHOW_KEYS)
-+ {
-+ /*
-+ I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS
-+ rather than in SHOW KEYS
-+ */
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ res= 0;
-+ }
-+ DBUG_RETURN(res);
-+ }
-+ else if (!tables->view)
-+ {
-+ TABLE *show_table= tables->table;
-+ KEY *key_info=show_table->s->key_info;
-+ if (show_table->file)
-+ show_table->file->info(HA_STATUS_VARIABLE |
-+ HA_STATUS_NO_LOCK |
-+ HA_STATUS_TIME);
-+ for (uint i=0 ; i < show_table->s->keys ; i++,key_info++)
-+ {
-+ KEY_PART_INFO *key_part= key_info->key_part;
-+ const char *str;
-+ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+ {
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(table_name->str, table_name->length, cs);
-+ table->field[3]->store((longlong) ((key_info->flags &
-+ HA_NOSAME) ? 0 : 1), TRUE);
-+ table->field[4]->store(db_name->str, db_name->length, cs);
-+ table->field[5]->store(key_info->name, strlen(key_info->name), cs);
-+ table->field[6]->store((longlong) (j+1), TRUE);
-+ str=(key_part->field ? key_part->field->field_name :
-+ "?unknown field?");
-+ table->field[7]->store(str, strlen(str), cs);
-+ if (show_table->file)
-+ {
-+ if (show_table->file->index_flags(i, j, 0) & HA_READ_ORDER)
-+ {
-+ table->field[8]->store(((key_part->key_part_flag &
-+ HA_REVERSE_SORT) ?
-+ "D" : "A"), 1, cs);
-+ table->field[8]->set_notnull();
-+ }
-+ KEY *key=show_table->key_info+i;
-+ if (key->rec_per_key[j])
-+ {
-+ ha_rows records=(show_table->file->stats.records /
-+ key->rec_per_key[j]);
-+ table->field[9]->store((longlong) records, TRUE);
-+ table->field[9]->set_notnull();
-+ }
-+ str= show_table->file->index_type(i);
-+ table->field[13]->store(str, strlen(str), cs);
-+ }
-+ if (!(key_info->flags & HA_FULLTEXT) &&
-+ (key_part->field &&
-+ key_part->length !=
-+ show_table->s->field[key_part->fieldnr-1]->key_length()))
-+ {
-+ table->field[10]->store((longlong) key_part->length /
-+ key_part->field->charset()->mbmaxlen, TRUE);
-+ table->field[10]->set_notnull();
-+ }
-+ uint flags= key_part->field ? key_part->field->flags : 0;
-+ const char *pos=(char*) ((flags & NOT_NULL_FLAG) ? "" : "YES");
-+ table->field[12]->store(pos, strlen(pos), cs);
-+ if (!show_table->s->keys_in_use.is_set(i))
-+ table->field[14]->store(STRING_WITH_LEN("disabled"), cs);
-+ else
-+ table->field[14]->store("", 0, cs);
-+ table->field[14]->set_notnull();
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ }
-+ DBUG_RETURN(res);
-+}
-+
-+
-+static int get_schema_views_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ DBUG_ENTER("get_schema_views_record");
-+ LEX_STRING *tmp_db_name, *tmp_table_name;
-+ char definer[USER_HOST_BUFF_SIZE];
-+ uint definer_len;
-+ bool updatable_view;
-+ /*
-+ if SELECT FROM I_S.VIEWS uses only fields
-+ which have OPEN_FRM_ONLY flag then 'tables'
-+ structure is zeroed and only tables->view is set.
-+ (see fill_schema_table_from_frm() function).
-+ So we should disable other fields filling.
-+ */
-+ bool only_share= !tables->definer.user.str;
-+
-+ if (tables->view)
-+ {
-+ Security_context *sctx= thd->security_ctx;
-+ if (!only_share && !tables->allowed_show)
-+ {
-+ if (!my_strcasecmp(system_charset_info, tables->definer.user.str,
-+ sctx->priv_user) &&
-+ !my_strcasecmp(system_charset_info, tables->definer.host.str,
-+ sctx->priv_host))
-+ tables->allowed_show= TRUE;
-+#ifndef NO_EMBEDDED_ACCESS_CHECKS
-+ else
-+ {
-+ if ((thd->col_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
-+ (SHOW_VIEW_ACL|SELECT_ACL))
-+ tables->allowed_show= TRUE;
-+ else
-+ {
-+ TABLE_LIST table_list;
-+ uint view_access;
-+ memset(&table_list, 0, sizeof(table_list));
-+ table_list.db= tables->view_db.str;
-+ table_list.table_name= tables->view_name.str;
-+ table_list.grant.privilege= thd->col_access;
-+ view_access= get_table_grant(thd, &table_list);
-+ if ((view_access & (SHOW_VIEW_ACL|SELECT_ACL)) ==
-+ (SHOW_VIEW_ACL|SELECT_ACL))
-+ tables->allowed_show= TRUE;
-+ }
-+ }
-+#endif
-+ }
-+ restore_record(table, s->default_values);
-+ tmp_db_name= &tables->view_db;
-+ tmp_table_name= &tables->view_name;
-+ if (only_share)
-+ {
-+ tmp_db_name= db_name;
-+ tmp_table_name= table_name;
-+ }
-+ table->field[1]->store(tmp_db_name->str, tmp_db_name->length, cs);
-+ table->field[2]->store(tmp_table_name->str, tmp_table_name->length, cs);
-+ if (!only_share)
-+ {
-+ if (tables->allowed_show)
-+ {
-+ table->field[3]->store(tables->view_body_utf8.str,
-+ tables->view_body_utf8.length,
-+ cs);
-+ }
-+
-+ if (tables->with_check != VIEW_CHECK_NONE)
-+ {
-+ if (tables->with_check == VIEW_CHECK_LOCAL)
-+ table->field[4]->store(STRING_WITH_LEN("LOCAL"), cs);
-+ else
-+ table->field[4]->store(STRING_WITH_LEN("CASCADED"), cs);
-+ }
-+ else
-+ table->field[4]->store(STRING_WITH_LEN("NONE"), cs);
-+
-+ updatable_view= 0;
-+ if (tables->algorithm != VIEW_ALGORITHM_TMPTABLE)
-+ {
-+ /*
-+ We should use tables->view->select_lex.item_list here and
-+ can not use Field_iterator_view because the view always uses
-+ temporary algorithm during opening for I_S and
-+ TABLE_LIST fields 'field_translation' & 'field_translation_end'
-+ are uninitialized is this case.
-+ */
-+ List<Item> *fields= &tables->view->select_lex.item_list;
-+ List_iterator<Item> it(*fields);
-+ Item *item;
-+ Item_field *field;
-+ /*
-+ check that at least one column in view is updatable
-+ */
-+ while ((item= it++))
-+ {
-+ if ((field= item->filed_for_view_update()) && field->field &&
-+ !field->field->table->pos_in_table_list->schema_table)
-+ {
-+ updatable_view= 1;
-+ break;
-+ }
-+ }
-+ if (updatable_view && !tables->view->can_be_merged())
-+ updatable_view= 0;
-+ }
-+ if (updatable_view)
-+ table->field[5]->store(STRING_WITH_LEN("YES"), cs);
-+ else
-+ table->field[5]->store(STRING_WITH_LEN("NO"), cs);
-+ definer_len= (strxmov(definer, tables->definer.user.str, "@",
-+ tables->definer.host.str, NullS) - definer);
-+ table->field[6]->store(definer, definer_len, cs);
-+ if (tables->view_suid)
-+ table->field[7]->store(STRING_WITH_LEN("DEFINER"), cs);
-+ else
-+ table->field[7]->store(STRING_WITH_LEN("INVOKER"), cs);
-+
-+ table->field[8]->store(tables->view_creation_ctx->get_client_cs()->csname,
-+ strlen(tables->view_creation_ctx->
-+ get_client_cs()->csname), cs);
-+
-+ table->field[9]->store(tables->view_creation_ctx->
-+ get_connection_cl()->name,
-+ strlen(tables->view_creation_ctx->
-+ get_connection_cl()->name), cs);
-+ }
-+
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ if (res && thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ }
-+ if (res)
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+}
-+
-+
-+bool store_constraints(THD *thd, TABLE *table, LEX_STRING *db_name,
-+ LEX_STRING *table_name, const char *key_name,
-+ uint key_len, const char *con_type, uint con_len)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(key_name, key_len, cs);
-+ table->field[3]->store(db_name->str, db_name->length, cs);
-+ table->field[4]->store(table_name->str, table_name->length, cs);
-+ table->field[5]->store(con_type, con_len, cs);
-+ return schema_table_store_record(thd, table);
-+}
-+
-+
-+static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ DBUG_ENTER("get_schema_constraints_record");
-+ if (res)
-+ {
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+ }
-+ else if (!tables->view)
-+ {
-+ List<FOREIGN_KEY_INFO> f_key_list;
-+ TABLE *show_table= tables->table;
-+ KEY *key_info=show_table->key_info;
-+ uint primary_key= show_table->s->primary_key;
-+
-+ // This is not needed since no statistics are displayed.
-+ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-+
-+ for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
-+ {
-+ if (i != primary_key && !(key_info->flags & HA_NOSAME))
-+ continue;
-+
-+ if (i == primary_key && !strcmp(key_info->name, primary_key_name))
-+ {
-+ if (store_constraints(thd, table, db_name, table_name, key_info->name,
-+ strlen(key_info->name),
-+ STRING_WITH_LEN("PRIMARY KEY")))
-+ DBUG_RETURN(1);
-+ }
-+ else if (key_info->flags & HA_NOSAME)
-+ {
-+ if (store_constraints(thd, table, db_name, table_name, key_info->name,
-+ strlen(key_info->name),
-+ STRING_WITH_LEN("UNIQUE")))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+
-+ show_table->file->get_foreign_key_list(thd, &f_key_list);
-+ FOREIGN_KEY_INFO *f_key_info;
-+ List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
-+ while ((f_key_info=it++))
-+ {
-+ if (store_constraints(thd, table, db_name, table_name,
-+ f_key_info->forein_id->str,
-+ strlen(f_key_info->forein_id->str),
-+ "FOREIGN KEY", 11))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ DBUG_RETURN(res);
-+}
-+
-+
-+static bool store_trigger(THD *thd, TABLE *table, LEX_STRING *db_name,
-+ LEX_STRING *table_name, LEX_STRING *trigger_name,
-+ enum trg_event_type event,
-+ enum trg_action_time_type timing,
-+ LEX_STRING *trigger_stmt,
-+ ulong sql_mode,
-+ LEX_STRING *definer_buffer,
-+ LEX_STRING *client_cs_name,
-+ LEX_STRING *connection_cl_name,
-+ LEX_STRING *db_cl_name)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ LEX_STRING sql_mode_rep;
-+
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(trigger_name->str, trigger_name->length, cs);
-+ table->field[3]->store(trg_event_type_names[event].str,
-+ trg_event_type_names[event].length, cs);
-+ table->field[5]->store(db_name->str, db_name->length, cs);
-+ table->field[6]->store(table_name->str, table_name->length, cs);
-+ table->field[9]->store(trigger_stmt->str, trigger_stmt->length, cs);
-+ table->field[10]->store(STRING_WITH_LEN("ROW"), cs);
-+ table->field[11]->store(trg_action_time_type_names[timing].str,
-+ trg_action_time_type_names[timing].length, cs);
-+ table->field[14]->store(STRING_WITH_LEN("OLD"), cs);
-+ table->field[15]->store(STRING_WITH_LEN("NEW"), cs);
-+
-+ sys_var_thd_sql_mode::symbolic_mode_representation(thd, sql_mode,
-+ &sql_mode_rep);
-+ table->field[17]->store(sql_mode_rep.str, sql_mode_rep.length, cs);
-+ table->field[18]->store(definer_buffer->str, definer_buffer->length, cs);
-+ table->field[19]->store(client_cs_name->str, client_cs_name->length, cs);
-+ table->field[20]->store(connection_cl_name->str,
-+ connection_cl_name->length, cs);
-+ table->field[21]->store(db_cl_name->str, db_cl_name->length, cs);
-+
-+ return schema_table_store_record(thd, table);
-+}
-+
-+
-+static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ DBUG_ENTER("get_schema_triggers_record");
-+ /*
-+ res can be non zero value when processed table is a view or
-+ error happened during opening of processed table.
-+ */
-+ if (res)
-+ {
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+ }
-+ if (!tables->view && tables->table->triggers)
-+ {
-+ Table_triggers_list *triggers= tables->table->triggers;
-+ int event, timing;
-+
-+ if (check_table_access(thd, TRIGGER_ACL, tables, 1, TRUE))
-+ goto ret;
-+
-+ for (event= 0; event < (int)TRG_EVENT_MAX; event++)
-+ {
-+ for (timing= 0; timing < (int)TRG_ACTION_MAX; timing++)
-+ {
-+ LEX_STRING trigger_name;
-+ LEX_STRING trigger_stmt;
-+ ulong sql_mode;
-+ char definer_holder[USER_HOST_BUFF_SIZE];
-+ LEX_STRING definer_buffer;
-+ LEX_STRING client_cs_name;
-+ LEX_STRING connection_cl_name;
-+ LEX_STRING db_cl_name;
-+
-+ definer_buffer.str= definer_holder;
-+ if (triggers->get_trigger_info(thd, (enum trg_event_type) event,
-+ (enum trg_action_time_type)timing,
-+ &trigger_name, &trigger_stmt,
-+ &sql_mode,
-+ &definer_buffer,
-+ &client_cs_name,
-+ &connection_cl_name,
-+ &db_cl_name))
-+ continue;
-+
-+ if (store_trigger(thd, table, db_name, table_name, &trigger_name,
-+ (enum trg_event_type) event,
-+ (enum trg_action_time_type) timing, &trigger_stmt,
-+ sql_mode,
-+ &definer_buffer,
-+ &client_cs_name,
-+ &connection_cl_name,
-+ &db_cl_name))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ }
-+ret:
-+ DBUG_RETURN(0);
-+}
-+
-+
-+void store_key_column_usage(TABLE *table, LEX_STRING *db_name,
-+ LEX_STRING *table_name, const char *key_name,
-+ uint key_len, const char *con_type, uint con_len,
-+ longlong idx)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(key_name, key_len, cs);
-+ table->field[4]->store(db_name->str, db_name->length, cs);
-+ table->field[5]->store(table_name->str, table_name->length, cs);
-+ table->field[6]->store(con_type, con_len, cs);
-+ table->field[7]->store((longlong) idx, TRUE);
-+}
-+
-+
-+static int get_schema_key_column_usage_record(THD *thd,
-+ TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ DBUG_ENTER("get_schema_key_column_usage_record");
-+ if (res)
-+ {
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+ }
-+ else if (!tables->view)
-+ {
-+ List<FOREIGN_KEY_INFO> f_key_list;
-+ TABLE *show_table= tables->table;
-+ KEY *key_info=show_table->key_info;
-+ uint primary_key= show_table->s->primary_key;
-+
-+ // This is not needed since no statistics are displayed.
-+ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-+
-+ for (uint i=0 ; i < show_table->s->keys ; i++, key_info++)
-+ {
-+ if (i != primary_key && !(key_info->flags & HA_NOSAME))
-+ continue;
-+ uint f_idx= 0;
-+ KEY_PART_INFO *key_part= key_info->key_part;
-+ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+ {
-+ if (key_part->field)
-+ {
-+ f_idx++;
-+ restore_record(table, s->default_values);
-+ store_key_column_usage(table, db_name, table_name,
-+ key_info->name,
-+ strlen(key_info->name),
-+ key_part->field->field_name,
-+ strlen(key_part->field->field_name),
-+ (longlong) f_idx);
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ }
-+
-+ show_table->file->get_foreign_key_list(thd, &f_key_list);
-+ FOREIGN_KEY_INFO *f_key_info;
-+ List_iterator_fast<FOREIGN_KEY_INFO> fkey_it(f_key_list);
-+ while ((f_key_info= fkey_it++))
-+ {
-+ LEX_STRING *f_info;
-+ LEX_STRING *r_info;
-+ List_iterator_fast<LEX_STRING> it(f_key_info->foreign_fields),
-+ it1(f_key_info->referenced_fields);
-+ uint f_idx= 0;
-+ while ((f_info= it++))
-+ {
-+ r_info= it1++;
-+ f_idx++;
-+ restore_record(table, s->default_values);
-+ store_key_column_usage(table, db_name, table_name,
-+ f_key_info->forein_id->str,
-+ f_key_info->forein_id->length,
-+ f_info->str, f_info->length,
-+ (longlong) f_idx);
-+ table->field[8]->store((longlong) f_idx, TRUE);
-+ table->field[8]->set_notnull();
-+ table->field[9]->store(f_key_info->referenced_db->str,
-+ f_key_info->referenced_db->length,
-+ system_charset_info);
-+ table->field[9]->set_notnull();
-+ table->field[10]->store(f_key_info->referenced_table->str,
-+ f_key_info->referenced_table->length,
-+ system_charset_info);
-+ table->field[10]->set_notnull();
-+ table->field[11]->store(r_info->str, r_info->length,
-+ system_charset_info);
-+ table->field[11]->set_notnull();
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ }
-+ DBUG_RETURN(res);
-+}
-+
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+static void collect_partition_expr(List<char> &field_list, String *str)
-+{
-+ List_iterator<char> part_it(field_list);
-+ ulong no_fields= field_list.elements;
-+ const char *field_str;
-+ str->length(0);
-+ while ((field_str= part_it++))
-+ {
-+ str->append(field_str);
-+ if (--no_fields != 0)
-+ str->append(",");
-+ }
-+ return;
-+}
-+#endif
-+
-+
-+static void store_schema_partitions_record(THD *thd, TABLE *schema_table,
-+ TABLE *showing_table,
-+ partition_element *part_elem,
-+ handler *file, uint part_id)
-+{
-+ TABLE* table= schema_table;
-+ CHARSET_INFO *cs= system_charset_info;
-+ PARTITION_INFO stat_info;
-+ MYSQL_TIME time;
-+ file->get_dynamic_partition_info(&stat_info, part_id);
-+ table->field[12]->store((longlong) stat_info.records, TRUE);
-+ table->field[13]->store((longlong) stat_info.mean_rec_length, TRUE);
-+ table->field[14]->store((longlong) stat_info.data_file_length, TRUE);
-+ if (stat_info.max_data_file_length)
-+ {
-+ table->field[15]->store((longlong) stat_info.max_data_file_length, TRUE);
-+ table->field[15]->set_notnull();
-+ }
-+ table->field[16]->store((longlong) stat_info.index_file_length, TRUE);
-+ table->field[17]->store((longlong) stat_info.delete_length, TRUE);
-+ if (stat_info.create_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t)stat_info.create_time);
-+ table->field[18]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[18]->set_notnull();
-+ }
-+ if (stat_info.update_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t)stat_info.update_time);
-+ table->field[19]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[19]->set_notnull();
-+ }
-+ if (stat_info.check_time)
-+ {
-+ thd->variables.time_zone->gmt_sec_to_TIME(&time,
-+ (my_time_t)stat_info.check_time);
-+ table->field[20]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ table->field[20]->set_notnull();
-+ }
-+ if (file->ha_table_flags() & (ulong) HA_HAS_CHECKSUM)
-+ {
-+ table->field[21]->store((longlong) stat_info.check_sum, TRUE);
-+ table->field[21]->set_notnull();
-+ }
-+ if (part_elem)
-+ {
-+ if (part_elem->part_comment)
-+ table->field[22]->store(part_elem->part_comment,
-+ strlen(part_elem->part_comment), cs);
-+ else
-+ table->field[22]->store(STRING_WITH_LEN(""), cs);
-+ if (part_elem->nodegroup_id != UNDEF_NODEGROUP)
-+ table->field[23]->store((longlong) part_elem->nodegroup_id, TRUE);
-+ else
-+ table->field[23]->store(STRING_WITH_LEN("default"), cs);
-+
-+ table->field[24]->set_notnull();
-+ if (part_elem->tablespace_name)
-+ table->field[24]->store(part_elem->tablespace_name,
-+ strlen(part_elem->tablespace_name), cs);
-+ else
-+ {
-+ char *ts= showing_table->file->get_tablespace_name(thd,0,0);
-+ if(ts)
-+ {
-+ table->field[24]->store(ts, strlen(ts), cs);
-+ my_free(ts, MYF(0));
-+ }
-+ else
-+ table->field[24]->set_null();
-+ }
-+ }
-+ return;
-+}
-+
-+
-+static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name,
-+ LEX_STRING *table_name)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ char buff[61];
-+ String tmp_res(buff, sizeof(buff), cs);
-+ String tmp_str;
-+ TABLE *show_table= tables->table;
-+ handler *file;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ partition_info *part_info;
-+#endif
-+ DBUG_ENTER("get_schema_partitions_record");
-+
-+ if (res)
-+ {
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+ }
-+ file= show_table->file;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ part_info= show_table->part_info;
-+ if (part_info)
-+ {
-+ partition_element *part_elem;
-+ List_iterator<partition_element> part_it(part_info->partitions);
-+ uint part_pos= 0, part_id= 0;
-+
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[2]->store(table_name->str, table_name->length, cs);
-+
-+
-+ /* Partition method*/
-+ switch (part_info->part_type) {
-+ case RANGE_PARTITION:
-+ table->field[7]->store(partition_keywords[PKW_RANGE].str,
-+ partition_keywords[PKW_RANGE].length, cs);
-+ break;
-+ case LIST_PARTITION:
-+ table->field[7]->store(partition_keywords[PKW_LIST].str,
-+ partition_keywords[PKW_LIST].length, cs);
-+ break;
-+ case HASH_PARTITION:
-+ tmp_res.length(0);
-+ if (part_info->linear_hash_ind)
-+ tmp_res.append(partition_keywords[PKW_LINEAR].str,
-+ partition_keywords[PKW_LINEAR].length);
-+ if (part_info->list_of_part_fields)
-+ tmp_res.append(partition_keywords[PKW_KEY].str,
-+ partition_keywords[PKW_KEY].length);
-+ else
-+ tmp_res.append(partition_keywords[PKW_HASH].str,
-+ partition_keywords[PKW_HASH].length);
-+ table->field[7]->store(tmp_res.ptr(), tmp_res.length(), cs);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ my_error(ER_OUT_OF_RESOURCES, MYF(0));
-+ current_thd->fatal_error();
-+ DBUG_RETURN(1);
-+ }
-+ table->field[7]->set_notnull();
-+
-+ /* Partition expression */
-+ if (part_info->part_expr)
-+ {
-+ table->field[9]->store(part_info->part_func_string,
-+ part_info->part_func_len, cs);
-+ }
-+ else if (part_info->list_of_part_fields)
-+ {
-+ collect_partition_expr(part_info->part_field_list, &tmp_str);
-+ table->field[9]->store(tmp_str.ptr(), tmp_str.length(), cs);
-+ }
-+ table->field[9]->set_notnull();
-+
-+ if (part_info->is_sub_partitioned())
-+ {
-+ /* Subpartition method */
-+ tmp_res.length(0);
-+ if (part_info->linear_hash_ind)
-+ tmp_res.append(partition_keywords[PKW_LINEAR].str,
-+ partition_keywords[PKW_LINEAR].length);
-+ if (part_info->list_of_subpart_fields)
-+ tmp_res.append(partition_keywords[PKW_KEY].str,
-+ partition_keywords[PKW_KEY].length);
-+ else
-+ tmp_res.append(partition_keywords[PKW_HASH].str,
-+ partition_keywords[PKW_HASH].length);
-+ table->field[8]->store(tmp_res.ptr(), tmp_res.length(), cs);
-+ table->field[8]->set_notnull();
-+
-+ /* Subpartition expression */
-+ if (part_info->subpart_expr)
-+ {
-+ table->field[10]->store(part_info->subpart_func_string,
-+ part_info->subpart_func_len, cs);
-+ }
-+ else if (part_info->list_of_subpart_fields)
-+ {
-+ collect_partition_expr(part_info->subpart_field_list, &tmp_str);
-+ table->field[10]->store(tmp_str.ptr(), tmp_str.length(), cs);
-+ }
-+ table->field[10]->set_notnull();
-+ }
-+
-+ while ((part_elem= part_it++))
-+ {
-+ table->field[3]->store(part_elem->partition_name,
-+ strlen(part_elem->partition_name), cs);
-+ table->field[3]->set_notnull();
-+ /* PARTITION_ORDINAL_POSITION */
-+ table->field[5]->store((longlong) ++part_pos, TRUE);
-+ table->field[5]->set_notnull();
-+
-+ /* Partition description */
-+ if (part_info->part_type == RANGE_PARTITION)
-+ {
-+ if (part_elem->range_value != LONGLONG_MAX)
-+ table->field[11]->store((longlong) part_elem->range_value, FALSE);
-+ else
-+ table->field[11]->store(partition_keywords[PKW_MAXVALUE].str,
-+ partition_keywords[PKW_MAXVALUE].length, cs);
-+ table->field[11]->set_notnull();
-+ }
-+ else if (part_info->part_type == LIST_PARTITION)
-+ {
-+ List_iterator<part_elem_value> list_val_it(part_elem->list_val_list);
-+ part_elem_value *list_value;
-+ uint no_items= part_elem->list_val_list.elements;
-+ tmp_str.length(0);
-+ tmp_res.length(0);
-+ if (part_elem->has_null_value)
-+ {
-+ tmp_str.append("NULL");
-+ if (no_items > 0)
-+ tmp_str.append(",");
-+ }
-+ while ((list_value= list_val_it++))
-+ {
-+ if (!list_value->unsigned_flag)
-+ tmp_res.set(list_value->value, cs);
-+ else
-+ tmp_res.set((ulonglong)list_value->value, cs);
-+ tmp_str.append(tmp_res);
-+ if (--no_items != 0)
-+ tmp_str.append(",");
-+ };
-+ table->field[11]->store(tmp_str.ptr(), tmp_str.length(), cs);
-+ table->field[11]->set_notnull();
-+ }
-+
-+ if (part_elem->subpartitions.elements)
-+ {
-+ List_iterator<partition_element> sub_it(part_elem->subpartitions);
-+ partition_element *subpart_elem;
-+ uint subpart_pos= 0;
-+
-+ while ((subpart_elem= sub_it++))
-+ {
-+ table->field[4]->store(subpart_elem->partition_name,
-+ strlen(subpart_elem->partition_name), cs);
-+ table->field[4]->set_notnull();
-+ /* SUBPARTITION_ORDINAL_POSITION */
-+ table->field[6]->store((longlong) ++subpart_pos, TRUE);
-+ table->field[6]->set_notnull();
-+
-+ store_schema_partitions_record(thd, table, show_table, subpart_elem,
-+ file, part_id);
-+ part_id++;
-+ if(schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ else
-+ {
-+ store_schema_partitions_record(thd, table, show_table, part_elem,
-+ file, part_id);
-+ part_id++;
-+ if(schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ DBUG_RETURN(0);
-+ }
-+ else
-+#endif
-+ {
-+ store_schema_partitions_record(thd, table, show_table, 0, file, 0);
-+ if(schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+#ifdef NOT_USED
-+static interval_type get_real_interval_type(interval_type i_type)
-+{
-+ switch (i_type) {
-+ case INTERVAL_YEAR:
-+ return INTERVAL_YEAR;
-+
-+ case INTERVAL_QUARTER:
-+ case INTERVAL_YEAR_MONTH:
-+ case INTERVAL_MONTH:
-+ return INTERVAL_MONTH;
-+
-+ case INTERVAL_WEEK:
-+ case INTERVAL_DAY:
-+ return INTERVAL_DAY;
-+
-+ case INTERVAL_DAY_HOUR:
-+ case INTERVAL_HOUR:
-+ return INTERVAL_HOUR;
-+
-+ case INTERVAL_DAY_MINUTE:
-+ case INTERVAL_HOUR_MINUTE:
-+ case INTERVAL_MINUTE:
-+ return INTERVAL_MINUTE;
-+
-+ case INTERVAL_DAY_SECOND:
-+ case INTERVAL_HOUR_SECOND:
-+ case INTERVAL_MINUTE_SECOND:
-+ case INTERVAL_SECOND:
-+ return INTERVAL_SECOND;
-+
-+ case INTERVAL_DAY_MICROSECOND:
-+ case INTERVAL_HOUR_MICROSECOND:
-+ case INTERVAL_MINUTE_MICROSECOND:
-+ case INTERVAL_SECOND_MICROSECOND:
-+ case INTERVAL_MICROSECOND:
-+ return INTERVAL_MICROSECOND;
-+ case INTERVAL_LAST:
-+ DBUG_ASSERT(0);
-+ }
-+ DBUG_ASSERT(0);
-+ return INTERVAL_SECOND;
-+}
-+
-+#endif
-+
-+#ifdef HAVE_EVENT_SCHEDULER
-+/*
-+ Loads an event from mysql.event and copies it's data to a row of
-+ I_S.EVENTS
-+
-+ Synopsis
-+ copy_event_to_schema_table()
-+ thd Thread
-+ sch_table The schema table (information_schema.event)
-+ event_table The event table to use for loading (mysql.event).
-+
-+ Returns
-+ 0 OK
-+ 1 Error
-+*/
-+
-+int
-+copy_event_to_schema_table(THD *thd, TABLE *sch_table, TABLE *event_table)
-+{
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ CHARSET_INFO *scs= system_charset_info;
-+ MYSQL_TIME time;
-+ Event_timed et;
-+ DBUG_ENTER("copy_event_to_schema_table");
-+
-+ restore_record(sch_table, s->default_values);
-+
-+ if (et.load_from_row(thd, event_table))
-+ {
-+ my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), event_table->alias);
-+ DBUG_RETURN(1);
-+ }
-+
-+ if (!(!wild || !wild[0] || !wild_compare(et.name.str, wild, 0)))
-+ DBUG_RETURN(0);
-+
-+ /*
-+ Skip events in schemas one does not have access to. The check is
-+ optimized. It's guaranteed in case of SHOW EVENTS that the user
-+ has access.
-+ */
-+ if (thd->lex->sql_command != SQLCOM_SHOW_EVENTS &&
-+ check_access(thd, EVENT_ACL, et.dbname.str, 0, 0, 1,
-+ is_schema_db(et.dbname.str, et.dbname.length)))
-+ DBUG_RETURN(0);
-+
-+ /* ->field[0] is EVENT_CATALOG and is by default NULL */
-+
-+ sch_table->field[ISE_EVENT_SCHEMA]->
-+ store(et.dbname.str, et.dbname.length,scs);
-+ sch_table->field[ISE_EVENT_NAME]->
-+ store(et.name.str, et.name.length, scs);
-+ sch_table->field[ISE_DEFINER]->
-+ store(et.definer.str, et.definer.length, scs);
-+ const String *tz_name= et.time_zone->get_name();
-+ sch_table->field[ISE_TIME_ZONE]->
-+ store(tz_name->ptr(), tz_name->length(), scs);
-+ sch_table->field[ISE_EVENT_BODY]->
-+ store(STRING_WITH_LEN("SQL"), scs);
-+ sch_table->field[ISE_EVENT_DEFINITION]->store(
-+ et.body_utf8.str, et.body_utf8.length, scs);
-+
-+ /* SQL_MODE */
-+ {
-+ LEX_STRING sql_mode;
-+ sys_var_thd_sql_mode::symbolic_mode_representation(thd, et.sql_mode,
-+ &sql_mode);
-+ sch_table->field[ISE_SQL_MODE]->
-+ store(sql_mode.str, sql_mode.length, scs);
-+ }
-+
-+ int not_used=0;
-+
-+ if (et.expression)
-+ {
-+ String show_str;
-+ /* type */
-+ sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("RECURRING"), scs);
-+
-+ if (Events::reconstruct_interval_expression(&show_str, et.interval,
-+ et.expression))
-+ DBUG_RETURN(1);
-+
-+ sch_table->field[ISE_INTERVAL_VALUE]->set_notnull();
-+ sch_table->field[ISE_INTERVAL_VALUE]->
-+ store(show_str.ptr(), show_str.length(), scs);
-+
-+ LEX_STRING *ival= &interval_type_to_name[et.interval];
-+ sch_table->field[ISE_INTERVAL_FIELD]->set_notnull();
-+ sch_table->field[ISE_INTERVAL_FIELD]->store(ival->str, ival->length, scs);
-+
-+ /* starts & ends . STARTS is always set - see sql_yacc.yy */
-+ et.time_zone->gmt_sec_to_TIME(&time, et.starts);
-+ sch_table->field[ISE_STARTS]->set_notnull();
-+ sch_table->field[ISE_STARTS]->
-+ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+
-+ if (!et.ends_null)
-+ {
-+ et.time_zone->gmt_sec_to_TIME(&time, et.ends);
-+ sch_table->field[ISE_ENDS]->set_notnull();
-+ sch_table->field[ISE_ENDS]->
-+ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ }
-+ }
-+ else
-+ {
-+ /* type */
-+ sch_table->field[ISE_EVENT_TYPE]->store(STRING_WITH_LEN("ONE TIME"), scs);
-+
-+ et.time_zone->gmt_sec_to_TIME(&time, et.execute_at);
-+ sch_table->field[ISE_EXECUTE_AT]->set_notnull();
-+ sch_table->field[ISE_EXECUTE_AT]->
-+ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ }
-+
-+ /* status */
-+
-+ switch (et.status)
-+ {
-+ case Event_parse_data::ENABLED:
-+ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("ENABLED"), scs);
-+ break;
-+ case Event_parse_data::SLAVESIDE_DISABLED:
-+ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("SLAVESIDE_DISABLED"),
-+ scs);
-+ break;
-+ case Event_parse_data::DISABLED:
-+ sch_table->field[ISE_STATUS]->store(STRING_WITH_LEN("DISABLED"), scs);
-+ break;
-+ default:
-+ DBUG_ASSERT(0);
-+ }
-+ sch_table->field[ISE_ORIGINATOR]->store(et.originator, TRUE);
-+
-+ /* on_completion */
-+ if (et.on_completion == Event_parse_data::ON_COMPLETION_DROP)
-+ sch_table->field[ISE_ON_COMPLETION]->
-+ store(STRING_WITH_LEN("NOT PRESERVE"), scs);
-+ else
-+ sch_table->field[ISE_ON_COMPLETION]->
-+ store(STRING_WITH_LEN("PRESERVE"), scs);
-+
-+ number_to_datetime(et.created, &time, 0, ¬_used);
-+ DBUG_ASSERT(not_used==0);
-+ sch_table->field[ISE_CREATED]->store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+
-+ number_to_datetime(et.modified, &time, 0, ¬_used);
-+ DBUG_ASSERT(not_used==0);
-+ sch_table->field[ISE_LAST_ALTERED]->
-+ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+
-+ if (et.last_executed)
-+ {
-+ et.time_zone->gmt_sec_to_TIME(&time, et.last_executed);
-+ sch_table->field[ISE_LAST_EXECUTED]->set_notnull();
-+ sch_table->field[ISE_LAST_EXECUTED]->
-+ store_time(&time, MYSQL_TIMESTAMP_DATETIME);
-+ }
-+
-+ sch_table->field[ISE_EVENT_COMMENT]->
-+ store(et.comment.str, et.comment.length, scs);
-+
-+ sch_table->field[ISE_CLIENT_CS]->set_notnull();
-+ sch_table->field[ISE_CLIENT_CS]->store(
-+ et.creation_ctx->get_client_cs()->csname,
-+ strlen(et.creation_ctx->get_client_cs()->csname),
-+ scs);
-+
-+ sch_table->field[ISE_CONNECTION_CL]->set_notnull();
-+ sch_table->field[ISE_CONNECTION_CL]->store(
-+ et.creation_ctx->get_connection_cl()->name,
-+ strlen(et.creation_ctx->get_connection_cl()->name),
-+ scs);
-+
-+ sch_table->field[ISE_DB_CL]->set_notnull();
-+ sch_table->field[ISE_DB_CL]->store(
-+ et.creation_ctx->get_db_cl()->name,
-+ strlen(et.creation_ctx->get_db_cl()->name),
-+ scs);
-+
-+ if (schema_table_store_record(thd, sch_table))
-+ DBUG_RETURN(1);
-+
-+ DBUG_RETURN(0);
-+}
-+#endif
-+
-+int fill_open_tables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_open_tables");
-+ const char *wild= thd->lex->wild ? thd->lex->wild->ptr() : NullS;
-+ TABLE *table= tables->table;
-+ CHARSET_INFO *cs= system_charset_info;
-+ OPEN_TABLE_LIST *open_list;
-+ if (!(open_list=list_open_tables(thd,thd->lex->select_lex.db, wild))
-+ && thd->is_fatal_error)
-+ DBUG_RETURN(1);
-+
-+ for (; open_list ; open_list=open_list->next)
-+ {
-+ restore_record(table, s->default_values);
-+ table->field[0]->store(open_list->db, strlen(open_list->db), cs);
-+ table->field[1]->store(open_list->table, strlen(open_list->table), cs);
-+ table->field[2]->store((longlong) open_list->in_use, TRUE);
-+ table->field[3]->store((longlong) open_list->locked, TRUE);
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_variables");
-+ int res= 0;
-+ LEX *lex= thd->lex;
-+ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-+ enum enum_schema_tables schema_table_idx=
-+ get_schema_table_idx(tables->schema_table);
-+ enum enum_var_type option_type= OPT_SESSION;
-+ bool upper_case_names= (schema_table_idx != SCH_VARIABLES);
-+ bool sorted_vars= (schema_table_idx == SCH_VARIABLES);
-+
-+ if (lex->option_type == OPT_GLOBAL ||
-+ schema_table_idx == SCH_GLOBAL_VARIABLES)
-+ option_type= OPT_GLOBAL;
-+
-+ rw_rdlock(&LOCK_system_variables_hash);
-+ res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
-+ option_type, NULL, "", tables->table, upper_case_names, cond);
-+ rw_unlock(&LOCK_system_variables_hash);
-+ DBUG_RETURN(res);
-+}
-+
-+
-+int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_status");
-+ LEX *lex= thd->lex;
-+ const char *wild= lex->wild ? lex->wild->ptr() : NullS;
-+ int res= 0;
-+ STATUS_VAR *tmp1, tmp;
-+ enum enum_schema_tables schema_table_idx=
-+ get_schema_table_idx(tables->schema_table);
-+ enum enum_var_type option_type;
-+ bool upper_case_names= (schema_table_idx != SCH_STATUS);
-+
-+ if (schema_table_idx == SCH_STATUS)
-+ {
-+ option_type= lex->option_type;
-+ if (option_type == OPT_GLOBAL)
-+ tmp1= &tmp;
-+ else
-+ tmp1= thd->initial_status_var;
-+ }
-+ else if (schema_table_idx == SCH_GLOBAL_STATUS)
-+ {
-+ option_type= OPT_GLOBAL;
-+ tmp1= &tmp;
-+ }
-+ else
-+ {
-+ option_type= OPT_SESSION;
-+ tmp1= &thd->status_var;
-+ }
-+
-+ pthread_mutex_lock(&LOCK_status);
-+ if (option_type == OPT_GLOBAL)
-+ calc_sum_of_all_status(&tmp);
-+ res= show_status_array(thd, wild,
-+ (SHOW_VAR *)all_status_vars.buffer,
-+ option_type, tmp1, "", tables->table,
-+ upper_case_names, cond);
-+ pthread_mutex_unlock(&LOCK_status);
-+ DBUG_RETURN(res);
-+}
-+
-+
-+/*
-+ Fill and store records into I_S.referential_constraints table
-+
-+ SYNOPSIS
-+ get_referential_constraints_record()
-+ thd thread handle
-+ tables table list struct(processed table)
-+ table I_S table
-+ res 1 means the error during opening of the processed table
-+ 0 means processed table is opened without error
-+ base_name db name
-+ file_name table name
-+
-+ RETURN
-+ 0 ok
-+ # error
-+*/
-+
-+static int
-+get_referential_constraints_record(THD *thd, TABLE_LIST *tables,
-+ TABLE *table, bool res,
-+ LEX_STRING *db_name, LEX_STRING *table_name)
-+{
-+ CHARSET_INFO *cs= system_charset_info;
-+ DBUG_ENTER("get_referential_constraints_record");
-+
-+ if (res)
-+ {
-+ if (thd->is_error())
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ thd->main_da.sql_errno(), thd->main_da.message());
-+ thd->clear_error();
-+ DBUG_RETURN(0);
-+ }
-+ if (!tables->view)
-+ {
-+ List<FOREIGN_KEY_INFO> f_key_list;
-+ TABLE *show_table= tables->table;
-+
-+ // This is not needed since no statistics are displayed.
-+ // show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME);
-+
-+ show_table->file->get_foreign_key_list(thd, &f_key_list);
-+ FOREIGN_KEY_INFO *f_key_info;
-+ List_iterator_fast<FOREIGN_KEY_INFO> it(f_key_list);
-+ while ((f_key_info= it++))
-+ {
-+ restore_record(table, s->default_values);
-+ table->field[1]->store(db_name->str, db_name->length, cs);
-+ table->field[9]->store(table_name->str, table_name->length, cs);
-+ table->field[2]->store(f_key_info->forein_id->str,
-+ f_key_info->forein_id->length, cs);
-+ table->field[4]->store(f_key_info->referenced_db->str,
-+ f_key_info->referenced_db->length, cs);
-+ table->field[10]->store(f_key_info->referenced_table->str,
-+ f_key_info->referenced_table->length, cs);
-+ if (f_key_info->referenced_key_name)
-+ {
-+ table->field[5]->store(f_key_info->referenced_key_name->str,
-+ f_key_info->referenced_key_name->length, cs);
-+ table->field[5]->set_notnull();
-+ }
-+ else
-+ table->field[5]->set_null();
-+ table->field[6]->store(STRING_WITH_LEN("NONE"), cs);
-+ table->field[7]->store(f_key_info->update_method->str,
-+ f_key_info->update_method->length, cs);
-+ table->field[8]->store(f_key_info->delete_method->str,
-+ f_key_info->delete_method->length, cs);
-+ if (schema_table_store_record(thd, table))
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+struct schema_table_ref
-+{
-+ const char *table_name;
-+ ST_SCHEMA_TABLE *schema_table;
-+};
-+
-+
-+/*
-+ Find schema_tables elment by name
-+
-+ SYNOPSIS
-+ find_schema_table_in_plugin()
-+ thd thread handler
-+ plugin plugin
-+ table_name table name
-+
-+ RETURN
-+ 0 table not found
-+ 1 found the schema table
-+*/
-+static my_bool find_schema_table_in_plugin(THD *thd, plugin_ref plugin,
-+ void* p_table)
-+{
-+ schema_table_ref *p_schema_table= (schema_table_ref *)p_table;
-+ const char* table_name= p_schema_table->table_name;
-+ ST_SCHEMA_TABLE *schema_table= plugin_data(plugin, ST_SCHEMA_TABLE *);
-+ DBUG_ENTER("find_schema_table_in_plugin");
-+
-+ if (!my_strcasecmp(system_charset_info,
-+ schema_table->table_name,
-+ table_name)) {
-+ p_schema_table->schema_table= schema_table;
-+ DBUG_RETURN(1);
-+ }
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Find schema_tables elment by name
-+
-+ SYNOPSIS
-+ find_schema_table()
-+ thd thread handler
-+ table_name table name
-+
-+ RETURN
-+ 0 table not found
-+ # pointer to 'schema_tables' element
-+*/
-+
-+ST_SCHEMA_TABLE *find_schema_table(THD *thd, const char* table_name)
-+{
-+ schema_table_ref schema_table_a;
-+ ST_SCHEMA_TABLE *schema_table= schema_tables;
-+ DBUG_ENTER("find_schema_table");
-+
-+ for (; schema_table->table_name; schema_table++)
-+ {
-+ if (!my_strcasecmp(system_charset_info,
-+ schema_table->table_name,
-+ table_name))
-+ DBUG_RETURN(schema_table);
-+ }
-+
-+ schema_table_a.table_name= table_name;
-+ if (plugin_foreach(thd, find_schema_table_in_plugin,
-+ MYSQL_INFORMATION_SCHEMA_PLUGIN, &schema_table_a))
-+ DBUG_RETURN(schema_table_a.schema_table);
-+
-+ DBUG_RETURN(NULL);
-+}
-+
-+
-+ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
-+{
-+ return &schema_tables[schema_table_idx];
-+}
-+
-+
-+/**
-+ Create information_schema table using schema_table data.
-+
-+ @note
-+ For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
-+ into it two numbers, based on modulus of base-10 numbers. In the ones
-+ position is the number of decimals. Tens position is unused. In the
-+ hundreds and thousands position is a two-digit decimal number representing
-+ length. Encode this value with (decimals*100)+length , where
-+ 0<decimals<10 and 0<=length<100 .
-+
-+ @param
-+ thd thread handler
-+
-+ @param table_list Used to pass I_S table information(fields info, tables
-+ parameters etc) and table name.
-+
-+ @retval \# Pointer to created table
-+ @retval NULL Can't create table
-+*/
-+
-+TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
-+{
-+ int field_count= 0;
-+ Item *item;
-+ TABLE *table;
-+ List<Item> field_list;
-+ ST_SCHEMA_TABLE *schema_table= table_list->schema_table;
-+ ST_FIELD_INFO *fields_info= schema_table->fields_info;
-+ CHARSET_INFO *cs= system_charset_info;
-+ DBUG_ENTER("create_schema_table");
-+
-+ for (; fields_info->field_name; fields_info++)
-+ {
-+ switch (fields_info->field_type) {
-+ case MYSQL_TYPE_TINY:
-+ case MYSQL_TYPE_LONG:
-+ case MYSQL_TYPE_SHORT:
-+ case MYSQL_TYPE_LONGLONG:
-+ case MYSQL_TYPE_INT24:
-+ if (!(item= new Item_return_int(fields_info->field_name,
-+ fields_info->field_length,
-+ fields_info->field_type,
-+ fields_info->value)))
-+ {
-+ DBUG_RETURN(0);
-+ }
-+ item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
-+ break;
-+ case MYSQL_TYPE_DATE:
-+ case MYSQL_TYPE_TIME:
-+ case MYSQL_TYPE_TIMESTAMP:
-+ case MYSQL_TYPE_DATETIME:
-+ if (!(item=new Item_return_date_time(fields_info->field_name,
-+ fields_info->field_type)))
-+ {
-+ DBUG_RETURN(0);
-+ }
-+ break;
-+ case MYSQL_TYPE_FLOAT:
-+ case MYSQL_TYPE_DOUBLE:
-+ if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC,
-+ fields_info->field_length)) == NULL)
-+ DBUG_RETURN(NULL);
-+ break;
-+ case MYSQL_TYPE_DECIMAL:
-+ case MYSQL_TYPE_NEWDECIMAL:
-+ if (!(item= new Item_decimal((longlong) fields_info->value, false)))
-+ {
-+ DBUG_RETURN(0);
-+ }
-+ item->unsigned_flag= (fields_info->field_flags & MY_I_S_UNSIGNED);
-+ item->decimals= fields_info->field_length%10;
-+ item->max_length= (fields_info->field_length/100)%100;
-+ if (item->unsigned_flag == 0)
-+ item->max_length+= 1;
-+ if (item->decimals > 0)
-+ item->max_length+= 1;
-+ item->set_name(fields_info->field_name,
-+ strlen(fields_info->field_name), cs);
-+ break;
-+ case MYSQL_TYPE_TINY_BLOB:
-+ case MYSQL_TYPE_MEDIUM_BLOB:
-+ case MYSQL_TYPE_LONG_BLOB:
-+ case MYSQL_TYPE_BLOB:
-+ if (!(item= new Item_blob(fields_info->field_name,
-+ fields_info->field_length)))
-+ {
-+ DBUG_RETURN(0);
-+ }
-+ break;
-+ default:
-+ /* Don't let unimplemented types pass through. Could be a grave error. */
-+ DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
-+
-+ if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
-+ {
-+ DBUG_RETURN(0);
-+ }
-+ item->set_name(fields_info->field_name,
-+ strlen(fields_info->field_name), cs);
-+ break;
-+ }
-+ field_list.push_back(item);
-+ item->maybe_null= (fields_info->field_flags & MY_I_S_MAYBE_NULL);
-+ field_count++;
-+ }
-+ TMP_TABLE_PARAM *tmp_table_param =
-+ (TMP_TABLE_PARAM*) (thd->alloc(sizeof(TMP_TABLE_PARAM)));
-+ tmp_table_param->init();
-+ tmp_table_param->table_charset= cs;
-+ tmp_table_param->field_count= field_count;
-+ tmp_table_param->schema_table= 1;
-+ SELECT_LEX *select_lex= thd->lex->current_select;
-+ if (!(table= create_tmp_table(thd, tmp_table_param,
-+ field_list, (ORDER*) 0, 0, 0,
-+ (select_lex->options | thd->options |
-+ TMP_TABLE_ALL_COLUMNS),
-+ HA_POS_ERROR, table_list->alias)))
-+ DBUG_RETURN(0);
-+ my_bitmap_map* bitmaps=
-+ (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count));
-+ bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count,
-+ FALSE);
-+ table->read_set= &table->def_read_set;
-+ bitmap_clear_all(table->read_set);
-+ table_list->schema_table_param= tmp_table_param;
-+ DBUG_RETURN(table);
-+}
-+
-+
-+/*
-+ For old SHOW compatibility. It is used when
-+ old SHOW doesn't have generated column names
-+ Make list of fields for SHOW
-+
-+ SYNOPSIS
-+ make_old_format()
-+ thd thread handler
-+ schema_table pointer to 'schema_tables' element
-+
-+ RETURN
-+ 1 error
-+ 0 success
-+*/
-+
-+int make_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ ST_FIELD_INFO *field_info= schema_table->fields_info;
-+ Name_resolution_context *context= &thd->lex->select_lex.context;
-+ for (; field_info->field_name; field_info++)
-+ {
-+ if (field_info->old_name)
-+ {
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (field)
-+ {
-+ field->set_name(field_info->old_name,
-+ strlen(field_info->old_name),
-+ system_charset_info);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ }
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+int make_schemata_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ char tmp[128];
-+ LEX *lex= thd->lex;
-+ SELECT_LEX *sel= lex->current_select;
-+ Name_resolution_context *context= &sel->context;
-+
-+ if (!sel->item_list.elements)
-+ {
-+ ST_FIELD_INFO *field_info= &schema_table->fields_info[1];
-+ String buffer(tmp,sizeof(tmp), system_charset_info);
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (!field || add_item_to_list(thd, field))
-+ return 1;
-+ buffer.length(0);
-+ buffer.append(field_info->old_name);
-+ if (lex->wild && lex->wild->ptr())
-+ {
-+ buffer.append(STRING_WITH_LEN(" ("));
-+ buffer.append(lex->wild->ptr());
-+ buffer.append(')');
-+ }
-+ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+ }
-+ return 0;
-+}
-+
-+
-+int make_table_names_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ char tmp[128];
-+ String buffer(tmp,sizeof(tmp), thd->charset());
-+ LEX *lex= thd->lex;
-+ Name_resolution_context *context= &lex->select_lex.context;
-+
-+ ST_FIELD_INFO *field_info= &schema_table->fields_info[2];
-+ buffer.length(0);
-+ buffer.append(field_info->old_name);
-+ buffer.append(lex->select_lex.db);
-+ if (lex->wild && lex->wild->ptr())
-+ {
-+ buffer.append(STRING_WITH_LEN(" ("));
-+ buffer.append(lex->wild->ptr());
-+ buffer.append(')');
-+ }
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+ if (thd->lex->verbose)
-+ {
-+ field->set_name(buffer.ptr(), buffer.length(), system_charset_info);
-+ field_info= &schema_table->fields_info[3];
-+ field= new Item_field(context, NullS, NullS, field_info->field_name);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ field->set_name(field_info->old_name, strlen(field_info->old_name),
-+ system_charset_info);
-+ }
-+ return 0;
-+}
-+
-+
-+int make_columns_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ int fields_arr[]= {3, 14, 13, 6, 15, 5, 16, 17, 18, -1};
-+ int *field_num= fields_arr;
-+ ST_FIELD_INFO *field_info;
-+ Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+ for (; *field_num >= 0; field_num++)
-+ {
-+ field_info= &schema_table->fields_info[*field_num];
-+ if (!thd->lex->verbose && (*field_num == 13 ||
-+ *field_num == 17 ||
-+ *field_num == 18))
-+ continue;
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (field)
-+ {
-+ field->set_name(field_info->old_name,
-+ strlen(field_info->old_name),
-+ system_charset_info);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+int make_character_sets_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ int fields_arr[]= {0, 2, 1, 3, -1};
-+ int *field_num= fields_arr;
-+ ST_FIELD_INFO *field_info;
-+ Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+ for (; *field_num >= 0; field_num++)
-+ {
-+ field_info= &schema_table->fields_info[*field_num];
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (field)
-+ {
-+ field->set_name(field_info->old_name,
-+ strlen(field_info->old_name),
-+ system_charset_info);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+int make_proc_old_format(THD *thd, ST_SCHEMA_TABLE *schema_table)
-+{
-+ int fields_arr[]= {2, 3, 4, 19, 16, 15, 14, 18, 20, 21, 22, -1};
-+ int *field_num= fields_arr;
-+ ST_FIELD_INFO *field_info;
-+ Name_resolution_context *context= &thd->lex->select_lex.context;
-+
-+ for (; *field_num >= 0; field_num++)
-+ {
-+ field_info= &schema_table->fields_info[*field_num];
-+ Item_field *field= new Item_field(context,
-+ NullS, NullS, field_info->field_name);
-+ if (field)
-+ {
-+ field->set_name(field_info->old_name,
-+ strlen(field_info->old_name),
-+ system_charset_info);
-+ if (add_item_to_list(thd, field))
-+ return 1;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ Create information_schema table
-+
-+ SYNOPSIS
-+ mysql_schema_table()
-+ thd thread handler
-+ lex pointer to LEX
-+ table_list pointer to table_list
-+
-+ RETURN
-+ 0 success
-+ 1 error
-+*/
-+
-+int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
-+{
-+ TABLE *table;
-+ DBUG_ENTER("mysql_schema_table");
-+ if (!(table= table_list->schema_table->create_table(thd, table_list)))
-+ DBUG_RETURN(1);
-+ table->s->tmp_table= SYSTEM_TMP_TABLE;
-+ table->grant.privilege= SELECT_ACL;
-+ /*
-+ This test is necessary to make
-+ case insensitive file systems +
-+ upper case table names(information schema tables) +
-+ views
-+ working correctly
-+ */
-+ if (table_list->schema_table_name)
-+ table->alias_name_used= my_strcasecmp(table_alias_charset,
-+ table_list->schema_table_name,
-+ table_list->alias);
-+ table_list->table_name= table->s->table_name.str;
-+ table_list->table_name_length= table->s->table_name.length;
-+ table_list->table= table;
-+ table->next= thd->derived_tables;
-+ thd->derived_tables= table;
-+ table_list->select_lex->options |= OPTION_SCHEMA_TABLE;
-+ lex->safe_to_cache_query= 0;
-+
-+ if (table_list->schema_table_reformed) // show command
-+ {
-+ SELECT_LEX *sel= lex->current_select;
-+ Item *item;
-+ Field_translator *transl, *org_transl;
-+
-+ if (table_list->field_translation)
-+ {
-+ Field_translator *end= table_list->field_translation_end;
-+ for (transl= table_list->field_translation; transl < end; transl++)
-+ {
-+ if (!transl->item->fixed &&
-+ transl->item->fix_fields(thd, &transl->item))
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+ }
-+ List_iterator_fast<Item> it(sel->item_list);
-+ if (!(transl=
-+ (Field_translator*)(thd->stmt_arena->
-+ alloc(sel->item_list.elements *
-+ sizeof(Field_translator)))))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ for (org_transl= transl; (item= it++); transl++)
-+ {
-+ transl->item= item;
-+ transl->name= item->name;
-+ if (!item->fixed && item->fix_fields(thd, &transl->item))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ }
-+ table_list->field_translation= org_transl;
-+ table_list->field_translation_end= transl;
-+ }
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Generate select from information_schema table
-+
-+ SYNOPSIS
-+ make_schema_select()
-+ thd thread handler
-+ sel pointer to SELECT_LEX
-+ schema_table_idx index of 'schema_tables' element
-+
-+ RETURN
-+ 0 success
-+ 1 error
-+*/
-+
-+int make_schema_select(THD *thd, SELECT_LEX *sel,
-+ enum enum_schema_tables schema_table_idx)
-+{
-+ ST_SCHEMA_TABLE *schema_table= get_schema_table(schema_table_idx);
-+ LEX_STRING db, table;
-+ DBUG_ENTER("make_schema_select");
-+ DBUG_PRINT("enter", ("mysql_schema_select: %s", schema_table->table_name));
-+ /*
-+ We have to make non const db_name & table_name
-+ because of lower_case_table_names
-+ */
-+ thd->make_lex_string(&db, INFORMATION_SCHEMA_NAME.str,
-+ INFORMATION_SCHEMA_NAME.length, 0);
-+ thd->make_lex_string(&table, schema_table->table_name,
-+ strlen(schema_table->table_name), 0);
-+ if (schema_table->old_format(thd, schema_table) || /* Handle old syntax */
-+ !sel->add_table_to_list(thd, new Table_ident(thd, db, table, 0),
-+ 0, 0, TL_READ))
-+ {
-+ DBUG_RETURN(1);
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Fill temporary schema tables before SELECT
-+
-+ SYNOPSIS
-+ get_schema_tables_result()
-+ join join which use schema tables
-+ executed_place place where I_S table processed
-+
-+ RETURN
-+ FALSE success
-+ TRUE error
-+*/
-+
-+bool get_schema_tables_result(JOIN *join,
-+ enum enum_schema_table_state executed_place)
-+{
-+ JOIN_TAB *tmp_join_tab= join->join_tab+join->tables;
-+ THD *thd= join->thd;
-+ LEX *lex= thd->lex;
-+ bool result= 0;
-+ DBUG_ENTER("get_schema_tables_result");
-+
-+ thd->no_warnings_for_error= 1;
-+ for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++)
-+ {
-+ if (!tab->table || !tab->table->pos_in_table_list)
-+ break;
-+
-+ TABLE_LIST *table_list= tab->table->pos_in_table_list;
-+ if (table_list->schema_table && thd->fill_information_schema_tables())
-+ {
-+ bool is_subselect= (&lex->unit != lex->current_select->master_unit() &&
-+ lex->current_select->master_unit()->item);
-+
-+ /* A value of 0 indicates a dummy implementation */
-+ if (table_list->schema_table->fill_table == 0)
-+ continue;
-+
-+ /* skip I_S optimizations specific to get_all_tables */
-+ if (thd->lex->describe &&
-+ (table_list->schema_table->fill_table != get_all_tables))
-+ continue;
-+
-+ /*
-+ If schema table is already processed and
-+ the statement is not a subselect then
-+ we don't need to fill this table again.
-+ If schema table is already processed and
-+ schema_table_state != executed_place then
-+ table is already processed and
-+ we should skip second data processing.
-+ */
-+ if (table_list->schema_table_state &&
-+ (!is_subselect || table_list->schema_table_state != executed_place))
-+ continue;
-+
-+ /*
-+ if table is used in a subselect and
-+ table has been processed earlier with the same
-+ 'executed_place' value then we should refresh the table.
-+ */
-+ if (table_list->schema_table_state && is_subselect)
-+ {
-+ table_list->table->file->extra(HA_EXTRA_NO_CACHE);
-+ table_list->table->file->extra(HA_EXTRA_RESET_STATE);
-+ table_list->table->file->ha_delete_all_rows();
-+ free_io_cache(table_list->table);
-+ filesort_free_buffers(table_list->table,1);
-+ table_list->table->null_row= 0;
-+ }
-+ else
-+ table_list->table->file->stats.records= 0;
-+
-+ if (table_list->schema_table->fill_table(thd, table_list,
-+ tab->select_cond))
-+ {
-+ result= 1;
-+ join->error= 1;
-+ tab->read_record.file= table_list->table->file;
-+ table_list->schema_table_state= executed_place;
-+ break;
-+ }
-+ tab->read_record.file= table_list->table->file;
-+ table_list->schema_table_state= executed_place;
-+ }
-+ }
-+ thd->no_warnings_for_error= 0;
-+ DBUG_RETURN(result);
-+}
-+
-+struct run_hton_fill_schema_files_args
-+{
-+ TABLE_LIST *tables;
-+ COND *cond;
-+};
-+
-+static my_bool run_hton_fill_schema_files(THD *thd, plugin_ref plugin,
-+ void *arg)
-+{
-+ struct run_hton_fill_schema_files_args *args=
-+ (run_hton_fill_schema_files_args *) arg;
-+ handlerton *hton= plugin_data(plugin, handlerton *);
-+ if(hton->fill_files_table && hton->state == SHOW_OPTION_YES)
-+ hton->fill_files_table(hton, thd, args->tables, args->cond);
-+ return false;
-+}
-+
-+int fill_schema_files(THD *thd, TABLE_LIST *tables, COND *cond)
-+{
-+ DBUG_ENTER("fill_schema_files");
-+
-+ struct run_hton_fill_schema_files_args args;
-+ args.tables= tables;
-+ args.cond= cond;
-+
-+ plugin_foreach(thd, run_hton_fill_schema_files,
-+ MYSQL_STORAGE_ENGINE_PLUGIN, &args);
-+
-+ DBUG_RETURN(0);
-+}
-+
-+
-+ST_FIELD_INFO schema_fields_info[]=
-+{
-+ {"CATALOG_NAME", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"SCHEMA_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
-+ SKIP_OPEN_TABLE},
-+ {"DEFAULT_CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ SKIP_OPEN_TABLE},
-+ {"DEFAULT_COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ SKIP_OPEN_TABLE},
-+ {"SQL_PATH", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO tables_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
-+ SKIP_OPEN_TABLE},
-+ {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Engine", OPEN_FRM_ONLY},
-+ {"VERSION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", OPEN_FRM_ONLY},
-+ {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", OPEN_FULL_TABLE},
-+ {"TABLE_ROWS", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", OPEN_FULL_TABLE},
-+ {"AVG_ROW_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", OPEN_FULL_TABLE},
-+ {"DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", OPEN_FULL_TABLE},
-+ {"MAX_DATA_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", OPEN_FULL_TABLE},
-+ {"INDEX_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", OPEN_FULL_TABLE},
-+ {"DATA_FREE", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", OPEN_FULL_TABLE},
-+ {"AUTO_INCREMENT", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Auto_increment", OPEN_FULL_TABLE},
-+ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", OPEN_FULL_TABLE},
-+ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", OPEN_FULL_TABLE},
-+ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", OPEN_FULL_TABLE},
-+ {"TABLE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
-+ OPEN_FRM_ONLY},
-+ {"CHECKSUM", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", OPEN_FULL_TABLE},
-+ {"CREATE_OPTIONS", 255, MYSQL_TYPE_STRING, 0, 1, "Create_options",
-+ OPEN_FRM_ONLY},
-+ {"TABLE_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO columns_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Field",
-+ OPEN_FRM_ONLY},
-+ {"ORDINAL_POSITION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0,
-+ MY_I_S_UNSIGNED, 0, OPEN_FRM_ONLY},
-+ {"COLUMN_DEFAULT", MAX_FIELD_VARCHARLENGTH, MYSQL_TYPE_STRING, 0,
-+ 1, "Default", OPEN_FRM_ONLY},
-+ {"IS_NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
-+ {"DATA_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"CHARACTER_MAXIMUM_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
-+ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
-+ {"CHARACTER_OCTET_LENGTH", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
-+ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
-+ {"NUMERIC_PRECISION", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG,
-+ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
-+ {"NUMERIC_SCALE", MY_INT64_NUM_DECIMAL_DIGITS , MYSQL_TYPE_LONGLONG,
-+ 0, (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FRM_ONLY},
-+ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FRM_ONLY},
-+ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 1, "Collation",
-+ OPEN_FRM_ONLY},
-+ {"COLUMN_TYPE", 65535, MYSQL_TYPE_STRING, 0, 0, "Type", OPEN_FRM_ONLY},
-+ {"COLUMN_KEY", 3, MYSQL_TYPE_STRING, 0, 0, "Key", OPEN_FRM_ONLY},
-+ {"EXTRA", 27, MYSQL_TYPE_STRING, 0, 0, "Extra", OPEN_FRM_ONLY},
-+ {"PRIVILEGES", 80, MYSQL_TYPE_STRING, 0, 0, "Privileges", OPEN_FRM_ONLY},
-+ {"COLUMN_COMMENT", 255, MYSQL_TYPE_STRING, 0, 0, "Comment", OPEN_FRM_ONLY},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO charsets_fields_info[]=
-+{
-+ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
-+ SKIP_OPEN_TABLE},
-+ {"DEFAULT_COLLATE_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "Default collation", SKIP_OPEN_TABLE},
-+ {"DESCRIPTION", 60, MYSQL_TYPE_STRING, 0, 0, "Description",
-+ SKIP_OPEN_TABLE},
-+ {"MAXLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Maxlen", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO collation_fields_info[]=
-+{
-+ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Collation",
-+ SKIP_OPEN_TABLE},
-+ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, "Charset",
-+ SKIP_OPEN_TABLE},
-+ {"ID", MY_INT32_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 0, "Id",
-+ SKIP_OPEN_TABLE},
-+ {"IS_DEFAULT", 3, MYSQL_TYPE_STRING, 0, 0, "Default", SKIP_OPEN_TABLE},
-+ {"IS_COMPILED", 3, MYSQL_TYPE_STRING, 0, 0, "Compiled", SKIP_OPEN_TABLE},
-+ {"SORTLEN", 3, MYSQL_TYPE_LONGLONG, 0, 0, "Sortlen", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO engines_fields_info[]=
-+{
-+ {"ENGINE", 64, MYSQL_TYPE_STRING, 0, 0, "Engine", SKIP_OPEN_TABLE},
-+ {"SUPPORT", 8, MYSQL_TYPE_STRING, 0, 0, "Support", SKIP_OPEN_TABLE},
-+ {"COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, "Comment", SKIP_OPEN_TABLE},
-+ {"TRANSACTIONS", 3, MYSQL_TYPE_STRING, 0, 1, "Transactions", SKIP_OPEN_TABLE},
-+ {"XA", 3, MYSQL_TYPE_STRING, 0, 1, "XA", SKIP_OPEN_TABLE},
-+ {"SAVEPOINTS", 3 ,MYSQL_TYPE_STRING, 0, 1, "Savepoints", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO events_fields_info[]=
-+{
-+ {"EVENT_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"EVENT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
-+ SKIP_OPEN_TABLE},
-+ {"EVENT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
-+ SKIP_OPEN_TABLE},
-+ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
-+ {"TIME_ZONE", 64, MYSQL_TYPE_STRING, 0, 0, "Time zone", SKIP_OPEN_TABLE},
-+ {"EVENT_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"EVENT_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"EVENT_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
-+ {"EXECUTE_AT", 0, MYSQL_TYPE_DATETIME, 0, 1, "Execute at", SKIP_OPEN_TABLE},
-+ {"INTERVAL_VALUE", 256, MYSQL_TYPE_STRING, 0, 1, "Interval value",
-+ SKIP_OPEN_TABLE},
-+ {"INTERVAL_FIELD", 18, MYSQL_TYPE_STRING, 0, 1, "Interval field",
-+ SKIP_OPEN_TABLE},
-+ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"STARTS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Starts", SKIP_OPEN_TABLE},
-+ {"ENDS", 0, MYSQL_TYPE_DATETIME, 0, 1, "Ends", SKIP_OPEN_TABLE},
-+ {"STATUS", 18, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
-+ {"ON_COMPLETION", 12, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"LAST_EXECUTED", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"EVENT_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"ORIGINATOR", 10, MYSQL_TYPE_LONGLONG, 0, 0, "Originator", SKIP_OPEN_TABLE},
-+ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "character_set_client", SKIP_OPEN_TABLE},
-+ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "collation_connection", SKIP_OPEN_TABLE},
-+ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "Database Collation", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+
-+ST_FIELD_INFO coll_charset_app_fields_info[]=
-+{
-+ {"COLLATION_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ SKIP_OPEN_TABLE},
-+ {"CHARACTER_SET_NAME", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO proc_fields_info[]=
-+{
-+ {"SPECIFIC_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"ROUTINE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"ROUTINE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Db",
-+ SKIP_OPEN_TABLE},
-+ {"ROUTINE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
-+ SKIP_OPEN_TABLE},
-+ {"ROUTINE_TYPE", 9, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
-+ {"DTD_IDENTIFIER", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"ROUTINE_BODY", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"ROUTINE_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"EXTERNAL_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"EXTERNAL_LANGUAGE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ SKIP_OPEN_TABLE},
-+ {"PARAMETER_STYLE", 8, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"IS_DETERMINISTIC", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"SQL_DATA_ACCESS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ SKIP_OPEN_TABLE},
-+ {"SQL_PATH", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, "Security_type",
-+ SKIP_OPEN_TABLE},
-+ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Created", SKIP_OPEN_TABLE},
-+ {"LAST_ALTERED", 0, MYSQL_TYPE_DATETIME, 0, 0, "Modified", SKIP_OPEN_TABLE},
-+ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"ROUTINE_COMMENT", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Comment",
-+ SKIP_OPEN_TABLE},
-+ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", SKIP_OPEN_TABLE},
-+ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "character_set_client", SKIP_OPEN_TABLE},
-+ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "collation_connection", SKIP_OPEN_TABLE},
-+ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "Database Collation", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO stat_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", OPEN_FRM_ONLY},
-+ {"NON_UNIQUE", 1, MYSQL_TYPE_LONGLONG, 0, 0, "Non_unique", OPEN_FRM_ONLY},
-+ {"INDEX_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"INDEX_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Key_name",
-+ OPEN_FRM_ONLY},
-+ {"SEQ_IN_INDEX", 2, MYSQL_TYPE_LONGLONG, 0, 0, "Seq_in_index", OPEN_FRM_ONLY},
-+ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Column_name",
-+ OPEN_FRM_ONLY},
-+ {"COLLATION", 1, MYSQL_TYPE_STRING, 0, 1, "Collation", OPEN_FRM_ONLY},
-+ {"CARDINALITY", MY_INT64_NUM_DECIMAL_DIGITS, MYSQL_TYPE_LONGLONG, 0, 1,
-+ "Cardinality", OPEN_FULL_TABLE},
-+ {"SUB_PART", 3, MYSQL_TYPE_LONGLONG, 0, 1, "Sub_part", OPEN_FRM_ONLY},
-+ {"PACKED", 10, MYSQL_TYPE_STRING, 0, 1, "Packed", OPEN_FRM_ONLY},
-+ {"NULLABLE", 3, MYSQL_TYPE_STRING, 0, 0, "Null", OPEN_FRM_ONLY},
-+ {"INDEX_TYPE", 16, MYSQL_TYPE_STRING, 0, 0, "Index_type", OPEN_FULL_TABLE},
-+ {"COMMENT", 16, MYSQL_TYPE_STRING, 0, 1, "Comment", OPEN_FRM_ONLY},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO view_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FRM_ONLY},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FRM_ONLY},
-+ {"VIEW_DEFINITION", 65535, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"CHECK_OPTION", 8, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"IS_UPDATABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"SECURITY_TYPE", 7, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO user_privileges_fields_info[]=
-+{
-+ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO schema_privileges_fields_info[]=
-+{
-+ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO table_privileges_fields_info[]=
-+{
-+ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO column_privileges_fields_info[]=
-+{
-+ {"GRANTEE", 81, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"PRIVILEGE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"IS_GRANTABLE", 3, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO table_constraints_fields_info[]=
-+{
-+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"CONSTRAINT_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO key_column_usage_fields_info[]=
-+{
-+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"ORDINAL_POSITION", 10 ,MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"POSITION_IN_UNIQUE_CONSTRAINT", 10 ,MYSQL_TYPE_LONGLONG, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"REFERENCED_TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"REFERENCED_COLUMN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO table_names_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Tables_in_",
-+ SKIP_OPEN_TABLE},
-+ {"TABLE_TYPE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table_type",
-+ OPEN_FRM_ONLY},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO open_tables_fields_info[]=
-+{
-+ {"Database", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Database",
-+ SKIP_OPEN_TABLE},
-+ {"Table",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table", SKIP_OPEN_TABLE},
-+ {"In_use", 1, MYSQL_TYPE_LONGLONG, 0, 0, "In_use", SKIP_OPEN_TABLE},
-+ {"Name_locked", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Name_locked", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO triggers_fields_info[]=
-+{
-+ {"TRIGGER_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"TRIGGER_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TRIGGER_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Trigger",
-+ OPEN_FULL_TABLE},
-+ {"EVENT_MANIPULATION", 6, MYSQL_TYPE_STRING, 0, 0, "Event", OPEN_FULL_TABLE},
-+ {"EVENT_OBJECT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"EVENT_OBJECT_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"EVENT_OBJECT_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Table",
-+ OPEN_FULL_TABLE},
-+ {"ACTION_ORDER", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"ACTION_CONDITION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"ACTION_STATEMENT", 65535, MYSQL_TYPE_STRING, 0, 0, "Statement",
-+ OPEN_FULL_TABLE},
-+ {"ACTION_ORIENTATION", 9, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"ACTION_TIMING", 6, MYSQL_TYPE_STRING, 0, 0, "Timing", OPEN_FULL_TABLE},
-+ {"ACTION_REFERENCE_OLD_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"ACTION_REFERENCE_NEW_TABLE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"ACTION_REFERENCE_OLD_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"ACTION_REFERENCE_NEW_ROW", 3, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"CREATED", 0, MYSQL_TYPE_DATETIME, 0, 1, "Created", OPEN_FULL_TABLE},
-+ {"SQL_MODE", 32*256, MYSQL_TYPE_STRING, 0, 0, "sql_mode", OPEN_FULL_TABLE},
-+ {"DEFINER", 77, MYSQL_TYPE_STRING, 0, 0, "Definer", OPEN_FULL_TABLE},
-+ {"CHARACTER_SET_CLIENT", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "character_set_client", OPEN_FULL_TABLE},
-+ {"COLLATION_CONNECTION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "collation_connection", OPEN_FULL_TABLE},
-+ {"DATABASE_COLLATION", MY_CS_NAME_SIZE, MYSQL_TYPE_STRING, 0, 0,
-+ "Database Collation", OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO partitions_fields_info[]=
-+{
-+ {"TABLE_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"TABLE_SCHEMA",NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"PARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"SUBPARTITION_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"PARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
-+ {"SUBPARTITION_ORDINAL_POSITION", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
-+ {"PARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"SUBPARTITION_METHOD", 12, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"PARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"SUBPARTITION_EXPRESSION", 65535, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"PARTITION_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
-+ OPEN_FULL_TABLE},
-+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
-+ OPEN_FULL_TABLE},
-+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
-+ OPEN_FULL_TABLE},
-+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
-+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
-+ OPEN_FULL_TABLE},
-+ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0, MY_I_S_UNSIGNED, 0,
-+ OPEN_FULL_TABLE},
-+ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, OPEN_FULL_TABLE},
-+ {"PARTITION_COMMENT", 80, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"NODEGROUP", 12 , MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO variables_fields_info[]=
-+{
-+ {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
-+ SKIP_OPEN_TABLE},
-+ {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO processlist_fields_info[]=
-+{
-+ {"ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, "Id", SKIP_OPEN_TABLE},
-+ {"USER", 16, MYSQL_TYPE_STRING, 0, 0, "User", SKIP_OPEN_TABLE},
-+ {"HOST", LIST_PROCESS_HOST_LEN, MYSQL_TYPE_STRING, 0, 0, "Host",
-+ SKIP_OPEN_TABLE},
-+ {"DB", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Db", SKIP_OPEN_TABLE},
-+ {"COMMAND", 16, MYSQL_TYPE_STRING, 0, 0, "Command", SKIP_OPEN_TABLE},
-+ {"TIME", 7, MYSQL_TYPE_LONG, 0, 0, "Time", SKIP_OPEN_TABLE},
-+ {"STATE", 64, MYSQL_TYPE_STRING, 0, 1, "State", SKIP_OPEN_TABLE},
-+ {"INFO", PROCESS_LIST_INFO_WIDTH, MYSQL_TYPE_STRING, 0, 1, "Info",
-+ SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+ST_FIELD_INFO plugin_fields_info[]=
-+{
-+ {"PLUGIN_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, "Name",
-+ SKIP_OPEN_TABLE},
-+ {"PLUGIN_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"PLUGIN_STATUS", 10, MYSQL_TYPE_STRING, 0, 0, "Status", SKIP_OPEN_TABLE},
-+ {"PLUGIN_TYPE", 80, MYSQL_TYPE_STRING, 0, 0, "Type", SKIP_OPEN_TABLE},
-+ {"PLUGIN_TYPE_VERSION", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"PLUGIN_LIBRARY", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, "Library",
-+ SKIP_OPEN_TABLE},
-+ {"PLUGIN_LIBRARY_VERSION", 20, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"PLUGIN_AUTHOR", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"PLUGIN_DESCRIPTION", 65535, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"PLUGIN_LICENSE", 80, MYSQL_TYPE_STRING, 0, 1, "License", SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+ST_FIELD_INFO files_fields_info[]=
-+{
-+ {"FILE_ID", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"FILE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"FILE_TYPE", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"TABLESPACE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ SKIP_OPEN_TABLE},
-+ {"TABLE_CATALOG", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"LOGFILE_GROUP_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ SKIP_OPEN_TABLE},
-+ {"LOGFILE_GROUP_NUMBER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"ENGINE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"FULLTEXT_KEYS", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"DELETED_ROWS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"UPDATE_COUNT", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"FREE_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TOTAL_EXTENTS", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"EXTENT_SIZE", 4, MYSQL_TYPE_LONGLONG, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"INITIAL_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
-+ {"MAXIMUM_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
-+ {"AUTOEXTEND_SIZE", 21, MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), 0, SKIP_OPEN_TABLE},
-+ {"CREATION_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"LAST_UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"LAST_ACCESS_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"RECOVER_TIME", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"TRANSACTION_COUNTER", 4, MYSQL_TYPE_LONGLONG, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {"VERSION", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Version", SKIP_OPEN_TABLE},
-+ {"ROW_FORMAT", 10, MYSQL_TYPE_STRING, 0, 1, "Row_format", SKIP_OPEN_TABLE},
-+ {"TABLE_ROWS", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Rows", SKIP_OPEN_TABLE},
-+ {"AVG_ROW_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Avg_row_length", SKIP_OPEN_TABLE},
-+ {"DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_length", SKIP_OPEN_TABLE},
-+ {"MAX_DATA_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Max_data_length", SKIP_OPEN_TABLE},
-+ {"INDEX_LENGTH", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Index_length", SKIP_OPEN_TABLE},
-+ {"DATA_FREE", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Data_free", SKIP_OPEN_TABLE},
-+ {"CREATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Create_time", SKIP_OPEN_TABLE},
-+ {"UPDATE_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Update_time", SKIP_OPEN_TABLE},
-+ {"CHECK_TIME", 0, MYSQL_TYPE_DATETIME, 0, 1, "Check_time", SKIP_OPEN_TABLE},
-+ {"CHECKSUM", 21 , MYSQL_TYPE_LONGLONG, 0,
-+ (MY_I_S_MAYBE_NULL | MY_I_S_UNSIGNED), "Checksum", SKIP_OPEN_TABLE},
-+ {"STATUS", 20, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE},
-+ {"EXTRA", 255, MYSQL_TYPE_STRING, 0, 1, 0, SKIP_OPEN_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+void init_fill_schema_files_row(TABLE* table)
-+{
-+ int i;
-+ for(i=0; files_fields_info[i].field_name!=NULL; i++)
-+ table->field[i]->set_null();
-+
-+ table->field[IS_FILES_STATUS]->set_notnull();
-+ table->field[IS_FILES_STATUS]->store("NORMAL", 6, system_charset_info);
-+}
-+
-+ST_FIELD_INFO referential_constraints_fields_info[]=
-+{
-+ {"CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0, OPEN_FULL_TABLE},
-+ {"CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"UNIQUE_CONSTRAINT_CATALOG", FN_REFLEN, MYSQL_TYPE_STRING, 0, 1, 0,
-+ OPEN_FULL_TABLE},
-+ {"UNIQUE_CONSTRAINT_SCHEMA", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {"UNIQUE_CONSTRAINT_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0,
-+ MY_I_S_MAYBE_NULL, 0, OPEN_FULL_TABLE},
-+ {"MATCH_OPTION", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"UPDATE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"DELETE_RULE", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0, OPEN_FULL_TABLE},
-+ {"REFERENCED_TABLE_NAME", NAME_CHAR_LEN, MYSQL_TYPE_STRING, 0, 0, 0,
-+ OPEN_FULL_TABLE},
-+ {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
-+};
-+
-+
-+/*
-+ Description of ST_FIELD_INFO in table.h
-+
-+ Make sure that the order of schema_tables and enum_schema_tables are the same.
-+
-+*/
-+
-+ST_SCHEMA_TABLE schema_tables[]=
-+{
-+ {"CHARACTER_SETS", charsets_fields_info, create_schema_table,
-+ fill_schema_charsets, make_character_sets_old_format, 0, -1, -1, 0, 0},
-+ {"COLLATIONS", collation_fields_info, create_schema_table,
-+ fill_schema_collation, make_old_format, 0, -1, -1, 0, 0},
-+ {"COLLATION_CHARACTER_SET_APPLICABILITY", coll_charset_app_fields_info,
-+ create_schema_table, fill_schema_coll_charset_app, 0, 0, -1, -1, 0, 0},
-+ {"COLUMNS", columns_fields_info, create_schema_table,
-+ get_all_tables, make_columns_old_format, get_schema_column_record, 1, 2, 0,
-+ OPTIMIZE_I_S_TABLE|OPEN_VIEW_FULL},
-+ {"COLUMN_PRIVILEGES", column_privileges_fields_info, create_schema_table,
-+ fill_schema_column_privileges, 0, 0, -1, -1, 0, 0},
-+ {"ENGINES", engines_fields_info, create_schema_table,
-+ fill_schema_engines, make_old_format, 0, -1, -1, 0, 0},
-+#ifdef HAVE_EVENT_SCHEDULER
-+ {"EVENTS", events_fields_info, create_schema_table,
-+ Events::fill_schema_events, make_old_format, 0, -1, -1, 0, 0},
-+#else
-+ {"EVENTS", events_fields_info, create_schema_table,
-+ 0, make_old_format, 0, -1, -1, 0, 0},
-+#endif
-+ {"FILES", files_fields_info, create_schema_table,
-+ fill_schema_files, 0, 0, -1, -1, 0, 0},
-+ {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
-+ fill_status, make_old_format, 0, 0, -1, 0, 0},
-+ {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
-+ fill_variables, make_old_format, 0, 0, -1, 0, 0},
-+ {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
-+ get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
-+ OPEN_TABLE_ONLY},
-+ {"OPEN_TABLES", open_tables_fields_info, create_schema_table,
-+ fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
-+ {"PARTITIONS", partitions_fields_info, create_schema_table,
-+ get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY},
-+ {"PLUGINS", plugin_fields_info, create_schema_table,
-+ fill_plugins, make_old_format, 0, -1, -1, 0, 0},
-+ {"PROCESSLIST", processlist_fields_info, create_schema_table,
-+ fill_schema_processlist, make_old_format, 0, -1, -1, 0, 0},
-+ {"PROFILING", query_profile_statistics_info, create_schema_table,
-+ fill_query_profile_statistics_info, make_profile_table_for_show,
-+ NULL, -1, -1, false, 0},
-+ {"REFERENTIAL_CONSTRAINTS", referential_constraints_fields_info,
-+ create_schema_table, get_all_tables, 0, get_referential_constraints_record,
-+ 1, 9, 0, OPEN_TABLE_ONLY},
-+ {"ROUTINES", proc_fields_info, create_schema_table,
-+ fill_schema_proc, make_proc_old_format, 0, -1, -1, 0, 0},
-+ {"SCHEMATA", schema_fields_info, create_schema_table,
-+ fill_schema_schemata, make_schemata_old_format, 0, 1, -1, 0, 0},
-+ {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
-+ fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0},
-+ {"SESSION_STATUS", variables_fields_info, create_schema_table,
-+ fill_status, make_old_format, 0, 0, -1, 0, 0},
-+ {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
-+ fill_variables, make_old_format, 0, 0, -1, 0, 0},
-+ {"STATISTICS", stat_fields_info, create_schema_table,
-+ get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
-+ OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
-+ {"STATUS", variables_fields_info, create_schema_table, fill_status,
-+ make_old_format, 0, 0, -1, 1, 0},
-+ {"TABLES", tables_fields_info, create_schema_table,
-+ get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
-+ OPTIMIZE_I_S_TABLE},
-+ {"TABLE_CONSTRAINTS", table_constraints_fields_info, create_schema_table,
-+ get_all_tables, 0, get_schema_constraints_record, 3, 4, 0, OPEN_TABLE_ONLY},
-+ {"TABLE_NAMES", table_names_fields_info, create_schema_table,
-+ get_all_tables, make_table_names_old_format, 0, 1, 2, 1, 0},
-+ {"TABLE_PRIVILEGES", table_privileges_fields_info, create_schema_table,
-+ fill_schema_table_privileges, 0, 0, -1, -1, 0, 0},
-+ {"TRIGGERS", triggers_fields_info, create_schema_table,
-+ get_all_tables, make_old_format, get_schema_triggers_record, 5, 6, 0,
-+ OPEN_TABLE_ONLY},
-+ {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table,
-+ fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
-+ {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
-+ make_old_format, 0, 0, -1, 1, 0},
-+ {"VIEWS", view_fields_info, create_schema_table,
-+ get_all_tables, 0, get_schema_views_record, 1, 2, 0,
-+ OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},
-+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
-+};
-+
-+
-+#ifdef HAVE_EXPLICIT_TEMPLATE_INSTANTIATION
-+template class List_iterator_fast<char>;
-+template class List<char>;
-+#endif
-+
-+int initialize_schema_table(st_plugin_int *plugin)
-+{
-+ ST_SCHEMA_TABLE *schema_table;
-+ DBUG_ENTER("initialize_schema_table");
-+
-+ if (!(schema_table= (ST_SCHEMA_TABLE *)my_malloc(sizeof(ST_SCHEMA_TABLE),
-+ MYF(MY_WME | MY_ZEROFILL))))
-+ DBUG_RETURN(1);
-+ /* Historical Requirement */
-+ plugin->data= schema_table; // shortcut for the future
-+ if (plugin->plugin->init)
-+ {
-+ schema_table->create_table= create_schema_table;
-+ schema_table->old_format= make_old_format;
-+ schema_table->idx_field1= -1,
-+ schema_table->idx_field2= -1;
-+
-+ /* Make the name available to the init() function. */
-+ schema_table->table_name= plugin->name.str;
-+
-+ if (plugin->plugin->init(schema_table))
-+ {
-+ sql_print_error("Plugin '%s' init function returned error.",
-+ plugin->name.str);
-+ plugin->data= NULL;
-+ my_free(schema_table, MYF(0));
-+ DBUG_RETURN(1);
-+ }
-+
-+ /* Make sure the plugin name is not set inside the init() function. */
-+ schema_table->table_name= plugin->name.str;
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+int finalize_schema_table(st_plugin_int *plugin)
-+{
-+ ST_SCHEMA_TABLE *schema_table= (ST_SCHEMA_TABLE *)plugin->data;
-+ DBUG_ENTER("finalize_schema_table");
-+
-+ if (schema_table)
-+ {
-+ if (plugin->plugin->deinit)
-+ {
-+ DBUG_PRINT("info", ("Deinitializing plugin: '%s'", plugin->name.str));
-+ if (plugin->plugin->deinit(NULL))
-+ {
-+ DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.",
-+ plugin->name.str));
-+ }
-+ }
-+ my_free(schema_table, MYF(0));
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/**
-+ Output trigger information (SHOW CREATE TRIGGER) to the client.
-+
-+ @param thd Thread context.
-+ @param triggers List of triggers for the table.
-+ @param trigger_idx Index of the trigger to dump.
-+
-+ @return Operation status
-+ @retval TRUE Error.
-+ @retval FALSE Success.
-+*/
-+
-+static bool show_create_trigger_impl(THD *thd,
-+ Table_triggers_list *triggers,
-+ int trigger_idx)
-+{
-+ int ret_code;
-+
-+ Protocol *p= thd->protocol;
-+ List<Item> fields;
-+
-+ LEX_STRING trg_name;
-+ ulonglong trg_sql_mode;
-+ LEX_STRING trg_sql_mode_str;
-+ LEX_STRING trg_sql_original_stmt;
-+ LEX_STRING trg_client_cs_name;
-+ LEX_STRING trg_connection_cl_name;
-+ LEX_STRING trg_db_cl_name;
-+
-+ CHARSET_INFO *trg_client_cs;
-+
-+ /*
-+ TODO: Check privileges here. This functionality will be added by
-+ implementation of the following WL items:
-+ - WL#2227: New privileges for new objects
-+ - WL#3482: Protect SHOW CREATE PROCEDURE | FUNCTION | VIEW | TRIGGER
-+ properly
-+
-+ SHOW TRIGGERS and I_S.TRIGGERS will be affected too.
-+ */
-+
-+ /* Prepare trigger "object". */
-+
-+ triggers->get_trigger_info(thd,
-+ trigger_idx,
-+ &trg_name,
-+ &trg_sql_mode,
-+ &trg_sql_original_stmt,
-+ &trg_client_cs_name,
-+ &trg_connection_cl_name,
-+ &trg_db_cl_name);
-+
-+ sys_var_thd_sql_mode::symbolic_mode_representation(thd,
-+ trg_sql_mode,
-+ &trg_sql_mode_str);
-+
-+ /* Resolve trigger client character set. */
-+
-+ if (resolve_charset(trg_client_cs_name.str, NULL, &trg_client_cs))
-+ return TRUE;
-+
-+ /* Send header. */
-+
-+ fields.push_back(new Item_empty_string("Trigger", NAME_LEN));
-+ fields.push_back(new Item_empty_string("sql_mode", trg_sql_mode_str.length));
-+
-+ {
-+ /*
-+ NOTE: SQL statement field must be not less than 1024 in order not to
-+ confuse old clients.
-+ */
-+
-+ Item_empty_string *stmt_fld=
-+ new Item_empty_string("SQL Original Statement",
-+ max(trg_sql_original_stmt.length, 1024));
-+
-+ stmt_fld->maybe_null= TRUE;
-+
-+ fields.push_back(stmt_fld);
-+ }
-+
-+ fields.push_back(new Item_empty_string("character_set_client",
-+ MY_CS_NAME_SIZE));
-+
-+ fields.push_back(new Item_empty_string("collation_connection",
-+ MY_CS_NAME_SIZE));
-+
-+ fields.push_back(new Item_empty_string("Database Collation",
-+ MY_CS_NAME_SIZE));
-+
-+ if (p->send_fields(&fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ return TRUE;
-+
-+ /* Send data. */
-+
-+ p->prepare_for_resend();
-+
-+ p->store(trg_name.str,
-+ trg_name.length,
-+ system_charset_info);
-+
-+ p->store(trg_sql_mode_str.str,
-+ trg_sql_mode_str.length,
-+ system_charset_info);
-+
-+ p->store(trg_sql_original_stmt.str,
-+ trg_sql_original_stmt.length,
-+ trg_client_cs);
-+
-+ p->store(trg_client_cs_name.str,
-+ trg_client_cs_name.length,
-+ system_charset_info);
-+
-+ p->store(trg_connection_cl_name.str,
-+ trg_connection_cl_name.length,
-+ system_charset_info);
-+
-+ p->store(trg_db_cl_name.str,
-+ trg_db_cl_name.length,
-+ system_charset_info);
-+
-+ ret_code= p->write();
-+
-+ if (!ret_code)
-+ my_eof(thd);
-+
-+ return ret_code != 0;
-+}
-+
-+
-+/**
-+ Read TRN and TRG files to obtain base table name for the specified
-+ trigger name and construct TABE_LIST object for the base table.
-+
-+ @param thd Thread context.
-+ @param trg_name Trigger name.
-+
-+ @return TABLE_LIST object corresponding to the base table.
-+
-+ TODO: This function is a copy&paste from add_table_to_list() and
-+ sp_add_to_query_tables(). The problem is that in order to be compatible
-+ with Stored Programs (Prepared Statements), we should not touch thd->lex.
-+ The "source" functions also add created TABLE_LIST object to the
-+ thd->lex->query_tables.
-+
-+ The plan to eliminate this copy&paste is to:
-+
-+ - get rid of sp_add_to_query_tables() and use Lex::add_table_to_list().
-+ Only add_table_to_list() must be used to add tables from the parser
-+ into Lex::query_tables list.
-+
-+ - do not update Lex::query_tables in add_table_to_list().
-+*/
-+
-+static TABLE_LIST *get_trigger_table_impl(
-+ THD *thd,
-+ const sp_name *trg_name)
-+{
-+ char trn_path_buff[FN_REFLEN];
-+
-+ LEX_STRING trn_path= { trn_path_buff, 0 };
-+ LEX_STRING tbl_name;
-+
-+ build_trn_path(thd, trg_name, &trn_path);
-+
-+ if (check_trn_exists(&trn_path))
-+ {
-+ my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
-+ return NULL;
-+ }
-+
-+ if (load_table_name_for_trigger(thd, trg_name, &trn_path, &tbl_name))
-+ return NULL;
-+
-+ /* We need to reset statement table list to be PS/SP friendly. */
-+
-+ TABLE_LIST *table;
-+
-+ if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST))))
-+ {
-+ my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST));
-+ return NULL;
-+ }
-+
-+ table->db_length= trg_name->m_db.length;
-+ table->db= thd->strmake(trg_name->m_db.str, trg_name->m_db.length);
-+
-+ table->table_name_length= tbl_name.length;
-+ table->table_name= thd->strmake(tbl_name.str, tbl_name.length);
-+
-+ table->alias= thd->strmake(tbl_name.str, tbl_name.length);
-+
-+ table->lock_type= TL_IGNORE;
-+ table->cacheable_table= 0;
-+
-+ return table;
-+}
-+
-+/**
-+ Read TRN and TRG files to obtain base table name for the specified
-+ trigger name and construct TABE_LIST object for the base table. Acquire
-+ LOCK_open when doing this.
-+
-+ @param thd Thread context.
-+ @param trg_name Trigger name.
-+
-+ @return TABLE_LIST object corresponding to the base table.
-+*/
-+
-+static TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name)
-+{
-+ /* Acquire LOCK_open (stop the server). */
-+
-+ pthread_mutex_lock(&LOCK_open);
-+
-+ /*
-+ Load base table name from the TRN-file and create TABLE_LIST object.
-+ */
-+
-+ TABLE_LIST *lst= get_trigger_table_impl(thd, trg_name);
-+
-+ /* Release LOCK_open (continue the server). */
-+
-+ pthread_mutex_unlock(&LOCK_open);
-+
-+ /* That's it. */
-+
-+ return lst;
-+}
-+
-+
-+/**
-+ SHOW CREATE TRIGGER high-level implementation.
-+
-+ @param thd Thread context.
-+ @param trg_name Trigger name.
-+
-+ @return Operation status
-+ @retval TRUE Error.
-+ @retval FALSE Success.
-+*/
-+
-+bool show_create_trigger(THD *thd, const sp_name *trg_name)
-+{
-+ TABLE_LIST *lst= get_trigger_table(thd, trg_name);
-+
-+ if (!lst)
-+ return TRUE;
-+
-+ if (check_table_access(thd, TRIGGER_ACL, lst, 1, TRUE))
-+ {
-+ my_error(ER_SPECIFIC_ACCESS_DENIED_ERROR, MYF(0), "TRIGGER");
-+ return TRUE;
-+ }
-+
-+ /*
-+ Open the table by name in order to load Table_triggers_list object.
-+
-+ NOTE: there is race condition here -- the table can be dropped after
-+ LOCK_open is released. It will be fixed later by introducing
-+ acquire-shared-table-name-lock functionality.
-+ */
-+
-+ uint num_tables; /* NOTE: unused, only to pass to open_tables(). */
-+
-+ if (open_tables(thd, &lst, &num_tables, 0))
-+ {
-+ my_error(ER_TRG_CANT_OPEN_TABLE, MYF(0),
-+ (const char *) trg_name->m_db.str,
-+ (const char *) lst->table_name);
-+
-+ return TRUE;
-+
-+ /* Perform closing actions and return error status. */
-+ }
-+
-+ Table_triggers_list *triggers= lst->table->triggers;
-+
-+ if (!triggers)
-+ {
-+ my_error(ER_TRG_DOES_NOT_EXIST, MYF(0));
-+ return TRUE;
-+ }
-+
-+ int trigger_idx= triggers->find_trigger_by_name(&trg_name->m_name);
-+
-+ if (trigger_idx < 0)
-+ {
-+ my_error(ER_TRG_CORRUPTED_FILE, MYF(0),
-+ (const char *) trg_name->m_db.str,
-+ (const char *) lst->table_name);
-+
-+ return TRUE;
-+ }
-+
-+ return show_create_trigger_impl(thd, triggers, trigger_idx);
-+
-+ /*
-+ NOTE: if show_create_trigger_impl() failed, that means we could not
-+ send data to the client. In this case we simply raise the error
-+ status and client connection will be closed.
-+ */
-+}
diff -urN mysql-old/sql/sql_string.cc mysql/sql/sql_string.cc
--- mysql-old/sql/sql_string.cc 2011-05-10 17:45:45.633349043 +0000
+++ mysql/sql/sql_string.cc 2011-05-10 17:56:01.616682376 +0000
@@ -60856,8136 +2552,6 @@ diff -urN mysql-old/sql/sql_table.cc mysql/sql/sql_table.cc
if (key->type == Key::MULTIPLE)
{
/* not a critical problem */
-diff -urN mysql-old/sql/sql_table.cc.orig mysql/sql/sql_table.cc.orig
---- mysql-old/sql/sql_table.cc.orig 1969-12-31 23:00:00.000000000 -0100
-+++ mysql/sql/sql_table.cc.orig 2011-04-12 12:11:35.000000000 +0000
-@@ -0,0 +1,8126 @@
-+/* Copyright 2000-2011, Oracle and/or its affiliates. All rights reserved.
-+
-+ This program is free software; you can redistribute it and/or modify
-+ it under the terms of the GNU General Public License as published by
-+ the Free Software Foundation; version 2 of the License.
-+
-+ This program is distributed in the hope that it will be useful,
-+ but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ GNU General Public License for more details.
-+
-+ You should have received a copy of the GNU General Public License
-+ along with this program; if not, write to the Free Software
-+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
-+ MA 02110-1301 USA */
-+
-+/* drop and alter of tables */
-+
-+#include "mysql_priv.h"
-+#include <hash.h>
-+#include <myisam.h>
-+#include <my_dir.h>
-+#include "sp_head.h"
-+#include "sql_trigger.h"
-+#include "sql_show.h"
-+#include "debug_sync.h"
-+
-+#ifdef __WIN__
-+#include <io.h>
-+#endif
-+
-+int creating_table= 0; // How many mysql_create_table are running
-+
-+const char *primary_key_name="PRIMARY";
-+
-+static bool check_if_keyname_exists(const char *name,KEY *start, KEY *end);
-+static char *make_unique_key_name(const char *field_name,KEY *start,KEY *end);
-+static int copy_data_between_tables(TABLE *from,TABLE *to,
-+ List<Create_field> &create, bool ignore,
-+ uint order_num, ORDER *order,
-+ ha_rows *copied,ha_rows *deleted,
-+ enum enum_enable_or_disable keys_onoff,
-+ bool error_if_not_empty);
-+
-+static bool prepare_blob_field(THD *thd, Create_field *sql_field);
-+static bool check_engine(THD *, const char *, HA_CREATE_INFO *);
-+static int
-+mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info,
-+ bool tmp_table,
-+ uint *db_options,
-+ handler *file, KEY **key_info_buffer,
-+ uint *key_count, int select_field_count);
-+static bool
-+mysql_prepare_alter_table(THD *thd, TABLE *table,
-+ HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info);
-+
-+#ifndef DBUG_OFF
-+
-+/* Wait until we get a 'mysql_kill' signal */
-+
-+static void wait_for_kill_signal(THD *thd)
-+{
-+ while (thd->killed == 0)
-+ sleep(1);
-+ // Reset signal and continue as if nothing happend
-+ thd->killed= THD::NOT_KILLED;
-+}
-+#endif
-+
-+
-+/**
-+ @brief Helper function for explain_filename
-+ @param thd Thread handle
-+ @param to_p Explained name in system_charset_info
-+ @param end_p End of the to_p buffer
-+ @param name Name to be converted
-+ @param name_len Length of the name, in bytes
-+*/
-+static char* add_identifier(THD* thd, char *to_p, const char * end_p,
-+ const char* name, uint name_len)
-+{
-+ uint res;
-+ uint errors;
-+ const char *conv_name;
-+ char tmp_name[FN_REFLEN];
-+ char conv_string[FN_REFLEN];
-+ int quote;
-+
-+ DBUG_ENTER("add_identifier");
-+ if (!name[name_len])
-+ conv_name= name;
-+ else
-+ {
-+ strnmov(tmp_name, name, name_len);
-+ tmp_name[name_len]= 0;
-+ conv_name= tmp_name;
-+ }
-+ res= strconvert(&my_charset_filename, conv_name, system_charset_info,
-+ conv_string, FN_REFLEN, &errors);
-+ if (!res || errors)
-+ {
-+ DBUG_PRINT("error", ("strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors));
-+ conv_name= name;
-+ }
-+ else
-+ {
-+ DBUG_PRINT("info", ("conv '%s' -> '%s'", conv_name, conv_string));
-+ conv_name= conv_string;
-+ }
-+
-+ quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) : '"';
-+
-+ if (quote != EOF && (end_p - to_p > 2))
-+ {
-+ *(to_p++)= (char) quote;
-+ while (*conv_name && (end_p - to_p - 1) > 0)
-+ {
-+ uint length= my_mbcharlen(system_charset_info, *conv_name);
-+ if (!length)
-+ length= 1;
-+ if (length == 1 && *conv_name == (char) quote)
-+ {
-+ if ((end_p - to_p) < 3)
-+ break;
-+ *(to_p++)= (char) quote;
-+ *(to_p++)= *(conv_name++);
-+ }
-+ else if (((long) length) < (end_p - to_p))
-+ {
-+ to_p= strnmov(to_p, conv_name, length);
-+ conv_name+= length;
-+ }
-+ else
-+ break; /* string already filled */
-+ }
-+ if (end_p > to_p) {
-+ *(to_p++)= (char) quote;
-+ if (end_p > to_p)
-+ *to_p= 0; /* terminate by NUL, but do not include it in the count */
-+ }
-+ }
-+ else
-+ to_p= strnmov(to_p, conv_name, end_p - to_p);
-+ DBUG_RETURN(to_p);
-+}
-+
-+
-+/**
-+ @brief Explain a path name by split it to database, table etc.
-+
-+ @details Break down the path name to its logic parts
-+ (database, table, partition, subpartition).
-+ filename_to_tablename cannot be used on partitions, due to the #P# part.
-+ There can be up to 6 '#', #P# for partition, #SP# for subpartition
-+ and #TMP# or #REN# for temporary or renamed partitions.
-+ This should be used when something should be presented to a user in a
-+ diagnostic, error etc. when it would be useful to know what a particular
-+ file [and directory] means. Such as SHOW ENGINE STATUS, error messages etc.
-+
-+ @param thd Thread handle
-+ @param from Path name in my_charset_filename
-+ Null terminated in my_charset_filename, normalized
-+ to use '/' as directory separation character.
-+ @param to Explained name in system_charset_info
-+ @param to_length Size of to buffer
-+ @param explain_mode Requested output format.
-+ EXPLAIN_ALL_VERBOSE ->
-+ [Database `db`, ]Table `tbl`[,[ Temporary| Renamed]
-+ Partition `p` [, Subpartition `sp`]]
-+ EXPLAIN_PARTITIONS_VERBOSE -> `db`.`tbl`
-+ [[ Temporary| Renamed] Partition `p`
-+ [, Subpartition `sp`]]
-+ EXPLAIN_PARTITIONS_AS_COMMENT -> `db`.`tbl` |*
-+ [,[ Temporary| Renamed] Partition `p`
-+ [, Subpartition `sp`]] *|
-+ (| is really a /, and it is all in one line)
-+
-+ @retval Length of returned string
-+*/
-+
-+uint explain_filename(THD* thd,
-+ const char *from,
-+ char *to,
-+ uint to_length,
-+ enum_explain_filename_mode explain_mode)
-+{
-+ uint res= 0;
-+ char *to_p= to;
-+ char *end_p= to_p + to_length;
-+ const char *db_name= NULL;
-+ int db_name_len= 0;
-+ const char *table_name;
-+ int table_name_len= 0;
-+ const char *part_name= NULL;
-+ int part_name_len= 0;
-+ const char *subpart_name= NULL;
-+ int subpart_name_len= 0;
-+ enum enum_file_name_type {NORMAL, TEMP, RENAMED} name_type= NORMAL;
-+ const char *tmp_p;
-+ DBUG_ENTER("explain_filename");
-+ DBUG_PRINT("enter", ("from '%s'", from));
-+ tmp_p= from;
-+ table_name= from;
-+ /*
-+ If '/' then take last directory part as database.
-+ '/' is the directory separator, not FN_LIB_CHAR
-+ */
-+ while ((tmp_p= strchr(tmp_p, '/')))
-+ {
-+ db_name= table_name;
-+ /* calculate the length */
-+ db_name_len= tmp_p - db_name;
-+ tmp_p++;
-+ table_name= tmp_p;
-+ }
-+ tmp_p= table_name;
-+ while (!res && (tmp_p= strchr(tmp_p, '#')))
-+ {
-+ tmp_p++;
-+ switch (tmp_p[0]) {
-+ case 'P':
-+ case 'p':
-+ if (tmp_p[1] == '#')
-+ part_name= tmp_p + 2;
-+ else
-+ res= 1;
-+ tmp_p+= 2;
-+ break;
-+ case 'S':
-+ case 's':
-+ if ((tmp_p[1] == 'P' || tmp_p[1] == 'p') && tmp_p[2] == '#')
-+ {
-+ part_name_len= tmp_p - part_name - 1;
-+ subpart_name= tmp_p + 3;
-+ }
-+ else
-+ res= 2;
-+ tmp_p+= 3;
-+ break;
-+ case 'T':
-+ case 't':
-+ if ((tmp_p[1] == 'M' || tmp_p[1] == 'm') &&
-+ (tmp_p[2] == 'P' || tmp_p[2] == 'p') &&
-+ tmp_p[3] == '#' && !tmp_p[4])
-+ name_type= TEMP;
-+ else
-+ res= 3;
-+ tmp_p+= 4;
-+ break;
-+ case 'R':
-+ case 'r':
-+ if ((tmp_p[1] == 'E' || tmp_p[1] == 'e') &&
-+ (tmp_p[2] == 'N' || tmp_p[2] == 'n') &&
-+ tmp_p[3] == '#' && !tmp_p[4])
-+ name_type= RENAMED;
-+ else
-+ res= 4;
-+ tmp_p+= 4;
-+ break;
-+ default:
-+ res= 5;
-+ }
-+ }
-+ if (res)
-+ {
-+ /* Better to give something back if we fail parsing, than nothing at all */
-+ DBUG_PRINT("info", ("Error in explain_filename: %u", res));
-+ sql_print_warning("Invalid (old?) table or database name '%s'", from);
-+ DBUG_RETURN(my_snprintf(to, to_length,
-+ "<result %u when explaining filename '%s'>",
-+ res, from));
-+ }
-+ if (part_name)
-+ {
-+ table_name_len= part_name - table_name - 3;
-+ if (subpart_name)
-+ subpart_name_len= strlen(subpart_name);
-+ else
-+ part_name_len= strlen(part_name);
-+ if (name_type != NORMAL)
-+ {
-+ if (subpart_name)
-+ subpart_name_len-= 5;
-+ else
-+ part_name_len-= 5;
-+ }
-+ }
-+ else
-+ table_name_len= strlen(table_name);
-+ if (db_name)
-+ {
-+ if (explain_mode == EXPLAIN_ALL_VERBOSE)
-+ {
-+ to_p= strnmov(to_p, ER(ER_DATABASE_NAME), end_p - to_p);
-+ *(to_p++)= ' ';
-+ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
-+ to_p= strnmov(to_p, ", ", end_p - to_p);
-+ }
-+ else
-+ {
-+ to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
-+ to_p= strnmov(to_p, ".", end_p - to_p);
-+ }
-+ }
-+ if (explain_mode == EXPLAIN_ALL_VERBOSE)
-+ {
-+ to_p= strnmov(to_p, ER(ER_TABLE_NAME), end_p - to_p);
-+ *(to_p++)= ' ';
-+ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
-+ }
-+ else
-+ to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
-+ if (part_name)
-+ {
-+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
-+ to_p= strnmov(to_p, " /* ", end_p - to_p);
-+ else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
-+ to_p= strnmov(to_p, " ", end_p - to_p);
-+ else
-+ to_p= strnmov(to_p, ", ", end_p - to_p);
-+ if (name_type != NORMAL)
-+ {
-+ if (name_type == TEMP)
-+ to_p= strnmov(to_p, ER(ER_TEMPORARY_NAME), end_p - to_p);
-+ else
-+ to_p= strnmov(to_p, ER(ER_RENAMED_NAME), end_p - to_p);
-+ to_p= strnmov(to_p, " ", end_p - to_p);
-+ }
-+ to_p= strnmov(to_p, ER(ER_PARTITION_NAME), end_p - to_p);
-+ *(to_p++)= ' ';
-+ to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
-+ if (subpart_name)
-+ {
-+ to_p= strnmov(to_p, ", ", end_p - to_p);
-+ to_p= strnmov(to_p, ER(ER_SUBPARTITION_NAME), end_p - to_p);
-+ *(to_p++)= ' ';
-+ to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
-+ }
-+ if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
-+ to_p= strnmov(to_p, " */", end_p - to_p);
-+ }
-+ DBUG_PRINT("exit", ("to '%s'", to));
-+ DBUG_RETURN(to_p - to);
-+}
-+
-+
-+/*
-+ Translate a file name to a table name (WL #1324).
-+
-+ SYNOPSIS
-+ filename_to_tablename()
-+ from The file name in my_charset_filename.
-+ to OUT The table name in system_charset_info.
-+ to_length The size of the table name buffer.
-+
-+ RETURN
-+ Table name length.
-+*/
-+
-+uint filename_to_tablename(const char *from, char *to, uint to_length)
-+{
-+ uint errors;
-+ size_t res;
-+ DBUG_ENTER("filename_to_tablename");
-+ DBUG_PRINT("enter", ("from '%s'", from));
-+
-+ if (!memcmp(from, tmp_file_prefix, tmp_file_prefix_length))
-+ {
-+ /* Temporary table name. */
-+ res= (strnmov(to, from, to_length) - to);
-+ }
-+ else
-+ {
-+ res= strconvert(&my_charset_filename, from,
-+ system_charset_info, to, to_length, &errors);
-+ if (errors) // Old 5.0 name
-+ {
-+ res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) -
-+ to);
-+ sql_print_error("Invalid (old?) table or database name '%s'", from);
-+ /*
-+ TODO: add a stored procedure for fix table and database names,
-+ and mention its name in error log.
-+ */
-+ }
-+ }
-+
-+ DBUG_PRINT("exit", ("to '%s'", to));
-+ DBUG_RETURN(res);
-+}
-+
-+
-+/**
-+ Check if given string begins with "#mysql50#" prefix
-+
-+ @param name string to check cut
-+
-+ @retval
-+ FALSE no prefix found
-+ @retval
-+ TRUE prefix found
-+*/
-+
-+bool check_mysql50_prefix(const char *name)
-+{
-+ return (name[0] == '#' &&
-+ !strncmp(name, MYSQL50_TABLE_NAME_PREFIX,
-+ MYSQL50_TABLE_NAME_PREFIX_LENGTH));
-+}
-+
-+
-+/**
-+ Check if given string begins with "#mysql50#" prefix, cut it if so.
-+
-+ @param from string to check and cut
-+ @param to[out] buffer for result string
-+ @param to_length its size
-+
-+ @retval
-+ 0 no prefix found
-+ @retval
-+ non-0 result string length
-+*/
-+
-+uint check_n_cut_mysql50_prefix(const char *from, char *to, uint to_length)
-+{
-+ if (check_mysql50_prefix(from))
-+ return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
-+ to_length - 1) - to);
-+ return 0;
-+}
-+
-+
-+/*
-+ Translate a table name to a file name (WL #1324).
-+
-+ SYNOPSIS
-+ tablename_to_filename()
-+ from The table name in system_charset_info.
-+ to OUT The file name in my_charset_filename.
-+ to_length The size of the file name buffer.
-+
-+ RETURN
-+ File name length.
-+*/
-+
-+uint tablename_to_filename(const char *from, char *to, uint to_length)
-+{
-+ uint errors, length;
-+ DBUG_ENTER("tablename_to_filename");
-+ DBUG_PRINT("enter", ("from '%s'", from));
-+
-+ if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
-+ {
-+ /*
-+ Check if the name supplied is a valid mysql 5.0 name and
-+ make the name a zero length string if it's not.
-+ Note that just returning zero length is not enough :
-+ a lot of places don't check the return value and expect
-+ a zero terminated string.
-+ */
-+ if (check_table_name(to, length, TRUE))
-+ {
-+ to[0]= 0;
-+ length= 0;
-+ }
-+ DBUG_RETURN(length);
-+ }
-+ length= strconvert(system_charset_info, from,
-+ &my_charset_filename, to, to_length, &errors);
-+ if (check_if_legal_tablename(to) &&
-+ length + 4 < to_length)
-+ {
-+ memcpy(to + length, "@@@", 4);
-+ length+= 3;
-+ }
-+ DBUG_PRINT("exit", ("to '%s'", to));
-+ DBUG_RETURN(length);
-+}
-+
-+
-+/*
-+ Creates path to a file: mysql_data_dir/db/table.ext
-+
-+ SYNOPSIS
-+ build_table_filename()
-+ buff Where to write result in my_charset_filename.
-+ This may be the same as table_name.
-+ bufflen buff size
-+ db Database name in system_charset_info.
-+ table_name Table name in system_charset_info.
-+ ext File extension.
-+ flags FN_FROM_IS_TMP or FN_TO_IS_TMP or FN_IS_TMP
-+ table_name is temporary, do not change.
-+
-+ NOTES
-+
-+ Uses database and table name, and extension to create
-+ a file name in mysql_data_dir. Database and table
-+ names are converted from system_charset_info into "fscs".
-+ Unless flags indicate a temporary table name.
-+ 'db' is always converted.
-+ 'ext' is not converted.
-+
-+ The conversion suppression is required for ALTER TABLE. This
-+ statement creates intermediate tables. These are regular
-+ (non-temporary) tables with a temporary name. Their path names must
-+ be derivable from the table name. So we cannot use
-+ build_tmptable_filename() for them.
-+
-+ RETURN
-+ path length
-+*/
-+
-+uint build_table_filename(char *buff, size_t bufflen, const char *db,
-+ const char *table_name, const char *ext, uint flags)
-+{
-+ char dbbuff[FN_REFLEN];
-+ char tbbuff[FN_REFLEN];
-+ DBUG_ENTER("build_table_filename");
-+ DBUG_PRINT("enter", ("db: '%s' table_name: '%s' ext: '%s' flags: %x",
-+ db, table_name, ext, flags));
-+
-+ if (flags & FN_IS_TMP) // FN_FROM_IS_TMP | FN_TO_IS_TMP
-+ strnmov(tbbuff, table_name, sizeof(tbbuff));
-+ else
-+ VOID(tablename_to_filename(table_name, tbbuff, sizeof(tbbuff)));
-+
-+ VOID(tablename_to_filename(db, dbbuff, sizeof(dbbuff)));
-+
-+ char *end = buff + bufflen;
-+ /* Don't add FN_ROOTDIR if mysql_data_home already includes it */
-+ char *pos = strnmov(buff, mysql_data_home, bufflen);
-+ size_t rootdir_len= strlen(FN_ROOTDIR);
-+ if (pos - rootdir_len >= buff &&
-+ memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
-+ pos= strnmov(pos, FN_ROOTDIR, end - pos);
-+ pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
-+#ifdef USE_SYMDIR
-+ unpack_dirname(buff, buff);
-+ pos= strend(buff);
-+#endif
-+ pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
-+
-+ DBUG_PRINT("exit", ("buff: '%s'", buff));
-+ DBUG_RETURN(pos - buff);
-+}
-+
-+
-+/*
-+ Creates path to a file: mysql_tmpdir/#sql1234_12_1.ext
-+
-+ SYNOPSIS
-+ build_tmptable_filename()
-+ thd The thread handle.
-+ buff Where to write result in my_charset_filename.
-+ bufflen buff size
-+
-+ NOTES
-+
-+ Uses current_pid, thread_id, and tmp_table counter to create
-+ a file name in mysql_tmpdir.
-+
-+ RETURN
-+ path length
-+*/
-+
-+uint build_tmptable_filename(THD* thd, char *buff, size_t bufflen)
-+{
-+ DBUG_ENTER("build_tmptable_filename");
-+
-+ char *p= strnmov(buff, mysql_tmpdir, bufflen);
-+ my_snprintf(p, bufflen - (p - buff), "/%s%lx_%lx_%x%s",
-+ tmp_file_prefix, current_pid,
-+ thd->thread_id, thd->tmp_table++, reg_ext);
-+
-+ if (lower_case_table_names)
-+ {
-+ /* Convert all except tmpdir to lower case */
-+ my_casedn_str(files_charset_info, p);
-+ }
-+
-+ size_t length= unpack_filename(buff, buff);
-+ DBUG_PRINT("exit", ("buff: '%s'", buff));
-+ DBUG_RETURN(length);
-+}
-+
-+/*
-+--------------------------------------------------------------------------
-+
-+ MODULE: DDL log
-+ -----------------
-+
-+ This module is used to ensure that we can recover from crashes that occur
-+ in the middle of a meta-data operation in MySQL. E.g. DROP TABLE t1, t2;
-+ We need to ensure that both t1 and t2 are dropped and not only t1 and
-+ also that each table drop is entirely done and not "half-baked".
-+
-+ To support this we create log entries for each meta-data statement in the
-+ ddl log while we are executing. These entries are dropped when the
-+ operation is completed.
-+
-+ At recovery those entries that were not completed will be executed.
-+
-+ There is only one ddl log in the system and it is protected by a mutex
-+ and there is a global struct that contains information about its current
-+ state.
-+
-+ History:
-+ First version written in 2006 by Mikael Ronstrom
-+--------------------------------------------------------------------------
-+*/
-+
-+
-+struct st_global_ddl_log
-+{
-+ /*
-+ We need to adjust buffer size to be able to handle downgrades/upgrades
-+ where IO_SIZE has changed. We'll set the buffer size such that we can
-+ handle that the buffer size was upto 4 times bigger in the version
-+ that wrote the DDL log.
-+ */
-+ char file_entry_buf[4*IO_SIZE];
-+ char file_name_str[FN_REFLEN];
-+ char *file_name;
-+ DDL_LOG_MEMORY_ENTRY *first_free;
-+ DDL_LOG_MEMORY_ENTRY *first_used;
-+ uint num_entries;
-+ File file_id;
-+ uint name_len;
-+ uint io_size;
-+ bool inited;
-+ bool do_release;
-+ bool recovery_phase;
-+ st_global_ddl_log() : inited(false), do_release(false) {}
-+};
-+
-+st_global_ddl_log global_ddl_log;
-+
-+pthread_mutex_t LOCK_gdl;
-+
-+#define DDL_LOG_ENTRY_TYPE_POS 0
-+#define DDL_LOG_ACTION_TYPE_POS 1
-+#define DDL_LOG_PHASE_POS 2
-+#define DDL_LOG_NEXT_ENTRY_POS 4
-+#define DDL_LOG_NAME_POS 8
-+
-+#define DDL_LOG_NUM_ENTRY_POS 0
-+#define DDL_LOG_NAME_LEN_POS 4
-+#define DDL_LOG_IO_SIZE_POS 8
-+
-+/*
-+ Read one entry from ddl log file
-+ SYNOPSIS
-+ read_ddl_log_file_entry()
-+ entry_no Entry number to read
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static bool read_ddl_log_file_entry(uint entry_no)
-+{
-+ bool error= FALSE;
-+ File file_id= global_ddl_log.file_id;
-+ uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
-+ uint io_size= global_ddl_log.io_size;
-+ DBUG_ENTER("read_ddl_log_file_entry");
-+
-+ if (my_pread(file_id, file_entry_buf, io_size, io_size * entry_no,
-+ MYF(MY_WME)) != io_size)
-+ error= TRUE;
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Write one entry from ddl log file
-+ SYNOPSIS
-+ write_ddl_log_file_entry()
-+ entry_no Entry number to write
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static bool write_ddl_log_file_entry(uint entry_no)
-+{
-+ bool error= FALSE;
-+ File file_id= global_ddl_log.file_id;
-+ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
-+ DBUG_ENTER("write_ddl_log_file_entry");
-+
-+ if (my_pwrite(file_id, (uchar*)file_entry_buf,
-+ IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE)
-+ error= TRUE;
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Write ddl log header
-+ SYNOPSIS
-+ write_ddl_log_header()
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static bool write_ddl_log_header()
-+{
-+ uint16 const_var;
-+ bool error= FALSE;
-+ DBUG_ENTER("write_ddl_log_header");
-+
-+ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
-+ global_ddl_log.num_entries);
-+ const_var= FN_LEN;
-+ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
-+ (ulong) const_var);
-+ const_var= IO_SIZE;
-+ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
-+ (ulong) const_var);
-+ if (write_ddl_log_file_entry(0UL))
-+ {
-+ sql_print_error("Error writing ddl log header");
-+ DBUG_RETURN(TRUE);
-+ }
-+ VOID(sync_ddl_log());
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Create ddl log file name
-+ SYNOPSIS
-+ create_ddl_log_file_name()
-+ file_name Filename setup
-+ RETURN VALUES
-+ NONE
-+*/
-+
-+static inline void create_ddl_log_file_name(char *file_name)
-+{
-+ strxmov(file_name, mysql_data_home, "/", "ddl_log.log", NullS);
-+}
-+
-+
-+/*
-+ Read header of ddl log file
-+ SYNOPSIS
-+ read_ddl_log_header()
-+ RETURN VALUES
-+ > 0 Last entry in ddl log
-+ 0 No entries in ddl log
-+ DESCRIPTION
-+ When we read the ddl log header we get information about maximum sizes
-+ of names in the ddl log and we also get information about the number
-+ of entries in the ddl log.
-+*/
-+
-+static uint read_ddl_log_header()
-+{
-+ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
-+ char file_name[FN_REFLEN];
-+ uint entry_no;
-+ bool successful_open= FALSE;
-+ DBUG_ENTER("read_ddl_log_header");
-+
-+ create_ddl_log_file_name(file_name);
-+ if ((global_ddl_log.file_id= my_open(file_name,
-+ O_RDWR | O_BINARY, MYF(0))) >= 0)
-+ {
-+ if (read_ddl_log_file_entry(0UL))
-+ {
-+ /* Write message into error log */
-+ sql_print_error("Failed to read ddl log file in recovery");
-+ }
-+ else
-+ successful_open= TRUE;
-+ }
-+ if (successful_open)
-+ {
-+ entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
-+ global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
-+ global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
-+ DBUG_ASSERT(global_ddl_log.io_size <=
-+ sizeof(global_ddl_log.file_entry_buf));
-+ }
-+ else
-+ {
-+ entry_no= 0;
-+ }
-+ global_ddl_log.first_free= NULL;
-+ global_ddl_log.first_used= NULL;
-+ global_ddl_log.num_entries= 0;
-+ VOID(pthread_mutex_init(&LOCK_gdl, MY_MUTEX_INIT_FAST));
-+ global_ddl_log.do_release= true;
-+ DBUG_RETURN(entry_no);
-+}
-+
-+
-+/*
-+ Read a ddl log entry
-+ SYNOPSIS
-+ read_ddl_log_entry()
-+ read_entry Number of entry to read
-+ out:entry_info Information from entry
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+ DESCRIPTION
-+ Read a specified entry in the ddl log
-+*/
-+
-+bool read_ddl_log_entry(uint read_entry, DDL_LOG_ENTRY *ddl_log_entry)
-+{
-+ char *file_entry_buf= (char*)&global_ddl_log.file_entry_buf;
-+ uint inx;
-+ uchar single_char;
-+ DBUG_ENTER("read_ddl_log_entry");
-+
-+ if (read_ddl_log_file_entry(read_entry))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ ddl_log_entry->entry_pos= read_entry;
-+ single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
-+ ddl_log_entry->entry_type= (enum ddl_log_entry_code)single_char;
-+ single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
-+ ddl_log_entry->action_type= (enum ddl_log_action_code)single_char;
-+ ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
-+ ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
-+ ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
-+ inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
-+ ddl_log_entry->from_name= &file_entry_buf[inx];
-+ inx+= global_ddl_log.name_len;
-+ ddl_log_entry->handler_name= &file_entry_buf[inx];
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ Initialise ddl log
-+ SYNOPSIS
-+ init_ddl_log()
-+
-+ DESCRIPTION
-+ Write the header of the ddl log file and length of names. Also set
-+ number of entries to zero.
-+
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static bool init_ddl_log()
-+{
-+ char file_name[FN_REFLEN];
-+ DBUG_ENTER("init_ddl_log");
-+
-+ if (global_ddl_log.inited)
-+ goto end;
-+
-+ global_ddl_log.io_size= IO_SIZE;
-+ global_ddl_log.name_len= FN_LEN;
-+ create_ddl_log_file_name(file_name);
-+ if ((global_ddl_log.file_id= my_create(file_name,
-+ CREATE_MODE,
-+ O_RDWR | O_TRUNC | O_BINARY,
-+ MYF(MY_WME))) < 0)
-+ {
-+ /* Couldn't create ddl log file, this is serious error */
-+ sql_print_error("Failed to open ddl log file");
-+ DBUG_RETURN(TRUE);
-+ }
-+ global_ddl_log.inited= TRUE;
-+ if (write_ddl_log_header())
-+ {
-+ VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
-+ global_ddl_log.inited= FALSE;
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+end:
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ Execute one action in a ddl log entry
-+ SYNOPSIS
-+ execute_ddl_log_action()
-+ ddl_log_entry Information in action entry to execute
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry)
-+{
-+ bool frm_action= FALSE;
-+ LEX_STRING handler_name;
-+ handler *file= NULL;
-+ MEM_ROOT mem_root;
-+ int error= TRUE;
-+ char to_path[FN_REFLEN];
-+ char from_path[FN_REFLEN];
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ char *par_ext= (char*)".par";
-+#endif
-+ handlerton *hton;
-+ DBUG_ENTER("execute_ddl_log_action");
-+
-+ if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
-+ {
-+ DBUG_RETURN(FALSE);
-+ }
-+ DBUG_PRINT("ddl_log",
-+ ("execute type %c next %u name '%s' from_name '%s' handler '%s'",
-+ ddl_log_entry->action_type,
-+ ddl_log_entry->next_entry,
-+ ddl_log_entry->name,
-+ ddl_log_entry->from_name,
-+ ddl_log_entry->handler_name));
-+ handler_name.str= (char*)ddl_log_entry->handler_name;
-+ handler_name.length= strlen(ddl_log_entry->handler_name);
-+ init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
-+ if (!strcmp(ddl_log_entry->handler_name, reg_ext))
-+ frm_action= TRUE;
-+ else
-+ {
-+ plugin_ref plugin= ha_resolve_by_name(thd, &handler_name);
-+ if (!plugin)
-+ {
-+ my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
-+ goto error;
-+ }
-+ hton= plugin_data(plugin, handlerton*);
-+ file= get_new_handler((TABLE_SHARE*)0, &mem_root, hton);
-+ if (!file)
-+ {
-+ mem_alloc_error(sizeof(handler));
-+ goto error;
-+ }
-+ }
-+ switch (ddl_log_entry->action_type)
-+ {
-+ case DDL_LOG_REPLACE_ACTION:
-+ case DDL_LOG_DELETE_ACTION:
-+ {
-+ if (ddl_log_entry->phase == 0)
-+ {
-+ if (frm_action)
-+ {
-+ strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
-+ if ((error= my_delete(to_path, MYF(MY_WME))))
-+ {
-+ if (my_errno != ENOENT)
-+ break;
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
-+ VOID(my_delete(to_path, MYF(MY_WME)));
-+#endif
-+ }
-+ else
-+ {
-+ if ((error= file->ha_delete_table(ddl_log_entry->name)))
-+ {
-+ if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
-+ break;
-+ }
-+ }
-+ if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
-+ break;
-+ VOID(sync_ddl_log());
-+ error= FALSE;
-+ if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
-+ break;
-+ }
-+ DBUG_ASSERT(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
-+ /*
-+ Fall through and perform the rename action of the replace
-+ action. We have already indicated the success of the delete
-+ action in the log entry by stepping up the phase.
-+ */
-+ }
-+ case DDL_LOG_RENAME_ACTION:
-+ {
-+ error= TRUE;
-+ if (frm_action)
-+ {
-+ strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
-+ strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
-+ if (my_rename(from_path, to_path, MYF(MY_WME)))
-+ break;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
-+ strxmov(from_path, ddl_log_entry->from_name, par_ext, NullS);
-+ VOID(my_rename(from_path, to_path, MYF(MY_WME)));
-+#endif
-+ }
-+ else
-+ {
-+ if (file->ha_rename_table(ddl_log_entry->from_name,
-+ ddl_log_entry->name))
-+ break;
-+ }
-+ if ((deactivate_ddl_log_entry(ddl_log_entry->entry_pos)))
-+ break;
-+ VOID(sync_ddl_log());
-+ error= FALSE;
-+ break;
-+ }
-+ default:
-+ DBUG_ASSERT(0);
-+ break;
-+ }
-+ delete file;
-+error:
-+ free_root(&mem_root, MYF(0));
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Get a free entry in the ddl log
-+ SYNOPSIS
-+ get_free_ddl_log_entry()
-+ out:active_entry A ddl log memory entry returned
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+static bool get_free_ddl_log_entry(DDL_LOG_MEMORY_ENTRY **active_entry,
-+ bool *write_header)
-+{
-+ DDL_LOG_MEMORY_ENTRY *used_entry;
-+ DDL_LOG_MEMORY_ENTRY *first_used= global_ddl_log.first_used;
-+ DBUG_ENTER("get_free_ddl_log_entry");
-+
-+ if (global_ddl_log.first_free == NULL)
-+ {
-+ if (!(used_entry= (DDL_LOG_MEMORY_ENTRY*)my_malloc(
-+ sizeof(DDL_LOG_MEMORY_ENTRY), MYF(MY_WME))))
-+ {
-+ sql_print_error("Failed to allocate memory for ddl log free list");
-+ DBUG_RETURN(TRUE);
-+ }
-+ global_ddl_log.num_entries++;
-+ used_entry->entry_pos= global_ddl_log.num_entries;
-+ *write_header= TRUE;
-+ }
-+ else
-+ {
-+ used_entry= global_ddl_log.first_free;
-+ global_ddl_log.first_free= used_entry->next_log_entry;
-+ *write_header= FALSE;
-+ }
-+ /*
-+ Move from free list to used list
-+ */
-+ used_entry->next_log_entry= first_used;
-+ used_entry->prev_log_entry= NULL;
-+ global_ddl_log.first_used= used_entry;
-+ if (first_used)
-+ first_used->prev_log_entry= used_entry;
-+
-+ *active_entry= used_entry;
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ External interface methods for the DDL log Module
-+ ---------------------------------------------------
-+*/
-+
-+/*
-+ SYNOPSIS
-+ write_ddl_log_entry()
-+ ddl_log_entry Information about log entry
-+ out:entry_written Entry information written into
-+
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+
-+ DESCRIPTION
-+ A careful write of the ddl log is performed to ensure that we can
-+ handle crashes occurring during CREATE and ALTER TABLE processing.
-+*/
-+
-+bool write_ddl_log_entry(DDL_LOG_ENTRY *ddl_log_entry,
-+ DDL_LOG_MEMORY_ENTRY **active_entry)
-+{
-+ bool error, write_header;
-+ DBUG_ENTER("write_ddl_log_entry");
-+
-+ if (init_ddl_log())
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
-+ (char)DDL_LOG_ENTRY_CODE;
-+ global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
-+ (char)ddl_log_entry->action_type;
-+ global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
-+ int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
-+ ddl_log_entry->next_entry);
-+ DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_LEN);
-+ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
-+ ddl_log_entry->name, FN_LEN - 1);
-+ if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
-+ ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION)
-+ {
-+ DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_LEN);
-+ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN],
-+ ddl_log_entry->from_name, FN_LEN - 1);
-+ }
-+ else
-+ global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
-+ DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_LEN);
-+ strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_LEN)],
-+ ddl_log_entry->handler_name, FN_LEN - 1);
-+ if (get_free_ddl_log_entry(active_entry, &write_header))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ error= FALSE;
-+ DBUG_PRINT("ddl_log",
-+ ("write type %c next %u name '%s' from_name '%s' handler '%s'",
-+ (char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
-+ ddl_log_entry->next_entry,
-+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
-+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
-+ + FN_LEN],
-+ (char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
-+ + (2*FN_LEN)]));
-+ if (write_ddl_log_file_entry((*active_entry)->entry_pos))
-+ {
-+ error= TRUE;
-+ sql_print_error("Failed to write entry_no = %u",
-+ (*active_entry)->entry_pos);
-+ }
-+ if (write_header && !error)
-+ {
-+ VOID(sync_ddl_log());
-+ if (write_ddl_log_header())
-+ error= TRUE;
-+ }
-+ if (error)
-+ release_ddl_log_memory_entry(*active_entry);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Write final entry in the ddl log
-+ SYNOPSIS
-+ write_execute_ddl_log_entry()
-+ first_entry First entry in linked list of entries
-+ to execute, if 0 = NULL it means that
-+ the entry is removed and the entries
-+ are put into the free list.
-+ complete Flag indicating we are simply writing
-+ info about that entry has been completed
-+ in:out:active_entry Entry to execute, 0 = NULL if the entry
-+ is written first time and needs to be
-+ returned. In this case the entry written
-+ is returned in this parameter
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+
-+ DESCRIPTION
-+ This is the last write in the ddl log. The previous log entries have
-+ already been written but not yet synched to disk.
-+ We write a couple of log entries that describes action to perform.
-+ This entries are set-up in a linked list, however only when a first
-+ execute entry is put as the first entry these will be executed.
-+ This routine writes this first
-+*/
-+
-+bool write_execute_ddl_log_entry(uint first_entry,
-+ bool complete,
-+ DDL_LOG_MEMORY_ENTRY **active_entry)
-+{
-+ bool write_header= FALSE;
-+ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
-+ DBUG_ENTER("write_execute_ddl_log_entry");
-+
-+ if (init_ddl_log())
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (!complete)
-+ {
-+ /*
-+ We haven't synched the log entries yet, we synch them now before
-+ writing the execute entry. If complete is true we haven't written
-+ any log entries before, we are only here to write the execute
-+ entry to indicate it is done.
-+ */
-+ VOID(sync_ddl_log());
-+ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
-+ }
-+ else
-+ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
-+ file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0; /* Ignored for execute entries */
-+ file_entry_buf[DDL_LOG_PHASE_POS]= 0;
-+ int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
-+ file_entry_buf[DDL_LOG_NAME_POS]= 0;
-+ file_entry_buf[DDL_LOG_NAME_POS + FN_LEN]= 0;
-+ file_entry_buf[DDL_LOG_NAME_POS + 2*FN_LEN]= 0;
-+ if (!(*active_entry))
-+ {
-+ if (get_free_ddl_log_entry(active_entry, &write_header))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ if (write_ddl_log_file_entry((*active_entry)->entry_pos))
-+ {
-+ sql_print_error("Error writing execute entry in ddl log");
-+ release_ddl_log_memory_entry(*active_entry);
-+ DBUG_RETURN(TRUE);
-+ }
-+ VOID(sync_ddl_log());
-+ if (write_header)
-+ {
-+ if (write_ddl_log_header())
-+ {
-+ release_ddl_log_memory_entry(*active_entry);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ For complex rename operations we need to deactivate individual entries.
-+ SYNOPSIS
-+ deactivate_ddl_log_entry()
-+ entry_no Entry position of record to change
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+ DESCRIPTION
-+ During replace operations where we start with an existing table called
-+ t1 and a replacement table called t1#temp or something else and where
-+ we want to delete t1 and rename t1#temp to t1 this is not possible to
-+ do in a safe manner unless the ddl log is informed of the phases in
-+ the change.
-+
-+ Delete actions are 1-phase actions that can be ignored immediately after
-+ being executed.
-+ Rename actions from x to y is also a 1-phase action since there is no
-+ interaction with any other handlers named x and y.
-+ Replace action where drop y and x -> y happens needs to be a two-phase
-+ action. Thus the first phase will drop y and the second phase will
-+ rename x -> y.
-+*/
-+
-+bool deactivate_ddl_log_entry(uint entry_no)
-+{
-+ char *file_entry_buf= (char*)global_ddl_log.file_entry_buf;
-+ DBUG_ENTER("deactivate_ddl_log_entry");
-+
-+ if (!read_ddl_log_file_entry(entry_no))
-+ {
-+ if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
-+ {
-+ if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
-+ file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
-+ (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
-+ file_entry_buf[DDL_LOG_PHASE_POS] == 1))
-+ file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
-+ else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
-+ {
-+ DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
-+ file_entry_buf[DDL_LOG_PHASE_POS]= 1;
-+ }
-+ else
-+ {
-+ DBUG_ASSERT(0);
-+ }
-+ if (write_ddl_log_file_entry(entry_no))
-+ {
-+ sql_print_error("Error in deactivating log entry. Position = %u",
-+ entry_no);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+ else
-+ {
-+ sql_print_error("Failed in reading entry before deactivating it");
-+ DBUG_RETURN(TRUE);
-+ }
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ Sync ddl log file
-+ SYNOPSIS
-+ sync_ddl_log()
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+bool sync_ddl_log()
-+{
-+ bool error= FALSE;
-+ DBUG_ENTER("sync_ddl_log");
-+
-+ if ((!global_ddl_log.recovery_phase) &&
-+ init_ddl_log())
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (my_sync(global_ddl_log.file_id, MYF(0)))
-+ {
-+ /* Write to error log */
-+ sql_print_error("Failed to sync ddl log");
-+ error= TRUE;
-+ }
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Release a log memory entry
-+ SYNOPSIS
-+ release_ddl_log_memory_entry()
-+ log_memory_entry Log memory entry to release
-+ RETURN VALUES
-+ NONE
-+*/
-+
-+void release_ddl_log_memory_entry(DDL_LOG_MEMORY_ENTRY *log_entry)
-+{
-+ DDL_LOG_MEMORY_ENTRY *first_free= global_ddl_log.first_free;
-+ DDL_LOG_MEMORY_ENTRY *next_log_entry= log_entry->next_log_entry;
-+ DDL_LOG_MEMORY_ENTRY *prev_log_entry= log_entry->prev_log_entry;
-+ DBUG_ENTER("release_ddl_log_memory_entry");
-+
-+ global_ddl_log.first_free= log_entry;
-+ log_entry->next_log_entry= first_free;
-+
-+ if (prev_log_entry)
-+ prev_log_entry->next_log_entry= next_log_entry;
-+ else
-+ global_ddl_log.first_used= next_log_entry;
-+ if (next_log_entry)
-+ next_log_entry->prev_log_entry= prev_log_entry;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Execute one entry in the ddl log. Executing an entry means executing
-+ a linked list of actions.
-+ SYNOPSIS
-+ execute_ddl_log_entry()
-+ first_entry Reference to first action in entry
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+*/
-+
-+bool execute_ddl_log_entry(THD *thd, uint first_entry)
-+{
-+ DDL_LOG_ENTRY ddl_log_entry;
-+ uint read_entry= first_entry;
-+ DBUG_ENTER("execute_ddl_log_entry");
-+
-+ pthread_mutex_lock(&LOCK_gdl);
-+ do
-+ {
-+ if (read_ddl_log_entry(read_entry, &ddl_log_entry))
-+ {
-+ /* Write to error log and continue with next log entry */
-+ sql_print_error("Failed to read entry = %u from ddl log",
-+ read_entry);
-+ break;
-+ }
-+ DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
-+ ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
-+
-+ if (execute_ddl_log_action(thd, &ddl_log_entry))
-+ {
-+ /* Write to error log and continue with next log entry */
-+ sql_print_error("Failed to execute action for entry = %u from ddl log",
-+ read_entry);
-+ break;
-+ }
-+ read_entry= ddl_log_entry.next_entry;
-+ } while (read_entry);
-+ pthread_mutex_unlock(&LOCK_gdl);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ Close the ddl log
-+ SYNOPSIS
-+ close_ddl_log()
-+ RETURN VALUES
-+ NONE
-+*/
-+
-+static void close_ddl_log()
-+{
-+ DBUG_ENTER("close_ddl_log");
-+ if (global_ddl_log.file_id >= 0)
-+ {
-+ VOID(my_close(global_ddl_log.file_id, MYF(MY_WME)));
-+ global_ddl_log.file_id= (File) -1;
-+ }
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Execute the ddl log at recovery of MySQL Server
-+ SYNOPSIS
-+ execute_ddl_log_recovery()
-+ RETURN VALUES
-+ NONE
-+*/
-+
-+void execute_ddl_log_recovery()
-+{
-+ uint num_entries, i;
-+ THD *thd;
-+ DDL_LOG_ENTRY ddl_log_entry;
-+ char file_name[FN_REFLEN];
-+ DBUG_ENTER("execute_ddl_log_recovery");
-+
-+ /*
-+ Initialise global_ddl_log struct
-+ */
-+ bzero(global_ddl_log.file_entry_buf, sizeof(global_ddl_log.file_entry_buf));
-+ global_ddl_log.inited= FALSE;
-+ global_ddl_log.recovery_phase= TRUE;
-+ global_ddl_log.io_size= IO_SIZE;
-+ global_ddl_log.file_id= (File) -1;
-+
-+ /*
-+ To be able to run this from boot, we allocate a temporary THD
-+ */
-+ if (!(thd=new THD))
-+ DBUG_VOID_RETURN;
-+ thd->thread_stack= (char*) &thd;
-+ thd->store_globals();
-+
-+ num_entries= read_ddl_log_header();
-+ for (i= 1; i < num_entries + 1; i++)
-+ {
-+ if (read_ddl_log_entry(i, &ddl_log_entry))
-+ {
-+ sql_print_error("Failed to read entry no = %u from ddl log",
-+ i);
-+ continue;
-+ }
-+ if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
-+ {
-+ if (execute_ddl_log_entry(thd, ddl_log_entry.next_entry))
-+ {
-+ /* Real unpleasant scenario but we continue anyways. */
-+ continue;
-+ }
-+ }
-+ }
-+ close_ddl_log();
-+ create_ddl_log_file_name(file_name);
-+ VOID(my_delete(file_name, MYF(0)));
-+ global_ddl_log.recovery_phase= FALSE;
-+ delete thd;
-+ /* Remember that we don't have a THD */
-+ my_pthread_setspecific_ptr(THR_THD, 0);
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+ Release all memory allocated to the ddl log
-+ SYNOPSIS
-+ release_ddl_log()
-+ RETURN VALUES
-+ NONE
-+*/
-+
-+void release_ddl_log()
-+{
-+ DDL_LOG_MEMORY_ENTRY *free_list= global_ddl_log.first_free;
-+ DDL_LOG_MEMORY_ENTRY *used_list= global_ddl_log.first_used;
-+ DBUG_ENTER("release_ddl_log");
-+
-+ if (!global_ddl_log.do_release)
-+ DBUG_VOID_RETURN;
-+
-+ pthread_mutex_lock(&LOCK_gdl);
-+ while (used_list)
-+ {
-+ DDL_LOG_MEMORY_ENTRY *tmp= used_list->next_log_entry;
-+ my_free(used_list, MYF(0));
-+ used_list= tmp;
-+ }
-+ while (free_list)
-+ {
-+ DDL_LOG_MEMORY_ENTRY *tmp= free_list->next_log_entry;
-+ my_free(free_list, MYF(0));
-+ free_list= tmp;
-+ }
-+ close_ddl_log();
-+ global_ddl_log.inited= 0;
-+ pthread_mutex_unlock(&LOCK_gdl);
-+ VOID(pthread_mutex_destroy(&LOCK_gdl));
-+ global_ddl_log.do_release= false;
-+ DBUG_VOID_RETURN;
-+}
-+
-+
-+/*
-+---------------------------------------------------------------------------
-+
-+ END MODULE DDL log
-+ --------------------
-+
-+---------------------------------------------------------------------------
-+*/
-+
-+
-+/**
-+ @brief construct a temporary shadow file name.
-+
-+ @details Make a shadow file name used by ALTER TABLE to construct the
-+ modified table (with keeping the original). The modified table is then
-+ moved back as original table. The name must start with the temp file
-+ prefix so it gets filtered out by table files listing routines.
-+
-+ @param[out] buff buffer to receive the constructed name
-+ @param bufflen size of buff
-+ @param lpt alter table data structure
-+
-+ @retval path length
-+*/
-+
-+uint build_table_shadow_filename(char *buff, size_t bufflen,
-+ ALTER_PARTITION_PARAM_TYPE *lpt)
-+{
-+ char tmp_name[FN_REFLEN];
-+ my_snprintf (tmp_name, sizeof (tmp_name), "%s-%s", tmp_file_prefix,
-+ lpt->table_name);
-+ return build_table_filename(buff, bufflen, lpt->db, tmp_name, "", FN_IS_TMP);
-+}
-+
-+
-+/*
-+ SYNOPSIS
-+ mysql_write_frm()
-+ lpt Struct carrying many parameters needed for this
-+ method
-+ flags Flags as defined below
-+ WFRM_INITIAL_WRITE If set we need to prepare table before
-+ creating the frm file
-+ WFRM_INSTALL_SHADOW If set we should install the new frm
-+ WFRM_KEEP_SHARE If set we know that the share is to be
-+ retained and thus we should ensure share
-+ object is correct, if not set we don't
-+ set the new partition syntax string since
-+ we know the share object is destroyed.
-+ WFRM_PACK_FRM If set we should pack the frm file and delete
-+ the frm file
-+
-+ RETURN VALUES
-+ TRUE Error
-+ FALSE Success
-+
-+ DESCRIPTION
-+ A support method that creates a new frm file and in this process it
-+ regenerates the partition data. It works fine also for non-partitioned
-+ tables since it only handles partitioned data if it exists.
-+*/
-+
-+bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags)
-+{
-+ /*
-+ Prepare table to prepare for writing a new frm file where the
-+ partitions in add/drop state have temporarily changed their state
-+ We set tmp_table to avoid get errors on naming of primary key index.
-+ */
-+ int error= 0;
-+ char path[FN_REFLEN+1];
-+ char shadow_path[FN_REFLEN+1];
-+ char shadow_frm_name[FN_REFLEN+1];
-+ char frm_name[FN_REFLEN+1];
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ char *part_syntax_buf;
-+ uint syntax_len;
-+#endif
-+ DBUG_ENTER("mysql_write_frm");
-+
-+ /*
-+ Build shadow frm file name
-+ */
-+ build_table_shadow_filename(shadow_path, sizeof(shadow_path) - 1, lpt);
-+ strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
-+ if (flags & WFRM_WRITE_SHADOW)
-+ {
-+ if (mysql_prepare_create_table(lpt->thd, lpt->create_info,
-+ lpt->alter_info,
-+ /*tmp_table*/ 1,
-+ &lpt->db_options,
-+ lpt->table->file,
-+ &lpt->key_info_buffer,
-+ &lpt->key_count,
-+ /*select_field_count*/ 0))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ {
-+ partition_info *part_info= lpt->table->part_info;
-+ if (part_info)
-+ {
-+ if (!(part_syntax_buf= generate_partition_syntax(part_info,
-+ &syntax_len,
-+ TRUE, TRUE)))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ part_info->part_info_string= part_syntax_buf;
-+ part_info->part_info_len= syntax_len;
-+ }
-+ }
-+#endif
-+ /* Write shadow frm file */
-+ lpt->create_info->table_options= lpt->db_options;
-+ if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db,
-+ lpt->table_name, lpt->create_info,
-+ lpt->alter_info->create_list, lpt->key_count,
-+ lpt->key_info_buffer, lpt->table->file)) ||
-+ lpt->table->file->ha_create_handler_files(shadow_path, NULL,
-+ CHF_CREATE_FLAG,
-+ lpt->create_info))
-+ {
-+ my_delete(shadow_frm_name, MYF(0));
-+ error= 1;
-+ goto end;
-+ }
-+ }
-+ if (flags & WFRM_PACK_FRM)
-+ {
-+ /*
-+ We need to pack the frm file and after packing it we delete the
-+ frm file to ensure it doesn't get used. This is only used for
-+ handlers that have the main version of the frm file stored in the
-+ handler.
-+ */
-+ uchar *data;
-+ size_t length;
-+ if (readfrm(shadow_path, &data, &length) ||
-+ packfrm(data, length, &lpt->pack_frm_data, &lpt->pack_frm_len))
-+ {
-+ my_free(data, MYF(MY_ALLOW_ZERO_PTR));
-+ my_free(lpt->pack_frm_data, MYF(MY_ALLOW_ZERO_PTR));
-+ mem_alloc_error(length);
-+ error= 1;
-+ goto end;
-+ }
-+ error= my_delete(shadow_frm_name, MYF(MY_WME));
-+ }
-+ if (flags & WFRM_INSTALL_SHADOW)
-+ {
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ partition_info *part_info= lpt->part_info;
-+#endif
-+ /*
-+ Build frm file name
-+ */
-+ build_table_filename(path, sizeof(path) - 1, lpt->db,
-+ lpt->table_name, "", 0);
-+ strxmov(frm_name, path, reg_ext, NullS);
-+ /*
-+ When we are changing to use new frm file we need to ensure that we
-+ don't collide with another thread in process to open the frm file.
-+ We start by deleting the .frm file and possible .par file. Then we
-+ write to the DDL log that we have completed the delete phase by
-+ increasing the phase of the log entry. Next step is to rename the
-+ new .frm file and the new .par file to the real name. After
-+ completing this we write a new phase to the log entry that will
-+ deactivate it.
-+ */
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (my_delete(frm_name, MYF(MY_WME)) ||
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ lpt->table->file->ha_create_handler_files(path, shadow_path,
-+ CHF_DELETE_FLAG, NULL) ||
-+ deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
-+ (sync_ddl_log(), FALSE) ||
-+#endif
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ my_rename(shadow_frm_name, frm_name, MYF(MY_WME)) ||
-+ lpt->table->file->ha_create_handler_files(path, shadow_path,
-+ CHF_RENAME_FLAG, NULL))
-+#else
-+ my_rename(shadow_frm_name, frm_name, MYF(MY_WME)))
-+#endif
-+ {
-+ error= 1;
-+ goto err;
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (part_info && (flags & WFRM_KEEP_SHARE))
-+ {
-+ TABLE_SHARE *share= lpt->table->s;
-+ char *tmp_part_syntax_str;
-+ if (!(part_syntax_buf= generate_partition_syntax(part_info,
-+ &syntax_len,
-+ TRUE, TRUE)))
-+ {
-+ error= 1;
-+ goto err;
-+ }
-+ if (share->partition_info_buffer_size < syntax_len + 1)
-+ {
-+ share->partition_info_buffer_size= syntax_len+1;
-+ if (!(tmp_part_syntax_str= (char*) strmake_root(&share->mem_root,
-+ part_syntax_buf,
-+ syntax_len)))
-+ {
-+ error= 1;
-+ goto err;
-+ }
-+ share->partition_info= tmp_part_syntax_str;
-+ }
-+ else
-+ memcpy((char*) share->partition_info, part_syntax_buf, syntax_len + 1);
-+ share->partition_info_len= part_info->part_info_len= syntax_len;
-+ part_info->part_info_string= part_syntax_buf;
-+ }
-+#endif
-+
-+err:
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
-+ part_info->frm_log_entry= NULL;
-+ VOID(sync_ddl_log());
-+#endif
-+ }
-+
-+end:
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ SYNOPSIS
-+ write_bin_log()
-+ thd Thread object
-+ clear_error is clear_error to be called
-+ query Query to log
-+ query_length Length of query
-+
-+ RETURN VALUES
-+ NONE
-+
-+ DESCRIPTION
-+ Write the binlog if open, routine used in multiple places in this
-+ file
-+*/
-+
-+int write_bin_log(THD *thd, bool clear_error,
-+ char const *query, ulong query_length)
-+{
-+ int error= 0;
-+ if (mysql_bin_log.is_open())
-+ {
-+ int errcode= 0;
-+ if (clear_error)
-+ thd->clear_error();
-+ else
-+ errcode= query_error_code(thd, TRUE);
-+ error= thd->binlog_query(THD::STMT_QUERY_TYPE,
-+ query, query_length, FALSE, FALSE, errcode);
-+ }
-+ return error;
-+}
-+
-+
-+/*
-+ delete (drop) tables.
-+
-+ SYNOPSIS
-+ mysql_rm_table()
-+ thd Thread handle
-+ tables List of tables to delete
-+ if_exists If 1, don't give error if one table doesn't exists
-+
-+ NOTES
-+ Will delete all tables that can be deleted and give a compact error
-+ messages for tables that could not be deleted.
-+ If a table is in use, we will wait for all users to free the table
-+ before dropping it
-+
-+ Wait if global_read_lock (FLUSH TABLES WITH READ LOCK) is set.
-+
-+ RETURN
-+ FALSE OK. In this case ok packet is sent to user
-+ TRUE Error
-+
-+*/
-+
-+bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
-+ my_bool drop_temporary)
-+{
-+ bool error= FALSE, need_start_waiters= FALSE;
-+ Drop_table_error_handler err_handler(thd->get_internal_handler());
-+ DBUG_ENTER("mysql_rm_table");
-+
-+ /* mark for close and remove all cached entries */
-+
-+ if (!drop_temporary)
-+ {
-+ if ((error= wait_if_global_read_lock(thd, 0, 1)))
-+ {
-+ my_error(ER_TABLE_NOT_LOCKED_FOR_WRITE, MYF(0), tables->table_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ else
-+ need_start_waiters= TRUE;
-+ }
-+
-+ /*
-+ Acquire LOCK_open after wait_if_global_read_lock(). If we would hold
-+ LOCK_open during wait_if_global_read_lock(), other threads could not
-+ close their tables. This would make a pretty deadlock.
-+ */
-+ thd->push_internal_handler(&err_handler);
-+ error= mysql_rm_table_part2(thd, tables, if_exists, drop_temporary, 0, 0);
-+ thd->pop_internal_handler();
-+
-+
-+ if (need_start_waiters)
-+ start_waiting_global_read_lock(thd);
-+
-+ if (error)
-+ DBUG_RETURN(TRUE);
-+ my_ok(thd);
-+ DBUG_RETURN(FALSE);
-+}
-+
-+/*
-+ Execute the drop of a normal or temporary table
-+
-+ SYNOPSIS
-+ mysql_rm_table_part2()
-+ thd Thread handler
-+ tables Tables to drop
-+ if_exists If set, don't give an error if table doesn't exists.
-+ In this case we give an warning of level 'NOTE'
-+ drop_temporary Only drop temporary tables
-+ drop_view Allow to delete VIEW .frm
-+ dont_log_query Don't write query to log files. This will also not
-+ generate warnings if the handler files doesn't exists
-+
-+ TODO:
-+ When logging to the binary log, we should log
-+ tmp_tables and transactional tables as separate statements if we
-+ are in a transaction; This is needed to get these tables into the
-+ cached binary log that is only written on COMMIT.
-+
-+ The current code only writes DROP statements that only uses temporary
-+ tables to the cache binary log. This should be ok on most cases, but
-+ not all.
-+
-+ RETURN
-+ 0 ok
-+ 1 Error
-+ -1 Thread was killed
-+*/
-+
-+int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
-+ bool drop_temporary, bool drop_view,
-+ bool dont_log_query)
-+{
-+ TABLE_LIST *table;
-+ char path[FN_REFLEN + 1], *alias;
-+ uint path_length;
-+ String wrong_tables;
-+ int error= 0;
-+ int non_temp_tables_count= 0;
-+ bool some_tables_deleted=0, tmp_table_deleted=0, foreign_key_error=0;
-+ String built_query;
-+ String built_tmp_query;
-+ DBUG_ENTER("mysql_rm_table_part2");
-+
-+ LINT_INIT(alias);
-+ LINT_INIT(path_length);
-+
-+ if (thd->current_stmt_binlog_row_based && !dont_log_query)
-+ {
-+ built_query.set_charset(system_charset_info);
-+ if (if_exists)
-+ built_query.append("DROP TABLE IF EXISTS ");
-+ else
-+ built_query.append("DROP TABLE ");
-+ }
-+
-+ mysql_ha_rm_tables(thd, tables, FALSE);
-+
-+ pthread_mutex_lock(&LOCK_open);
-+
-+ /* Disable drop of enabled log tables, must be done before name locking */
-+ for (table= tables; table; table= table->next_local)
-+ {
-+ if (check_if_log_table(table->db_length, table->db,
-+ table->table_name_length, table->table_name, 1))
-+ {
-+ my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP");
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(1);
-+ }
-+ }
-+
-+ if (!drop_temporary && lock_table_names_exclusively(thd, tables))
-+ {
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(1);
-+ }
-+
-+ for (table= tables; table; table= table->next_local)
-+ {
-+ char *db=table->db;
-+ handlerton *table_type;
-+ enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
-+
-+ DBUG_PRINT("table", ("table_l: '%s'.'%s' table: 0x%lx s: 0x%lx",
-+ table->db, table->table_name, (long) table->table,
-+ table->table ? (long) table->table->s : (long) -1));
-+
-+ error= drop_temporary_table(thd, table);
-+
-+ switch (error) {
-+ case 0:
-+ // removed temporary table
-+ tmp_table_deleted= 1;
-+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED &&
-+ thd->current_stmt_binlog_row_based)
-+ {
-+ if (built_tmp_query.is_empty())
-+ {
-+ built_tmp_query.set_charset(system_charset_info);
-+ built_tmp_query.append("DROP TEMPORARY TABLE IF EXISTS ");
-+ }
-+
-+ built_tmp_query.append("`");
-+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
-+ {
-+ built_tmp_query.append(db);
-+ built_tmp_query.append("`.`");
-+ }
-+ built_tmp_query.append(table->table_name);
-+ built_tmp_query.append("`,");
-+ }
-+
-+ continue;
-+ case -1:
-+ DBUG_ASSERT(thd->in_sub_stmt);
-+ error= 1;
-+ goto err_with_placeholders;
-+ default:
-+ // temporary table not found
-+ error= 0;
-+ }
-+
-+ /*
-+ If row-based replication is used and the table is not a
-+ temporary table, we add the table name to the drop statement
-+ being built. The string always end in a comma and the comma
-+ will be chopped off before being written to the binary log.
-+ */
-+ if (!drop_temporary && thd->current_stmt_binlog_row_based && !dont_log_query)
-+ {
-+ non_temp_tables_count++;
-+ /*
-+ Don't write the database name if it is the current one (or if
-+ thd->db is NULL).
-+ */
-+ built_query.append("`");
-+ if (thd->db == NULL || strcmp(db,thd->db) != 0)
-+ {
-+ built_query.append(db);
-+ built_query.append("`.`");
-+ }
-+
-+ built_query.append(table->table_name);
-+ built_query.append("`,");
-+ }
-+
-+ if (!drop_temporary)
-+ {
-+ TABLE *locked_table;
-+ abort_locked_tables(thd, db, table->table_name);
-+ remove_table_from_cache(thd, db, table->table_name,
-+ RTFC_WAIT_OTHER_THREAD_FLAG |
-+ RTFC_CHECK_KILLED_FLAG);
-+ /*
-+ If the table was used in lock tables, remember it so that
-+ unlock_table_names can free it
-+ */
-+ if ((locked_table= drop_locked_tables(thd, db, table->table_name)))
-+ table->table= locked_table;
-+
-+ if (thd->killed)
-+ {
-+ error= -1;
-+ goto err_with_placeholders;
-+ }
-+ alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
-+ /* remove .frm file and engine files */
-+ path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
-+ reg_ext,
-+ table->internal_tmp_table ?
-+ FN_IS_TMP : 0);
-+ }
-+ DEBUG_SYNC(thd, "rm_table_part2_before_delete_table");
-+ if (drop_temporary ||
-+ ((access(path, F_OK) &&
-+ ha_create_table_from_engine(thd, db, alias)) ||
-+ (!drop_view &&
-+ mysql_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
-+ {
-+ // Table was not found on disk and table can't be created from engine
-+ if (if_exists)
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
-+ table->table_name);
-+ else
-+ error= 1;
-+ }
-+ else
-+ {
-+ char *end;
-+ /*
-+ Cannot use the db_type from the table, since that might have changed
-+ while waiting for the exclusive name lock. We are under LOCK_open,
-+ so reading from the frm-file is safe.
-+ */
-+ if (frm_db_type == DB_TYPE_UNKNOWN)
-+ {
-+ mysql_frm_type(thd, path, &frm_db_type);
-+ DBUG_PRINT("info", ("frm_db_type %d from %s", frm_db_type, path));
-+ }
-+ table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
-+ // Remove extension for delete
-+ *(end= path + path_length - reg_ext_length)= '\0';
-+ DBUG_PRINT("info", ("deleting table of type %d",
-+ (table_type ? table_type->db_type : 0)));
-+ error= ha_delete_table(thd, table_type, path, db, table->table_name,
-+ !dont_log_query);
-+
-+ /* No error if non existent table and 'IF EXIST' clause or view */
-+ if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
-+ (if_exists || table_type == NULL))
-+ {
-+ error= 0;
-+ thd->clear_error();
-+ }
-+ if (error == HA_ERR_ROW_IS_REFERENCED)
-+ {
-+ /* the table is referenced by a foreign key constraint */
-+ foreign_key_error=1;
-+ }
-+ if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
-+ {
-+ int new_error;
-+ /* Delete the table definition file */
-+ strmov(end,reg_ext);
-+ if (!(new_error=my_delete(path,MYF(MY_WME))))
-+ {
-+ some_tables_deleted=1;
-+ new_error= Table_triggers_list::drop_all_triggers(thd, db,
-+ table->table_name);
-+ }
-+ error|= new_error;
-+ }
-+ }
-+ if (error)
-+ {
-+ if (wrong_tables.length())
-+ wrong_tables.append(',');
-+ wrong_tables.append(String(table->table_name,system_charset_info));
-+ }
-+ DBUG_PRINT("table", ("table: 0x%lx s: 0x%lx", (long) table->table,
-+ table->table ? (long) table->table->s : (long) -1));
-+ }
-+ /*
-+ It's safe to unlock LOCK_open: we have an exclusive lock
-+ on the table name.
-+ */
-+ pthread_mutex_unlock(&LOCK_open);
-+ DEBUG_SYNC(thd, "rm_table_part2_before_binlog");
-+ thd->thread_specific_used|= tmp_table_deleted;
-+ error= 0;
-+ if (wrong_tables.length())
-+ {
-+ if (!foreign_key_error)
-+ my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
-+ wrong_tables.c_ptr());
-+ else
-+ my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
-+ error= 1;
-+ }
-+
-+ if (some_tables_deleted || tmp_table_deleted || !error)
-+ {
-+ query_cache_invalidate3(thd, tables, 0);
-+ if (!dont_log_query)
-+ {
-+ if (!thd->current_stmt_binlog_row_based ||
-+ (non_temp_tables_count > 0 && !tmp_table_deleted))
-+ {
-+ /*
-+ In this case, we are either using statement-based
-+ replication or using row-based replication but have only
-+ deleted one or more non-temporary tables (and no temporary
-+ tables). In this case, we can write the original query into
-+ the binary log.
-+ */
-+ error |= write_bin_log(thd, !error, thd->query(), thd->query_length());
-+ }
-+ else if (thd->current_stmt_binlog_row_based &&
-+ tmp_table_deleted)
-+ {
-+ if (non_temp_tables_count > 0)
-+ {
-+ /*
-+ In this case we have deleted both temporary and
-+ non-temporary tables, so:
-+ - since we have deleted a non-temporary table we have to
-+ binlog the statement, but
-+ - since we have deleted a temporary table we cannot binlog
-+ the statement (since the table may have not been created on the
-+ slave - check "if" branch below, this might cause the slave to
-+ stop).
-+
-+ Instead, we write a built statement, only containing the
-+ non-temporary tables, to the binary log
-+ */
-+ built_query.chop(); // Chop of the last comma
-+ built_query.append(" /* generated by server */");
-+ error|= write_bin_log(thd, !error, built_query.ptr(), built_query.length());
-+ }
-+
-+ /*
-+ One needs to always log any temporary table drop, if:
-+ 1. thread logging format is mixed mode; AND
-+ 2. current statement logging format is set to row.
-+ */
-+ if (thd->variables.binlog_format == BINLOG_FORMAT_MIXED)
-+ {
-+ /*
-+ In this case we have deleted some temporary tables but we are using
-+ row based logging for the statement. However, thread uses mixed mode
-+ format, thence we need to log the dropping as we cannot tell for
-+ sure whether the create was logged as statement previously or not, ie,
-+ before switching to row mode.
-+ */
-+ built_tmp_query.chop(); // Chop of the last comma
-+ built_tmp_query.append(" /* generated by server */");
-+ error|= write_bin_log(thd, !error, built_tmp_query.ptr(), built_tmp_query.length());
-+ }
-+ }
-+
-+ /*
-+ The remaining cases are:
-+ - no tables were deleted and
-+ - only temporary tables were deleted and row-based
-+ replication is used.
-+ In both these cases, nothing should be written to the binary
-+ log.
-+ */
-+ }
-+ }
-+ pthread_mutex_lock(&LOCK_open);
-+err_with_placeholders:
-+ unlock_table_names(thd, tables, (TABLE_LIST*) 0);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/*
-+ Quickly remove a table.
-+
-+ SYNOPSIS
-+ quick_rm_table()
-+ base The handlerton handle.
-+ db The database name.
-+ table_name The table name.
-+ flags flags for build_table_filename().
-+
-+ RETURN
-+ 0 OK
-+ != 0 Error
-+*/
-+
-+bool quick_rm_table(handlerton *base,const char *db,
-+ const char *table_name, uint flags)
-+{
-+ char path[FN_REFLEN + 1];
-+ bool error= 0;
-+ DBUG_ENTER("quick_rm_table");
-+
-+ uint path_length= build_table_filename(path, sizeof(path) - 1,
-+ db, table_name, reg_ext, flags);
-+ if (my_delete(path,MYF(0)))
-+ error= 1; /* purecov: inspected */
-+ path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
-+ if (!(flags & FRM_ONLY))
-+ error|= ha_delete_table(current_thd, base, path, db, table_name, 0);
-+ DBUG_RETURN(error);
-+}
-+
-+/*
-+ Sort keys in the following order:
-+ - PRIMARY KEY
-+ - UNIQUE keys where all column are NOT NULL
-+ - UNIQUE keys that don't contain partial segments
-+ - Other UNIQUE keys
-+ - Normal keys
-+ - Fulltext keys
-+
-+ This will make checking for duplicated keys faster and ensure that
-+ PRIMARY keys are prioritized.
-+*/
-+
-+static int sort_keys(KEY *a, KEY *b)
-+{
-+ ulong a_flags= a->flags, b_flags= b->flags;
-+
-+ if (a_flags & HA_NOSAME)
-+ {
-+ if (!(b_flags & HA_NOSAME))
-+ return -1;
-+ if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
-+ {
-+ /* Sort NOT NULL keys before other keys */
-+ return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
-+ }
-+ if (a->name == primary_key_name)
-+ return -1;
-+ if (b->name == primary_key_name)
-+ return 1;
-+ /* Sort keys don't containing partial segments before others */
-+ if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
-+ return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
-+ }
-+ else if (b_flags & HA_NOSAME)
-+ return 1; // Prefer b
-+
-+ if ((a_flags ^ b_flags) & HA_FULLTEXT)
-+ {
-+ return (a_flags & HA_FULLTEXT) ? 1 : -1;
-+ }
-+ /*
-+ Prefer original key order. usable_key_parts contains here
-+ the original key position.
-+ */
-+ return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
-+ (a->usable_key_parts > b->usable_key_parts) ? 1 :
-+ 0);
-+}
-+
-+/*
-+ Check TYPELIB (set or enum) for duplicates
-+
-+ SYNOPSIS
-+ check_duplicates_in_interval()
-+ set_or_name "SET" or "ENUM" string for warning message
-+ name name of the checked column
-+ typelib list of values for the column
-+ dup_val_count returns count of duplicate elements
-+
-+ DESCRIPTION
-+ This function prints an warning for each value in list
-+ which has some duplicates on its right
-+
-+ RETURN VALUES
-+ 0 ok
-+ 1 Error
-+*/
-+
-+bool check_duplicates_in_interval(const char *set_or_name,
-+ const char *name, TYPELIB *typelib,
-+ CHARSET_INFO *cs, unsigned int *dup_val_count)
-+{
-+ TYPELIB tmp= *typelib;
-+ const char **cur_value= typelib->type_names;
-+ unsigned int *cur_length= typelib->type_lengths;
-+ *dup_val_count= 0;
-+
-+ for ( ; tmp.count > 1; cur_value++, cur_length++)
-+ {
-+ tmp.type_names++;
-+ tmp.type_lengths++;
-+ tmp.count--;
-+ if (find_type2(&tmp, (const char*)*cur_value, *cur_length, cs))
-+ {
-+ if ((current_thd->variables.sql_mode &
-+ (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES)))
-+ {
-+ my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
-+ name,*cur_value,set_or_name);
-+ return 1;
-+ }
-+ push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_DUPLICATED_VALUE_IN_TYPE,
-+ ER(ER_DUPLICATED_VALUE_IN_TYPE),
-+ name,*cur_value,set_or_name);
-+ (*dup_val_count)++;
-+ }
-+ }
-+ return 0;
-+}
-+
-+
-+/*
-+ Check TYPELIB (set or enum) max and total lengths
-+
-+ SYNOPSIS
-+ calculate_interval_lengths()
-+ cs charset+collation pair of the interval
-+ typelib list of values for the column
-+ max_length length of the longest item
-+ tot_length sum of the item lengths
-+
-+ DESCRIPTION
-+ After this function call:
-+ - ENUM uses max_length
-+ - SET uses tot_length.
-+
-+ RETURN VALUES
-+ void
-+*/
-+void calculate_interval_lengths(CHARSET_INFO *cs, TYPELIB *interval,
-+ uint32 *max_length, uint32 *tot_length)
-+{
-+ const char **pos;
-+ uint *len;
-+ *max_length= *tot_length= 0;
-+ for (pos= interval->type_names, len= interval->type_lengths;
-+ *pos ; pos++, len++)
-+ {
-+ size_t length= cs->cset->numchars(cs, *pos, *pos + *len);
-+ *tot_length+= length;
-+ set_if_bigger(*max_length, (uint32)length);
-+ }
-+}
-+
-+
-+/*
-+ Prepare a create_table instance for packing
-+
-+ SYNOPSIS
-+ prepare_create_field()
-+ sql_field field to prepare for packing
-+ blob_columns count for BLOBs
-+ timestamps count for timestamps
-+ table_flags table flags
-+
-+ DESCRIPTION
-+ This function prepares a Create_field instance.
-+ Fields such as pack_flag are valid after this call.
-+
-+ RETURN VALUES
-+ 0 ok
-+ 1 Error
-+*/
-+
-+int prepare_create_field(Create_field *sql_field,
-+ uint *blob_columns,
-+ int *timestamps, int *timestamps_with_niladic,
-+ longlong table_flags)
-+{
-+ unsigned int dup_val_count;
-+ DBUG_ENTER("prepare_field");
-+
-+ /*
-+ This code came from mysql_prepare_create_table.
-+ Indent preserved to make patching easier
-+ */
-+ DBUG_ASSERT(sql_field->charset);
-+
-+ switch (sql_field->sql_type) {
-+ case MYSQL_TYPE_BLOB:
-+ case MYSQL_TYPE_MEDIUM_BLOB:
-+ case MYSQL_TYPE_TINY_BLOB:
-+ case MYSQL_TYPE_LONG_BLOB:
-+ sql_field->pack_flag=FIELDFLAG_BLOB |
-+ pack_length_to_packflag(sql_field->pack_length -
-+ portable_sizeof_char_ptr);
-+ if (sql_field->charset->state & MY_CS_BINSORT)
-+ sql_field->pack_flag|=FIELDFLAG_BINARY;
-+ sql_field->length=8; // Unireg field length
-+ sql_field->unireg_check=Field::BLOB_FIELD;
-+ (*blob_columns)++;
-+ break;
-+ case MYSQL_TYPE_GEOMETRY:
-+#ifdef HAVE_SPATIAL
-+ if (!(table_flags & HA_CAN_GEOMETRY))
-+ {
-+ my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
-+ MYF(0), "GEOMETRY");
-+ DBUG_RETURN(1);
-+ }
-+ sql_field->pack_flag=FIELDFLAG_GEOM |
-+ pack_length_to_packflag(sql_field->pack_length -
-+ portable_sizeof_char_ptr);
-+ if (sql_field->charset->state & MY_CS_BINSORT)
-+ sql_field->pack_flag|=FIELDFLAG_BINARY;
-+ sql_field->length=8; // Unireg field length
-+ sql_field->unireg_check=Field::BLOB_FIELD;
-+ (*blob_columns)++;
-+ break;
-+#else
-+ my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
-+ sym_group_geom.name, sym_group_geom.needed_define);
-+ DBUG_RETURN(1);
-+#endif /*HAVE_SPATIAL*/
-+ case MYSQL_TYPE_VARCHAR:
-+#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
-+ if (table_flags & HA_NO_VARCHAR)
-+ {
-+ /* convert VARCHAR to CHAR because handler is not yet up to date */
-+ sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
-+ sql_field->pack_length= calc_pack_length(sql_field->sql_type,
-+ (uint) sql_field->length);
-+ if ((sql_field->length / sql_field->charset->mbmaxlen) >
-+ MAX_FIELD_CHARLENGTH)
-+ {
-+ my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
-+ MYF(0), sql_field->field_name, MAX_FIELD_CHARLENGTH);
-+ DBUG_RETURN(1);
-+ }
-+ }
-+#endif
-+ /* fall through */
-+ case MYSQL_TYPE_STRING:
-+ sql_field->pack_flag=0;
-+ if (sql_field->charset->state & MY_CS_BINSORT)
-+ sql_field->pack_flag|=FIELDFLAG_BINARY;
-+ break;
-+ case MYSQL_TYPE_ENUM:
-+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
-+ FIELDFLAG_INTERVAL;
-+ if (sql_field->charset->state & MY_CS_BINSORT)
-+ sql_field->pack_flag|=FIELDFLAG_BINARY;
-+ sql_field->unireg_check=Field::INTERVAL_FIELD;
-+ if (check_duplicates_in_interval("ENUM",sql_field->field_name,
-+ sql_field->interval,
-+ sql_field->charset, &dup_val_count))
-+ DBUG_RETURN(1);
-+ break;
-+ case MYSQL_TYPE_SET:
-+ sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
-+ FIELDFLAG_BITFIELD;
-+ if (sql_field->charset->state & MY_CS_BINSORT)
-+ sql_field->pack_flag|=FIELDFLAG_BINARY;
-+ sql_field->unireg_check=Field::BIT_FIELD;
-+ if (check_duplicates_in_interval("SET",sql_field->field_name,
-+ sql_field->interval,
-+ sql_field->charset, &dup_val_count))
-+ DBUG_RETURN(1);
-+ /* Check that count of unique members is not more then 64 */
-+ if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8)
-+ {
-+ my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(1);
-+ }
-+ break;
-+ case MYSQL_TYPE_DATE: // Rest of string types
-+ case MYSQL_TYPE_NEWDATE:
-+ case MYSQL_TYPE_TIME:
-+ case MYSQL_TYPE_DATETIME:
-+ case MYSQL_TYPE_NULL:
-+ sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
-+ break;
-+ case MYSQL_TYPE_BIT:
-+ /*
-+ We have sql_field->pack_flag already set here, see
-+ mysql_prepare_create_table().
-+ */
-+ break;
-+ case MYSQL_TYPE_NEWDECIMAL:
-+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
-+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
-+ FIELDFLAG_DECIMAL) |
-+ (sql_field->flags & ZEROFILL_FLAG ?
-+ FIELDFLAG_ZEROFILL : 0) |
-+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
-+ break;
-+ case MYSQL_TYPE_TIMESTAMP:
-+ /* We should replace old TIMESTAMP fields with their newer analogs */
-+ if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
-+ {
-+ if (!*timestamps)
-+ {
-+ sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
-+ (*timestamps_with_niladic)++;
-+ }
-+ else
-+ sql_field->unireg_check= Field::NONE;
-+ }
-+ else if (sql_field->unireg_check != Field::NONE)
-+ (*timestamps_with_niladic)++;
-+
-+ (*timestamps)++;
-+ /* fall-through */
-+ default:
-+ sql_field->pack_flag=(FIELDFLAG_NUMBER |
-+ (sql_field->flags & UNSIGNED_FLAG ? 0 :
-+ FIELDFLAG_DECIMAL) |
-+ (sql_field->flags & ZEROFILL_FLAG ?
-+ FIELDFLAG_ZEROFILL : 0) |
-+ f_settype((uint) sql_field->sql_type) |
-+ (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
-+ break;
-+ }
-+ if (!(sql_field->flags & NOT_NULL_FLAG))
-+ sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
-+ if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
-+ sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
-+ DBUG_RETURN(0);
-+}
-+
-+/*
-+ Preparation for table creation
-+
-+ SYNOPSIS
-+ mysql_prepare_create_table()
-+ thd Thread object.
-+ create_info Create information (like MAX_ROWS).
-+ alter_info List of columns and indexes to create
-+ tmp_table If a temporary table is to be created.
-+ db_options INOUT Table options (like HA_OPTION_PACK_RECORD).
-+ file The handler for the new table.
-+ key_info_buffer OUT An array of KEY structs for the indexes.
-+ key_count OUT The number of elements in the array.
-+ select_field_count The number of fields coming from a select table.
-+
-+ DESCRIPTION
-+ Prepares the table and key structures for table creation.
-+
-+ NOTES
-+ sets create_info->varchar if the table has a varchar
-+
-+ RETURN VALUES
-+ FALSE OK
-+ TRUE error
-+*/
-+
-+static int
-+mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info,
-+ bool tmp_table,
-+ uint *db_options,
-+ handler *file, KEY **key_info_buffer,
-+ uint *key_count, int select_field_count)
-+{
-+ const char *key_name;
-+ Create_field *sql_field,*dup_field;
-+ uint field,null_fields,blob_columns,max_key_length;
-+ ulong record_offset= 0;
-+ KEY *key_info;
-+ KEY_PART_INFO *key_part_info;
-+ int timestamps= 0, timestamps_with_niladic= 0;
-+ int field_no,dup_no;
-+ int select_field_pos,auto_increment=0;
-+ List_iterator<Create_field> it(alter_info->create_list);
-+ List_iterator<Create_field> it2(alter_info->create_list);
-+ uint total_uneven_bit_length= 0;
-+ DBUG_ENTER("mysql_prepare_create_table");
-+
-+ select_field_pos= alter_info->create_list.elements - select_field_count;
-+ null_fields=blob_columns=0;
-+ create_info->varchar= 0;
-+ max_key_length= file->max_key_length();
-+
-+ for (field_no=0; (sql_field=it++) ; field_no++)
-+ {
-+ CHARSET_INFO *save_cs;
-+
-+ /*
-+ Initialize length from its original value (number of characters),
-+ which was set in the parser. This is necessary if we're
-+ executing a prepared statement for the second time.
-+ */
-+ sql_field->length= sql_field->char_length;
-+ if (!sql_field->charset)
-+ sql_field->charset= create_info->default_table_charset;
-+ /*
-+ table_charset is set in ALTER TABLE if we want change character set
-+ for all varchar/char columns.
-+ But the table charset must not affect the BLOB fields, so don't
-+ allow to change my_charset_bin to somethig else.
-+ */
-+ if (create_info->table_charset && sql_field->charset != &my_charset_bin)
-+ sql_field->charset= create_info->table_charset;
-+
-+ save_cs= sql_field->charset;
-+ if ((sql_field->flags & BINCMP_FLAG) &&
-+ !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
-+ MY_CS_BINSORT,MYF(0))))
-+ {
-+ char tmp[65];
-+ strmake(strmake(tmp, save_cs->csname, sizeof(tmp)-4),
-+ STRING_WITH_LEN("_bin"));
-+ my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /*
-+ Convert the default value from client character
-+ set into the column character set if necessary.
-+ */
-+ if (sql_field->def &&
-+ save_cs != sql_field->def->collation.collation &&
-+ (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
-+ sql_field->sql_type == MYSQL_TYPE_STRING ||
-+ sql_field->sql_type == MYSQL_TYPE_SET ||
-+ sql_field->sql_type == MYSQL_TYPE_ENUM))
-+ {
-+ /*
-+ Starting from 5.1 we work here with a copy of Create_field
-+ created by the caller, not with the instance that was
-+ originally created during parsing. It's OK to create
-+ a temporary item and initialize with it a member of the
-+ copy -- this item will be thrown away along with the copy
-+ at the end of execution, and thus not introduce a dangling
-+ pointer in the parsed tree of a prepared statement or a
-+ stored procedure statement.
-+ */
-+ sql_field->def= sql_field->def->safe_charset_converter(save_cs);
-+
-+ if (sql_field->def == NULL)
-+ {
-+ /* Could not convert */
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+
-+ if (sql_field->sql_type == MYSQL_TYPE_SET ||
-+ sql_field->sql_type == MYSQL_TYPE_ENUM)
-+ {
-+ uint32 dummy;
-+ CHARSET_INFO *cs= sql_field->charset;
-+ TYPELIB *interval= sql_field->interval;
-+
-+ /*
-+ Create typelib from interval_list, and if necessary
-+ convert strings from client character set to the
-+ column character set.
-+ */
-+ if (!interval)
-+ {
-+ /*
-+ Create the typelib in runtime memory - we will free the
-+ occupied memory at the same time when we free this
-+ sql_field -- at the end of execution.
-+ */
-+ interval= sql_field->interval= typelib(thd->mem_root,
-+ sql_field->interval_list);
-+ List_iterator<String> int_it(sql_field->interval_list);
-+ String conv, *tmp;
-+ char comma_buf[2];
-+ int comma_length= cs->cset->wc_mb(cs, ',', (uchar*) comma_buf,
-+ (uchar*) comma_buf +
-+ sizeof(comma_buf));
-+ DBUG_ASSERT(comma_length > 0);
-+ for (uint i= 0; (tmp= int_it++); i++)
-+ {
-+ size_t lengthsp;
-+ if (String::needs_conversion(tmp->length(), tmp->charset(),
-+ cs, &dummy))
-+ {
-+ uint cnv_errs;
-+ conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
-+ interval->type_names[i]= strmake_root(thd->mem_root, conv.ptr(),
-+ conv.length());
-+ interval->type_lengths[i]= conv.length();
-+ }
-+
-+ // Strip trailing spaces.
-+ lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
-+ interval->type_lengths[i]);
-+ interval->type_lengths[i]= lengthsp;
-+ ((uchar *)interval->type_names[i])[lengthsp]= '\0';
-+ if (sql_field->sql_type == MYSQL_TYPE_SET)
-+ {
-+ if (cs->coll->instr(cs, interval->type_names[i],
-+ interval->type_lengths[i],
-+ comma_buf, comma_length, NULL, 0))
-+ {
-+ my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "set", tmp->ptr());
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+ sql_field->interval_list.empty(); // Don't need interval_list anymore
-+ }
-+
-+ if (sql_field->sql_type == MYSQL_TYPE_SET)
-+ {
-+ uint32 field_length;
-+ if (sql_field->def != NULL)
-+ {
-+ char *not_used;
-+ uint not_used2;
-+ bool not_found= 0;
-+ String str, *def= sql_field->def->val_str(&str);
-+ if (def == NULL) /* SQL "NULL" maps to NULL */
-+ {
-+ if ((sql_field->flags & NOT_NULL_FLAG) != 0)
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* else, NULL is an allowed value */
-+ (void) find_set(interval, NULL, 0,
-+ cs, ¬_used, ¬_used2, ¬_found);
-+ }
-+ else /* not NULL */
-+ {
-+ (void) find_set(interval, def->ptr(), def->length(),
-+ cs, ¬_used, ¬_used2, ¬_found);
-+ }
-+
-+ if (not_found)
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ calculate_interval_lengths(cs, interval, &dummy, &field_length);
-+ sql_field->length= field_length + (interval->count - 1);
-+ }
-+ else /* MYSQL_TYPE_ENUM */
-+ {
-+ uint32 field_length;
-+ DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
-+ if (sql_field->def != NULL)
-+ {
-+ String str, *def= sql_field->def->val_str(&str);
-+ if (def == NULL) /* SQL "NULL" maps to NULL */
-+ {
-+ if ((sql_field->flags & NOT_NULL_FLAG) != 0)
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* else, the defaults yield the correct length for NULLs. */
-+ }
-+ else /* not NULL */
-+ {
-+ def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
-+ if (find_type2(interval, def->ptr(), def->length(), cs) == 0) /* not found */
-+ {
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+ calculate_interval_lengths(cs, interval, &field_length, &dummy);
-+ sql_field->length= field_length;
-+ }
-+ set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
-+ }
-+
-+ if (sql_field->sql_type == MYSQL_TYPE_BIT)
-+ {
-+ sql_field->pack_flag= FIELDFLAG_NUMBER;
-+ if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
-+ total_uneven_bit_length+= sql_field->length & 7;
-+ else
-+ sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
-+ }
-+
-+ sql_field->create_length_to_internal_length();
-+ if (prepare_blob_field(thd, sql_field))
-+ DBUG_RETURN(TRUE);
-+
-+ if (!(sql_field->flags & NOT_NULL_FLAG))
-+ null_fields++;
-+
-+ if (check_column_name(sql_field->field_name))
-+ {
-+ my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* Check if we have used the same field name before */
-+ for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
-+ {
-+ if (my_strcasecmp(system_charset_info,
-+ sql_field->field_name,
-+ dup_field->field_name) == 0)
-+ {
-+ /*
-+ If this was a CREATE ... SELECT statement, accept a field
-+ redefinition if we are changing a field in the SELECT part
-+ */
-+ if (field_no < select_field_pos || dup_no >= select_field_pos)
-+ {
-+ my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ else
-+ {
-+ /* Field redefined */
-+ sql_field->def= dup_field->def;
-+ sql_field->sql_type= dup_field->sql_type;
-+ sql_field->charset= (dup_field->charset ?
-+ dup_field->charset :
-+ create_info->default_table_charset);
-+ sql_field->length= dup_field->char_length;
-+ sql_field->pack_length= dup_field->pack_length;
-+ sql_field->key_length= dup_field->key_length;
-+ sql_field->decimals= dup_field->decimals;
-+ sql_field->create_length_to_internal_length();
-+ sql_field->unireg_check= dup_field->unireg_check;
-+ /*
-+ We're making one field from two, the result field will have
-+ dup_field->flags as flags. If we've incremented null_fields
-+ because of sql_field->flags, decrement it back.
-+ */
-+ if (!(sql_field->flags & NOT_NULL_FLAG))
-+ null_fields--;
-+ sql_field->flags= dup_field->flags;
-+ sql_field->interval= dup_field->interval;
-+ it2.remove(); // Remove first (create) definition
-+ select_field_pos--;
-+ break;
-+ }
-+ }
-+ }
-+ /* Don't pack rows in old tables if the user has requested this */
-+ if ((sql_field->flags & BLOB_FLAG) ||
-+ (sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
-+ create_info->row_type != ROW_TYPE_FIXED))
-+ (*db_options)|= HA_OPTION_PACK_RECORD;
-+ it2.rewind();
-+ }
-+
-+ /* record_offset will be increased with 'length-of-null-bits' later */
-+ record_offset= 0;
-+ null_fields+= total_uneven_bit_length;
-+
-+ it.rewind();
-+ while ((sql_field=it++))
-+ {
-+ DBUG_ASSERT(sql_field->charset != 0);
-+
-+ if (prepare_create_field(sql_field, &blob_columns,
-+ ×tamps, ×tamps_with_niladic,
-+ file->ha_table_flags()))
-+ DBUG_RETURN(TRUE);
-+ if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
-+ create_info->varchar= TRUE;
-+ sql_field->offset= record_offset;
-+ if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
-+ auto_increment++;
-+ record_offset+= sql_field->pack_length;
-+ }
-+ if (timestamps_with_niladic > 1)
-+ {
-+ my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
-+ ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (auto_increment > 1)
-+ {
-+ my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (auto_increment &&
-+ (file->ha_table_flags() & HA_NO_AUTO_INCREMENT))
-+ {
-+ my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
-+ ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
-+ {
-+ my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
-+ MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* Create keys */
-+
-+ List_iterator<Key> key_iterator(alter_info->key_list);
-+ List_iterator<Key> key_iterator2(alter_info->key_list);
-+ uint key_parts=0, fk_key_count=0;
-+ bool primary_key=0,unique_key=0;
-+ Key *key, *key2;
-+ uint tmp, key_number;
-+ /* special marker for keys to be ignored */
-+ static char ignore_key[1];
-+
-+ /* Calculate number of key segements */
-+ *key_count= 0;
-+
-+ while ((key=key_iterator++))
-+ {
-+ DBUG_PRINT("info", ("key name: '%s' type: %d", key->name ? key->name :
-+ "(none)" , key->type));
-+ LEX_STRING key_name_str;
-+ if (key->type == Key::FOREIGN_KEY)
-+ {
-+ fk_key_count++;
-+ Foreign_key *fk_key= (Foreign_key*) key;
-+ if (fk_key->ref_columns.elements &&
-+ fk_key->ref_columns.elements != fk_key->columns.elements)
-+ {
-+ my_error(ER_WRONG_FK_DEF, MYF(0),
-+ (fk_key->name ? fk_key->name : "foreign key without name"),
-+ ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
-+ DBUG_RETURN(TRUE);
-+ }
-+ continue;
-+ }
-+ (*key_count)++;
-+ tmp=file->max_key_parts();
-+ if (key->columns.elements > tmp)
-+ {
-+ my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
-+ DBUG_RETURN(TRUE);
-+ }
-+ key_name_str.str= (char*) key->name;
-+ key_name_str.length= key->name ? strlen(key->name) : 0;
-+ if (check_string_char_length(&key_name_str, "", NAME_CHAR_LEN,
-+ system_charset_info, 1))
-+ {
-+ my_error(ER_TOO_LONG_IDENT, MYF(0), key->name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ key_iterator2.rewind ();
-+ if (key->type != Key::FOREIGN_KEY)
-+ {
-+ while ((key2 = key_iterator2++) != key)
-+ {
-+ /*
-+ foreign_key_prefix(key, key2) returns 0 if key or key2, or both, is
-+ 'generated', and a generated key is a prefix of the other key.
-+ Then we do not need the generated shorter key.
-+ */
-+ if ((key2->type != Key::FOREIGN_KEY &&
-+ key2->name != ignore_key &&
-+ !foreign_key_prefix(key, key2)))
-+ {
-+ /* TODO: issue warning message */
-+ /* mark that the generated key should be ignored */
-+ if (!key2->generated ||
-+ (key->generated && key->columns.elements <
-+ key2->columns.elements))
-+ key->name= ignore_key;
-+ else
-+ {
-+ key2->name= ignore_key;
-+ key_parts-= key2->columns.elements;
-+ (*key_count)--;
-+ }
-+ break;
-+ }
-+ }
-+ }
-+ if (key->name != ignore_key)
-+ key_parts+=key->columns.elements;
-+ else
-+ (*key_count)--;
-+ if (key->name && !tmp_table && (key->type != Key::PRIMARY) &&
-+ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
-+ {
-+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ tmp=file->max_keys();
-+ if (*key_count > tmp)
-+ {
-+ my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ (*key_info_buffer)= key_info= (KEY*) sql_calloc(sizeof(KEY) * (*key_count));
-+ key_part_info=(KEY_PART_INFO*) sql_calloc(sizeof(KEY_PART_INFO)*key_parts);
-+ if (!*key_info_buffer || ! key_part_info)
-+ DBUG_RETURN(TRUE); // Out of memory
-+
-+ key_iterator.rewind();
-+ key_number=0;
-+ for (; (key=key_iterator++) ; key_number++)
-+ {
-+ uint key_length=0;
-+ Key_part_spec *column;
-+
-+ if (key->name == ignore_key)
-+ {
-+ /* ignore redundant keys */
-+ do
-+ key=key_iterator++;
-+ while (key && key->name == ignore_key);
-+ if (!key)
-+ break;
-+ }
-+
-+ switch (key->type) {
-+ case Key::MULTIPLE:
-+ key_info->flags= 0;
-+ break;
-+ case Key::FULLTEXT:
-+ key_info->flags= HA_FULLTEXT;
-+ if ((key_info->parser_name= &key->key_create_info.parser_name)->str)
-+ key_info->flags|= HA_USES_PARSER;
-+ else
-+ key_info->parser_name= 0;
-+ break;
-+ case Key::SPATIAL:
-+#ifdef HAVE_SPATIAL
-+ key_info->flags= HA_SPATIAL;
-+ break;
-+#else
-+ my_error(ER_FEATURE_DISABLED, MYF(0),
-+ sym_group_geom.name, sym_group_geom.needed_define);
-+ DBUG_RETURN(TRUE);
-+#endif
-+ case Key::FOREIGN_KEY:
-+ key_number--; // Skip this key
-+ continue;
-+ default:
-+ key_info->flags = HA_NOSAME;
-+ break;
-+ }
-+ if (key->generated)
-+ key_info->flags|= HA_GENERATED_KEY;
-+
-+ key_info->key_parts=(uint8) key->columns.elements;
-+ key_info->key_part=key_part_info;
-+ key_info->usable_key_parts= key_number;
-+ key_info->algorithm= key->key_create_info.algorithm;
-+
-+ if (key->type == Key::FULLTEXT)
-+ {
-+ if (!(file->ha_table_flags() & HA_CAN_FULLTEXT))
-+ {
-+ my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT),
-+ MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ /*
-+ Make SPATIAL to be RTREE by default
-+ SPATIAL only on BLOB or at least BINARY, this
-+ actually should be replaced by special GEOM type
-+ in near future when new frm file is ready
-+ checking for proper key parts number:
-+ */
-+
-+ /* TODO: Add proper checks if handler supports key_type and algorithm */
-+ if (key_info->flags & HA_SPATIAL)
-+ {
-+ if (!(file->ha_table_flags() & HA_CAN_RTREEKEYS))
-+ {
-+ my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
-+ MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (key_info->key_parts != 1)
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ else if (key_info->algorithm == HA_KEY_ALG_RTREE)
-+ {
-+#ifdef HAVE_RTREE_KEYS
-+ if ((key_info->key_parts & 1) == 1)
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "RTREE INDEX");
-+ DBUG_RETURN(TRUE);
-+ }
-+ /* TODO: To be deleted */
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "RTREE INDEX");
-+ DBUG_RETURN(TRUE);
-+#else
-+ my_error(ER_FEATURE_DISABLED, MYF(0),
-+ sym_group_rtree.name, sym_group_rtree.needed_define);
-+ DBUG_RETURN(TRUE);
-+#endif
-+ }
-+
-+ /* Take block size from key part or table part */
-+ /*
-+ TODO: Add warning if block size changes. We can't do it here, as
-+ this may depend on the size of the key
-+ */
-+ key_info->block_size= (key->key_create_info.block_size ?
-+ key->key_create_info.block_size :
-+ create_info->key_block_size);
-+
-+ if (key_info->block_size)
-+ key_info->flags|= HA_USES_BLOCK_SIZE;
-+
-+ List_iterator<Key_part_spec> cols(key->columns), cols2(key->columns);
-+ CHARSET_INFO *ft_key_charset=0; // for FULLTEXT
-+ for (uint column_nr=0 ; (column=cols++) ; column_nr++)
-+ {
-+ uint length;
-+ Key_part_spec *dup_column;
-+
-+ it.rewind();
-+ field=0;
-+ while ((sql_field=it++) &&
-+ my_strcasecmp(system_charset_info,
-+ column->field_name,
-+ sql_field->field_name))
-+ field++;
-+ if (!sql_field)
-+ {
-+ my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ while ((dup_column= cols2++) != column)
-+ {
-+ if (!my_strcasecmp(system_charset_info,
-+ column->field_name, dup_column->field_name))
-+ {
-+ my_printf_error(ER_DUP_FIELDNAME,
-+ ER(ER_DUP_FIELDNAME),MYF(0),
-+ column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ cols2.rewind();
-+ if (key->type == Key::FULLTEXT)
-+ {
-+ if ((sql_field->sql_type != MYSQL_TYPE_STRING &&
-+ sql_field->sql_type != MYSQL_TYPE_VARCHAR &&
-+ !f_is_blob(sql_field->pack_flag)) ||
-+ sql_field->charset == &my_charset_bin ||
-+ sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
-+ (ft_key_charset && sql_field->charset != ft_key_charset))
-+ {
-+ my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name);
-+ DBUG_RETURN(-1);
-+ }
-+ ft_key_charset=sql_field->charset;
-+ /*
-+ for fulltext keys keyseg length is 1 for blobs (it's ignored in ft
-+ code anyway, and 0 (set to column width later) for char's. it has
-+ to be correct col width for char's, as char data are not prefixed
-+ with length (unlike blobs, where ft code takes data length from a
-+ data prefix, ignoring column->length).
-+ */
-+ column->length=test(f_is_blob(sql_field->pack_flag));
-+ }
-+ else
-+ {
-+ column->length*= sql_field->charset->mbmaxlen;
-+
-+ if (key->type == Key::SPATIAL)
-+ {
-+ if (column->length)
-+ {
-+ my_error(ER_WRONG_SUB_KEY, MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ if (!f_is_geom(sql_field->pack_flag))
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "SPATIAL INDEX");
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+
-+ if (f_is_blob(sql_field->pack_flag) ||
-+ (f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
-+ {
-+ if (!(file->ha_table_flags() & HA_CAN_INDEX_BLOBS))
-+ {
-+ my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
-+ Field::GEOM_POINT)
-+ column->length= 25;
-+ if (!column->length)
-+ {
-+ my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+#ifdef HAVE_SPATIAL
-+ if (key->type == Key::SPATIAL)
-+ {
-+ if (!column->length)
-+ {
-+ /*
-+ 4 is: (Xmin,Xmax,Ymin,Ymax), this is for 2D case
-+ Lately we'll extend this code to support more dimensions
-+ */
-+ column->length= 4*sizeof(double);
-+ }
-+ }
-+#endif
-+ if (!(sql_field->flags & NOT_NULL_FLAG))
-+ {
-+ if (key->type == Key::PRIMARY)
-+ {
-+ /* Implicitly set primary key fields to NOT NULL for ISO conf. */
-+ sql_field->flags|= NOT_NULL_FLAG;
-+ sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
-+ null_fields--;
-+ }
-+ else
-+ {
-+ key_info->flags|= HA_NULL_PART_KEY;
-+ if (!(file->ha_table_flags() & HA_NULL_IN_KEY))
-+ {
-+ my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (key->type == Key::SPATIAL)
-+ {
-+ my_message(ER_SPATIAL_CANT_HAVE_NULL,
-+ ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+ if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
-+ {
-+ if (column_nr == 0 || (file->ha_table_flags() & HA_AUTO_PART_KEY))
-+ auto_increment--; // Field is used
-+ }
-+ }
-+
-+ key_part_info->fieldnr= field;
-+ key_part_info->offset= (uint16) sql_field->offset;
-+ key_part_info->key_type=sql_field->pack_flag;
-+ length= sql_field->key_length;
-+
-+ if (column->length)
-+ {
-+ if (f_is_blob(sql_field->pack_flag))
-+ {
-+ if ((length=column->length) > max_key_length ||
-+ length > file->max_key_part_length())
-+ {
-+ length=min(max_key_length, file->max_key_part_length());
-+ if (key->type == Key::MULTIPLE)
-+ {
-+ /* not a critical problem */
-+ char warn_buff[MYSQL_ERRMSG_SIZE];
-+ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
-+ length);
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_TOO_LONG_KEY, warn_buff);
-+ /* Align key length to multibyte char boundary */
-+ length-= length % sql_field->charset->mbmaxlen;
-+ }
-+ else
-+ {
-+ my_error(ER_TOO_LONG_KEY,MYF(0),length);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+ else if (!f_is_geom(sql_field->pack_flag) &&
-+ (column->length > length ||
-+ !Field::type_can_have_key_part (sql_field->sql_type) ||
-+ ((f_is_packed(sql_field->pack_flag) ||
-+ ((file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS) &&
-+ (key_info->flags & HA_NOSAME))) &&
-+ column->length != length)))
-+ {
-+ my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ else if (!(file->ha_table_flags() & HA_NO_PREFIX_CHAR_KEYS))
-+ length=column->length;
-+ }
-+ else if (length == 0)
-+ {
-+ my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (length > file->max_key_part_length() && key->type != Key::FULLTEXT)
-+ {
-+ length= file->max_key_part_length();
-+ if (key->type == Key::MULTIPLE)
-+ {
-+ /* not a critical problem */
-+ char warn_buff[MYSQL_ERRMSG_SIZE];
-+ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
-+ length);
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ ER_TOO_LONG_KEY, warn_buff);
-+ /* Align key length to multibyte char boundary */
-+ length-= length % sql_field->charset->mbmaxlen;
-+ }
-+ else
-+ {
-+ my_error(ER_TOO_LONG_KEY,MYF(0),length);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ key_part_info->length=(uint16) length;
-+ /* Use packed keys for long strings on the first column */
-+ if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
-+ !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
-+ (length >= KEY_DEFAULT_PACK_LENGTH &&
-+ (sql_field->sql_type == MYSQL_TYPE_STRING ||
-+ sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
-+ sql_field->pack_flag & FIELDFLAG_BLOB)))
-+ {
-+ if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
-+ sql_field->sql_type == MYSQL_TYPE_VARCHAR)
-+ key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
-+ else
-+ key_info->flags|= HA_PACK_KEY;
-+ }
-+ /* Check if the key segment is partial, set the key flag accordingly */
-+ if (length != sql_field->key_length)
-+ key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
-+
-+ key_length+=length;
-+ key_part_info++;
-+
-+ /* Create the key name based on the first column (if not given) */
-+ if (column_nr == 0)
-+ {
-+ if (key->type == Key::PRIMARY)
-+ {
-+ if (primary_key)
-+ {
-+ my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
-+ MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ key_name=primary_key_name;
-+ primary_key=1;
-+ }
-+ else if (!(key_name = key->name))
-+ key_name=make_unique_key_name(sql_field->field_name,
-+ *key_info_buffer, key_info);
-+ if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
-+ {
-+ my_error(ER_DUP_KEYNAME, MYF(0), key_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ key_info->name=(char*) key_name;
-+ }
-+ }
-+ if (!key_info->name || check_column_name(key_info->name))
-+ {
-+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (!(key_info->flags & HA_NULL_PART_KEY))
-+ unique_key=1;
-+ key_info->key_length=(uint16) key_length;
-+ if (key_length > max_key_length && key->type != Key::FULLTEXT)
-+ {
-+ my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
-+ DBUG_RETURN(TRUE);
-+ }
-+ key_info++;
-+ }
-+ if (!unique_key && !primary_key &&
-+ (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY))
-+ {
-+ my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (auto_increment > 0)
-+ {
-+ my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ /* Sort keys in optimized order */
-+ my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
-+ (qsort_cmp) sort_keys);
-+ create_info->null_bits= null_fields;
-+
-+ /* Check fields. */
-+ it.rewind();
-+ while ((sql_field=it++))
-+ {
-+ Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
-+
-+ if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
-+ !sql_field->def &&
-+ sql_field->sql_type == MYSQL_TYPE_TIMESTAMP &&
-+ (sql_field->flags & NOT_NULL_FLAG) &&
-+ (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
-+ {
-+ /*
-+ An error should be reported if:
-+ - NO_ZERO_DATE SQL mode is active;
-+ - there is no explicit DEFAULT clause (default column value);
-+ - this is a TIMESTAMP column;
-+ - the column is not NULL;
-+ - this is not the DEFAULT CURRENT_TIMESTAMP column.
-+
-+ In other words, an error should be reported if
-+ - NO_ZERO_DATE SQL mode is active;
-+ - the column definition is equivalent to
-+ 'column_name TIMESTAMP DEFAULT 0'.
-+ */
-+
-+ my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+
-+ DBUG_RETURN(FALSE);
-+}
-+
-+
-+/*
-+ Set table default charset, if not set
-+
-+ SYNOPSIS
-+ set_table_default_charset()
-+ create_info Table create information
-+
-+ DESCRIPTION
-+ If the table character set was not given explicitely,
-+ let's fetch the database default character set and
-+ apply it to the table.
-+*/
-+
-+static void set_table_default_charset(THD *thd,
-+ HA_CREATE_INFO *create_info, char *db)
-+{
-+ /*
-+ If the table character set was not given explicitly,
-+ let's fetch the database default character set and
-+ apply it to the table.
-+ */
-+ if (!create_info->default_table_charset)
-+ {
-+ HA_CREATE_INFO db_info;
-+
-+ load_db_opt_by_name(thd, db, &db_info);
-+
-+ create_info->default_table_charset= db_info.default_table_charset;
-+ }
-+}
-+
-+
-+/*
-+ Extend long VARCHAR fields to blob & prepare field if it's a blob
-+
-+ SYNOPSIS
-+ prepare_blob_field()
-+ sql_field Field to check
-+
-+ RETURN
-+ 0 ok
-+ 1 Error (sql_field can't be converted to blob)
-+ In this case the error is given
-+*/
-+
-+static bool prepare_blob_field(THD *thd, Create_field *sql_field)
-+{
-+ DBUG_ENTER("prepare_blob_field");
-+
-+ if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
-+ !(sql_field->flags & BLOB_FLAG))
-+ {
-+ /* Convert long VARCHAR columns to TEXT or BLOB */
-+ char warn_buff[MYSQL_ERRMSG_SIZE];
-+
-+ if (sql_field->def || (thd->variables.sql_mode & (MODE_STRICT_TRANS_TABLES |
-+ MODE_STRICT_ALL_TABLES)))
-+ {
-+ my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
-+ MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
-+ DBUG_RETURN(1);
-+ }
-+ sql_field->sql_type= MYSQL_TYPE_BLOB;
-+ sql_field->flags|= BLOB_FLAG;
-+ my_snprintf(warn_buff, sizeof(warn_buff), ER(ER_AUTO_CONVERT), sql_field->field_name,
-+ (sql_field->charset == &my_charset_bin) ? "VARBINARY" : "VARCHAR",
-+ (sql_field->charset == &my_charset_bin) ? "BLOB" : "TEXT");
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
-+ warn_buff);
-+ }
-+
-+ if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
-+ {
-+ if (sql_field->sql_type == FIELD_TYPE_BLOB ||
-+ sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
-+ sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB)
-+ {
-+ /* The user has given a length to the blob column */
-+ sql_field->sql_type= get_blob_type_from_length(sql_field->length);
-+ sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
-+ }
-+ sql_field->length= 0;
-+ }
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Preparation of Create_field for SP function return values.
-+ Based on code used in the inner loop of mysql_prepare_create_table()
-+ above.
-+
-+ SYNOPSIS
-+ sp_prepare_create_field()
-+ thd Thread object
-+ sql_field Field to prepare
-+
-+ DESCRIPTION
-+ Prepares the field structures for field creation.
-+
-+*/
-+
-+void sp_prepare_create_field(THD *thd, Create_field *sql_field)
-+{
-+ if (sql_field->sql_type == MYSQL_TYPE_SET ||
-+ sql_field->sql_type == MYSQL_TYPE_ENUM)
-+ {
-+ uint32 field_length, dummy;
-+ if (sql_field->sql_type == MYSQL_TYPE_SET)
-+ {
-+ calculate_interval_lengths(sql_field->charset,
-+ sql_field->interval, &dummy,
-+ &field_length);
-+ sql_field->length= field_length +
-+ (sql_field->interval->count - 1);
-+ }
-+ else /* MYSQL_TYPE_ENUM */
-+ {
-+ calculate_interval_lengths(sql_field->charset,
-+ sql_field->interval,
-+ &field_length, &dummy);
-+ sql_field->length= field_length;
-+ }
-+ set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
-+ }
-+
-+ if (sql_field->sql_type == MYSQL_TYPE_BIT)
-+ {
-+ sql_field->pack_flag= FIELDFLAG_NUMBER |
-+ FIELDFLAG_TREAT_BIT_AS_CHAR;
-+ }
-+ sql_field->create_length_to_internal_length();
-+ DBUG_ASSERT(sql_field->def == 0);
-+ /* Can't go wrong as sql_field->def is not defined */
-+ (void) prepare_blob_field(thd, sql_field);
-+}
-+
-+
-+/*
-+ Write CREATE TABLE binlog
-+
-+ SYNOPSIS
-+ write_create_table_bin_log()
-+ thd Thread object
-+ create_info Create information
-+ internal_tmp_table Set to 1 if this is an internal temporary table
-+
-+ DESCRIPTION
-+ This function only is called in mysql_create_table_no_lock and
-+ mysql_create_table
-+
-+ RETURN VALUES
-+ NONE
-+ */
-+static inline int write_create_table_bin_log(THD *thd,
-+ const HA_CREATE_INFO *create_info,
-+ bool internal_tmp_table)
-+{
-+ /*
-+ Don't write statement if:
-+ - It is an internal temporary table,
-+ - Row-based logging is used and it we are creating a temporary table, or
-+ - The binary log is not open.
-+ Otherwise, the statement shall be binlogged.
-+ */
-+ if (!internal_tmp_table &&
-+ (!thd->current_stmt_binlog_row_based ||
-+ (thd->current_stmt_binlog_row_based &&
-+ !(create_info->options & HA_LEX_CREATE_TMP_TABLE))))
-+ return write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ return 0;
-+}
-+
-+
-+/*
-+ Create a table
-+
-+ SYNOPSIS
-+ mysql_create_table_no_lock()
-+ thd Thread object
-+ db Database
-+ table_name Table name
-+ create_info Create information (like MAX_ROWS)
-+ fields List of fields to create
-+ keys List of keys to create
-+ internal_tmp_table Set to 1 if this is an internal temporary table
-+ (From ALTER TABLE)
-+ select_field_count
-+
-+ DESCRIPTION
-+ If one creates a temporary table, this is automatically opened
-+
-+ Note that this function assumes that caller already have taken
-+ name-lock on table being created or used some other way to ensure
-+ that concurrent operations won't intervene. mysql_create_table()
-+ is a wrapper that can be used for this.
-+
-+ no_log is needed for the case of CREATE ... SELECT,
-+ as the logging will be done later in sql_insert.cc
-+ select_field_count is also used for CREATE ... SELECT,
-+ and must be zero for standard create of table.
-+
-+ RETURN VALUES
-+ FALSE OK
-+ TRUE error
-+*/
-+
-+bool mysql_create_table_no_lock(THD *thd,
-+ const char *db, const char *table_name,
-+ HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info,
-+ bool internal_tmp_table,
-+ uint select_field_count)
-+{
-+ char path[FN_REFLEN + 1];
-+ uint path_length;
-+ const char *alias;
-+ uint db_options, key_count;
-+ KEY *key_info_buffer;
-+ handler *file;
-+ bool error= TRUE;
-+ DBUG_ENTER("mysql_create_table_no_lock");
-+ DBUG_PRINT("enter", ("db: '%s' table: '%s' tmp: %d",
-+ db, table_name, internal_tmp_table));
-+
-+
-+ /* Check for duplicate fields and check type of table to create */
-+ if (!alter_info->create_list.elements)
-+ {
-+ my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
-+ MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ if (check_engine(thd, table_name, create_info))
-+ DBUG_RETURN(TRUE);
-+ db_options= create_info->table_options;
-+ if (create_info->row_type == ROW_TYPE_DYNAMIC)
-+ db_options|=HA_OPTION_PACK_RECORD;
-+ alias= table_case_name(create_info, table_name);
-+ if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
-+ create_info->db_type)))
-+ {
-+ mem_alloc_error(sizeof(handler));
-+ DBUG_RETURN(TRUE);
-+ }
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ partition_info *part_info= thd->work_part_info;
-+
-+ if (!part_info && create_info->db_type->partition_flags &&
-+ (create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
-+ {
-+ /*
-+ Table is not defined as a partitioned table but the engine handles
-+ all tables as partitioned. The handler will set up the partition info
-+ object with the default settings.
-+ */
-+ thd->work_part_info= part_info= new partition_info();
-+ if (!part_info)
-+ {
-+ mem_alloc_error(sizeof(partition_info));
-+ DBUG_RETURN(TRUE);
-+ }
-+ file->set_auto_partitions(part_info);
-+ part_info->default_engine_type= create_info->db_type;
-+ part_info->is_auto_partitioned= TRUE;
-+ }
-+ if (part_info)
-+ {
-+ /*
-+ The table has been specified as a partitioned table.
-+ If this is part of an ALTER TABLE the handler will be the partition
-+ handler but we need to specify the default handler to use for
-+ partitions also in the call to check_partition_info. We transport
-+ this information in the default_db_type variable, it is either
-+ DB_TYPE_DEFAULT or the engine set in the ALTER TABLE command.
-+
-+ Check that we don't use foreign keys in the table since it won't
-+ work even with InnoDB beneath it.
-+ */
-+ List_iterator<Key> key_iterator(alter_info->key_list);
-+ Key *key;
-+ handlerton *part_engine_type= create_info->db_type;
-+ char *part_syntax_buf;
-+ uint syntax_len;
-+ handlerton *engine_type;
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
-+ {
-+ my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
-+ goto err;
-+ }
-+ while ((key= key_iterator++))
-+ {
-+ if (key->type == Key::FOREIGN_KEY &&
-+ !part_info->is_auto_partitioned)
-+ {
-+ my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
-+ goto err;
-+ }
-+ }
-+ if ((part_engine_type == partition_hton) &&
-+ part_info->default_engine_type)
-+ {
-+ /*
-+ This only happens at ALTER TABLE.
-+ default_engine_type was assigned from the engine set in the ALTER
-+ TABLE command.
-+ */
-+ ;
-+ }
-+ else
-+ {
-+ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
-+ {
-+ part_info->default_engine_type= create_info->db_type;
-+ }
-+ else
-+ {
-+ if (part_info->default_engine_type == NULL)
-+ {
-+ part_info->default_engine_type= ha_checktype(thd,
-+ DB_TYPE_DEFAULT, 0, 0);
-+ }
-+ }
-+ }
-+ DBUG_PRINT("info", ("db_type = %s create_info->db_type = %s",
-+ ha_resolve_storage_engine_name(part_info->default_engine_type),
-+ ha_resolve_storage_engine_name(create_info->db_type)));
-+ if (part_info->check_partition_info(thd, &engine_type, file,
-+ create_info, TRUE))
-+ goto err;
-+ part_info->default_engine_type= engine_type;
-+
-+ /*
-+ We reverse the partitioning parser and generate a standard format
-+ for syntax stored in frm file.
-+ */
-+ if (!(part_syntax_buf= generate_partition_syntax(part_info,
-+ &syntax_len,
-+ TRUE, TRUE)))
-+ goto err;
-+ part_info->part_info_string= part_syntax_buf;
-+ part_info->part_info_len= syntax_len;
-+ if ((!(engine_type->partition_flags &&
-+ engine_type->partition_flags() & HA_CAN_PARTITION)) ||
-+ create_info->db_type == partition_hton)
-+ {
-+ /*
-+ The handler assigned to the table cannot handle partitioning.
-+ Assign the partition handler as the handler of the table.
-+ */
-+ DBUG_PRINT("info", ("db_type: %s",
-+ ha_resolve_storage_engine_name(create_info->db_type)));
-+ delete file;
-+ create_info->db_type= partition_hton;
-+ if (!(file= get_ha_partition(part_info)))
-+ {
-+ DBUG_RETURN(TRUE);
-+ }
-+ /*
-+ If we have default number of partitions or subpartitions we
-+ might require to set-up the part_info object such that it
-+ creates a proper .par file. The current part_info object is
-+ only used to create the frm-file and .par-file.
-+ */
-+ if (part_info->use_default_no_partitions &&
-+ part_info->no_parts &&
-+ (int)part_info->no_parts !=
-+ file->get_default_no_partitions(create_info))
-+ {
-+ uint i;
-+ List_iterator<partition_element> part_it(part_info->partitions);
-+ part_it++;
-+ DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
-+ for (i= 1; i < part_info->partitions.elements; i++)
-+ (part_it++)->part_state= PART_TO_BE_DROPPED;
-+ }
-+ else if (part_info->is_sub_partitioned() &&
-+ part_info->use_default_no_subpartitions &&
-+ part_info->no_subparts &&
-+ (int)part_info->no_subparts !=
-+ file->get_default_no_partitions(create_info))
-+ {
-+ DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
-+ part_info->no_subparts= file->get_default_no_partitions(create_info);
-+ }
-+ }
-+ else if (create_info->db_type != engine_type)
-+ {
-+ /*
-+ We come here when we don't use a partitioned handler.
-+ Since we use a partitioned table it must be "native partitioned".
-+ We have switched engine from defaults, most likely only specified
-+ engines in partition clauses.
-+ */
-+ delete file;
-+ if (!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
-+ engine_type)))
-+ {
-+ mem_alloc_error(sizeof(handler));
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ }
-+#endif
-+
-+ set_table_default_charset(thd, create_info, (char*) db);
-+
-+ if (mysql_prepare_create_table(thd, create_info, alter_info,
-+ internal_tmp_table,
-+ &db_options, file,
-+ &key_info_buffer, &key_count,
-+ select_field_count))
-+ goto err;
-+
-+ /* Check if table exists */
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
-+ {
-+ path_length= build_tmptable_filename(thd, path, sizeof(path));
-+ create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
-+ }
-+ else
-+ {
-+ path_length= build_table_filename(path, sizeof(path) - 1, db, alias, reg_ext,
-+ internal_tmp_table ? FN_IS_TMP : 0);
-+ }
-+
-+ /* Check if table already exists */
-+ if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
-+ find_temporary_table(thd, db, table_name))
-+ {
-+ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ {
-+ create_info->table_existed= 1; // Mark that table existed
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
-+ alias);
-+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
-+ goto err;
-+ }
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
-+ goto err;
-+ }
-+
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ if (!access(path,F_OK))
-+ {
-+ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ goto warn;
-+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
-+ goto unlock_and_end;
-+ }
-+ /*
-+ We don't assert here, but check the result, because the table could be
-+ in the table definition cache and in the same time the .frm could be
-+ missing from the disk, in case of manual intervention which deletes
-+ the .frm file. The user has to use FLUSH TABLES; to clear the cache.
-+ Then she could create the table. This case is pretty obscure and
-+ therefore we don't introduce a new error message only for it.
-+ */
-+ if (get_cached_table_share(db, table_name))
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
-+ goto unlock_and_end;
-+ }
-+ }
-+
-+ /*
-+ Check that table with given name does not already
-+ exist in any storage engine. In such a case it should
-+ be discovered and the error ER_TABLE_EXISTS_ERROR be returned
-+ unless user specified CREATE TABLE IF EXISTS
-+ The LOCK_open mutex has been locked to make sure no
-+ one else is attempting to discover the table. Since
-+ it's not on disk as a frm file, no one could be using it!
-+ */
-+ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ bool create_if_not_exists =
-+ create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
-+ int retcode = ha_table_exists_in_engine(thd, db, table_name);
-+ DBUG_PRINT("info", ("exists_in_engine: %u",retcode));
-+ switch (retcode)
-+ {
-+ case HA_ERR_NO_SUCH_TABLE:
-+ /* Normal case, no table exists. we can go and create it */
-+ break;
-+ case HA_ERR_TABLE_EXIST:
-+ DBUG_PRINT("info", ("Table existed in handler"));
-+
-+ if (create_if_not_exists)
-+ goto warn;
-+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
-+ goto unlock_and_end;
-+ break;
-+ default:
-+ DBUG_PRINT("info", ("error: %u from storage engine", retcode));
-+ my_error(retcode, MYF(0),table_name);
-+ goto unlock_and_end;
-+ }
-+ }
-+
-+ thd_proc_info(thd, "creating table");
-+ create_info->table_existed= 0; // Mark that table is created
-+
-+#ifdef HAVE_READLINK
-+ if (test_if_data_home_dir(create_info->data_file_name))
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "DATA DIRECTORY");
-+ goto unlock_and_end;
-+ }
-+ if (test_if_data_home_dir(create_info->index_file_name))
-+ {
-+ my_error(ER_WRONG_ARGUMENTS, MYF(0), "INDEX DIRECTORY");
-+ goto unlock_and_end;
-+ }
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (check_partition_dirs(thd->lex->part_info))
-+ {
-+ goto unlock_and_end;
-+ }
-+#endif /* WITH_PARTITION_STORAGE_ENGINE */
-+
-+ if (!my_use_symdir || (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE))
-+#endif /* HAVE_READLINK */
-+ {
-+ if (create_info->data_file_name)
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
-+ "DATA DIRECTORY");
-+ if (create_info->index_file_name)
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
-+ WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
-+ "INDEX DIRECTORY");
-+ create_info->data_file_name= create_info->index_file_name= 0;
-+ }
-+ create_info->table_options=db_options;
-+
-+ path[path_length - reg_ext_length]= '\0'; // Remove .frm extension
-+ if (rea_create_table(thd, path, db, table_name,
-+ create_info, alter_info->create_list,
-+ key_count, key_info_buffer, file))
-+ goto unlock_and_end;
-+
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
-+ {
-+ /* Open table and put in temporary table list */
-+ if (!(open_temporary_table(thd, path, db, table_name, 1)))
-+ {
-+ (void) rm_temporary_table(create_info->db_type, path);
-+ goto unlock_and_end;
-+ }
-+ thd->thread_specific_used= TRUE;
-+ }
-+
-+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
-+unlock_and_end:
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+
-+err:
-+ thd_proc_info(thd, "After create");
-+ delete file;
-+ DBUG_RETURN(error);
-+
-+warn:
-+ error= FALSE;
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
-+ alias);
-+ create_info->table_existed= 1; // Mark that table existed
-+ error= write_create_table_bin_log(thd, create_info, internal_tmp_table);
-+ goto unlock_and_end;
-+}
-+
-+
-+/*
-+ Database and name-locking aware wrapper for mysql_create_table_no_lock(),
-+*/
-+
-+bool mysql_create_table(THD *thd, const char *db, const char *table_name,
-+ HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info,
-+ bool internal_tmp_table,
-+ uint select_field_count)
-+{
-+ TABLE *name_lock= 0;
-+ bool result;
-+ DBUG_ENTER("mysql_create_table");
-+
-+ /* Wait for any database locks */
-+ pthread_mutex_lock(&LOCK_lock_db);
-+ while (!thd->killed &&
-+ hash_search(&lock_db_cache,(uchar*) db, strlen(db)))
-+ {
-+ wait_for_condition(thd, &LOCK_lock_db, &COND_refresh);
-+ pthread_mutex_lock(&LOCK_lock_db);
-+ }
-+
-+ if (thd->killed)
-+ {
-+ pthread_mutex_unlock(&LOCK_lock_db);
-+ DBUG_RETURN(TRUE);
-+ }
-+ creating_table++;
-+ pthread_mutex_unlock(&LOCK_lock_db);
-+
-+ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
-+ {
-+ result= TRUE;
-+ goto unlock;
-+ }
-+ if (!name_lock)
-+ {
-+ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ {
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
-+ table_name);
-+ create_info->table_existed= 1;
-+ result= FALSE;
-+ write_create_table_bin_log(thd, create_info, internal_tmp_table);
-+ }
-+ else
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
-+ result= TRUE;
-+ }
-+ goto unlock;
-+ }
-+ }
-+
-+ result= mysql_create_table_no_lock(thd, db, table_name, create_info,
-+ alter_info,
-+ internal_tmp_table,
-+ select_field_count);
-+
-+unlock:
-+ if (name_lock)
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlink_open_table(thd, name_lock, FALSE);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ pthread_mutex_lock(&LOCK_lock_db);
-+ if (!--creating_table && creating_database)
-+ pthread_cond_signal(&COND_refresh);
-+ pthread_mutex_unlock(&LOCK_lock_db);
-+ DBUG_RETURN(result);
-+}
-+
-+
-+/*
-+** Give the key name after the first field with an optional '_#' after
-+**/
-+
-+static bool
-+check_if_keyname_exists(const char *name, KEY *start, KEY *end)
-+{
-+ for (KEY *key=start ; key != end ; key++)
-+ if (!my_strcasecmp(system_charset_info,name,key->name))
-+ return 1;
-+ return 0;
-+}
-+
-+
-+static char *
-+make_unique_key_name(const char *field_name,KEY *start,KEY *end)
-+{
-+ char buff[MAX_FIELD_NAME],*buff_end;
-+
-+ if (!check_if_keyname_exists(field_name,start,end) &&
-+ my_strcasecmp(system_charset_info,field_name,primary_key_name))
-+ return (char*) field_name; // Use fieldname
-+ buff_end=strmake(buff,field_name, sizeof(buff)-4);
-+
-+ /*
-+ Only 3 chars + '\0' left, so need to limit to 2 digit
-+ This is ok as we can't have more than 100 keys anyway
-+ */
-+ for (uint i=2 ; i< 100; i++)
-+ {
-+ *buff_end= '_';
-+ int10_to_str(i, buff_end+1, 10);
-+ if (!check_if_keyname_exists(buff,start,end))
-+ return sql_strdup(buff);
-+ }
-+ return (char*) "not_specified"; // Should never happen
-+}
-+
-+
-+/****************************************************************************
-+** Alter a table definition
-+****************************************************************************/
-+
-+
-+/*
-+ Rename a table.
-+
-+ SYNOPSIS
-+ mysql_rename_table()
-+ base The handlerton handle.
-+ old_db The old database name.
-+ old_name The old table name.
-+ new_db The new database name.
-+ new_name The new table name.
-+ flags flags for build_table_filename().
-+ FN_FROM_IS_TMP old_name is temporary.
-+ FN_TO_IS_TMP new_name is temporary.
-+ NO_FRM_RENAME Don't rename the FRM file
-+ but only the table in the storage engine.
-+
-+ RETURN
-+ FALSE OK
-+ TRUE Error
-+*/
-+
-+bool
-+mysql_rename_table(handlerton *base, const char *old_db,
-+ const char *old_name, const char *new_db,
-+ const char *new_name, uint flags)
-+{
-+ THD *thd= current_thd;
-+ char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
-+ lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1];
-+ char *from_base= from, *to_base= to;
-+ char tmp_name[NAME_LEN+1];
-+ handler *file;
-+ int error=0;
-+ DBUG_ENTER("mysql_rename_table");
-+ DBUG_PRINT("enter", ("old: '%s'.'%s' new: '%s'.'%s'",
-+ old_db, old_name, new_db, new_name));
-+
-+ file= (base == NULL ? 0 :
-+ get_new_handler((TABLE_SHARE*) 0, thd->mem_root, base));
-+
-+ build_table_filename(from, sizeof(from) - 1, old_db, old_name, "",
-+ flags & FN_FROM_IS_TMP);
-+ build_table_filename(to, sizeof(to) - 1, new_db, new_name, "",
-+ flags & FN_TO_IS_TMP);
-+
-+ /*
-+ If lower_case_table_names == 2 (case-preserving but case-insensitive
-+ file system) and the storage is not HA_FILE_BASED, we need to provide
-+ a lowercase file name, but we leave the .frm in mixed case.
-+ */
-+ if (lower_case_table_names == 2 && file &&
-+ !(file->ha_table_flags() & HA_FILE_BASED))
-+ {
-+ strmov(tmp_name, old_name);
-+ my_casedn_str(files_charset_info, tmp_name);
-+ build_table_filename(lc_from, sizeof(lc_from) - 1, old_db, tmp_name, "",
-+ flags & FN_FROM_IS_TMP);
-+ from_base= lc_from;
-+
-+ strmov(tmp_name, new_name);
-+ my_casedn_str(files_charset_info, tmp_name);
-+ build_table_filename(lc_to, sizeof(lc_to) - 1, new_db, tmp_name, "",
-+ flags & FN_TO_IS_TMP);
-+ to_base= lc_to;
-+ }
-+
-+ if (!file || !(error=file->ha_rename_table(from_base, to_base)))
-+ {
-+ if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
-+ {
-+ error=my_errno;
-+ /* Restore old file name */
-+ if (file)
-+ file->ha_rename_table(to_base, from_base);
-+ }
-+ }
-+ delete file;
-+ if (error == HA_ERR_WRONG_COMMAND)
-+ my_error(ER_NOT_SUPPORTED_YET, MYF(0), "ALTER TABLE");
-+ else if (error)
-+ my_error(ER_ERROR_ON_RENAME, MYF(0), from, to, error);
-+ DBUG_RETURN(error != 0);
-+}
-+
-+
-+/*
-+ Force all other threads to stop using the table
-+
-+ SYNOPSIS
-+ wait_while_table_is_used()
-+ thd Thread handler
-+ table Table to remove from cache
-+ function HA_EXTRA_PREPARE_FOR_DROP if table is to be deleted
-+ HA_EXTRA_FORCE_REOPEN if table is not be used
-+ HA_EXTRA_PREPARE_FOR_RENAME if table is to be renamed
-+ NOTES
-+ When returning, the table will be unusable for other threads until
-+ the table is closed.
-+
-+ PREREQUISITES
-+ Lock on LOCK_open
-+ Win32 clients must also have a WRITE LOCK on the table !
-+*/
-+
-+void wait_while_table_is_used(THD *thd, TABLE *table,
-+ enum ha_extra_function function)
-+{
-+ DBUG_ENTER("wait_while_table_is_used");
-+ DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
-+ table->s->table_name.str, (ulong) table->s,
-+ table->db_stat, table->s->version));
-+
-+ safe_mutex_assert_owner(&LOCK_open);
-+
-+ VOID(table->file->extra(function));
-+ /* Mark all tables that are in use as 'old' */
-+ mysql_lock_abort(thd, table, TRUE); /* end threads waiting on lock */
-+
-+ /* Wait until all there are no other threads that has this table open */
-+ remove_table_from_cache(thd, table->s->db.str,
-+ table->s->table_name.str,
-+ RTFC_WAIT_OTHER_THREAD_FLAG);
-+ DBUG_VOID_RETURN;
-+}
-+
-+/*
-+ Close a cached table
-+
-+ SYNOPSIS
-+ close_cached_table()
-+ thd Thread handler
-+ table Table to remove from cache
-+
-+ NOTES
-+ Function ends by signaling threads waiting for the table to try to
-+ reopen the table.
-+
-+ PREREQUISITES
-+ Lock on LOCK_open
-+ Win32 clients must also have a WRITE LOCK on the table !
-+*/
-+
-+void close_cached_table(THD *thd, TABLE *table)
-+{
-+ DBUG_ENTER("close_cached_table");
-+
-+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-+ /* Close lock if this is not got with LOCK TABLES */
-+ if (thd->lock)
-+ {
-+ mysql_unlock_tables(thd, thd->lock);
-+ thd->lock=0; // Start locked threads
-+ }
-+ /* Close all copies of 'table'. This also frees all LOCK TABLES lock */
-+ unlink_open_table(thd, table, TRUE);
-+
-+ /* When lock on LOCK_open is freed other threads can continue */
-+ broadcast_refresh();
-+ DBUG_VOID_RETURN;
-+}
-+
-+static int send_check_errmsg(THD *thd, TABLE_LIST* table,
-+ const char* operator_name, const char* errmsg)
-+
-+{
-+ Protocol *protocol= thd->protocol;
-+ protocol->prepare_for_resend();
-+ protocol->store(table->alias, system_charset_info);
-+ protocol->store((char*) operator_name, system_charset_info);
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ protocol->store(errmsg, system_charset_info);
-+ thd->clear_error();
-+ if (protocol->write())
-+ return -1;
-+ return 1;
-+}
-+
-+
-+static int prepare_for_restore(THD* thd, TABLE_LIST* table,
-+ HA_CHECK_OPT *check_opt)
-+{
-+ DBUG_ENTER("prepare_for_restore");
-+
-+ if (table->table) // do not overwrite existing tables on restore
-+ {
-+ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
-+ "table exists, will not overwrite on restore"
-+ ));
-+ }
-+ else
-+ {
-+ char* backup_dir= thd->lex->backup_dir;
-+ char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1], uname[FN_REFLEN];
-+ char* table_name= table->table_name;
-+ char* db= table->db;
-+
-+ VOID(tablename_to_filename(table->table_name, uname, sizeof(uname) - 1));
-+
-+ if (fn_format_relative_to_data_home(src_path, uname, backup_dir, reg_ext))
-+ DBUG_RETURN(-1); // protect buffer overflow
-+
-+ build_table_filename(dst_path, sizeof(dst_path) - 1,
-+ db, table_name, reg_ext, 0);
-+
-+ if (lock_and_wait_for_table_name(thd,table))
-+ DBUG_RETURN(-1);
-+
-+ if (my_copy(src_path, dst_path, MYF(MY_WME)))
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlock_table_name(thd, table);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
-+ "Failed copying .frm file"));
-+ }
-+ if (mysql_truncate(thd, table, 1))
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlock_table_name(thd, table);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
-+ "Failed generating table from .frm file"));
-+ }
-+ }
-+
-+ /*
-+ Now we should be able to open the partially restored table
-+ to finish the restore in the handler later on
-+ */
-+ pthread_mutex_lock(&LOCK_open);
-+ if (reopen_name_locked_table(thd, table, TRUE))
-+ {
-+ unlock_table_name(thd, table);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(send_check_errmsg(thd, table, "restore",
-+ "Failed to open partially restored table"));
-+ }
-+ /* A MERGE table must not come here. */
-+ DBUG_ASSERT(!table->table || !table->table->child_l);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
-+ HA_CHECK_OPT *check_opt)
-+{
-+ int error= 0;
-+ TABLE tmp_table, *table;
-+ TABLE_SHARE *share;
-+ char from[FN_REFLEN],tmp[FN_REFLEN+32];
-+ const char **ext;
-+ MY_STAT stat_info;
-+ DBUG_ENTER("prepare_for_repair");
-+
-+ if (!(check_opt->sql_flags & TT_USEFRM))
-+ DBUG_RETURN(0);
-+
-+ if (!(table= table_list->table)) /* if open_ltable failed */
-+ {
-+ char key[MAX_DBKEY_LENGTH];
-+ uint key_length;
-+
-+ key_length= create_table_def_key(thd, key, table_list, 0);
-+ pthread_mutex_lock(&LOCK_open);
-+ if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
-+ &error))))
-+ {
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(0); // Can't open frm file
-+ }
-+
-+ if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE))
-+ {
-+ release_table_share(share, RELEASE_NORMAL);
-+ pthread_mutex_unlock(&LOCK_open);
-+ DBUG_RETURN(0); // Out of memory
-+ }
-+ table= &tmp_table;
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+
-+ /*
-+ REPAIR TABLE ... USE_FRM for temporary tables makes little sense.
-+ */
-+ if (table->s->tmp_table)
-+ {
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Cannot repair temporary table from .frm file");
-+ goto end;
-+ }
-+
-+ /*
-+ User gave us USE_FRM which means that the header in the index file is
-+ trashed.
-+ In this case we will try to fix the table the following way:
-+ - Rename the data file to a temporary name
-+ - Truncate the table
-+ - Replace the new data file with the old one
-+ - Run a normal repair using the new index file and the old data file
-+ */
-+
-+ if (table->s->frm_version != FRM_VER_TRUE_VARCHAR)
-+ {
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Failed repairing incompatible .frm file");
-+ goto end;
-+ }
-+
-+ /*
-+ Check if this is a table type that stores index and data separately,
-+ like ISAM or MyISAM. We assume fixed order of engine file name
-+ extentions array. First element of engine file name extentions array
-+ is meta/index file extention. Second element - data file extention.
-+ */
-+ ext= table->file->bas_ext();
-+ if (!ext[0] || !ext[1])
-+ goto end; // No data file
-+
-+ // Name of data file
-+ strxmov(from, table->s->normalized_path.str, ext[1], NullS);
-+ if (!my_stat(from, &stat_info, MYF(0)))
-+ goto end; // Can't use USE_FRM flag
-+
-+ my_snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
-+ from, current_pid, thd->thread_id);
-+
-+ /* If we could open the table, close it */
-+ if (table_list->table)
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ close_cached_table(thd, table);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ if (lock_and_wait_for_table_name(thd,table_list))
-+ {
-+ error= -1;
-+ goto end;
-+ }
-+ if (my_rename(from, tmp, MYF(MY_WME)))
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlock_table_name(thd, table_list);
-+ pthread_mutex_unlock(&LOCK_open);
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Failed renaming data file");
-+ goto end;
-+ }
-+ if (mysql_truncate(thd, table_list, 1))
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlock_table_name(thd, table_list);
-+ pthread_mutex_unlock(&LOCK_open);
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Failed generating table from .frm file");
-+ goto end;
-+ }
-+ if (my_rename(tmp, from, MYF(MY_WME)))
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlock_table_name(thd, table_list);
-+ pthread_mutex_unlock(&LOCK_open);
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Failed restoring .MYD file");
-+ goto end;
-+ }
-+
-+ /*
-+ Now we should be able to open the partially repaired table
-+ to finish the repair in the handler later on.
-+ */
-+ pthread_mutex_lock(&LOCK_open);
-+ if (reopen_name_locked_table(thd, table_list, TRUE))
-+ {
-+ unlock_table_name(thd, table_list);
-+ pthread_mutex_unlock(&LOCK_open);
-+ error= send_check_errmsg(thd, table_list, "repair",
-+ "Failed to open partially repaired table");
-+ goto end;
-+ }
-+ pthread_mutex_unlock(&LOCK_open);
-+
-+end:
-+ if (table == &tmp_table)
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ closefrm(table, 1); // Free allocated memory
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ DBUG_RETURN(error);
-+}
-+
-+
-+
-+/*
-+ RETURN VALUES
-+ FALSE Message sent to net (admin operation went ok)
-+ TRUE Message should be sent by caller
-+ (admin operation or network communication failed)
-+*/
-+static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
-+ HA_CHECK_OPT* check_opt,
-+ const char *operator_name,
-+ thr_lock_type lock_type,
-+ bool open_for_modify,
-+ bool no_warnings_for_error,
-+ uint extra_open_options,
-+ int (*prepare_func)(THD *, TABLE_LIST *,
-+ HA_CHECK_OPT *),
-+ int (handler::*operator_func)(THD *,
-+ HA_CHECK_OPT *),
-+ int (view_operator_func)(THD *, TABLE_LIST*))
-+{
-+ TABLE_LIST *table;
-+ SELECT_LEX *select= &thd->lex->select_lex;
-+ List<Item> field_list;
-+ Item *item;
-+ Protocol *protocol= thd->protocol;
-+ LEX *lex= thd->lex;
-+ int result_code;
-+ DBUG_ENTER("mysql_admin_table");
-+
-+ if (end_active_trans(thd))
-+ DBUG_RETURN(1);
-+ field_list.push_back(item = new Item_empty_string("Table", NAME_CHAR_LEN*2));
-+ item->maybe_null = 1;
-+ field_list.push_back(item = new Item_empty_string("Op", 10));
-+ item->maybe_null = 1;
-+ field_list.push_back(item = new Item_empty_string("Msg_type", 10));
-+ item->maybe_null = 1;
-+ field_list.push_back(item = new Item_empty_string("Msg_text", 255));
-+ item->maybe_null = 1;
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ mysql_ha_rm_tables(thd, tables, FALSE);
-+
-+ for (table= tables; table; table= table->next_local)
-+ {
-+ char table_name[NAME_LEN*2+2];
-+ char* db = table->db;
-+ bool fatal_error=0;
-+
-+ DBUG_PRINT("admin", ("table: '%s'.'%s'", table->db, table->table_name));
-+ DBUG_PRINT("admin", ("extra_open_options: %u", extra_open_options));
-+ strxmov(table_name, db, ".", table->table_name, NullS);
-+ thd->open_options|= extra_open_options;
-+ table->lock_type= lock_type;
-+ /* open only one table from local list of command */
-+ {
-+ TABLE_LIST *save_next_global, *save_next_local;
-+ save_next_global= table->next_global;
-+ table->next_global= 0;
-+ save_next_local= table->next_local;
-+ table->next_local= 0;
-+ select->table_list.first= table;
-+ /*
-+ Time zone tables and SP tables can be add to lex->query_tables list,
-+ so it have to be prepared.
-+ TODO: Investigate if we can put extra tables into argument instead of
-+ using lex->query_tables
-+ */
-+ lex->query_tables= table;
-+ lex->query_tables_last= &table->next_global;
-+ lex->query_tables_own_last= 0;
-+ thd->no_warnings_for_error= no_warnings_for_error;
-+ if (view_operator_func == NULL)
-+ table->required_type=FRMTYPE_TABLE;
-+
-+ open_and_lock_tables(thd, table);
-+ thd->no_warnings_for_error= 0;
-+ table->next_global= save_next_global;
-+ table->next_local= save_next_local;
-+ thd->open_options&= ~extra_open_options;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (table->table)
-+ {
-+ /*
-+ Set up which partitions that should be processed
-+ if ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR PARTITION ..
-+ */
-+ Alter_info *alter_info= &lex->alter_info;
-+
-+ if (alter_info->flags & ALTER_ADMIN_PARTITION)
-+ {
-+ if (!table->table->part_info)
-+ {
-+ my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+ uint no_parts_found;
-+ uint no_parts_opt= alter_info->partition_names.elements;
-+ no_parts_found= set_part_state(alter_info, table->table->part_info,
-+ PART_CHANGED);
-+ if (no_parts_found != no_parts_opt &&
-+ (!(alter_info->flags & ALTER_ALL_PARTITION)))
-+ {
-+ char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
-+ size_t length;
-+ DBUG_PRINT("admin", ("sending non existent partition error"));
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ length= my_snprintf(buff, sizeof(buff),
-+ ER(ER_DROP_PARTITION_NON_EXISTENT),
-+ table_name);
-+ protocol->store(buff, length, system_charset_info);
-+ if(protocol->write())
-+ goto err;
-+ my_eof(thd);
-+ goto err;
-+ }
-+ }
-+ }
-+#endif
-+ }
-+ DBUG_PRINT("admin", ("table: 0x%lx", (long) table->table));
-+
-+ if (prepare_func)
-+ {
-+ DBUG_PRINT("admin", ("calling prepare_func"));
-+ switch ((*prepare_func)(thd, table, check_opt)) {
-+ case 1: // error, message written to net
-+ ha_autocommit_or_rollback(thd, 1);
-+ end_trans(thd, ROLLBACK);
-+ close_thread_tables(thd);
-+ DBUG_PRINT("admin", ("simple error, admin next table"));
-+ continue;
-+ case -1: // error, message could be written to net
-+ /* purecov: begin inspected */
-+ DBUG_PRINT("admin", ("severe error, stop"));
-+ goto err;
-+ /* purecov: end */
-+ default: // should be 0 otherwise
-+ DBUG_PRINT("admin", ("prepare_func succeeded"));
-+ ;
-+ }
-+ }
-+
-+ /*
-+ CHECK TABLE command is only command where VIEW allowed here and this
-+ command use only temporary teble method for VIEWs resolving => there
-+ can't be VIEW tree substitition of join view => if opening table
-+ succeed then table->table will have real TABLE pointer as value (in
-+ case of join view substitution table->table can be 0, but here it is
-+ impossible)
-+ */
-+ if (!table->table)
-+ {
-+ DBUG_PRINT("admin", ("open table failed"));
-+ if (!thd->warn_list.elements)
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
-+ /* if it was a view will check md5 sum */
-+ if (table->view &&
-+ view_checksum(thd, table) == HA_ADMIN_WRONG_CHECKSUM)
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ ER_VIEW_CHECKSUM, ER(ER_VIEW_CHECKSUM));
-+ if (thd->main_da.is_error() &&
-+ (thd->main_da.sql_errno() == ER_NO_SUCH_TABLE ||
-+ thd->main_da.sql_errno() == ER_FILE_NOT_FOUND))
-+ /* A missing table is just issued as a failed command */
-+ result_code= HA_ADMIN_FAILED;
-+ else
-+ /* Default failure code is corrupt table */
-+ result_code= HA_ADMIN_CORRUPT;
-+ goto send_result;
-+ }
-+
-+ if (table->view)
-+ {
-+ DBUG_PRINT("admin", ("calling view_operator_func"));
-+ result_code= (*view_operator_func)(thd, table);
-+ goto send_result;
-+ }
-+
-+ if (table->schema_table)
-+ {
-+ result_code= HA_ADMIN_NOT_IMPLEMENTED;
-+ goto send_result;
-+ }
-+
-+ if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
-+ {
-+ /* purecov: begin inspected */
-+ char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
-+ size_t length;
-+ DBUG_PRINT("admin", ("sending error message"));
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ length= my_snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
-+ table_name);
-+ protocol->store(buff, length, system_charset_info);
-+ ha_autocommit_or_rollback(thd, 0);
-+ end_trans(thd, COMMIT);
-+ close_thread_tables(thd);
-+ lex->reset_query_tables_list(FALSE);
-+ table->table=0; // For query cache
-+ if (protocol->write())
-+ goto err;
-+ thd->main_da.reset_diagnostics_area();
-+ continue;
-+ /* purecov: end */
-+ }
-+
-+ /* Close all instances of the table to allow repair to rename files */
-+ if (lock_type == TL_WRITE && table->table->s->version)
-+ {
-+ DBUG_PRINT("admin", ("removing table from cache"));
-+ pthread_mutex_lock(&LOCK_open);
-+ const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open,
-+ "Waiting to get writelock");
-+ mysql_lock_abort(thd,table->table, TRUE);
-+ remove_table_from_cache(thd, table->table->s->db.str,
-+ table->table->s->table_name.str,
-+ RTFC_WAIT_OTHER_THREAD_FLAG |
-+ RTFC_CHECK_KILLED_FLAG);
-+ thd->exit_cond(old_message);
-+ DBUG_EXECUTE_IF("wait_in_mysql_admin_table", wait_for_kill_signal(thd););
-+ if (thd->killed)
-+ goto err;
-+ /* Flush entries in the query cache involving this table. */
-+ query_cache_invalidate3(thd, table->table, 0);
-+ open_for_modify= 0;
-+ }
-+
-+ if (table->table->s->crashed && operator_func == &handler::ha_check)
-+ {
-+ /* purecov: begin inspected */
-+ DBUG_PRINT("admin", ("sending crashed warning"));
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+ protocol->store(STRING_WITH_LEN("warning"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Table is marked as crashed"),
-+ system_charset_info);
-+ if (protocol->write())
-+ goto err;
-+ /* purecov: end */
-+ }
-+
-+ if (operator_func == &handler::ha_repair &&
-+ !(check_opt->sql_flags & TT_USEFRM))
-+ {
-+ if ((table->table->file->check_old_types() == HA_ADMIN_NEEDS_ALTER) ||
-+ (table->table->file->ha_check_for_upgrade(check_opt) ==
-+ HA_ADMIN_NEEDS_ALTER))
-+ {
-+ DBUG_PRINT("admin", ("recreating table"));
-+ ha_autocommit_or_rollback(thd, 1);
-+ close_thread_tables(thd);
-+ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
-+ result_code= mysql_recreate_table(thd, table);
-+ reenable_binlog(thd);
-+ /*
-+ mysql_recreate_table() can push OK or ERROR.
-+ Clear 'OK' status. If there is an error, keep it:
-+ we will store the error message in a result set row
-+ and then clear.
-+ */
-+ if (thd->main_da.is_ok())
-+ thd->main_da.reset_diagnostics_area();
-+ goto send_result;
-+ }
-+ }
-+
-+ DBUG_PRINT("admin", ("calling operator_func '%s'", operator_name));
-+ result_code = (table->table->file->*operator_func)(thd, check_opt);
-+ DBUG_PRINT("admin", ("operator_func returned: %d", result_code));
-+
-+send_result:
-+
-+ lex->cleanup_after_one_table_open();
-+ thd->clear_error(); // these errors shouldn't get client
-+ {
-+ List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
-+ MYSQL_ERROR *err;
-+ while ((err= it++))
-+ {
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store((char*) operator_name, system_charset_info);
-+ protocol->store(warning_level_names[err->level].str,
-+ warning_level_names[err->level].length,
-+ system_charset_info);
-+ protocol->store(err->msg, system_charset_info);
-+ if (protocol->write())
-+ goto err;
-+ }
-+ mysql_reset_errors(thd, true);
-+ }
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+
-+send_result_message:
-+
-+ DBUG_PRINT("info", ("result_code: %d", result_code));
-+ switch (result_code) {
-+ case HA_ADMIN_NOT_IMPLEMENTED:
-+ {
-+ char buf[MYSQL_ERRMSG_SIZE];
-+ size_t length=my_snprintf(buf, sizeof(buf),
-+ ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
-+ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
-+ protocol->store(buf, length, system_charset_info);
-+ }
-+ break;
-+
-+ case HA_ADMIN_NOT_BASE_TABLE:
-+ {
-+ char buf[MYSQL_ERRMSG_SIZE];
-+ size_t length= my_snprintf(buf, sizeof(buf),
-+ ER(ER_BAD_TABLE_ERROR), table_name);
-+ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
-+ protocol->store(buf, length, system_charset_info);
-+ }
-+ break;
-+
-+ case HA_ADMIN_OK:
-+ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("OK"), system_charset_info);
-+ break;
-+
-+ case HA_ADMIN_FAILED:
-+ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Operation failed"),
-+ system_charset_info);
-+ break;
-+
-+ case HA_ADMIN_REJECT:
-+ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Operation need committed state"),
-+ system_charset_info);
-+ open_for_modify= FALSE;
-+ break;
-+
-+ case HA_ADMIN_ALREADY_DONE:
-+ protocol->store(STRING_WITH_LEN("status"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Table is already up to date"),
-+ system_charset_info);
-+ break;
-+
-+ case HA_ADMIN_CORRUPT:
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Corrupt"), system_charset_info);
-+ fatal_error=1;
-+ break;
-+
-+ case HA_ADMIN_INVALID:
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN("Invalid argument"),
-+ system_charset_info);
-+ break;
-+
-+ case HA_ADMIN_TRY_ALTER:
-+ {
-+ /*
-+ This is currently used only by InnoDB. ha_innobase::optimize() answers
-+ "try with alter", so here we close the table, do an ALTER TABLE,
-+ reopen the table and do ha_innobase::analyze() on it.
-+ We have to end the row, so analyze could return more rows.
-+ */
-+ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
-+ protocol->store(STRING_WITH_LEN(
-+ "Table does not support optimize, doing recreate + analyze instead"),
-+ system_charset_info);
-+ if (protocol->write())
-+ goto err;
-+ ha_autocommit_or_rollback(thd, 0);
-+ close_thread_tables(thd);
-+ DBUG_PRINT("info", ("HA_ADMIN_TRY_ALTER, trying analyze..."));
-+ TABLE_LIST *save_next_local= table->next_local,
-+ *save_next_global= table->next_global;
-+ table->next_local= table->next_global= 0;
-+ tmp_disable_binlog(thd); // binlogging is done by caller if wanted
-+ result_code= mysql_recreate_table(thd, table);
-+ reenable_binlog(thd);
-+ /*
-+ mysql_recreate_table() can push OK or ERROR.
-+ Clear 'OK' status. If there is an error, keep it:
-+ we will store the error message in a result set row
-+ and then clear.
-+ */
-+ if (thd->main_da.is_ok())
-+ thd->main_da.reset_diagnostics_area();
-+ ha_autocommit_or_rollback(thd, 0);
-+ close_thread_tables(thd);
-+ if (!result_code) // recreation went ok
-+ {
-+ if ((table->table= open_ltable(thd, table, lock_type, 0)) &&
-+ ((result_code= table->table->file->ha_analyze(thd, check_opt)) > 0))
-+ result_code= 0; // analyze went ok
-+ }
-+ /* Start a new row for the final status row */
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+ if (result_code) // either mysql_recreate_table or analyze failed
-+ {
-+ DBUG_ASSERT(thd->is_error());
-+ if (thd->is_error())
-+ {
-+ const char *err_msg= thd->main_da.message();
-+ if (!thd->vio_ok())
-+ {
-+ sql_print_error("%s", err_msg);
-+ }
-+ else
-+ {
-+ /* Hijack the row already in-progress. */
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ protocol->store(err_msg, system_charset_info);
-+ if (protocol->write())
-+ goto err;
-+ /* Start off another row for HA_ADMIN_FAILED */
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+ protocol->store(operator_name, system_charset_info);
-+ }
-+ thd->clear_error();
-+ }
-+ }
-+ result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
-+ table->next_local= save_next_local;
-+ table->next_global= save_next_global;
-+ goto send_result_message;
-+ }
-+ case HA_ADMIN_WRONG_CHECKSUM:
-+ {
-+ protocol->store(STRING_WITH_LEN("note"), system_charset_info);
-+ protocol->store(ER(ER_VIEW_CHECKSUM), strlen(ER(ER_VIEW_CHECKSUM)),
-+ system_charset_info);
-+ break;
-+ }
-+
-+ case HA_ADMIN_NEEDS_UPGRADE:
-+ case HA_ADMIN_NEEDS_ALTER:
-+ {
-+ char buf[MYSQL_ERRMSG_SIZE];
-+ size_t length;
-+
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ length=my_snprintf(buf, sizeof(buf), ER(ER_TABLE_NEEDS_UPGRADE),
-+ table->table_name);
-+ protocol->store(buf, length, system_charset_info);
-+ fatal_error=1;
-+ break;
-+ }
-+
-+ default: // Probably HA_ADMIN_INTERNAL_ERROR
-+ {
-+ char buf[MYSQL_ERRMSG_SIZE];
-+ size_t length=my_snprintf(buf, sizeof(buf),
-+ "Unknown - internal error %d during operation",
-+ result_code);
-+ protocol->store(STRING_WITH_LEN("error"), system_charset_info);
-+ protocol->store(buf, length, system_charset_info);
-+ fatal_error=1;
-+ break;
-+ }
-+ }
-+ if (table->table)
-+ {
-+ if (fatal_error)
-+ table->table->s->version=0; // Force close of table
-+ else if (open_for_modify)
-+ {
-+ if (table->table->s->tmp_table)
-+ table->table->file->info(HA_STATUS_CONST);
-+ else
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ remove_table_from_cache(thd, table->table->s->db.str,
-+ table->table->s->table_name.str, RTFC_NO_FLAG);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ /* May be something modified consequently we have to invalidate cache */
-+ query_cache_invalidate3(thd, table->table, 0);
-+ }
-+ }
-+ ha_autocommit_or_rollback(thd, 0);
-+ end_trans(thd, COMMIT);
-+ close_thread_tables(thd);
-+ table->table=0; // For query cache
-+ if (protocol->write())
-+ goto err;
-+ }
-+
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+
-+err:
-+ ha_autocommit_or_rollback(thd, 1);
-+ end_trans(thd, ROLLBACK);
-+ close_thread_tables(thd); // Shouldn't be needed
-+ if (table)
-+ table->table=0;
-+ DBUG_RETURN(TRUE);
-+}
-+
-+
-+bool mysql_backup_table(THD* thd, TABLE_LIST* table_list)
-+{
-+ DBUG_ENTER("mysql_backup_table");
-+ WARN_DEPRECATED(thd, "6.0", "BACKUP TABLE",
-+ "MySQL Administrator (mysqldump, mysql)");
-+ DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
-+ "backup", TL_READ, 0, 0, 0, 0,
-+ &handler::ha_backup, 0));
-+}
-+
-+
-+bool mysql_restore_table(THD* thd, TABLE_LIST* table_list)
-+{
-+ DBUG_ENTER("mysql_restore_table");
-+ WARN_DEPRECATED(thd, "6.0", "RESTORE TABLE",
-+ "MySQL Administrator (mysqldump, mysql)");
-+ DBUG_RETURN(mysql_admin_table(thd, table_list, 0,
-+ "restore", TL_WRITE, 1, 1, 0,
-+ &prepare_for_restore,
-+ &handler::ha_restore, 0));
-+}
-+
-+
-+bool mysql_repair_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
-+{
-+ DBUG_ENTER("mysql_repair_table");
-+ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
-+ "repair", TL_WRITE, 1,
-+ test(check_opt->sql_flags & TT_USEFRM),
-+ HA_OPEN_FOR_REPAIR,
-+ &prepare_for_repair,
-+ &handler::ha_repair, 0));
-+}
-+
-+
-+bool mysql_optimize_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
-+{
-+ DBUG_ENTER("mysql_optimize_table");
-+ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
-+ "optimize", TL_WRITE, 1,0,0,0,
-+ &handler::ha_optimize, 0));
-+}
-+
-+
-+/*
-+ Assigned specified indexes for a table into key cache
-+
-+ SYNOPSIS
-+ mysql_assign_to_keycache()
-+ thd Thread object
-+ tables Table list (one table only)
-+
-+ RETURN VALUES
-+ FALSE ok
-+ TRUE error
-+*/
-+
-+bool mysql_assign_to_keycache(THD* thd, TABLE_LIST* tables,
-+ LEX_STRING *key_cache_name)
-+{
-+ HA_CHECK_OPT check_opt;
-+ KEY_CACHE *key_cache;
-+ DBUG_ENTER("mysql_assign_to_keycache");
-+
-+ check_opt.init();
-+ pthread_mutex_lock(&LOCK_global_system_variables);
-+ if (!(key_cache= get_key_cache(key_cache_name)))
-+ {
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ my_error(ER_UNKNOWN_KEY_CACHE, MYF(0), key_cache_name->str);
-+ DBUG_RETURN(TRUE);
-+ }
-+ pthread_mutex_unlock(&LOCK_global_system_variables);
-+ check_opt.key_cache= key_cache;
-+ DBUG_RETURN(mysql_admin_table(thd, tables, &check_opt,
-+ "assign_to_keycache", TL_READ_NO_INSERT, 0, 0,
-+ 0, 0, &handler::assign_to_keycache, 0));
-+}
-+
-+
-+/*
-+ Reassign all tables assigned to a key cache to another key cache
-+
-+ SYNOPSIS
-+ reassign_keycache_tables()
-+ thd Thread object
-+ src_cache Reference to the key cache to clean up
-+ dest_cache New key cache
-+
-+ NOTES
-+ This is called when one sets a key cache size to zero, in which
-+ case we have to move the tables associated to this key cache to
-+ the "default" one.
-+
-+ One has to ensure that one never calls this function while
-+ some other thread is changing the key cache. This is assured by
-+ the caller setting src_cache->in_init before calling this function.
-+
-+ We don't delete the old key cache as there may still be pointers pointing
-+ to it for a while after this function returns.
-+
-+ RETURN VALUES
-+ 0 ok
-+*/
-+
-+int reassign_keycache_tables(THD *thd, KEY_CACHE *src_cache,
-+ KEY_CACHE *dst_cache)
-+{
-+ DBUG_ENTER("reassign_keycache_tables");
-+
-+ DBUG_ASSERT(src_cache != dst_cache);
-+ DBUG_ASSERT(src_cache->in_init);
-+ src_cache->param_buff_size= 0; // Free key cache
-+ ha_resize_key_cache(src_cache);
-+ ha_change_key_cache(src_cache, dst_cache);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Preload specified indexes for a table into key cache
-+
-+ SYNOPSIS
-+ mysql_preload_keys()
-+ thd Thread object
-+ tables Table list (one table only)
-+
-+ RETURN VALUES
-+ FALSE ok
-+ TRUE error
-+*/
-+
-+bool mysql_preload_keys(THD* thd, TABLE_LIST* tables)
-+{
-+ DBUG_ENTER("mysql_preload_keys");
-+ /*
-+ We cannot allow concurrent inserts. The storage engine reads
-+ directly from the index file, bypassing the cache. It could read
-+ outdated information if parallel inserts into cache blocks happen.
-+ */
-+ DBUG_RETURN(mysql_admin_table(thd, tables, 0,
-+ "preload_keys", TL_READ_NO_INSERT, 0, 0, 0, 0,
-+ &handler::preload_keys, 0));
-+}
-+
-+
-+
-+/**
-+ @brief Create frm file based on I_S table
-+
-+ @param[in] thd thread handler
-+ @param[in] schema_table I_S table
-+ @param[in] dst_path path where frm should be created
-+ @param[in] create_info Create info
-+
-+ @return Operation status
-+ @retval 0 success
-+ @retval 1 error
-+*/
-+
-+
-+bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table,
-+ char *dst_path, HA_CREATE_INFO *create_info)
-+{
-+ HA_CREATE_INFO local_create_info;
-+ Alter_info alter_info;
-+ bool tmp_table= (create_info->options & HA_LEX_CREATE_TMP_TABLE);
-+ uint keys= schema_table->table->s->keys;
-+ uint db_options= 0;
-+ DBUG_ENTER("mysql_create_like_schema_frm");
-+
-+ bzero((char*) &local_create_info, sizeof(local_create_info));
-+ local_create_info.db_type= schema_table->table->s->db_type();
-+ local_create_info.row_type= schema_table->table->s->row_type;
-+ local_create_info.default_table_charset=default_charset_info;
-+ alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
-+ schema_table->table->use_all_columns();
-+ if (mysql_prepare_alter_table(thd, schema_table->table,
-+ &local_create_info, &alter_info))
-+ DBUG_RETURN(1);
-+ if (mysql_prepare_create_table(thd, &local_create_info, &alter_info,
-+ tmp_table, &db_options,
-+ schema_table->table->file,
-+ &schema_table->table->s->key_info, &keys, 0))
-+ DBUG_RETURN(1);
-+ local_create_info.max_rows= 0;
-+ if (mysql_create_frm(thd, dst_path, NullS, NullS,
-+ &local_create_info, alter_info.create_list,
-+ keys, schema_table->table->s->key_info,
-+ schema_table->table->file))
-+ DBUG_RETURN(1);
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Create a table identical to the specified table
-+
-+ SYNOPSIS
-+ mysql_create_like_table()
-+ thd Thread object
-+ table Table list element for target table
-+ src_table Table list element for source table
-+ create_info Create info
-+
-+ RETURN VALUES
-+ FALSE OK
-+ TRUE error
-+*/
-+
-+bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table,
-+ HA_CREATE_INFO *create_info)
-+{
-+ TABLE *name_lock= 0;
-+ char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1];
-+ uint dst_path_length;
-+ char *db= table->db;
-+ char *table_name= table->table_name;
-+ int err;
-+ bool res= TRUE;
-+ uint not_used;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ char tmp_path[FN_REFLEN];
-+#endif
-+ char ts_name[FN_LEN + 1];
-+ myf flags= MY_DONT_OVERWRITE_FILE;
-+ DBUG_ENTER("mysql_create_like_table");
-+
-+
-+ /*
-+ By opening source table we guarantee that it exists and no concurrent
-+ DDL operation will mess with it. Later we also take an exclusive
-+ name-lock on target table name, which makes copying of .frm file,
-+ call to ha_create_table() and binlogging atomic against concurrent DML
-+ and DDL operations on target table. Thus by holding both these "locks"
-+ we ensure that our statement is properly isolated from all concurrent
-+ operations which matter.
-+ */
-+ if (open_tables(thd, &src_table, ¬_used, 0))
-+ DBUG_RETURN(TRUE);
-+
-+ /*
-+ For bug#25875, Newly created table through CREATE TABLE .. LIKE
-+ has no ndb_dd attributes;
-+ Add something to get possible tablespace info from src table,
-+ it can get valid tablespace name only for disk-base ndb table
-+ */
-+ if ((src_table->table->file->get_tablespace_name(thd, ts_name, FN_LEN)))
-+ {
-+ create_info->tablespace= ts_name;
-+ create_info->storage_media= HA_SM_DISK;
-+ }
-+
-+ strxmov(src_path, src_table->table->s->path.str, reg_ext, NullS);
-+
-+ DBUG_EXECUTE_IF("sleep_create_like_before_check_if_exists", my_sleep(6000000););
-+
-+ /*
-+ Check that destination tables does not exist. Note that its name
-+ was already checked when it was added to the table list.
-+ */
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
-+ {
-+ if (src_table->table->file->ht == partition_hton)
-+ {
-+ my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
-+ goto err;
-+ }
-+ if (find_temporary_table(thd, db, table_name))
-+ goto table_exists;
-+ dst_path_length= build_tmptable_filename(thd, dst_path, sizeof(dst_path));
-+ create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
-+ }
-+ else
-+ {
-+ if (lock_table_name_if_not_cached(thd, db, table_name, &name_lock))
-+ goto err;
-+ if (!name_lock)
-+ goto table_exists;
-+ dst_path_length= build_table_filename(dst_path, sizeof(dst_path) - 1,
-+ db, table_name, reg_ext, 0);
-+ if (!access(dst_path, F_OK))
-+ goto table_exists;
-+ }
-+
-+ DBUG_EXECUTE_IF("sleep_create_like_before_copy", my_sleep(6000000););
-+
-+ if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
-+ flags|= MY_SYNC;
-+
-+ /*
-+ Create a new table by copying from source table
-+ and sync the new table if the flag MY_SYNC is set
-+
-+ Altough exclusive name-lock on target table protects us from concurrent
-+ DML and DDL operations on it we still want to wrap .FRM creation and call
-+ to ha_create_table() in critical section protected by LOCK_open in order
-+ to provide minimal atomicity against operations which disregard name-locks,
-+ like I_S implementation, for example. This is a temporary and should not
-+ be copied. Instead we should fix our code to always honor name-locks.
-+
-+ Also some engines (e.g. NDB cluster) require that LOCK_open should be held
-+ during the call to ha_create_table(). See bug #28614 for more info.
-+ */
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (src_table->schema_table)
-+ {
-+ if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info))
-+ {
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ goto err;
-+ }
-+ }
-+ else if (my_copy(src_path, dst_path, flags))
-+ {
-+ if (my_errno == ENOENT)
-+ my_error(ER_BAD_DB_ERROR,MYF(0),db);
-+ else
-+ my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ goto err;
-+ }
-+
-+ /*
-+ As mysql_truncate don't work on a new table at this stage of
-+ creation, instead create the table directly (for both normal
-+ and temporary tables).
-+ */
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ /*
-+ For partitioned tables we need to copy the .par file as well since
-+ it is used in open_table_def to even be able to create a new handler.
-+ */
-+ if (src_table->table->file->ht == partition_hton)
-+ {
-+ fn_format(tmp_path, dst_path, reg_ext, ".par", MYF(MY_REPLACE_EXT));
-+ strmov(dst_path, tmp_path);
-+ fn_format(tmp_path, src_path, reg_ext, ".par", MYF(MY_REPLACE_EXT));
-+ strmov(src_path, tmp_path);
-+ my_copy(src_path, dst_path, MYF(MY_DONT_OVERWRITE_FILE));
-+ }
-+#endif
-+
-+ DBUG_EXECUTE_IF("sleep_create_like_before_ha_create", my_sleep(6000000););
-+
-+ dst_path[dst_path_length - reg_ext_length]= '\0'; // Remove .frm
-+ if (thd->variables.keep_files_on_create)
-+ create_info->options|= HA_CREATE_KEEP_FILES;
-+ err= ha_create_table(thd, dst_path, db, table_name, create_info, 1);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
-+ {
-+ if (err || !open_temporary_table(thd, dst_path, db, table_name, 1))
-+ {
-+ (void) rm_temporary_table(create_info->db_type,
-+ dst_path); /* purecov: inspected */
-+ goto err; /* purecov: inspected */
-+ }
-+ thd->thread_specific_used= TRUE;
-+ }
-+ else if (err)
-+ {
-+ (void) quick_rm_table(create_info->db_type, db,
-+ table_name, 0); /* purecov: inspected */
-+ goto err; /* purecov: inspected */
-+ }
-+
-+goto binlog;
-+
-+table_exists:
-+ if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
-+ {
-+ char warn_buff[MYSQL_ERRMSG_SIZE];
-+ my_snprintf(warn_buff, sizeof(warn_buff),
-+ ER(ER_TABLE_EXISTS_ERROR), table_name);
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_TABLE_EXISTS_ERROR,warn_buff);
-+ }
-+ else
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
-+ goto err;
-+ }
-+
-+binlog:
-+ DBUG_EXECUTE_IF("sleep_create_like_before_binlogging", my_sleep(6000000););
-+
-+ /*
-+ We have to write the query before we unlock the tables.
-+ */
-+ if (thd->current_stmt_binlog_row_based)
-+ {
-+ /*
-+ Since temporary tables are not replicated under row-based
-+ replication, CREATE TABLE ... LIKE ... needs special
-+ treatement. We have four cases to consider, according to the
-+ following decision table:
-+
-+ ==== ========= ========= ==============================
-+ Case Target Source Write to binary log
-+ ==== ========= ========= ==============================
-+ 1 normal normal Original statement
-+ 2 normal temporary Generated statement
-+ 3 temporary normal Nothing
-+ 4 temporary temporary Nothing
-+ ==== ========= ========= ==============================
-+ */
-+ if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
-+ {
-+ if (src_table->table->s->tmp_table) // Case 2
-+ {
-+ char buf[2048];
-+ String query(buf, sizeof(buf), system_charset_info);
-+ query.length(0); // Have to zero it since constructor doesn't
-+
-+ /*
-+ Here we open the destination table, on which we already have
-+ name-lock. This is needed for store_create_info() to work.
-+ The table will be closed by unlink_open_table() at the end
-+ of this function.
-+ */
-+ table->table= name_lock;
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (reopen_name_locked_table(thd, table, FALSE))
-+ {
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ goto err;
-+ }
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+
-+ /*
-+ The condition avoids a crash as described in BUG#48506. Other
-+ binlogging problems related to CREATE TABLE IF NOT EXISTS LIKE
-+ when the existing object is a view will be solved by BUG 47442.
-+ */
-+ if (!table->view)
-+ {
-+ IF_DBUG(int result=)
-+ store_create_info(thd, table, &query,
-+ create_info, FALSE /* show_database */);
-+
-+ DBUG_ASSERT(result == 0); // store_create_info() always return 0
-+ if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
-+ goto err;
-+ }
-+ }
-+ else // Case 1
-+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
-+ goto err;
-+ }
-+ /*
-+ Case 3 and 4 does nothing under RBR
-+ */
-+ }
-+ else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
-+ goto err;
-+
-+ res= FALSE;
-+
-+err:
-+ if (name_lock)
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlink_open_table(thd, name_lock, FALSE);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ DBUG_RETURN(res);
-+}
-+
-+
-+bool mysql_analyze_table(THD* thd, TABLE_LIST* tables, HA_CHECK_OPT* check_opt)
-+{
-+ thr_lock_type lock_type = TL_READ_NO_INSERT;
-+
-+ DBUG_ENTER("mysql_analyze_table");
-+ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
-+ "analyze", lock_type, 1, 0, 0, 0,
-+ &handler::ha_analyze, 0));
-+}
-+
-+
-+bool mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt)
-+{
-+ thr_lock_type lock_type = TL_READ_NO_INSERT;
-+
-+ DBUG_ENTER("mysql_check_table");
-+ DBUG_RETURN(mysql_admin_table(thd, tables, check_opt,
-+ "check", lock_type,
-+ 0, 0, HA_OPEN_FOR_REPAIR, 0,
-+ &handler::ha_check, &view_checksum));
-+}
-+
-+
-+/* table_list should contain just one table */
-+static int
-+mysql_discard_or_import_tablespace(THD *thd,
-+ TABLE_LIST *table_list,
-+ enum tablespace_op_type tablespace_op)
-+{
-+ TABLE *table;
-+ my_bool discard;
-+ int error;
-+ DBUG_ENTER("mysql_discard_or_import_tablespace");
-+
-+ /*
-+ Note that DISCARD/IMPORT TABLESPACE always is the only operation in an
-+ ALTER TABLE
-+ */
-+
-+ thd_proc_info(thd, "discard_or_import_tablespace");
-+
-+ discard= test(tablespace_op == DISCARD_TABLESPACE);
-+
-+ /*
-+ We set this flag so that ha_innobase::open and ::external_lock() do
-+ not complain when we lock the table
-+ */
-+ thd->tablespace_op= TRUE;
-+ if (!(table=open_ltable(thd, table_list, TL_WRITE, 0)))
-+ {
-+ thd->tablespace_op=FALSE;
-+ DBUG_RETURN(-1);
-+ }
-+
-+ error= table->file->ha_discard_or_import_tablespace(discard);
-+
-+ thd_proc_info(thd, "end");
-+
-+ if (error)
-+ goto err;
-+
-+ /*
-+ The 0 in the call below means 'not in a transaction', which means
-+ immediate invalidation; that is probably what we wish here
-+ */
-+ query_cache_invalidate3(thd, table_list, 0);
-+
-+ /* The ALTER TABLE is always in its own transaction */
-+ error = ha_autocommit_or_rollback(thd, 0);
-+ if (end_active_trans(thd))
-+ error=1;
-+ if (error)
-+ goto err;
-+ error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
-+
-+err:
-+ ha_autocommit_or_rollback(thd, error);
-+ thd->tablespace_op=FALSE;
-+
-+ if (error == 0)
-+ {
-+ my_ok(thd);
-+ DBUG_RETURN(0);
-+ }
-+
-+ table->file->print_error(error, MYF(0));
-+
-+ DBUG_RETURN(-1);
-+}
-+
-+/**
-+ @brief Check if both DROP and CREATE are present for an index in ALTER TABLE
-+
-+ @details Checks if any index is being modified (present as both DROP INDEX
-+ and ADD INDEX) in the current ALTER TABLE statement. Needed for disabling
-+ online ALTER TABLE.
-+
-+ @param table The table being altered
-+ @param alter_info The ALTER TABLE structure
-+ @return presence of index being altered
-+ @retval FALSE No such index
-+ @retval TRUE Have at least 1 index modified
-+*/
-+
-+static bool
-+is_index_maintenance_unique (TABLE *table, Alter_info *alter_info)
-+{
-+ List_iterator<Key> key_it(alter_info->key_list);
-+ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
-+ Key *key;
-+
-+ while ((key= key_it++))
-+ {
-+ if (key->name)
-+ {
-+ Alter_drop *drop;
-+
-+ drop_it.rewind();
-+ while ((drop= drop_it++))
-+ {
-+ if (drop->type == Alter_drop::KEY &&
-+ !my_strcasecmp(system_charset_info, key->name, drop->name))
-+ return TRUE;
-+ }
-+ }
-+ }
-+ return FALSE;
-+}
-+
-+
-+/*
-+ SYNOPSIS
-+ compare_tables()
-+ table The original table.
-+ alter_info Alter options, fields and keys for the new
-+ table.
-+ create_info Create options for the new table.
-+ order_num Number of order list elements.
-+ need_copy_table OUT Result of the comparison. Undefined if error.
-+ Otherwise is one of:
-+ ALTER_TABLE_METADATA_ONLY No copy needed
-+ ALTER_TABLE_DATA_CHANGED Data changes,
-+ copy needed
-+ ALTER_TABLE_INDEX_CHANGED Index changes,
-+ copy might be needed
-+ key_info_buffer OUT An array of KEY structs for new indexes
-+ index_drop_buffer OUT An array of offsets into table->key_info.
-+ index_drop_count OUT The number of elements in the array.
-+ index_add_buffer OUT An array of offsets into key_info_buffer.
-+ index_add_count OUT The number of elements in the array.
-+ candidate_key_count OUT The number of candidate keys in original table.
-+
-+ DESCRIPTION
-+ 'table' (first argument) contains information of the original
-+ table, which includes all corresponding parts that the new
-+ table has in arguments create_list, key_list and create_info.
-+
-+ By comparing the changes between the original and new table
-+ we can determine how much it has changed after ALTER TABLE
-+ and whether we need to make a copy of the table, or just change
-+ the .frm file.
-+
-+ If there are no data changes, but index changes, 'index_drop_buffer'
-+ and/or 'index_add_buffer' are populated with offsets into
-+ table->key_info or key_info_buffer respectively for the indexes
-+ that need to be dropped and/or (re-)created.
-+
-+ RETURN VALUES
-+ TRUE error
-+ FALSE success
-+*/
-+
-+static
-+bool
-+compare_tables(TABLE *table,
-+ Alter_info *alter_info,
-+ HA_CREATE_INFO *create_info,
-+ uint order_num,
-+ enum_alter_table_change_level *need_copy_table,
-+ KEY **key_info_buffer,
-+ uint **index_drop_buffer, uint *index_drop_count,
-+ uint **index_add_buffer, uint *index_add_count,
-+ uint *candidate_key_count)
-+{
-+ Field **f_ptr, *field;
-+ uint changes= 0, tmp;
-+ uint key_count;
-+ List_iterator_fast<Create_field> new_field_it, tmp_new_field_it;
-+ Create_field *new_field, *tmp_new_field;
-+ KEY_PART_INFO *key_part;
-+ KEY_PART_INFO *end;
-+ THD *thd= table->in_use;
-+ /*
-+ Remember if the new definition has new VARCHAR column;
-+ create_info->varchar will be reset in mysql_prepare_create_table.
-+ */
-+ bool varchar= create_info->varchar;
-+ bool not_nullable= true;
-+ DBUG_ENTER("compare_tables");
-+
-+ /*
-+ Create a copy of alter_info.
-+ To compare the new and old table definitions, we need to "prepare"
-+ the new definition - transform it from parser output to a format
-+ that describes the final table layout (all column defaults are
-+ initialized, duplicate columns are removed). This is done by
-+ mysql_prepare_create_table. Unfortunately,
-+ mysql_prepare_create_table performs its transformations
-+ "in-place", that is, modifies the argument. Since we would
-+ like to keep compare_tables() idempotent (not altering any
-+ of the arguments) we create a copy of alter_info here and
-+ pass it to mysql_prepare_create_table, then use the result
-+ to evaluate possibility of fast ALTER TABLE, and then
-+ destroy the copy.
-+ */
-+ Alter_info tmp_alter_info(*alter_info, thd->mem_root);
-+ uint db_options= 0; /* not used */
-+
-+ /* Create the prepared information. */
-+ if (mysql_prepare_create_table(thd, create_info,
-+ &tmp_alter_info,
-+ (table->s->tmp_table != NO_TMP_TABLE),
-+ &db_options,
-+ table->file, key_info_buffer,
-+ &key_count, 0))
-+ DBUG_RETURN(1);
-+ /* Allocate result buffers. */
-+ if (! (*index_drop_buffer=
-+ (uint*) thd->alloc(sizeof(uint) * table->s->keys)) ||
-+ ! (*index_add_buffer=
-+ (uint*) thd->alloc(sizeof(uint) * tmp_alter_info.key_list.elements)))
-+ DBUG_RETURN(1);
-+
-+ /*
-+ Some very basic checks. If number of fields changes, or the
-+ handler, we need to run full ALTER TABLE. In the future
-+ new fields can be added and old dropped without copy, but
-+ not yet.
-+
-+ Test also that engine was not given during ALTER TABLE, or
-+ we are force to run regular alter table (copy).
-+ E.g. ALTER TABLE tbl_name ENGINE=MyISAM.
-+
-+ For the following ones we also want to run regular alter table:
-+ ALTER TABLE tbl_name ORDER BY ..
-+ ALTER TABLE tbl_name CONVERT TO CHARACTER SET ..
-+
-+ At the moment we can't handle altering temporary tables without a copy.
-+ We also test if OPTIMIZE TABLE was given and was mapped to alter table.
-+ In that case we always do full copy.
-+
-+ There was a bug prior to mysql-4.0.25. Number of null fields was
-+ calculated incorrectly. As a result frm and data files gets out of
-+ sync after fast alter table. There is no way to determine by which
-+ mysql version (in 4.0 and 4.1 branches) table was created, thus we
-+ disable fast alter table for all tables created by mysql versions
-+ prior to 5.0 branch.
-+ See BUG#6236.
-+ */
-+ if (table->s->fields != alter_info->create_list.elements ||
-+ table->s->db_type() != create_info->db_type ||
-+ table->s->tmp_table ||
-+ create_info->used_fields & HA_CREATE_USED_ENGINE ||
-+ create_info->used_fields & HA_CREATE_USED_CHARSET ||
-+ create_info->used_fields & HA_CREATE_USED_DEFAULT_CHARSET ||
-+ (table->s->row_type != create_info->row_type) ||
-+ create_info->used_fields & HA_CREATE_USED_PACK_KEYS ||
-+ create_info->used_fields & HA_CREATE_USED_MAX_ROWS ||
-+ (alter_info->flags & (ALTER_RECREATE | ALTER_FOREIGN_KEY)) ||
-+ order_num ||
-+ !table->s->mysql_version ||
-+ (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar))
-+ {
-+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+ DBUG_RETURN(0);
-+ }
-+
-+ /*
-+ Use transformed info to evaluate possibility of fast ALTER TABLE
-+ but use the preserved field to persist modifications.
-+ */
-+ new_field_it.init(alter_info->create_list);
-+ tmp_new_field_it.init(tmp_alter_info.create_list);
-+
-+ /*
-+ Go through fields and check if the original ones are compatible
-+ with new table.
-+ */
-+ for (f_ptr= table->field, new_field= new_field_it++,
-+ tmp_new_field= tmp_new_field_it++;
-+ (field= *f_ptr);
-+ f_ptr++, new_field= new_field_it++,
-+ tmp_new_field= tmp_new_field_it++)
-+ {
-+ /* Make sure we have at least the default charset in use. */
-+ if (!new_field->charset)
-+ new_field->charset= create_info->default_table_charset;
-+
-+ /* Check that NULL behavior is same for old and new fields */
-+ if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
-+ (uint) (field->flags & NOT_NULL_FLAG))
-+ {
-+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+ DBUG_RETURN(0);
-+ }
-+
-+ /* Don't pack rows in old tables if the user has requested this. */
-+ if (create_info->row_type == ROW_TYPE_DYNAMIC ||
-+ (tmp_new_field->flags & BLOB_FLAG) ||
-+ (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
-+ create_info->row_type != ROW_TYPE_FIXED))
-+ create_info->table_options|= HA_OPTION_PACK_RECORD;
-+
-+ /* Check if field was renamed */
-+ field->flags&= ~FIELD_IS_RENAMED;
-+ if (my_strcasecmp(system_charset_info,
-+ field->field_name,
-+ tmp_new_field->field_name))
-+ field->flags|= FIELD_IS_RENAMED;
-+
-+ /* Evaluate changes bitmap and send to check_if_incompatible_data() */
-+ if (!(tmp= field->is_equal(tmp_new_field)))
-+ {
-+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+ DBUG_RETURN(0);
-+ }
-+ // Clear indexed marker
-+ field->flags&= ~FIELD_IN_ADD_INDEX;
-+ changes|= tmp;
-+ }
-+
-+ /*
-+ Go through keys and check if the original ones are compatible
-+ with new table.
-+ */
-+ KEY *table_key;
-+ KEY *table_key_end= table->key_info + table->s->keys;
-+ KEY *new_key;
-+ KEY *new_key_end= *key_info_buffer + key_count;
-+
-+ DBUG_PRINT("info", ("index count old: %d new: %d",
-+ table->s->keys, key_count));
-+ /*
-+ Step through all keys of the old table and search matching new keys.
-+ */
-+ *index_drop_count= 0;
-+ *index_add_count= 0;
-+ *candidate_key_count= 0;
-+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
-+ {
-+ KEY_PART_INFO *table_part;
-+ KEY_PART_INFO *table_part_end= table_key->key_part + table_key->key_parts;
-+ KEY_PART_INFO *new_part;
-+
-+ /*
-+ Check if key is a candidate key, i.e. a unique index with no index
-+ fields nullable, then key is either already primary key or could
-+ be promoted to primary key if the original primary key is dropped.
-+ Count all candidate keys.
-+ */
-+ not_nullable= true;
-+ for (table_part= table_key->key_part;
-+ table_part < table_part_end;
-+ table_part++)
-+ {
-+ not_nullable= not_nullable && (! table_part->field->maybe_null());
-+ }
-+ if ((table_key->flags & HA_NOSAME) && not_nullable)
-+ (*candidate_key_count)++;
-+
-+ /* Search a new key with the same name. */
-+ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
-+ {
-+ if (! strcmp(table_key->name, new_key->name))
-+ break;
-+ }
-+ if (new_key >= new_key_end)
-+ {
-+ /* Key not found. Add the offset of the key to the drop buffer. */
-+ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
-+ DBUG_PRINT("info", ("index dropped: '%s'", table_key->name));
-+ continue;
-+ }
-+
-+ /* Check that the key types are compatible between old and new tables. */
-+ if ((table_key->algorithm != new_key->algorithm) ||
-+ ((table_key->flags & HA_KEYFLAG_MASK) !=
-+ (new_key->flags & HA_KEYFLAG_MASK)) ||
-+ (table_key->key_parts != new_key->key_parts))
-+ goto index_changed;
-+
-+ /*
-+ Check that the key parts remain compatible between the old and
-+ new tables.
-+ */
-+ for (table_part= table_key->key_part, new_part= new_key->key_part;
-+ table_part < table_part_end;
-+ table_part++, new_part++)
-+ {
-+ /*
-+ Key definition has changed if we are using a different field or
-+ if the used key part length is different. We know that the fields
-+ did not change. Comparing field numbers is sufficient.
-+ */
-+ if ((table_part->length != new_part->length) ||
-+ (table_part->fieldnr - 1 != new_part->fieldnr))
-+ goto index_changed;
-+ }
-+ continue;
-+
-+ index_changed:
-+ /* Key modified. Add the offset of the key to both buffers. */
-+ (*index_drop_buffer)[(*index_drop_count)++]= table_key - table->key_info;
-+ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
-+ key_part= new_key->key_part;
-+ end= key_part + new_key->key_parts;
-+ for(; key_part != end; key_part++)
-+ {
-+ // Mark field to be part of new key
-+ field= table->field[key_part->fieldnr];
-+ field->flags|= FIELD_IN_ADD_INDEX;
-+ }
-+ DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
-+ }
-+ /*end of for (; table_key < table_key_end;) */
-+
-+ /*
-+ Step through all keys of the new table and find matching old keys.
-+ */
-+ for (new_key= *key_info_buffer; new_key < new_key_end; new_key++)
-+ {
-+ /* Search an old key with the same name. */
-+ for (table_key= table->key_info; table_key < table_key_end; table_key++)
-+ {
-+ if (! strcmp(table_key->name, new_key->name))
-+ break;
-+ }
-+ if (table_key >= table_key_end)
-+ {
-+ /* Key not found. Add the offset of the key to the add buffer. */
-+ (*index_add_buffer)[(*index_add_count)++]= new_key - *key_info_buffer;
-+ key_part= new_key->key_part;
-+ end= key_part + new_key->key_parts;
-+ for(; key_part != end; key_part++)
-+ {
-+ // Mark field to be part of new key
-+ field= table->field[key_part->fieldnr];
-+ field->flags|= FIELD_IN_ADD_INDEX;
-+ }
-+ DBUG_PRINT("info", ("index added: '%s'", new_key->name));
-+ }
-+ }
-+
-+ /* Check if changes are compatible with current handler without a copy */
-+ if (table->file->check_if_incompatible_data(create_info, changes))
-+ {
-+ *need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+ DBUG_RETURN(0);
-+ }
-+
-+ if (*index_drop_count || *index_add_count)
-+ {
-+ *need_copy_table= ALTER_TABLE_INDEX_CHANGED;
-+ DBUG_RETURN(0);
-+ }
-+
-+ *need_copy_table= ALTER_TABLE_METADATA_ONLY; // Tables are compatible
-+ DBUG_RETURN(0);
-+}
-+
-+
-+/*
-+ Manages enabling/disabling of indexes for ALTER TABLE
-+
-+ SYNOPSIS
-+ alter_table_manage_keys()
-+ table Target table
-+ indexes_were_disabled Whether the indexes of the from table
-+ were disabled
-+ keys_onoff ENABLE | DISABLE | LEAVE_AS_IS
-+
-+ RETURN VALUES
-+ FALSE OK
-+ TRUE Error
-+*/
-+
-+static
-+bool alter_table_manage_keys(TABLE *table, int indexes_were_disabled,
-+ enum enum_enable_or_disable keys_onoff)
-+{
-+ int error= 0;
-+ DBUG_ENTER("alter_table_manage_keys");
-+ DBUG_PRINT("enter", ("table=%p were_disabled=%d on_off=%d",
-+ table, indexes_were_disabled, keys_onoff));
-+
-+ switch (keys_onoff) {
-+ case ENABLE:
-+ error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
-+ break;
-+ case LEAVE_AS_IS:
-+ if (!indexes_were_disabled)
-+ break;
-+ /* fall-through: disabled indexes */
-+ case DISABLE:
-+ error= table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
-+ }
-+
-+ if (error == HA_ERR_WRONG_COMMAND)
-+ {
-+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
-+ table->s->table_name.str);
-+ error= 0;
-+ } else if (error)
-+ table->file->print_error(error, MYF(0));
-+
-+ DBUG_RETURN(error);
-+}
-+
-+
-+/**
-+ Prepare column and key definitions for CREATE TABLE in ALTER TABLE.
-+
-+ This function transforms parse output of ALTER TABLE - lists of
-+ columns and keys to add, drop or modify into, essentially,
-+ CREATE TABLE definition - a list of columns and keys of the new
-+ table. While doing so, it also performs some (bug not all)
-+ semantic checks.
-+
-+ This function is invoked when we know that we're going to
-+ perform ALTER TABLE via a temporary table -- i.e. fast ALTER TABLE
-+ is not possible, perhaps because the ALTER statement contains
-+ instructions that require change in table data, not only in
-+ table definition or indexes.
-+
-+ @param[in,out] thd thread handle. Used as a memory pool
-+ and source of environment information.
-+ @param[in] table the source table, open and locked
-+ Used as an interface to the storage engine
-+ to acquire additional information about
-+ the original table.
-+ @param[in,out] create_info A blob with CREATE/ALTER TABLE
-+ parameters
-+ @param[in,out] alter_info Another blob with ALTER/CREATE parameters.
-+ Originally create_info was used only in
-+ CREATE TABLE and alter_info only in ALTER TABLE.
-+ But since ALTER might end-up doing CREATE,
-+ this distinction is gone and we just carry
-+ around two structures.
-+
-+ @return
-+ Fills various create_info members based on information retrieved
-+ from the storage engine.
-+ Sets create_info->varchar if the table has a VARCHAR column.
-+ Prepares alter_info->create_list and alter_info->key_list with
-+ columns and keys of the new table.
-+ @retval TRUE error, out of memory or a semantical error in ALTER
-+ TABLE instructions
-+ @retval FALSE success
-+*/
-+
-+static bool
-+mysql_prepare_alter_table(THD *thd, TABLE *table,
-+ HA_CREATE_INFO *create_info,
-+ Alter_info *alter_info)
-+{
-+ /* New column definitions are added here */
-+ List<Create_field> new_create_list;
-+ /* New key definitions are added here */
-+ List<Key> new_key_list;
-+ List_iterator<Alter_drop> drop_it(alter_info->drop_list);
-+ List_iterator<Create_field> def_it(alter_info->create_list);
-+ List_iterator<Alter_column> alter_it(alter_info->alter_list);
-+ List_iterator<Key> key_it(alter_info->key_list);
-+ List_iterator<Create_field> find_it(new_create_list);
-+ List_iterator<Create_field> field_it(new_create_list);
-+ List<Key_part_spec> key_parts;
-+ uint db_create_options= (table->s->db_create_options
-+ & ~(HA_OPTION_PACK_RECORD));
-+ uint used_fields= create_info->used_fields;
-+ KEY *key_info=table->key_info;
-+ bool rc= TRUE;
-+
-+ DBUG_ENTER("mysql_prepare_alter_table");
-+
-+ create_info->varchar= FALSE;
-+ /* Let new create options override the old ones */
-+ if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
-+ create_info->min_rows= table->s->min_rows;
-+ if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
-+ create_info->max_rows= table->s->max_rows;
-+ if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
-+ create_info->avg_row_length= table->s->avg_row_length;
-+ if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
-+ create_info->default_table_charset= table->s->table_charset;
-+ if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
-+ {
-+ /* Table has an autoincrement, copy value to new table */
-+ table->file->info(HA_STATUS_AUTO);
-+ create_info->auto_increment_value= table->file->stats.auto_increment_value;
-+ }
-+ if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
-+ create_info->key_block_size= table->s->key_block_size;
-+
-+ if (!create_info->tablespace && create_info->storage_media != HA_SM_MEMORY)
-+ {
-+ char *tablespace= static_cast<char *>(thd->alloc(FN_LEN + 1));
-+ /*
-+ Regular alter table of disk stored table (no tablespace/storage change)
-+ Copy tablespace name
-+ */
-+ if (tablespace &&
-+ (table->file->get_tablespace_name(thd, tablespace, FN_LEN)))
-+ create_info->tablespace= tablespace;
-+ }
-+ restore_record(table, s->default_values); // Empty record for DEFAULT
-+ Create_field *def;
-+
-+ /*
-+ First collect all fields from table which isn't in drop_list
-+ */
-+ Field **f_ptr,*field;
-+ for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
-+ {
-+ if (field->type() == MYSQL_TYPE_STRING)
-+ create_info->varchar= TRUE;
-+ /* Check if field should be dropped */
-+ Alter_drop *drop;
-+ drop_it.rewind();
-+ while ((drop=drop_it++))
-+ {
-+ if (drop->type == Alter_drop::COLUMN &&
-+ !my_strcasecmp(system_charset_info,field->field_name, drop->name))
-+ {
-+ /* Reset auto_increment value if it was dropped */
-+ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
-+ !(used_fields & HA_CREATE_USED_AUTO))
-+ {
-+ create_info->auto_increment_value=0;
-+ create_info->used_fields|=HA_CREATE_USED_AUTO;
-+ }
-+ break;
-+ }
-+ }
-+ if (drop)
-+ {
-+ drop_it.remove();
-+ continue;
-+ }
-+ /* Check if field is changed */
-+ def_it.rewind();
-+ while ((def=def_it++))
-+ {
-+ if (def->change &&
-+ !my_strcasecmp(system_charset_info,field->field_name, def->change))
-+ break;
-+ }
-+ if (def)
-+ { // Field is changed
-+ def->field=field;
-+ if (!def->after)
-+ {
-+ new_create_list.push_back(def);
-+ def_it.remove();
-+ }
-+ }
-+ else
-+ {
-+ /*
-+ This field was not dropped and not changed, add it to the list
-+ for the new table.
-+ */
-+ def= new Create_field(field, field);
-+ new_create_list.push_back(def);
-+ alter_it.rewind(); // Change default if ALTER
-+ Alter_column *alter;
-+ while ((alter=alter_it++))
-+ {
-+ if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
-+ break;
-+ }
-+ if (alter)
-+ {
-+ if (def->sql_type == MYSQL_TYPE_BLOB)
-+ {
-+ my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
-+ goto err;
-+ }
-+ if ((def->def=alter->def)) // Use new default
-+ def->flags&= ~NO_DEFAULT_VALUE_FLAG;
-+ else
-+ def->flags|= NO_DEFAULT_VALUE_FLAG;
-+ alter_it.remove();
-+ }
-+ }
-+ }
-+ def_it.rewind();
-+ while ((def=def_it++)) // Add new columns
-+ {
-+ if (def->change && ! def->field)
-+ {
-+ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
-+ goto err;
-+ }
-+ /*
-+ Check that the DATE/DATETIME not null field we are going to add is
-+ either has a default value or the '0000-00-00' is allowed by the
-+ set sql mode.
-+ If the '0000-00-00' value isn't allowed then raise the error_if_not_empty
-+ flag to allow ALTER TABLE only if the table to be altered is empty.
-+ */
-+ if ((def->sql_type == MYSQL_TYPE_DATE ||
-+ def->sql_type == MYSQL_TYPE_NEWDATE ||
-+ def->sql_type == MYSQL_TYPE_DATETIME) &&
-+ !alter_info->datetime_field &&
-+ !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
-+ thd->variables.sql_mode & MODE_NO_ZERO_DATE)
-+ {
-+ alter_info->datetime_field= def;
-+ alter_info->error_if_not_empty= TRUE;
-+ }
-+ if (!def->after)
-+ new_create_list.push_back(def);
-+ else if (def->after == first_keyword)
-+ new_create_list.push_front(def);
-+ else
-+ {
-+ Create_field *find;
-+ find_it.rewind();
-+ while ((find=find_it++)) // Add new columns
-+ {
-+ if (!my_strcasecmp(system_charset_info,def->after, find->field_name))
-+ break;
-+ }
-+ if (!find)
-+ {
-+ my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
-+ goto err;
-+ }
-+ find_it.after(def); // Put element after this
-+ alter_info->change_level= ALTER_TABLE_DATA_CHANGED;
-+ }
-+ }
-+ if (alter_info->alter_list.elements)
-+ {
-+ my_error(ER_BAD_FIELD_ERROR, MYF(0),
-+ alter_info->alter_list.head()->name, table->s->table_name.str);
-+ goto err;
-+ }
-+ if (!new_create_list.elements)
-+ {
-+ my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
-+ MYF(0));
-+ goto err;
-+ }
-+
-+ /*
-+ Collect all keys which isn't in drop list. Add only those
-+ for which some fields exists.
-+ */
-+
-+ for (uint i=0 ; i < table->s->keys ; i++,key_info++)
-+ {
-+ char *key_name= key_info->name;
-+ Alter_drop *drop;
-+ drop_it.rewind();
-+ while ((drop=drop_it++))
-+ {
-+ if (drop->type == Alter_drop::KEY &&
-+ !my_strcasecmp(system_charset_info,key_name, drop->name))
-+ break;
-+ }
-+ if (drop)
-+ {
-+ drop_it.remove();
-+ continue;
-+ }
-+
-+ KEY_PART_INFO *key_part= key_info->key_part;
-+ key_parts.empty();
-+ for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
-+ {
-+ if (!key_part->field)
-+ continue; // Wrong field (from UNIREG)
-+ const char *key_part_name=key_part->field->field_name;
-+ Create_field *cfield;
-+ field_it.rewind();
-+ while ((cfield=field_it++))
-+ {
-+ if (cfield->change)
-+ {
-+ if (!my_strcasecmp(system_charset_info, key_part_name,
-+ cfield->change))
-+ break;
-+ }
-+ else if (!my_strcasecmp(system_charset_info,
-+ key_part_name, cfield->field_name))
-+ break;
-+ }
-+ if (!cfield)
-+ continue; // Field is removed
-+ uint key_part_length=key_part->length;
-+ if (cfield->field) // Not new field
-+ {
-+ /*
-+ If the field can't have only a part used in a key according to its
-+ new type, or should not be used partially according to its
-+ previous type, or the field length is less than the key part
-+ length, unset the key part length.
-+
-+ We also unset the key part length if it is the same as the
-+ old field's length, so the whole new field will be used.
-+
-+ BLOBs may have cfield->length == 0, which is why we test it before
-+ checking whether cfield->length < key_part_length (in chars).
-+ */
-+ if (!Field::type_can_have_key_part(cfield->field->type()) ||
-+ !Field::type_can_have_key_part(cfield->sql_type) ||
-+ /* spatial keys can't have sub-key length */
-+ (key_info->flags & HA_SPATIAL) ||
-+ (cfield->field->field_length == key_part_length &&
-+ !f_is_blob(key_part->key_type)) ||
-+ (cfield->length && (cfield->length < key_part_length /
-+ key_part->field->charset()->mbmaxlen)))
-+ key_part_length= 0; // Use whole field
-+ }
-+ key_part_length /= key_part->field->charset()->mbmaxlen;
-+ key_parts.push_back(new Key_part_spec(cfield->field_name,
-+ key_part_length));
-+ }
-+ if (key_parts.elements)
-+ {
-+ KEY_CREATE_INFO key_create_info;
-+ Key *key;
-+ enum Key::Keytype key_type;
-+ bzero((char*) &key_create_info, sizeof(key_create_info));
-+
-+ key_create_info.algorithm= key_info->algorithm;
-+ if (key_info->flags & HA_USES_BLOCK_SIZE)
-+ key_create_info.block_size= key_info->block_size;
-+ if (key_info->flags & HA_USES_PARSER)
-+ key_create_info.parser_name= *plugin_name(key_info->parser);
-+
-+ if (key_info->flags & HA_SPATIAL)
-+ key_type= Key::SPATIAL;
-+ else if (key_info->flags & HA_NOSAME)
-+ {
-+ if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
-+ key_type= Key::PRIMARY;
-+ else
-+ key_type= Key::UNIQUE;
-+ }
-+ else if (key_info->flags & HA_FULLTEXT)
-+ key_type= Key::FULLTEXT;
-+ else
-+ key_type= Key::MULTIPLE;
-+
-+ key= new Key(key_type, key_name,
-+ &key_create_info,
-+ test(key_info->flags & HA_GENERATED_KEY),
-+ key_parts);
-+ new_key_list.push_back(key);
-+ }
-+ }
-+ {
-+ Key *key;
-+ while ((key=key_it++)) // Add new keys
-+ {
-+ if (key->type != Key::FOREIGN_KEY)
-+ new_key_list.push_back(key);
-+ if (key->name &&
-+ !my_strcasecmp(system_charset_info,key->name,primary_key_name))
-+ {
-+ my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name);
-+ goto err;
-+ }
-+ }
-+ }
-+
-+ if (alter_info->drop_list.elements)
-+ {
-+ my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
-+ alter_info->drop_list.head()->name);
-+ goto err;
-+ }
-+ if (alter_info->alter_list.elements)
-+ {
-+ my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
-+ alter_info->alter_list.head()->name);
-+ goto err;
-+ }
-+
-+ if (!create_info->comment.str)
-+ {
-+ create_info->comment.str= table->s->comment.str;
-+ create_info->comment.length= table->s->comment.length;
-+ }
-+
-+ table->file->update_create_info(create_info);
-+ if ((create_info->table_options &
-+ (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
-+ (used_fields & HA_CREATE_USED_PACK_KEYS))
-+ db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
-+ if (create_info->table_options &
-+ (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
-+ db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
-+ if (create_info->table_options &
-+ (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
-+ db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
-+ HA_OPTION_NO_DELAY_KEY_WRITE);
-+ create_info->table_options|= db_create_options;
-+
-+ if (table->s->tmp_table)
-+ create_info->options|=HA_LEX_CREATE_TMP_TABLE;
-+
-+ rc= FALSE;
-+ alter_info->create_list.swap(new_create_list);
-+ alter_info->key_list.swap(new_key_list);
-+err:
-+ DBUG_RETURN(rc);
-+}
-+
-+
-+/*
-+ Alter table
-+
-+ SYNOPSIS
-+ mysql_alter_table()
-+ thd Thread handle
-+ new_db If there is a RENAME clause
-+ new_name If there is a RENAME clause
-+ create_info Information from the parsing phase about new
-+ table properties.
-+ table_list The table to change.
-+ alter_info Lists of fields, keys to be changed, added
-+ or dropped.
-+ order_num How many ORDER BY fields has been specified.
-+ order List of fields to ORDER BY.
-+ ignore Whether we have ALTER IGNORE TABLE
-+
-+ DESCRIPTION
-+ This is a veery long function and is everything but the kitchen sink :)
-+ It is used to alter a table and not only by ALTER TABLE but also
-+ CREATE|DROP INDEX are mapped on this function.
-+
-+ When the ALTER TABLE statement just does a RENAME or ENABLE|DISABLE KEYS,
-+ or both, then this function short cuts its operation by renaming
-+ the table and/or enabling/disabling the keys. In this case, the FRM is
-+ not changed, directly by mysql_alter_table. However, if there is a
-+ RENAME + change of a field, or an index, the short cut is not used.
-+ See how `create_list` is used to generate the new FRM regarding the
-+ structure of the fields. The same is done for the indices of the table.
-+
-+ Important is the fact, that this function tries to do as little work as
-+ possible, by finding out whether a intermediate table is needed to copy
-+ data into and when finishing the altering to use it as the original table.
-+ For this reason the function compare_tables() is called, which decides
-+ based on all kind of data how similar are the new and the original
-+ tables.
-+
-+ RETURN VALUES
-+ FALSE OK
-+ TRUE Error
-+*/
-+
-+bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
-+ HA_CREATE_INFO *create_info,
-+ TABLE_LIST *table_list,
-+ Alter_info *alter_info,
-+ uint order_num, ORDER *order, bool ignore)
-+{
-+ TABLE *table, *new_table= 0, *name_lock= 0;
-+ int error= 0;
-+ char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1];
-+ char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
-+ char index_file[FN_REFLEN], data_file[FN_REFLEN];
-+ char path[FN_REFLEN + 1];
-+ char reg_path[FN_REFLEN+1];
-+ ha_rows copied,deleted;
-+ handlerton *old_db_type, *new_db_type, *save_old_db_type;
-+ legacy_db_type table_type;
-+ frm_type_enum frm_type;
-+ enum_alter_table_change_level need_copy_table= ALTER_TABLE_METADATA_ONLY;
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ uint fast_alter_partition= 0;
-+ bool partition_changed= FALSE;
-+#endif
-+ bool need_lock_for_indexes= TRUE;
-+ KEY *key_info_buffer;
-+ uint index_drop_count= 0;
-+ uint *index_drop_buffer= NULL;
-+ uint index_add_count= 0;
-+ uint *index_add_buffer= NULL;
-+ uint candidate_key_count= 0;
-+ bool no_pk;
-+ DBUG_ENTER("mysql_alter_table");
-+
-+ /*
-+ Check if we attempt to alter mysql.slow_log or
-+ mysql.general_log table and return an error if
-+ it is the case.
-+ TODO: this design is obsolete and will be removed.
-+ */
-+ if (table_list && table_list->db && table_list->table_name)
-+ {
-+ int table_kind= 0;
-+
-+ table_kind= check_if_log_table(table_list->db_length, table_list->db,
-+ table_list->table_name_length,
-+ table_list->table_name, 0);
-+
-+ if (table_kind)
-+ {
-+ /* Disable alter of enabled log tables */
-+ if (logger.is_log_table_enabled(table_kind))
-+ {
-+ my_error(ER_BAD_LOG_STATEMENT, MYF(0), "ALTER");
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* Disable alter of log tables to unsupported engine */
-+ if ((create_info->used_fields & HA_CREATE_USED_ENGINE) &&
-+ (!create_info->db_type || /* unknown engine */
-+ !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
-+ {
-+ my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (alter_info->flags & ALTER_PARTITION)
-+ {
-+ my_error(ER_WRONG_USAGE, MYF(0), "PARTITION", "log table");
-+ DBUG_RETURN(TRUE);
-+ }
-+#endif
-+ }
-+ }
-+
-+ /*
-+ Assign variables table_name, new_name, db, new_db, path, reg_path
-+ to simplify further comparisions: we want to see if it's a RENAME
-+ later just by comparing the pointers, avoiding the need for strcmp.
-+ */
-+ thd_proc_info(thd, "init");
-+ table_name=table_list->table_name;
-+ alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
-+ db=table_list->db;
-+ if (!new_db || !my_strcasecmp(table_alias_charset, new_db, db))
-+ new_db= db;
-+ build_table_filename(reg_path, sizeof(reg_path) - 1, db, table_name, reg_ext, 0);
-+ build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0);
-+
-+ mysql_ha_rm_tables(thd, table_list, FALSE);
-+
-+ /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
-+ if (alter_info->tablespace_op != NO_TABLESPACE_OP)
-+ /* Conditionally writes to binlog. */
-+ DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
-+ alter_info->tablespace_op));
-+ strxnmov(new_name_buff, sizeof (new_name_buff) - 1, mysql_data_home, "/", db,
-+ "/", table_name, reg_ext, NullS);
-+ (void) unpack_filename(new_name_buff, new_name_buff);
-+ /*
-+ If this is just a rename of a view, short cut to the
-+ following scenario: 1) lock LOCK_open 2) do a RENAME
-+ 2) unlock LOCK_open.
-+ This is a copy-paste added to make sure
-+ ALTER (sic:) TABLE .. RENAME works for views. ALTER VIEW is handled
-+ as an independent branch in mysql_execute_command. The need
-+ for a copy-paste arose because the main code flow of ALTER TABLE
-+ ... RENAME tries to use open_ltable, which does not work for views
-+ (open_ltable was never modified to merge table lists of child tables
-+ into the main table list, like open_tables does).
-+ This code is wrong and will be removed, please do not copy.
-+ */
-+ frm_type= mysql_frm_type(thd, new_name_buff, &table_type);
-+ /* Rename a view */
-+ /* Sic: there is a race here */
-+ if (frm_type == FRMTYPE_VIEW && !(alter_info->flags & ~ALTER_RENAME))
-+ {
-+ /*
-+ The following branch handles "ALTER VIEW v1 /no arguments/;"
-+ This feature is not documented one.
-+ However, before "OPTIMIZE TABLE t1;" was implemented,
-+ ALTER TABLE with no alter_specifications was used to force-rebuild
-+ the table. That's why this grammar is allowed. That's why we ignore
-+ it for views. So just do nothing in such a case.
-+ */
-+ if (!new_name)
-+ {
-+ my_ok(thd);
-+ DBUG_RETURN(FALSE);
-+ }
-+
-+ /*
-+ Avoid problems with a rename on a table that we have locked or
-+ if the user is trying to to do this in a transcation context
-+ */
-+
-+ if (thd->locked_tables || thd->active_transaction())
-+ {
-+ my_message(ER_LOCK_OR_ACTIVE_TRANSACTION,
-+ ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ if (wait_if_global_read_lock(thd,0,1))
-+ DBUG_RETURN(TRUE);
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (lock_table_names(thd, table_list))
-+ {
-+ error= 1;
-+ goto view_err;
-+ }
-+
-+ if (!do_rename(thd, table_list, new_db, new_name, new_name, 1))
-+ {
-+ if (mysql_bin_log.is_open())
-+ {
-+ thd->clear_error();
-+ Query_log_event qinfo(thd, thd->query(), thd->query_length(),
-+ 0, FALSE, 0);
-+ if ((error= mysql_bin_log.write(&qinfo)))
-+ goto view_err_unlock;
-+ }
-+ my_ok(thd);
-+ }
-+
-+view_err_unlock:
-+ unlock_table_names(thd, table_list, (TABLE_LIST*) 0);
-+
-+view_err:
-+ pthread_mutex_unlock(&LOCK_open);
-+ start_waiting_global_read_lock(thd);
-+ DBUG_RETURN(error);
-+ }
-+
-+ if (!(table= open_n_lock_single_table(thd, table_list, TL_WRITE_ALLOW_READ)))
-+ DBUG_RETURN(TRUE);
-+ table->use_all_columns();
-+
-+ /*
-+ Prohibit changing of the UNION list of a non-temporary MERGE table
-+ under LOCK tables. It would be quite difficult to reuse a shrinked
-+ set of tables from the old table or to open a new TABLE object for
-+ an extended list and verify that they belong to locked tables.
-+ */
-+ if (thd->locked_tables &&
-+ (create_info->used_fields & HA_CREATE_USED_UNION) &&
-+ (table->s->tmp_table == NO_TMP_TABLE))
-+ {
-+ my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ /* Check that we are not trying to rename to an existing table */
-+ if (new_name)
-+ {
-+ DBUG_PRINT("info", ("new_db.new_name: '%s'.'%s'", new_db, new_name));
-+ strmov(new_name_buff,new_name);
-+ strmov(new_alias= new_alias_buff, new_name);
-+ if (lower_case_table_names)
-+ {
-+ if (lower_case_table_names != 2)
-+ {
-+ my_casedn_str(files_charset_info, new_name_buff);
-+ new_alias= new_name; // Create lower case table name
-+ }
-+ my_casedn_str(files_charset_info, new_name);
-+ }
-+ if (new_db == db &&
-+ !my_strcasecmp(table_alias_charset, new_name_buff, table_name))
-+ {
-+ /*
-+ Source and destination table names are equal: make later check
-+ easier.
-+ */
-+ new_alias= new_name= table_name;
-+ }
-+ else
-+ {
-+ if (table->s->tmp_table != NO_TMP_TABLE)
-+ {
-+ if (find_temporary_table(thd,new_db,new_name_buff))
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name_buff);
-+ DBUG_RETURN(TRUE);
-+ }
-+ }
-+ else
-+ {
-+ if (lock_table_name_if_not_cached(thd, new_db, new_name, &name_lock))
-+ DBUG_RETURN(TRUE);
-+ if (!name_lock)
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
-+ DBUG_RETURN(TRUE);
-+ }
-+
-+ build_table_filename(new_name_buff, sizeof(new_name_buff) - 1,
-+ new_db, new_name_buff, reg_ext, 0);
-+ if (!access(new_name_buff, F_OK))
-+ {
-+ /* Table will be closed in do_command() */
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias);
-+ goto err;
-+ }
-+ }
-+ }
-+ }
-+ else
-+ {
-+ new_alias= (lower_case_table_names == 2) ? alias : table_name;
-+ new_name= table_name;
-+ }
-+
-+ old_db_type= table->s->db_type();
-+ if (!create_info->db_type)
-+ {
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (table->part_info &&
-+ create_info->used_fields & HA_CREATE_USED_ENGINE)
-+ {
-+ /*
-+ This case happens when the user specified
-+ ENGINE = x where x is a non-existing storage engine
-+ We set create_info->db_type to default_engine_type
-+ to ensure we don't change underlying engine type
-+ due to a erroneously given engine name.
-+ */
-+ create_info->db_type= table->part_info->default_engine_type;
-+ }
-+ else
-+#endif
-+ create_info->db_type= old_db_type;
-+ }
-+
-+ if (check_engine(thd, new_name, create_info))
-+ goto err;
-+ new_db_type= create_info->db_type;
-+
-+ if ((new_db_type != old_db_type ||
-+ alter_info->flags & ALTER_PARTITION) &&
-+ !table->file->can_switch_engines())
-+ {
-+ my_error(ER_ROW_IS_REFERENCED, MYF(0));
-+ goto err;
-+ }
-+
-+ /*
-+ If this is an ALTER TABLE and no explicit row type specified reuse
-+ the table's row type.
-+ Note : this is the same as if the row type was specified explicitly.
-+ */
-+ if (create_info->row_type == ROW_TYPE_NOT_USED)
-+ {
-+ /* ALTER TABLE without explicit row type */
-+ create_info->row_type= table->s->row_type;
-+ }
-+ else
-+ {
-+ /* ALTER TABLE with specific row type */
-+ create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
-+ }
-+
-+ DBUG_PRINT("info", ("old type: %s new type: %s",
-+ ha_resolve_storage_engine_name(old_db_type),
-+ ha_resolve_storage_engine_name(new_db_type)));
-+ if (ha_check_storage_engine_flag(old_db_type, HTON_ALTER_NOT_SUPPORTED) ||
-+ ha_check_storage_engine_flag(new_db_type, HTON_ALTER_NOT_SUPPORTED))
-+ {
-+ DBUG_PRINT("info", ("doesn't support alter"));
-+ my_error(ER_ILLEGAL_HA, MYF(0), table_name);
-+ goto err;
-+ }
-+
-+ thd_proc_info(thd, "setup");
-+ if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
-+ !table->s->tmp_table) // no need to touch frm
-+ {
-+ switch (alter_info->keys_onoff) {
-+ case LEAVE_AS_IS:
-+ break;
-+ case ENABLE:
-+ /*
-+ wait_while_table_is_used() ensures that table being altered is
-+ opened only by this thread and that TABLE::TABLE_SHARE::version
-+ of TABLE object corresponding to this table is 0.
-+ The latter guarantees that no DML statement will open this table
-+ until ALTER TABLE finishes (i.e. until close_thread_tables())
-+ while the fact that the table is still open gives us protection
-+ from concurrent DDL statements.
-+ */
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000););
-+ error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
-+ /* COND_refresh will be signaled in close_thread_tables() */
-+ break;
-+ case DISABLE:
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
-+ /* COND_refresh will be signaled in close_thread_tables() */
-+ break;
-+ default:
-+ DBUG_ASSERT(FALSE);
-+ error= 0;
-+ break;
-+ }
-+ if (error == HA_ERR_WRONG_COMMAND)
-+ {
-+ error= 0;
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
-+ table->alias);
-+ }
-+
-+ /*
-+ Unlike to the above case close_cached_table() below will remove ALL
-+ instances of TABLE from table cache (it will also remove table lock
-+ held by this thread). So to make actual table renaming and writing
-+ to binlog atomic we have to put them into the same critical section
-+ protected by LOCK_open mutex. This also removes gap for races between
-+ access() and mysql_rename_table() calls.
-+ */
-+
-+ if (!error && (new_name != table_name || new_db != db))
-+ {
-+ thd_proc_info(thd, "rename");
-+
-+ /*
-+ Workaround InnoDB ending the transaction when the table instance
-+ is unlocked/closed (close_cached_table below), otherwise the trx
-+ state will differ between the server and storage engine layers.
-+ */
-+ ha_autocommit_or_rollback(thd, 0);
-+
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ /*
-+ Then do a 'simple' rename of the table. First we need to close all
-+ instances of 'source' table.
-+ */
-+ close_cached_table(thd, table);
-+ /*
-+ Then, we want check once again that target table does not exist.
-+ Actually the order of these two steps does not matter since
-+ earlier we took name-lock on the target table, so we do them
-+ in this particular order only to be consistent with 5.0, in which
-+ we don't take this name-lock and where this order really matters.
-+ TODO: Investigate if we need this access() check at all.
-+ */
-+ if (!access(new_name_buff,F_OK))
-+ {
-+ my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_name);
-+ error= -1;
-+ }
-+ else
-+ {
-+ *fn_ext(new_name)=0;
-+ if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
-+ error= -1;
-+ else if (Table_triggers_list::change_table_name(thd, db, table_name,
-+ new_db, new_alias))
-+ {
-+ VOID(mysql_rename_table(old_db_type, new_db, new_alias, db,
-+ table_name, 0));
-+ error= -1;
-+ }
-+ }
-+ }
-+ else
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+
-+ if (error == HA_ERR_WRONG_COMMAND)
-+ {
-+ error= 0;
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
-+ table->alias);
-+ }
-+
-+ if (!error)
-+ {
-+ error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
-+ if (!error)
-+ my_ok(thd);
-+ }
-+ else if (error > 0)
-+ {
-+ table->file->print_error(error, MYF(0));
-+ error= -1;
-+ }
-+ if (name_lock)
-+ unlink_open_table(thd, name_lock, FALSE);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ table_list->table= NULL; // For query cache
-+ query_cache_invalidate3(thd, table_list, 0);
-+ DBUG_RETURN(error);
-+ }
-+
-+ /* We have to do full alter table. */
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (prep_alter_part_table(thd, table, alter_info, create_info, old_db_type,
-+ &partition_changed, &fast_alter_partition))
-+ goto err;
-+#endif
-+ /*
-+ If the old table had partitions and we are doing ALTER TABLE ...
-+ engine= <new_engine>, the new table must preserve the original
-+ partitioning. That means that the new engine is still the
-+ partitioning engine, not the engine specified in the parser.
-+ This is discovered in prep_alter_part_table, which in such case
-+ updates create_info->db_type.
-+ Now we need to update the stack copy of create_info->db_type,
-+ as otherwise we won't be able to correctly move the files of the
-+ temporary table to the result table files.
-+ */
-+ new_db_type= create_info->db_type;
-+
-+ if (is_index_maintenance_unique (table, alter_info))
-+ need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+
-+ if (mysql_prepare_alter_table(thd, table, create_info, alter_info))
-+ goto err;
-+
-+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-+ need_copy_table= alter_info->change_level;
-+
-+ set_table_default_charset(thd, create_info, db);
-+
-+ if (thd->variables.old_alter_table
-+ || (table->s->db_type() != create_info->db_type)
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ || partition_changed
-+#endif
-+ )
-+ need_copy_table= ALTER_TABLE_DATA_CHANGED;
-+ else
-+ {
-+ enum_alter_table_change_level need_copy_table_res;
-+ /* Check how much the tables differ. */
-+ if (compare_tables(table, alter_info,
-+ create_info, order_num,
-+ &need_copy_table_res,
-+ &key_info_buffer,
-+ &index_drop_buffer, &index_drop_count,
-+ &index_add_buffer, &index_add_count,
-+ &candidate_key_count))
-+ goto err;
-+
-+ DBUG_EXECUTE_IF("alter_table_only_metadata_change", {
-+ if (need_copy_table_res != ALTER_TABLE_METADATA_ONLY)
-+ goto err; });
-+ DBUG_EXECUTE_IF("alter_table_only_index_change", {
-+ if (need_copy_table_res != ALTER_TABLE_INDEX_CHANGED)
-+ goto err; });
-+
-+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-+ need_copy_table= need_copy_table_res;
-+ }
-+
-+ /*
-+ If there are index changes only, try to do them online. "Index
-+ changes only" means also that the handler for the table does not
-+ change. The table is open and locked. The handler can be accessed.
-+ */
-+ if (need_copy_table == ALTER_TABLE_INDEX_CHANGED)
-+ {
-+ int pk_changed= 0;
-+ ulong alter_flags= 0;
-+ ulong needed_online_flags= 0;
-+ ulong needed_fast_flags= 0;
-+ KEY *key;
-+ uint *idx_p;
-+ uint *idx_end_p;
-+
-+ alter_flags= table->file->alter_table_flags(alter_info->flags);
-+ DBUG_PRINT("info", ("alter_flags: %lu", alter_flags));
-+ /* Check dropped indexes. */
-+ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
-+ idx_p < idx_end_p;
-+ idx_p++)
-+ {
-+ key= table->key_info + *idx_p;
-+ DBUG_PRINT("info", ("index dropped: '%s'", key->name));
-+ if (key->flags & HA_NOSAME)
-+ {
-+ /*
-+ Unique key. Check for "PRIMARY".
-+ or if dropping last unique key
-+ */
-+ if ((uint) (key - table->key_info) == table->s->primary_key)
-+ {
-+ DBUG_PRINT("info", ("Dropping primary key"));
-+ /* Primary key. */
-+ needed_online_flags|= HA_ONLINE_DROP_PK_INDEX;
-+ needed_fast_flags|= HA_ONLINE_DROP_PK_INDEX_NO_WRITES;
-+ pk_changed++;
-+ candidate_key_count--;
-+ }
-+ else
-+ {
-+ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
-+ bool is_candidate_key= true;
-+
-+ /* Non-primary unique key. */
-+ needed_online_flags|= HA_ONLINE_DROP_UNIQUE_INDEX;
-+ needed_fast_flags|= HA_ONLINE_DROP_UNIQUE_INDEX_NO_WRITES;
-+
-+ /*
-+ Check if all fields in key are declared
-+ NOT NULL and adjust candidate_key_count
-+ */
-+ for (KEY_PART_INFO *key_part= key->key_part;
-+ key_part < part_end;
-+ key_part++)
-+ is_candidate_key=
-+ (is_candidate_key &&
-+ (! table->field[key_part->fieldnr-1]->maybe_null()));
-+ if (is_candidate_key)
-+ candidate_key_count--;
-+ }
-+ }
-+ else
-+ {
-+ /* Non-unique key. */
-+ needed_online_flags|= HA_ONLINE_DROP_INDEX;
-+ needed_fast_flags|= HA_ONLINE_DROP_INDEX_NO_WRITES;
-+ }
-+ }
-+ no_pk= ((table->s->primary_key == MAX_KEY) ||
-+ (needed_online_flags & HA_ONLINE_DROP_PK_INDEX));
-+ /* Check added indexes. */
-+ for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
-+ idx_p < idx_end_p;
-+ idx_p++)
-+ {
-+ key= key_info_buffer + *idx_p;
-+ DBUG_PRINT("info", ("index added: '%s'", key->name));
-+ if (key->flags & HA_NOSAME)
-+ {
-+ /* Unique key */
-+
-+ KEY_PART_INFO *part_end= key->key_part + key->key_parts;
-+ bool is_candidate_key= true;
-+
-+ /*
-+ Check if all fields in key are declared
-+ NOT NULL
-+ */
-+ for (KEY_PART_INFO *key_part= key->key_part;
-+ key_part < part_end;
-+ key_part++)
-+ is_candidate_key=
-+ (is_candidate_key &&
-+ (! table->field[key_part->fieldnr]->maybe_null()));
-+
-+ /*
-+ Check for "PRIMARY"
-+ or if adding first unique key
-+ defined on non-nullable fields
-+ */
-+
-+ if ((!my_strcasecmp(system_charset_info,
-+ key->name, primary_key_name)) ||
-+ (no_pk && candidate_key_count == 0 && is_candidate_key))
-+ {
-+ DBUG_PRINT("info", ("Adding primary key"));
-+ /* Primary key. */
-+ needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
-+ needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
-+ pk_changed++;
-+ no_pk= false;
-+ }
-+ else
-+ {
-+ /* Non-primary unique key. */
-+ needed_online_flags|= HA_ONLINE_ADD_UNIQUE_INDEX;
-+ needed_fast_flags|= HA_ONLINE_ADD_UNIQUE_INDEX_NO_WRITES;
-+ }
-+ }
-+ else
-+ {
-+ /* Non-unique key. */
-+ needed_online_flags|= HA_ONLINE_ADD_INDEX;
-+ needed_fast_flags|= HA_ONLINE_ADD_INDEX_NO_WRITES;
-+ }
-+ }
-+
-+ if ((candidate_key_count > 0) &&
-+ (needed_online_flags & HA_ONLINE_DROP_PK_INDEX))
-+ {
-+ /*
-+ Dropped primary key when there is some other unique
-+ not null key that should be converted to primary key
-+ */
-+ needed_online_flags|= HA_ONLINE_ADD_PK_INDEX;
-+ needed_fast_flags|= HA_ONLINE_ADD_PK_INDEX_NO_WRITES;
-+ pk_changed= 2;
-+ }
-+
-+ DBUG_PRINT("info", ("needed_online_flags: 0x%lx, needed_fast_flags: 0x%lx",
-+ needed_online_flags, needed_fast_flags));
-+ /*
-+ Online or fast add/drop index is possible only if
-+ the primary key is not added and dropped in the same statement.
-+ Otherwise we have to recreate the table.
-+ need_copy_table is no-zero at this place.
-+ */
-+ if ( pk_changed < 2 )
-+ {
-+ if ((alter_flags & needed_online_flags) == needed_online_flags)
-+ {
-+ /* All required online flags are present. */
-+ need_copy_table= ALTER_TABLE_METADATA_ONLY;
-+ need_lock_for_indexes= FALSE;
-+ }
-+ else if ((alter_flags & needed_fast_flags) == needed_fast_flags)
-+ {
-+ /* All required fast flags are present. */
-+ need_copy_table= ALTER_TABLE_METADATA_ONLY;
-+ }
-+ }
-+ DBUG_PRINT("info", ("need_copy_table: %u need_lock: %d",
-+ need_copy_table, need_lock_for_indexes));
-+ }
-+
-+ /*
-+ better have a negative test here, instead of positive, like
-+ alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|...
-+ so that ALTER TABLE won't break when somebody will add new flag
-+ */
-+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-+ create_info->frm_only= 1;
-+
-+#ifdef WITH_PARTITION_STORAGE_ENGINE
-+ if (fast_alter_partition)
-+ {
-+ DBUG_ASSERT(!name_lock);
-+ DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
-+ create_info, table_list,
-+ db, table_name,
-+ fast_alter_partition));
-+ }
-+#endif
-+
-+ my_snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
-+ current_pid, thd->thread_id);
-+ /* Safety fix for innodb */
-+ if (lower_case_table_names)
-+ my_casedn_str(files_charset_info, tmp_name);
-+
-+ /*
-+ Handling of symlinked tables:
-+ If no rename:
-+ Create new data file and index file on the same disk as the
-+ old data and index files.
-+ Copy data.
-+ Rename new data file over old data file and new index file over
-+ old index file.
-+ Symlinks are not changed.
-+
-+ If rename:
-+ Create new data file and index file on the same disk as the
-+ old data and index files. Create also symlinks to point at
-+ the new tables.
-+ Copy data.
-+ At end, rename intermediate tables, and symlinks to intermediate
-+ table, to final table name.
-+ Remove old table and old symlinks
-+
-+ If rename is made to another database:
-+ Create new tables in new database.
-+ Copy data.
-+ Remove old table and symlinks.
-+ */
-+ if (!strcmp(db, new_db)) // Ignore symlink if db changed
-+ {
-+ if (create_info->index_file_name)
-+ {
-+ /* Fix index_file_name to have 'tmp_name' as basename */
-+ strmov(index_file, tmp_name);
-+ create_info->index_file_name=fn_same(index_file,
-+ create_info->index_file_name,
-+ 1);
-+ }
-+ if (create_info->data_file_name)
-+ {
-+ /* Fix data_file_name to have 'tmp_name' as basename */
-+ strmov(data_file, tmp_name);
-+ create_info->data_file_name=fn_same(data_file,
-+ create_info->data_file_name,
-+ 1);
-+ }
-+ }
-+ else
-+ create_info->data_file_name=create_info->index_file_name=0;
-+
-+ DEBUG_SYNC(thd, "alter_table_before_create_table_no_lock");
-+ /*
-+ Create a table with a temporary name.
-+ With create_info->frm_only == 1 this creates a .frm file only.
-+ We don't log the statement, it will be logged later.
-+ */
-+ tmp_disable_binlog(thd);
-+ error= mysql_create_table_no_lock(thd, new_db, tmp_name,
-+ create_info,
-+ alter_info,
-+ 1, 0);
-+ reenable_binlog(thd);
-+ if (error)
-+ goto err;
-+
-+ /* Open the table if we need to copy the data. */
-+ DBUG_PRINT("info", ("need_copy_table: %u", need_copy_table));
-+ if (need_copy_table != ALTER_TABLE_METADATA_ONLY)
-+ {
-+ if (table->s->tmp_table)
-+ {
-+ TABLE_LIST tbl;
-+ bzero((void*) &tbl, sizeof(tbl));
-+ tbl.db= new_db;
-+ tbl.table_name= tbl.alias= tmp_name;
-+ /* Table is in thd->temporary_tables */
-+ new_table= open_table(thd, &tbl, thd->mem_root, (bool*) 0,
-+ MYSQL_LOCK_IGNORE_FLUSH);
-+ }
-+ else
-+ {
-+ char path[FN_REFLEN + 1];
-+ /* table is a normal table: Create temporary table in same directory */
-+ build_table_filename(path, sizeof(path) - 1, new_db, tmp_name, "",
-+ FN_IS_TMP);
-+ /* Open our intermediate table */
-+ new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
-+ }
-+ if (!new_table)
-+ goto err1;
-+ /*
-+ Note: In case of MERGE table, we do not attach children. We do not
-+ copy data for MERGE tables. Only the children have data.
-+ */
-+ }
-+
-+ /* Copy the data if necessary. */
-+ thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
-+ thd->cuted_fields=0L;
-+ copied=deleted=0;
-+ /*
-+ We do not copy data for MERGE tables. Only the children have data.
-+ MERGE tables have HA_NO_COPY_ON_ALTER set.
-+ */
-+ if (new_table && !(new_table->file->ha_table_flags() & HA_NO_COPY_ON_ALTER))
-+ {
-+ /* We don't want update TIMESTAMP fields during ALTER TABLE. */
-+ new_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
-+ new_table->next_number_field=new_table->found_next_number_field;
-+ thd_proc_info(thd, "copy to tmp table");
-+ error= copy_data_between_tables(table, new_table,
-+ alter_info->create_list, ignore,
-+ order_num, order, &copied, &deleted,
-+ alter_info->keys_onoff,
-+ alter_info->error_if_not_empty);
-+ }
-+ else
-+ {
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ thd_proc_info(thd, "manage keys");
-+ alter_table_manage_keys(table, table->file->indexes_are_disabled(),
-+ alter_info->keys_onoff);
-+ error= ha_autocommit_or_rollback(thd, 0);
-+ if (end_active_trans(thd))
-+ error= 1;
-+ }
-+ thd->count_cuted_fields= CHECK_FIELD_IGNORE;
-+
-+ /* If we did not need to copy, we might still need to add/drop indexes. */
-+ if (! new_table)
-+ {
-+ uint *key_numbers;
-+ uint *keyno_p;
-+ KEY *key_info;
-+ KEY *key;
-+ uint *idx_p;
-+ uint *idx_end_p;
-+ KEY_PART_INFO *key_part;
-+ KEY_PART_INFO *part_end;
-+ DBUG_PRINT("info", ("No new_table, checking add/drop index"));
-+
-+ table->file->ha_prepare_for_alter();
-+ if (index_add_count)
-+ {
-+ /* The add_index() method takes an array of KEY structs. */
-+ key_info= (KEY*) thd->alloc(sizeof(KEY) * index_add_count);
-+ key= key_info;
-+ for (idx_p= index_add_buffer, idx_end_p= idx_p + index_add_count;
-+ idx_p < idx_end_p;
-+ idx_p++, key++)
-+ {
-+ /* Copy the KEY struct. */
-+ *key= key_info_buffer[*idx_p];
-+ /* Fix the key parts. */
-+ part_end= key->key_part + key->key_parts;
-+ for (key_part= key->key_part; key_part < part_end; key_part++)
-+ key_part->field= table->field[key_part->fieldnr];
-+ }
-+ /* Add the indexes. */
-+ if ((error= table->file->add_index(table, key_info, index_add_count)))
-+ {
-+ /*
-+ Exchange the key_info for the error message. If we exchange
-+ key number by key name in the message later, we need correct info.
-+ */
-+ KEY *save_key_info= table->key_info;
-+ table->key_info= key_info;
-+ table->file->print_error(error, MYF(0));
-+ table->key_info= save_key_info;
-+ goto err1;
-+ }
-+ }
-+ /*end of if (index_add_count)*/
-+
-+ if (index_drop_count)
-+ {
-+ /* The prepare_drop_index() method takes an array of key numbers. */
-+ key_numbers= (uint*) thd->alloc(sizeof(uint) * index_drop_count);
-+ keyno_p= key_numbers;
-+ /* Get the number of each key. */
-+ for (idx_p= index_drop_buffer, idx_end_p= idx_p + index_drop_count;
-+ idx_p < idx_end_p;
-+ idx_p++, keyno_p++)
-+ *keyno_p= *idx_p;
-+ /*
-+ Tell the handler to prepare for drop indexes.
-+ This re-numbers the indexes to get rid of gaps.
-+ */
-+ if ((error= table->file->prepare_drop_index(table, key_numbers,
-+ index_drop_count)))
-+ {
-+ table->file->print_error(error, MYF(0));
-+ goto err1;
-+ }
-+
-+ /* Tell the handler to finally drop the indexes. */
-+ if ((error= table->file->final_drop_index(table)))
-+ {
-+ table->file->print_error(error, MYF(0));
-+ goto err1;
-+ }
-+ }
-+ /*end of if (index_drop_count)*/
-+
-+ /*
-+ The final .frm file is already created as a temporary file
-+ and will be renamed to the original table name later.
-+ */
-+
-+ /* Need to commit before a table is unlocked (NDB requirement). */
-+ DBUG_PRINT("info", ("Committing before unlocking table"));
-+ if (ha_autocommit_or_rollback(thd, 0) || end_active_trans(thd))
-+ goto err1;
-+ }
-+ /*end of if (! new_table) for add/drop index*/
-+
-+ if (table->s->tmp_table != NO_TMP_TABLE)
-+ {
-+ /* We changed a temporary table */
-+ if (error)
-+ goto err1;
-+ /* Close lock if this is a transactional table */
-+ if (thd->lock)
-+ {
-+ mysql_unlock_tables(thd, thd->lock);
-+ thd->lock=0;
-+ }
-+ /*
-+ If LOCK TABLES list is not empty and contains this table,
-+ unlock the table and remove the table from this list.
-+ */
-+ mysql_lock_remove(thd, thd->locked_tables, table, FALSE);
-+ /* Remove link to old table and rename the new one */
-+ close_temporary_table(thd, table, 1, 1);
-+ /* Should pass the 'new_name' as we store table name in the cache */
-+ if (rename_temporary_table(thd, new_table, new_db, new_name))
-+ goto err1;
-+ /* We don't replicate alter table statement on temporary tables */
-+ if (!thd->current_stmt_binlog_row_based &&
-+ write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
-+ DBUG_RETURN(TRUE);
-+ goto end_temporary;
-+ }
-+
-+ if (new_table)
-+ {
-+ /*
-+ Close the intermediate table that will be the new table.
-+ Note that MERGE tables do not have their children attached here.
-+ */
-+ intern_close_table(new_table);
-+ my_free(new_table,MYF(0));
-+ }
-+ DEBUG_SYNC(thd, "alter_table_before_rename_result_table");
-+ VOID(pthread_mutex_lock(&LOCK_open));
-+ if (error)
-+ {
-+ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ goto err;
-+ }
-+
-+ /*
-+ Data is copied. Now we:
-+ 1) Wait until all other threads close old version of table.
-+ 2) Close instances of table open by this thread and replace them
-+ with exclusive name-locks.
-+ 3) Rename the old table to a temp name, rename the new one to the
-+ old name.
-+ 4) If we are under LOCK TABLES and don't do ALTER TABLE ... RENAME
-+ we reopen new version of table.
-+ 5) Write statement to the binary log.
-+ 6) If we are under LOCK TABLES and do ALTER TABLE ... RENAME we
-+ remove name-locks from list of open tables and table cache.
-+ 7) If we are not not under LOCK TABLES we rely on close_thread_tables()
-+ call to remove name-locks from table cache and list of open table.
-+ */
-+
-+ thd_proc_info(thd, "rename result table");
-+ my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
-+ current_pid, thd->thread_id);
-+ if (lower_case_table_names)
-+ my_casedn_str(files_charset_info, old_name);
-+
-+ wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME);
-+ close_data_files_and_morph_locks(thd, db, table_name);
-+
-+ error=0;
-+ save_old_db_type= old_db_type;
-+
-+ /*
-+ This leads to the storage engine (SE) not being notified for renames in
-+ mysql_rename_table(), because we just juggle with the FRM and nothing
-+ more. If we have an intermediate table, then we notify the SE that
-+ it should become the actual table. Later, we will recycle the old table.
-+ However, in case of ALTER TABLE RENAME there might be no intermediate
-+ table. This is when the old and new tables are compatible, according to
-+ compare_table(). Then, we need one additional call to
-+ mysql_rename_table() with flag NO_FRM_RENAME, which does nothing else but
-+ actual rename in the SE and the FRM is not touched. Note that, if the
-+ table is renamed and the SE is also changed, then an intermediate table
-+ is created and the additional call will not take place.
-+ */
-+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-+ {
-+ DBUG_ASSERT(new_db_type == old_db_type);
-+ /* This type cannot happen in regular ALTER. */
-+ new_db_type= old_db_type= NULL;
-+ }
-+ if (mysql_rename_table(old_db_type, db, table_name, db, old_name,
-+ FN_TO_IS_TMP))
-+ {
-+ error=1;
-+ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
-+ }
-+ else if (mysql_rename_table(new_db_type, new_db, tmp_name, new_db,
-+ new_alias, FN_FROM_IS_TMP) ||
-+ ((new_name != table_name || new_db != db) && // we also do rename
-+ (need_copy_table != ALTER_TABLE_METADATA_ONLY ||
-+ mysql_rename_table(save_old_db_type, db, table_name, new_db,
-+ new_alias, NO_FRM_RENAME)) &&
-+ Table_triggers_list::change_table_name(thd, db, table_name,
-+ new_db, new_alias)))
-+ {
-+ /* Try to get everything back. */
-+ error=1;
-+ VOID(quick_rm_table(new_db_type,new_db,new_alias, 0));
-+ VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
-+ VOID(mysql_rename_table(old_db_type, db, old_name, db, alias,
-+ FN_FROM_IS_TMP));
-+ }
-+
-+ if (error)
-+ {
-+ /* This shouldn't happen. But let us play it safe. */
-+ goto err_with_placeholders;
-+ }
-+
-+ if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
-+ {
-+ /*
-+ Now we have to inform handler that new .FRM file is in place.
-+ To do this we need to obtain a handler object for it.
-+ NO need to tamper with MERGE tables. The real open is done later.
-+ */
-+ TABLE *t_table;
-+ if (new_name != table_name || new_db != db)
-+ {
-+ table_list->alias= new_name;
-+ table_list->table_name= new_name;
-+ table_list->table_name_length= strlen(new_name);
-+ table_list->db= new_db;
-+ table_list->db_length= strlen(new_db);
-+ table_list->table= name_lock;
-+ if (reopen_name_locked_table(thd, table_list, FALSE))
-+ goto err_with_placeholders;
-+ t_table= table_list->table;
-+ }
-+ else
-+ {
-+ if (reopen_table(table))
-+ goto err_with_placeholders;
-+ t_table= table;
-+ }
-+ /* Tell the handler that a new frm file is in place. */
-+ if (t_table->file->ha_create_handler_files(path, NULL, CHF_INDEX_FLAG,
-+ create_info))
-+ goto err_with_placeholders;
-+ if (thd->locked_tables && new_name == table_name && new_db == db)
-+ {
-+ /*
-+ We are going to reopen table down on the road, so we have to restore
-+ state of the TABLE object which we used for obtaining of handler
-+ object to make it suitable for reopening.
-+ */
-+ DBUG_ASSERT(t_table == table);
-+ table->open_placeholder= 1;
-+ close_handle_and_leave_table_as_lock(table);
-+ }
-+ }
-+
-+ VOID(quick_rm_table(old_db_type, db, old_name, FN_IS_TMP));
-+
-+ if (thd->locked_tables && new_name == table_name && new_db == db)
-+ {
-+ thd->in_lock_tables= 1;
-+ error= reopen_tables(thd, 1, 1);
-+ thd->in_lock_tables= 0;
-+ if (error)
-+ goto err_with_placeholders;
-+ }
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+
-+ thd_proc_info(thd, "end");
-+
-+ DBUG_EXECUTE_IF("sleep_alter_before_main_binlog", my_sleep(6000000););
-+ DEBUG_SYNC(thd, "alter_table_before_main_binlog");
-+
-+ ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
-+ thd->query(), thd->query_length(),
-+ db, table_name);
-+
-+ DBUG_ASSERT(!(mysql_bin_log.is_open() &&
-+ thd->current_stmt_binlog_row_based &&
-+ (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
-+ if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
-+ DBUG_RETURN(TRUE);
-+
-+ if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
-+ {
-+ /*
-+ For the alter table to be properly flushed to the logs, we
-+ have to open the new table. If not, we get a problem on server
-+ shutdown. But we do not need to attach MERGE children.
-+ */
-+ char path[FN_REFLEN];
-+ TABLE *t_table;
-+ build_table_filename(path + 1, sizeof(path) - 1, new_db, table_name, "", 0);
-+ t_table= open_temporary_table(thd, path, new_db, tmp_name, 0);
-+ if (t_table)
-+ {
-+ intern_close_table(t_table);
-+ my_free(t_table, MYF(0));
-+ }
-+ else
-+ sql_print_warning("Could not open table %s.%s after rename\n",
-+ new_db,table_name);
-+ ha_flush_logs(old_db_type);
-+ }
-+ table_list->table=0; // For query cache
-+ query_cache_invalidate3(thd, table_list, 0);
-+
-+ if (thd->locked_tables && (new_name != table_name || new_db != db))
-+ {
-+ /*
-+ If are we under LOCK TABLES and did ALTER TABLE with RENAME we need
-+ to remove placeholders for the old table and for the target table
-+ from the list of open tables and table cache. If we are not under
-+ LOCK TABLES we can rely on close_thread_tables() doing this job.
-+ */
-+ pthread_mutex_lock(&LOCK_open);
-+ unlink_open_table(thd, table, FALSE);
-+ unlink_open_table(thd, name_lock, FALSE);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+
-+end_temporary:
-+ my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
-+ (ulong) (copied + deleted), (ulong) deleted,
-+ (ulong) thd->cuted_fields);
-+ my_ok(thd, copied + deleted, 0L, tmp_name);
-+ thd->some_tables_deleted=0;
-+ DBUG_RETURN(FALSE);
-+
-+err1:
-+ if (new_table)
-+ {
-+ /* close_temporary_table() frees the new_table pointer. */
-+ close_temporary_table(thd, new_table, 1, 1);
-+ }
-+ else
-+ VOID(quick_rm_table(new_db_type, new_db, tmp_name,
-+ create_info->frm_only
-+ ? FN_IS_TMP | FRM_ONLY
-+ : FN_IS_TMP));
-+
-+err:
-+ /*
-+ No default value was provided for a DATE/DATETIME field, the
-+ current sql_mode doesn't allow the '0000-00-00' value and
-+ the table to be altered isn't empty.
-+ Report error here.
-+ */
-+ if (alter_info->error_if_not_empty && thd->row_count)
-+ {
-+ const char *f_val= 0;
-+ enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
-+ switch (alter_info->datetime_field->sql_type)
-+ {
-+ case MYSQL_TYPE_DATE:
-+ case MYSQL_TYPE_NEWDATE:
-+ f_val= "0000-00-00";
-+ t_type= MYSQL_TIMESTAMP_DATE;
-+ break;
-+ case MYSQL_TYPE_DATETIME:
-+ f_val= "0000-00-00 00:00:00";
-+ t_type= MYSQL_TIMESTAMP_DATETIME;
-+ break;
-+ default:
-+ /* Shouldn't get here. */
-+ DBUG_ASSERT(0);
-+ }
-+ bool save_abort_on_warning= thd->abort_on_warning;
-+ thd->abort_on_warning= TRUE;
-+ make_truncated_value_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
-+ f_val, strlength(f_val), t_type,
-+ alter_info->datetime_field->field_name);
-+ thd->abort_on_warning= save_abort_on_warning;
-+ }
-+ if (name_lock)
-+ {
-+ pthread_mutex_lock(&LOCK_open);
-+ unlink_open_table(thd, name_lock, FALSE);
-+ pthread_mutex_unlock(&LOCK_open);
-+ }
-+ DBUG_RETURN(TRUE);
-+
-+err_with_placeholders:
-+ /*
-+ An error happened while we were holding exclusive name-lock on table
-+ being altered. To be safe under LOCK TABLES we should remove placeholders
-+ from list of open tables list and table cache.
-+ */
-+ unlink_open_table(thd, table, FALSE);
-+ if (name_lock)
-+ unlink_open_table(thd, name_lock, FALSE);
-+ VOID(pthread_mutex_unlock(&LOCK_open));
-+ DBUG_RETURN(TRUE);
-+}
-+/* mysql_alter_table */
-+
-+static int
-+copy_data_between_tables(TABLE *from,TABLE *to,
-+ List<Create_field> &create,
-+ bool ignore,
-+ uint order_num, ORDER *order,
-+ ha_rows *copied,
-+ ha_rows *deleted,
-+ enum enum_enable_or_disable keys_onoff,
-+ bool error_if_not_empty)
-+{
-+ int error;
-+ Copy_field *copy,*copy_end;
-+ ulong found_count,delete_count;
-+ THD *thd= current_thd;
-+ uint length= 0;
-+ SORT_FIELD *sortorder;
-+ READ_RECORD info;
-+ TABLE_LIST tables;
-+ List<Item> fields;
-+ List<Item> all_fields;
-+ ha_rows examined_rows;
-+ bool auto_increment_field_copied= 0;
-+ ulong save_sql_mode;
-+ ulonglong prev_insert_id;
-+ DBUG_ENTER("copy_data_between_tables");
-+
-+ /*
-+ Turn off recovery logging since rollback of an alter table is to
-+ delete the new table so there is no need to log the changes to it.
-+
-+ This needs to be done before external_lock
-+ */
-+ error= ha_enable_transaction(thd, FALSE);
-+ if (error)
-+ DBUG_RETURN(-1);
-+
-+ if (!(copy= new Copy_field[to->s->fields]))
-+ DBUG_RETURN(-1); /* purecov: inspected */
-+
-+ if (to->file->ha_external_lock(thd, F_WRLCK))
-+ DBUG_RETURN(-1);
-+
-+ /* We need external lock before we can disable/enable keys */
-+ alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
-+
-+ /* We can abort alter table for any table type */
-+ thd->abort_on_warning= !ignore && test(thd->variables.sql_mode &
-+ (MODE_STRICT_TRANS_TABLES |
-+ MODE_STRICT_ALL_TABLES));
-+
-+ from->file->info(HA_STATUS_VARIABLE);
-+ to->file->ha_start_bulk_insert(from->file->stats.records);
-+
-+ save_sql_mode= thd->variables.sql_mode;
-+
-+ List_iterator<Create_field> it(create);
-+ Create_field *def;
-+ copy_end=copy;
-+ for (Field **ptr=to->field ; *ptr ; ptr++)
-+ {
-+ def=it++;
-+ if (def->field)
-+ {
-+ if (*ptr == to->next_number_field)
-+ {
-+ auto_increment_field_copied= TRUE;
-+ /*
-+ If we are going to copy contents of one auto_increment column to
-+ another auto_increment column it is sensible to preserve zeroes.
-+ This condition also covers case when we are don't actually alter
-+ auto_increment column.
-+ */
-+ if (def->field == from->found_next_number_field)
-+ thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
-+ }
-+ (copy_end++)->set(*ptr,def->field,0);
-+ }
-+
-+ }
-+
-+ found_count=delete_count=0;
-+
-+ if (order)
-+ {
-+ if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
-+ {
-+ char warn_buff[MYSQL_ERRMSG_SIZE];
-+ my_snprintf(warn_buff, sizeof(warn_buff),
-+ "ORDER BY ignored as there is a user-defined clustered index"
-+ " in the table '%-.192s'", from->s->table_name.str);
-+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
-+ warn_buff);
-+ }
-+ else
-+ {
-+ from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
-+ MYF(MY_FAE | MY_ZEROFILL));
-+ bzero((char *) &tables, sizeof(tables));
-+ tables.table= from;
-+ tables.alias= tables.table_name= from->s->table_name.str;
-+ tables.db= from->s->db.str;
-+ error= 1;
-+
-+ if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
-+ setup_order(thd, thd->lex->select_lex.ref_pointer_array,
-+ &tables, fields, all_fields, order) ||
-+ !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
-+ (from->sort.found_records= filesort(thd, from, sortorder, length,
-+ (SQL_SELECT *) 0, HA_POS_ERROR,
-+ 1, &examined_rows)) ==
-+ HA_POS_ERROR)
-+ goto err;
-+ }
-+ };
-+
-+ /* Tell handler that we have values for all columns in the to table */
-+ to->use_all_columns();
-+ init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE);
-+ if (ignore)
-+ to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
-+ thd->row_count= 0;
-+ restore_record(to, s->default_values); // Create empty record
-+ while (!(error=info.read_record(&info)))
-+ {
-+ if (thd->killed)
-+ {
-+ thd->send_kill_message();
-+ error= 1;
-+ break;
-+ }
-+ thd->row_count++;
-+ /* Return error if source table isn't empty. */
-+ if (error_if_not_empty)
-+ {
-+ error= 1;
-+ break;
-+ }
-+ if (to->next_number_field)
-+ {
-+ if (auto_increment_field_copied)
-+ to->auto_increment_field_not_null= TRUE;
-+ else
-+ to->next_number_field->reset();
-+ }
-+
-+ for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
-+ {
-+ copy_ptr->do_copy(copy_ptr);
-+ }
-+ prev_insert_id= to->file->next_insert_id;
-+ error=to->file->ha_write_row(to->record[0]);
-+ to->auto_increment_field_not_null= FALSE;
-+ if (error)
-+ {
-+ if (!ignore ||
-+ to->file->is_fatal_error(error, HA_CHECK_DUP))
-+ {
-+ if (!to->file->is_fatal_error(error, HA_CHECK_DUP))
-+ {
-+ uint key_nr= to->file->get_dup_key(error);
-+ if ((int) key_nr >= 0)
-+ {
-+ const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
-+ if (key_nr == 0 &&
-+ (to->key_info[0].key_part[0].field->flags &
-+ AUTO_INCREMENT_FLAG))
-+ err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
-+ to->file->print_keydup_error(key_nr, err_msg);
-+ break;
-+ }
-+ }
-+
-+ to->file->print_error(error,MYF(0));
-+ break;
-+ }
-+ to->file->restore_auto_increment(prev_insert_id);
-+ delete_count++;
-+ }
-+ else
-+ found_count++;
-+ }
-+ end_read_record(&info);
-+ free_io_cache(from);
-+ delete [] copy; // This is never 0
-+
-+ if (to->file->ha_end_bulk_insert() && error <= 0)
-+ {
-+ to->file->print_error(my_errno,MYF(0));
-+ error=1;
-+ }
-+ to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
-+
-+ if (ha_enable_transaction(thd, TRUE))
-+ {
-+ error= 1;
-+ goto err;
-+ }
-+
-+ /*
-+ Ensure that the new table is saved properly to disk so that we
-+ can do a rename
-+ */
-+ if (ha_autocommit_or_rollback(thd, 0))
-+ error=1;
-+ if (end_active_trans(thd))
-+ error=1;
-+
-+ err:
-+ thd->variables.sql_mode= save_sql_mode;
-+ thd->abort_on_warning= 0;
-+ free_io_cache(from);
-+ *copied= found_count;
-+ *deleted=delete_count;
-+ to->file->ha_release_auto_increment();
-+ if (to->file->ha_external_lock(thd,F_UNLCK))
-+ error=1;
-+ DBUG_RETURN(error > 0 ? -1 : 0);
-+}
-+
-+
-+/*
-+ Recreates tables by calling mysql_alter_table().
-+
-+ SYNOPSIS
-+ mysql_recreate_table()
-+ thd Thread handler
-+ tables Tables to recreate
-+
-+ RETURN
-+ Like mysql_alter_table().
-+*/
-+bool mysql_recreate_table(THD *thd, TABLE_LIST *table_list)
-+{
-+ HA_CREATE_INFO create_info;
-+ Alter_info alter_info;
-+
-+ DBUG_ENTER("mysql_recreate_table");
-+ DBUG_ASSERT(!table_list->next_global);
-+ /*
-+ table_list->table has been closed and freed. Do not reference
-+ uninitialized data. open_tables() could fail.
-+ */
-+ table_list->table= NULL;
-+
-+ bzero((char*) &create_info, sizeof(create_info));
-+ create_info.row_type=ROW_TYPE_NOT_USED;
-+ create_info.default_table_charset=default_charset_info;
-+ /* Force alter table to recreate table */
-+ alter_info.flags= (ALTER_CHANGE_COLUMN | ALTER_RECREATE);
-+ DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
-+ table_list, &alter_info, 0,
-+ (ORDER *) 0, 0));
-+}
-+
-+
-+bool mysql_checksum_table(THD *thd, TABLE_LIST *tables,
-+ HA_CHECK_OPT *check_opt)
-+{
-+ TABLE_LIST *table;
-+ List<Item> field_list;
-+ Item *item;
-+ Protocol *protocol= thd->protocol;
-+ DBUG_ENTER("mysql_checksum_table");
-+
-+ field_list.push_back(item = new Item_empty_string("Table", NAME_LEN*2));
-+ item->maybe_null= 1;
-+ field_list.push_back(item= new Item_int("Checksum", (longlong) 1,
-+ MY_INT64_NUM_DECIMAL_DIGITS));
-+ item->maybe_null= 1;
-+ if (protocol->send_fields(&field_list,
-+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
-+ DBUG_RETURN(TRUE);
-+
-+ /* Open one table after the other to keep lock time as short as possible. */
-+ for (table= tables; table; table= table->next_local)
-+ {
-+ char table_name[NAME_LEN*2+2];
-+ TABLE *t;
-+
-+ strxmov(table_name, table->db ,".", table->table_name, NullS);
-+
-+ t= table->table= open_n_lock_single_table(thd, table, TL_READ);
-+ thd->clear_error(); // these errors shouldn't get client
-+
-+ protocol->prepare_for_resend();
-+ protocol->store(table_name, system_charset_info);
-+
-+ if (!t)
-+ {
-+ /* Table didn't exist */
-+ protocol->store_null();
-+ thd->clear_error();
-+ }
-+ else
-+ {
-+ if (t->file->ha_table_flags() & HA_HAS_CHECKSUM &&
-+ !(check_opt->flags & T_EXTEND))
-+ protocol->store((ulonglong)t->file->checksum());
-+ else if (!(t->file->ha_table_flags() & HA_HAS_CHECKSUM) &&
-+ (check_opt->flags & T_QUICK))
-+ protocol->store_null();
-+ else
-+ {
-+ /* calculating table's checksum */
-+ ha_checksum crc= 0;
-+ uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
-+
-+ t->use_all_columns();
-+
-+ if (t->file->ha_rnd_init(1))
-+ protocol->store_null();
-+ else
-+ {
-+ for (;;)
-+ {
-+ if (thd->killed)
-+ {
-+ /*
-+ we've been killed; let handler clean up, and remove the
-+ partial current row from the recordset (embedded lib)
-+ */
-+ t->file->ha_rnd_end();
-+ thd->protocol->remove_last_row();
-+ goto err;
-+ }
-+ ha_checksum row_crc= 0;
-+ int error= t->file->rnd_next(t->record[0]);
-+ if (unlikely(error))
-+ {
-+ if (error == HA_ERR_RECORD_DELETED)
-+ continue;
-+ break;
-+ }
-+ if (t->s->null_bytes)
-+ {
-+ /* fix undefined null bits */
-+ t->record[0][t->s->null_bytes-1] |= null_mask;
-+ if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
-+ t->record[0][0] |= 1;
-+
-+ row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
-+ }
-+
-+ for (uint i= 0; i < t->s->fields; i++ )
-+ {
-+ Field *f= t->field[i];
-+
-+ /*
-+ BLOB and VARCHAR have pointers in their field, we must convert
-+ to string; GEOMETRY is implemented on top of BLOB.
-+ BIT may store its data among NULL bits, convert as well.
-+ */
-+ switch (f->type()) {
-+ case MYSQL_TYPE_BLOB:
-+ case MYSQL_TYPE_VARCHAR:
-+ case MYSQL_TYPE_GEOMETRY:
-+ case MYSQL_TYPE_BIT:
-+ {
-+ String tmp;
-+ f->val_str(&tmp);
-+ row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
-+ tmp.length());
-+ break;
-+ }
-+ default:
-+ row_crc= my_checksum(row_crc, f->ptr, f->pack_length());
-+ break;
-+ }
-+ }
-+
-+ crc+= row_crc;
-+ }
-+ protocol->store((ulonglong)crc);
-+ t->file->ha_rnd_end();
-+ }
-+ }
-+ thd->clear_error();
-+ close_thread_tables(thd);
-+ table->table=0; // For query cache
-+ }
-+ if (protocol->write())
-+ goto err;
-+ }
-+
-+ my_eof(thd);
-+ DBUG_RETURN(FALSE);
-+
-+ err:
-+ close_thread_tables(thd); // Shouldn't be needed
-+ if (table)
-+ table->table=0;
-+ DBUG_RETURN(TRUE);
-+}
-+
-+static bool check_engine(THD *thd, const char *table_name,
-+ HA_CREATE_INFO *create_info)
-+{
-+ handlerton **new_engine= &create_info->db_type;
-+ handlerton *req_engine= *new_engine;
-+ bool no_substitution=
-+ test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION);
-+ if (!(*new_engine= ha_checktype(thd, ha_legacy_type(req_engine),
-+ no_substitution, 1)))
-+ return TRUE;
-+
-+ if (req_engine && req_engine != *new_engine)
-+ {
-+ push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
-+ ER_WARN_USING_OTHER_HANDLER,
-+ ER(ER_WARN_USING_OTHER_HANDLER),
-+ ha_resolve_storage_engine_name(*new_engine),
-+ table_name);
-+ }
-+ if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
-+ ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
-+ {
-+ if (create_info->used_fields & HA_CREATE_USED_ENGINE)
-+ {
-+ my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
-+ ha_resolve_storage_engine_name(*new_engine), "TEMPORARY");
-+ *new_engine= 0;
-+ return TRUE;
-+ }
-+ *new_engine= myisam_hton;
-+ }
-+ return FALSE;
-+}
diff -urN mysql-old/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
--- mysql-old/sql/sql_yacc.cc 2011-05-10 17:45:45.636682376 +0000
+++ mysql/sql/sql_yacc.cc 2011-05-10 17:56:01.630015710 +0000
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:39 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:39 UTC (permalink / raw
To: gentoo-commits
commit: aee1a7a4f37dba8edaa041624fb26a3873350b49
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:38:58 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:38:58 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=aee1a7a4
Fix whitespace so patch applies.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
07110_all_mysql_gcc-4.2_5.1.69.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/07110_all_mysql_gcc-4.2_5.1.69.patch b/07110_all_mysql_gcc-4.2_5.1.69.patch
index e5919c4..e897fd5 100644
--- a/07110_all_mysql_gcc-4.2_5.1.69.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.69.patch
@@ -1264,8 +1264,8 @@ diff -ur mysql-orig/sql/item_func.h mysql/sql/item_func.h
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{
-- max_length= min(args[0]->max_length, MY_INT64_NUM_DECIMAL_DIGITS);
-+ max_length= MYSQL_MIN(args[0]->max_length, MY_INT64_NUM_DECIMAL_DIGITS);
+- max_length= min(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
++ max_length= MYSQL_MIN(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
unsigned_flag=1;
}
longlong val_int();
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:42 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:42 UTC (permalink / raw
To: gentoo-commits
commit: ad2e63d56dca89b9b199745d96bf3e6f69763f6d
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:42:08 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:42:08 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ad2e63d5
Isn't tweak patches by hand fun?
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
07110_all_mysql_gcc-4.2_5.1.69.patch | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/07110_all_mysql_gcc-4.2_5.1.69.patch b/07110_all_mysql_gcc-4.2_5.1.69.patch
index e897fd5..3d0a742 100644
--- a/07110_all_mysql_gcc-4.2_5.1.69.patch
+++ b/07110_all_mysql_gcc-4.2_5.1.69.patch
@@ -1260,13 +1260,12 @@ diff -ur mysql-orig/sql/item_func.cc mysql/sql/item_func.cc
diff -ur mysql-orig/sql/item_func.h mysql/sql/item_func.h
--- mysql-orig/sql/item_func.h 2012-08-14 01:12:29.423437567 +0000
+++ mysql/sql/item_func.h 2012-08-14 01:14:59.402197785 +0000
-@@ -421,7 +421,7 @@
+@@ -421,6 +421,6 @@
const char *func_name() const { return "cast_as_unsigned"; }
void fix_length_and_dec()
{
- max_length= min(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
+ max_length= MYSQL_MIN(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
- unsigned_flag=1;
}
longlong val_int();
diff -ur mysql-orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-05-28 19:46 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-05-28 19:46 UTC (permalink / raw
To: gentoo-commits
commit: f319183325f146dadbd0b99bac64d37bfd76391a
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Tue May 28 19:46:12 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue May 28 19:46:12 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f3191833
Another tweaked patch, the only difference is the copyright line that got changed in the upstream source.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
00000_index.txt | 8 +-
07340_all_mysql_hardened_x86_strings-5.1.69.patch | 424 ++++++++++++++++++++++
2 files changed, 431 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index ebf5c95..1e19e1d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -763,7 +763,13 @@
@@ Bug#57386: Enlarge the stacksize used for trackback.
@patch 07340_all_mysql_hardened_x86_strings.patch
-@ver 5.01.51.00 to 5.01.99.99
+@ver 5.01.51.00 to 5.01.68.99
+@pn mysql
+@pn mysql-cluster
+@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
+
+@patch 07340_all_mysql_hardened_x86_strings-5.1.69.patch
+@ver 5.01.69.00 to 5.01.99.99
@pn mysql
@pn mysql-cluster
@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
diff --git a/07340_all_mysql_hardened_x86_strings-5.1.69.patch b/07340_all_mysql_hardened_x86_strings-5.1.69.patch
new file mode 100644
index 0000000..dd6ba9e
--- /dev/null
+++ b/07340_all_mysql_hardened_x86_strings-5.1.69.patch
@@ -0,0 +1,424 @@
+As part of fixing the TEXTRELs, we must remove this file seperately because
+applying a move of .s -> .S on a case-insensitive file-system will cause patch
+to break.
+
+diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
+--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
++++ b/strings/strings-x86.s 1970-01-01 01:00:00.000000000 +0100
+@@ -1,416 +0,0 @@
+-# Copyright (c) 2000, 2002-2004 MySQL AB
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; version 2 of the License.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+-
+-# Optimized string functions Intel 80x86 (gcc/gas syntax)
+-
+- .file "strings.s"
+- .version "1.00"
+-
+-.text
+-
+-# Move a alligned, not overlapped, by (long) divided memory area
+-# Args: to,from,length
+-
+-.globl bmove_align
+- .type bmove_align,@function
+-bmove_align:
+- movl %edi,%edx
+- push %esi
+- movl 4(%esp),%edi # to
+- movl 8(%esp),%esi # from
+- movl 12(%esp),%ecx # length
+- addw $3,%cx # fix if not divisible with long
+- shrw $2,%cx
+- jz .ba_20
+- .p2align 4,,7
+-.ba_10:
+- movl -4(%esi,%ecx),%eax
+- movl %eax,-4(%edi,%ecx)
+- decl %ecx
+- jnz .ba_10
+-.ba_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_align_end:
+- .size bmove_align,.bmove_align_end-bmove_align
+-
+- # Move a string from higher to lower
+- # Arg from_end+1,to_end+1,length
+-
+-.globl bmove_upp
+- .type bmove_upp,@function
+-bmove_upp:
+- movl %edi,%edx # Remember %edi
+- push %esi
+- movl 8(%esp),%edi # dst
+- movl 16(%esp),%ecx # length
+- movl 12(%esp),%esi # source
+- test %ecx,%ecx
+- jz .bu_20
+- subl %ecx,%esi # To start of strings
+- subl %ecx,%edi
+-
+- .p2align 4,,7
+-.bu_10: movb -1(%esi,%ecx),%al
+- movb %al,-1(%edi,%ecx)
+- decl %ecx
+- jnz .bu_10
+-.bu_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_upp_end:
+- .size bmove_upp,.bmove_upp_end-bmove_upp
+-
+- # Append fillchars to string
+- # Args: dest,len,fill
+-
+-.globl strappend
+- .type strappend,@function
+-strappend:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- clrl %eax # Find end of string
+- repne
+- scasb
+- jnz sa_99 # String to long, shorten it
+- movzb 16(%esp),%eax # Fillchar
+- decl %edi # Point at end null
+- incl %ecx # rep made one dec for null-char
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern.
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+-sa_99: movb $0,(%edi) # End of string
+- popl %edi
+- ret
+-.strappend_end:
+- .size strappend,.strappend_end-strappend
+-
+- # Find if string contains any char in another string
+- # Arg: str,set
+- # Ret: Pointer to first found char in str
+-
+-.globl strcont
+- .type strcont,@function
+-strcont:
+- movl %edi,%edx
+- pushl %esi
+- movl 8(%esp),%esi # str
+- movl 12(%esp),%ecx # set
+- clrb %ah # For endtest
+- jmp sc_60
+-
+-sc_10: scasb
+- jz sc_fo # Found char
+-sc_20: cmp (%edi),%ah # Test if null
+- jnz sc_10 # Not end of set yet
+- incl %esi # Next char in str
+-sc_60: movl %ecx,%edi # %edi = Set
+- movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jnz sc_20 # Not end of string
+- clrl %esi # Return Null
+-sc_fo: movl %esi,%eax # Char found here
+- movl %edx,%edi # Restore
+- popl %esi
+- ret
+-.strcont_end:
+- .size strcont,.strcont_end-strcont
+-
+- # Find end of string
+- # Arg: str
+- # ret: Pointer to end null
+-
+-.globl strend
+- .type strend,@function
+-strend:
+- movl %edi,%edx # Save
+- movl 4(%esp),%edi # str
+- clrl %eax # Find end of string
+- movl %eax,%ecx
+- decl %ecx # ECX = -1
+- repne
+- scasb
+- movl %edi,%eax
+- decl %eax # End of string
+- movl %edx,%edi # Restore
+- ret
+-.strend_end:
+- .size strend,.strend_end-strend
+-
+- # Make a string with len fill-chars and endnull
+- # Args: dest,len,fill
+- # Ret: dest+len
+-
+-.globl strfill
+- .type strfill,@function
+-strfill:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- movzb 16(%esp),%eax # Fill
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+- movb %cl,(%edi) # End NULL
+- movl %edi,%eax # End i %eax
+- popl %edi
+- ret
+-.strfill_end:
+- .size strfill,.strfill_end-strfill
+-
+-
+- # Find a char in or end of a string
+- # Arg: str,char
+- # Ret: pointer to found char or NullS
+-
+-.globl strcend
+- .type strcend,@function
+-strcend:
+- movl %edi,%edx
+- movl 4(%esp),%edi # str
+- movb 8(%esp),%ah # search
+- clrb %al # for scasb to find end
+-
+-se_10: cmpb (%edi),%ah
+- jz se_20 # Found char
+- scasb
+- jnz se_10 # Not end
+- dec %edi # Not found, point at end of string
+-se_20: movl %edi,%eax
+- movl %edx,%edi # Restore
+- ret
+-.strcend_end:
+- .size strcend,.strcend_end-strcend
+-
+- # Test if string has a given suffix
+-
+-.globl is_prefix
+- .type is_prefix,@function
+-is_prefix:
+- movl %edi,%edx # Save %edi
+- pushl %esi # and %esi
+- movl 12(%esp),%esi # get suffix
+- movl 8(%esp),%edi # s1
+- movl $1,%eax # Ok and zero-test
+-ip_10: cmpb (%esi),%ah
+- jz suf_ok # End of string/ found suffix
+- cmpsb # Compare strings
+- jz ip_10 # Same, possible prefix
+- xor %eax,%eax # Not suffix
+-suf_ok: popl %esi
+- movl %edx,%edi
+- ret
+-.is_prefix_end:
+- .size is_prefix,.is_prefix_end-is_prefix
+-
+- # Find a substring in string
+- # Arg: str,search
+-
+-.globl strstr
+- .type strstr,@function
+-
+-strstr:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%esi # str
+- movl 16(%esp),%edi # search
+- movl %edi,%ecx
+- incl %ecx # %ecx = search+1
+- movb (%edi),%ah # %ah = First char in search
+- jmp sf_10
+-
+-sf_00: movl %edx,%esi # si = Current str-pos
+-sf_10: movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jz sf_90 # End of string, didn't find search
+- incl %esi
+- cmpb %al,%ah
+- jnz sf_10 # Didn't find first char, continue
+- movl %esi,%edx # Save str-pos in %edx
+- movl %ecx,%edi
+-sf_20: cmpb $0,(%edi)
+- jz sf_fo # Found substring
+- cmpsb
+- jz sf_20 # Char ok
+- jmp sf_00 # Next str-pos
+-
+-sf_90: movl $1,%edx # Return Null
+-sf_fo: movl %edx,%eax # Char found here
+- decl %eax # Pointed one after
+- popl %esi
+- popl %edi
+- ret
+-.strstr_end:
+- .size strstr,.strstr_end-strstr
+-
+-
+- # Find a substring in string, return index
+- # Arg: str,search
+-
+-.globl strinstr
+- .type strinstr,@function
+-
+-strinstr:
+- pushl %ebp
+- movl %esp,%ebp
+- pushl 12(%ebp) # search
+- pushl 8(%ebp) # str
+- call strstr
+- add $8,%esp
+- or %eax,%eax
+- jz si_99 # Not found, return NULL
+- sub 8(%ebp),%eax # Pos from start
+- inc %eax # And first pos = 1
+-si_99: popl %ebp
+- ret
+-.strinstr_end:
+- .size strinstr,.strinstr_end-strinstr
+-
+- # Make a string of len length from another string
+- # Arg: dst,src,length
+- # ret: end of dst
+-
+-.globl strmake
+- .type strmake,@function
+-
+-strmake:
+- pushl %edi
+- pushl %esi
+- mov 12(%esp),%edi # dst
+- movl $0,%edx
+- movl 20(%esp),%ecx # length
+- movl 16(%esp),%esi # src
+- cmpl %edx,%ecx
+- jz sm_90
+-sm_00: movb (%esi,%edx),%al
+- cmpb $0,%al
+- jz sm_90
+- movb %al,(%edi,%edx)
+- incl %edx
+- cmpl %edx,%ecx
+- jnz sm_00
+-sm_90: movb $0,(%edi,%edx)
+-sm_99: lea (%edi,%edx),%eax # Return pointer to end null
+- pop %esi
+- pop %edi
+- ret
+-.strmake_end:
+- .size strmake,.strmake_end-strmake
+-
+- # Move a string with max len chars
+- # arg: dst,src,len
+- # ret: pos to first null or dst+len
+-
+-.globl strnmov
+- .type strnmov,@function
+-strnmov:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%edi # dst
+- movl 16(%esp),%esi # src
+- movl 20(%esp),%ecx # Length of memory-area
+- jecxz snm_99 # Nothing to do
+- clrb %al # For test of end-null
+-
+-snm_10: cmpb (%esi),%al # Next char to move
+- movsb # move arg
+- jz snm_20 # last char, fill with null
+- loop snm_10 # Continue moving
+- incl %edi # Point two after last
+-snm_20: decl %edi # Point at first null (or last+1)
+-snm_99: movl %edi,%eax # Pointer at last char
+- popl %esi
+- popl %edi
+- ret
+-.strnmov_end:
+- .size strnmov,.strnmov_end-strnmov
+-
+-
+-.globl strmov
+- .type strmov,@function
+-strmov:
+- movl %esi,%ecx # Save old %esi and %edi
+- movl %edi,%edx
+- movl 8(%esp),%esi # get source pointer (s2)
+- movl 4(%esp),%edi # %edi -> s1
+-smo_10: movb (%esi),%al
+- movsb # move arg
+- andb %al,%al
+- jnz smo_10 # Not last
+- movl %edi,%eax
+- dec %eax
+- movl %ecx,%esi # Restore
+- movl %edx,%edi
+- ret
+-.strmov_end:
+- .size strmov,.strmov_end-strmov
+-
+-.globl strxmov
+- .type strxmov,@function
+-strxmov:
+- movl %ebx,%edx # Save %ebx, %esi and %edi
+- mov %esi,%ecx
+- push %edi
+- leal 8(%esp),%ebx # Get destination
+- movl (%ebx),%edi
+- xorb %al,%al
+- jmp next_str # Handle source ebx+4
+-
+-start_str:
+- movsb
+- cmpb -1(%edi),%al
+- jne start_str
+- decl %edi # Don't copy last null
+-
+-next_str:
+- addl $4,%ebx
+- movl (%ebx),%esi
+- orl %esi,%esi
+- jne start_str
+- movb %al,0(%edi) # Force last to ASCII 0
+-
+- movl %edi,%eax # Return ptr to ASCII 0
+- pop %edi # Restore registers
+- movl %ecx,%esi
+- movl %edx,%ebx
+- ret
+-.strxmov_end:
+- .size strxmov,.strxmov_end-strxmov
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-06-06 20:32 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2013-06-06 20:32 UTC (permalink / raw
To: gentoo-commits
commit: fd0e11d8af27529c833478102b4f38de9bf2e774
Author: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 6 17:25:34 2013 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Thu Jun 6 17:25:34 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=fd0e11d8
This patch was merged upstream in 5.6.12.
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
---
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1e19e1d..1d7b12e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1501,7 +1501,7 @@
@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20003_all_fix-5.6-library.patch
-@ver 5.06.00.00 to 5.06.99.99
+@ver 5.06.00.00 to 5.06.11.99
@pn mysql
@@ Fix bad references to zlib and readline upstream bugs 68277 and 63130
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-06-25 15:48 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2013-06-25 15:48 UTC (permalink / raw
To: gentoo-commits
commit: 49e88ae5db0f3e696681ca0e6085bc82675d49fb
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Tue Jun 25 15:44:48 2013 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Tue Jun 25 15:45:33 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=49e88ae5
Regenerate 07340 patch for mysql-5.1.70.
---
00000_index.txt | 8 +-
07340_all_mysql_hardened_x86_strings-5.1.70.patch | 424 ++++++++++++++++++++++
2 files changed, 431 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1d7b12e..ad88bff 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -769,7 +769,13 @@
@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
@patch 07340_all_mysql_hardened_x86_strings-5.1.69.patch
-@ver 5.01.69.00 to 5.01.99.99
+@ver 5.01.69.00 to 5.01.69.99
+@pn mysql
+@pn mysql-cluster
+@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
+
+@patch 07340_all_mysql_hardened_x86_strings-5.1.70.patch
+@ver 5.01.70.00 to 5.01.99.99
@pn mysql
@pn mysql-cluster
@@ Gentoo Bug #344031: Fix new TEXTRELs (remove old strings-x86.s file, for case-insensitive file-systems).
diff --git a/07340_all_mysql_hardened_x86_strings-5.1.70.patch b/07340_all_mysql_hardened_x86_strings-5.1.70.patch
new file mode 100644
index 0000000..79741d3
--- /dev/null
+++ b/07340_all_mysql_hardened_x86_strings-5.1.70.patch
@@ -0,0 +1,424 @@
+As part of fixing the TEXTRELs, we must remove this file seperately because
+applying a move of .s -> .S on a case-insensitive file-system will cause patch
+to break.
+
+diff -urN a/strings/strings-x86.s b/strings/strings-x86.s
+--- a/strings/strings-x86.s 2010-11-09 21:29:32.192000076 +0100
++++ b/strings/strings-x86.s 1970-01-01 01:00:00.000000000 +0100
+@@ -1,416 +0,0 @@
+-# Copyright (c) 2000, 2002-2004 MySQL AB
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; version 2 of the License.
+-#
+-# This program is distributed in the hope that it will be useful,
+-# but WITHOUT ANY WARRANTY; without even the implied warranty of
+-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-# GNU General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+-
+-# Optimized string functions Intel 80x86 (gcc/gas syntax)
+-
+- .file "strings.s"
+- .version "1.00"
+-
+-.text
+-
+-# Move a alligned, not overlapped, by (long) divided memory area
+-# Args: to,from,length
+-
+-.globl bmove_align
+- .type bmove_align,@function
+-bmove_align:
+- movl %edi,%edx
+- push %esi
+- movl 4(%esp),%edi # to
+- movl 8(%esp),%esi # from
+- movl 12(%esp),%ecx # length
+- addw $3,%cx # fix if not divisible with long
+- shrw $2,%cx
+- jz .ba_20
+- .p2align 4,,7
+-.ba_10:
+- movl -4(%esi,%ecx),%eax
+- movl %eax,-4(%edi,%ecx)
+- decl %ecx
+- jnz .ba_10
+-.ba_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_align_end:
+- .size bmove_align,.bmove_align_end-bmove_align
+-
+- # Move a string from higher to lower
+- # Arg from_end+1,to_end+1,length
+-
+-.globl bmove_upp
+- .type bmove_upp,@function
+-bmove_upp:
+- movl %edi,%edx # Remember %edi
+- push %esi
+- movl 8(%esp),%edi # dst
+- movl 16(%esp),%ecx # length
+- movl 12(%esp),%esi # source
+- test %ecx,%ecx
+- jz .bu_20
+- subl %ecx,%esi # To start of strings
+- subl %ecx,%edi
+-
+- .p2align 4,,7
+-.bu_10: movb -1(%esi,%ecx),%al
+- movb %al,-1(%edi,%ecx)
+- decl %ecx
+- jnz .bu_10
+-.bu_20: pop %esi
+- movl %edx,%edi
+- ret
+-
+-.bmove_upp_end:
+- .size bmove_upp,.bmove_upp_end-bmove_upp
+-
+- # Append fillchars to string
+- # Args: dest,len,fill
+-
+-.globl strappend
+- .type strappend,@function
+-strappend:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- clrl %eax # Find end of string
+- repne
+- scasb
+- jnz sa_99 # String to long, shorten it
+- movzb 16(%esp),%eax # Fillchar
+- decl %edi # Point at end null
+- incl %ecx # rep made one dec for null-char
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern.
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+-sa_99: movb $0,(%edi) # End of string
+- popl %edi
+- ret
+-.strappend_end:
+- .size strappend,.strappend_end-strappend
+-
+- # Find if string contains any char in another string
+- # Arg: str,set
+- # Ret: Pointer to first found char in str
+-
+-.globl strcont
+- .type strcont,@function
+-strcont:
+- movl %edi,%edx
+- pushl %esi
+- movl 8(%esp),%esi # str
+- movl 12(%esp),%ecx # set
+- clrb %ah # For endtest
+- jmp sc_60
+-
+-sc_10: scasb
+- jz sc_fo # Found char
+-sc_20: cmp (%edi),%ah # Test if null
+- jnz sc_10 # Not end of set yet
+- incl %esi # Next char in str
+-sc_60: movl %ecx,%edi # %edi = Set
+- movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jnz sc_20 # Not end of string
+- clrl %esi # Return Null
+-sc_fo: movl %esi,%eax # Char found here
+- movl %edx,%edi # Restore
+- popl %esi
+- ret
+-.strcont_end:
+- .size strcont,.strcont_end-strcont
+-
+- # Find end of string
+- # Arg: str
+- # ret: Pointer to end null
+-
+-.globl strend
+- .type strend,@function
+-strend:
+- movl %edi,%edx # Save
+- movl 4(%esp),%edi # str
+- clrl %eax # Find end of string
+- movl %eax,%ecx
+- decl %ecx # ECX = -1
+- repne
+- scasb
+- movl %edi,%eax
+- decl %eax # End of string
+- movl %edx,%edi # Restore
+- ret
+-.strend_end:
+- .size strend,.strend_end-strend
+-
+- # Make a string with len fill-chars and endnull
+- # Args: dest,len,fill
+- # Ret: dest+len
+-
+-.globl strfill
+- .type strfill,@function
+-strfill:
+- pushl %edi
+- movl 8(%esp),%edi # Memory pointer
+- movl 12(%esp),%ecx # Length
+- movzb 16(%esp),%eax # Fill
+-
+- movb %al,%ah # (2) Set up a 32 bit pattern
+- movw %ax,%dx # (2)
+- shll $16,%eax # (3)
+- movw %dx,%ax # (2) %eax has the 32 bit pattern.
+-
+- movl %ecx,%edx # (2) Save the count of bytes.
+- shrl $2,%ecx # (2) Number of dwords.
+- rep
+- stosl # (5 + 5n)
+- movb $3,%cl # (2)
+- and %edx,%ecx # (2) Fill in the odd bytes
+- rep
+- stosb # Move last bytes if any
+-
+- movb %cl,(%edi) # End NULL
+- movl %edi,%eax # End i %eax
+- popl %edi
+- ret
+-.strfill_end:
+- .size strfill,.strfill_end-strfill
+-
+-
+- # Find a char in or end of a string
+- # Arg: str,char
+- # Ret: pointer to found char or NullS
+-
+-.globl strcend
+- .type strcend,@function
+-strcend:
+- movl %edi,%edx
+- movl 4(%esp),%edi # str
+- movb 8(%esp),%ah # search
+- clrb %al # for scasb to find end
+-
+-se_10: cmpb (%edi),%ah
+- jz se_20 # Found char
+- scasb
+- jnz se_10 # Not end
+- dec %edi # Not found, point at end of string
+-se_20: movl %edi,%eax
+- movl %edx,%edi # Restore
+- ret
+-.strcend_end:
+- .size strcend,.strcend_end-strcend
+-
+- # Test if string has a given suffix
+-
+-.globl is_prefix
+- .type is_prefix,@function
+-is_prefix:
+- movl %edi,%edx # Save %edi
+- pushl %esi # and %esi
+- movl 12(%esp),%esi # get suffix
+- movl 8(%esp),%edi # s1
+- movl $1,%eax # Ok and zero-test
+-ip_10: cmpb (%esi),%ah
+- jz suf_ok # End of string/ found suffix
+- cmpsb # Compare strings
+- jz ip_10 # Same, possible prefix
+- xor %eax,%eax # Not suffix
+-suf_ok: popl %esi
+- movl %edx,%edi
+- ret
+-.is_prefix_end:
+- .size is_prefix,.is_prefix_end-is_prefix
+-
+- # Find a substring in string
+- # Arg: str,search
+-
+-.globl strstr
+- .type strstr,@function
+-
+-strstr:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%esi # str
+- movl 16(%esp),%edi # search
+- movl %edi,%ecx
+- incl %ecx # %ecx = search+1
+- movb (%edi),%ah # %ah = First char in search
+- jmp sf_10
+-
+-sf_00: movl %edx,%esi # si = Current str-pos
+-sf_10: movb (%esi),%al # Test if this char exist
+- andb %al,%al
+- jz sf_90 # End of string, didn't find search
+- incl %esi
+- cmpb %al,%ah
+- jnz sf_10 # Didn't find first char, continue
+- movl %esi,%edx # Save str-pos in %edx
+- movl %ecx,%edi
+-sf_20: cmpb $0,(%edi)
+- jz sf_fo # Found substring
+- cmpsb
+- jz sf_20 # Char ok
+- jmp sf_00 # Next str-pos
+-
+-sf_90: movl $1,%edx # Return Null
+-sf_fo: movl %edx,%eax # Char found here
+- decl %eax # Pointed one after
+- popl %esi
+- popl %edi
+- ret
+-.strstr_end:
+- .size strstr,.strstr_end-strstr
+-
+-
+- # Find a substring in string, return index
+- # Arg: str,search
+-
+-.globl strinstr
+- .type strinstr,@function
+-
+-strinstr:
+- pushl %ebp
+- movl %esp,%ebp
+- pushl 12(%ebp) # search
+- pushl 8(%ebp) # str
+- call strstr
+- add $8,%esp
+- or %eax,%eax
+- jz si_99 # Not found, return NULL
+- sub 8(%ebp),%eax # Pos from start
+- inc %eax # And first pos = 1
+-si_99: popl %ebp
+- ret
+-.strinstr_end:
+- .size strinstr,.strinstr_end-strinstr
+-
+- # Make a string of len length from another string
+- # Arg: dst,src,length
+- # ret: end of dst
+-
+-.globl strmake
+- .type strmake,@function
+-
+-strmake:
+- pushl %edi
+- pushl %esi
+- mov 12(%esp),%edi # dst
+- movl $0,%edx
+- movl 20(%esp),%ecx # length
+- movl 16(%esp),%esi # src
+- cmpl %edx,%ecx
+- jz sm_90
+-sm_00: movb (%esi,%edx),%al
+- cmpb $0,%al
+- jz sm_90
+- movb %al,(%edi,%edx)
+- incl %edx
+- cmpl %edx,%ecx
+- jnz sm_00
+-sm_90: movb $0,(%edi,%edx)
+-sm_99: lea (%edi,%edx),%eax # Return pointer to end null
+- pop %esi
+- pop %edi
+- ret
+-.strmake_end:
+- .size strmake,.strmake_end-strmake
+-
+- # Move a string with max len chars
+- # arg: dst,src,len
+- # ret: pos to first null or dst+len
+-
+-.globl strnmov
+- .type strnmov,@function
+-strnmov:
+- pushl %edi
+- pushl %esi
+- movl 12(%esp),%edi # dst
+- movl 16(%esp),%esi # src
+- movl 20(%esp),%ecx # Length of memory-area
+- jecxz snm_99 # Nothing to do
+- clrb %al # For test of end-null
+-
+-snm_10: cmpb (%esi),%al # Next char to move
+- movsb # move arg
+- jz snm_20 # last char, fill with null
+- loop snm_10 # Continue moving
+- incl %edi # Point two after last
+-snm_20: decl %edi # Point at first null (or last+1)
+-snm_99: movl %edi,%eax # Pointer at last char
+- popl %esi
+- popl %edi
+- ret
+-.strnmov_end:
+- .size strnmov,.strnmov_end-strnmov
+-
+-
+-.globl strmov
+- .type strmov,@function
+-strmov:
+- movl %esi,%ecx # Save old %esi and %edi
+- movl %edi,%edx
+- movl 8(%esp),%esi # get source pointer (s2)
+- movl 4(%esp),%edi # %edi -> s1
+-smo_10: movb (%esi),%al
+- movsb # move arg
+- andb %al,%al
+- jnz smo_10 # Not last
+- movl %edi,%eax
+- dec %eax
+- movl %ecx,%esi # Restore
+- movl %edx,%edi
+- ret
+-.strmov_end:
+- .size strmov,.strmov_end-strmov
+-
+-.globl strxmov
+- .type strxmov,@function
+-strxmov:
+- movl %ebx,%edx # Save %ebx, %esi and %edi
+- mov %esi,%ecx
+- push %edi
+- leal 8(%esp),%ebx # Get destination
+- movl (%ebx),%edi
+- xorb %al,%al
+- jmp next_str # Handle source ebx+4
+-
+-start_str:
+- movsb
+- cmpb -1(%edi),%al
+- jne start_str
+- decl %edi # Don't copy last null
+-
+-next_str:
+- addl $4,%ebx
+- movl (%ebx),%esi
+- orl %esi,%esi
+- jne start_str
+- movb %al,0(%edi) # Force last to ASCII 0
+-
+- movl %edi,%eax # Return ptr to ASCII 0
+- pop %edi # Restore registers
+- movl %ecx,%esi
+- movl %edx,%ebx
+- ret
+-.strxmov_end:
+- .size strxmov,.strxmov_end-strxmov
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-06-27 12:31 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-06-27 12:31 UTC (permalink / raw
To: gentoo-commits
commit: 78c8f664193cc391058346f3b99c3ca0dd81d9f2
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Thu May 2 23:46:14 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Jun 27 12:28:43 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=78c8f664
Respin mysql_config patch for mariadb 5.5
---
00000_index.txt | 6 ++++
01050_all_mariadb_mysql_config_cleanup-5.5.patch | 45 ++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index ad88bff..9dcdfe0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -240,6 +240,12 @@
@pn mariadb
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
+@ver 5.05.00.00 to 10.01.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
@pn mysql
diff --git a/01050_all_mariadb_mysql_config_cleanup-5.5.patch b/01050_all_mariadb_mysql_config_cleanup-5.5.patch
new file mode 100644
index 0000000..873138f
--- /dev/null
+++ b/01050_all_mariadb_mysql_config_cleanup-5.5.patch
@@ -0,0 +1,45 @@
+--- mysql.old/scripts/mysql_config.sh 2013-05-02 20:30:14.000000000 -0400
++++ mysql.new/scripts/mysql_config.sh 2013-05-02 20:32:36.000000000 -0400
+@@ -128,25 +128,29 @@
+ cflags="$include @CFLAGS@ " #note: end space!
+
+ # Remove some options that a client doesn't have to care about
+-# FIXME until we have a --cxxflags, we need to remove -Xa
+-# and -xstrconst to make --cflags usable for Sun Forte C++
+-# FIXME until we have a --cxxflags, we need to remove -AC99
+-# to make --cflags usable for HP C++ (aCC)
+-for remove in DDBUG_OFF DSAFE_MUTEX DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \
+- DEXTRA_DEBUG DHAVE_valgrind O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
+- 'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
+- Xa xstrconst "xc99=none" AC99 \
+- unroll2 ip mp restrict
++tmpcflags=""
++for f in $cflags
+ do
+- # The first option we might strip will always have a space before it because
+- # we set -I$pkgincludedir as the first option
+- cflags=`echo "$cflags"|sed -e "s/ -$remove */ /g"`
++ case "${f}" in
++ -DDBUG_OFF) f="" ;;
++ -DSAFE_MUTEX) f="" ;;
++ -DUNIV_MUST_NOT_INLINE) f="" ;;
++ -DFORCE_INIT_OF_VARS) f="" ;;
++ -DEXTRA_DEBUG) f="" ;;
++ -DHAVE_valgrind) f="" ;;
++ -[ID]*) tmpcflags="${tmpcflags} ${f}" ;;
++ -[Ll]*)
++ libs="${libs} ${f}"
++ libs_r="${libs_r} ${f}"
++ embedded_libs="${embedded_libs} ${f}"
++ ;;
++ esac
+ done
+-cflags=`echo "$cflags"|sed -e 's/ *\$//'`
++cflags="${tmpcflags# }"
+
+ # Same for --libs(_r)
+-for remove in lmtmalloc static-libcxa i-static static-intel
++for remove in lmtmalloc static-libcxa i-static static-intel lprobes_mysql
+ do
+ # We know the strings starts with a space
+ libs=`echo "$libs"|sed -e "s/ -$remove */ /g"`
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-06-27 12:31 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-06-27 12:31 UTC (permalink / raw
To: gentoo-commits
commit: 5896cab74ab4df3afedcbce256e55d88ef9a37bd
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Fri May 3 02:23:20 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Jun 27 12:28:43 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=5896cab7
Respin mysql_config patch for mysql 5.5
---
00000_index.txt | 7 ++++-
01050_all_mysql_config_cleanup-5.5.patch | 45 ++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 9dcdfe0..3b18905 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -241,11 +241,16 @@
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 10.01.99.99
+@ver 5.05.00.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mysql_config_cleanup-5.5.patch
+@ver 5.05.00.00 to 5.05.99.99
+@pn mysql
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
@pn mysql
diff --git a/01050_all_mysql_config_cleanup-5.5.patch b/01050_all_mysql_config_cleanup-5.5.patch
new file mode 100644
index 0000000..72a1f75
--- /dev/null
+++ b/01050_all_mysql_config_cleanup-5.5.patch
@@ -0,0 +1,45 @@
+--- mysql.old/scripts/mysql_config.sh 2013-05-02 20:30:14.000000000 -0400
++++ mysql.new/scripts/mysql_config.sh 2013-05-02 20:32:36.000000000 -0400
+@@ -128,25 +128,29 @@
+ cflags="$include @CFLAGS@ " #note: end space!
+
+ # Remove some options that a client doesn't have to care about
+-# FIXME until we have a --cxxflags, we need to remove -Xa
+-# and -xstrconst to make --cflags usable for Sun Forte C++
+-# FIXME until we have a --cxxflags, we need to remove -AC99
+-# to make --cflags usable for HP C++ (aCC)
+-for remove in DDBUG_OFF DSAFE_MUTEX DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \
+- DEXTRA_DEBUG DHAVE_purify O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
+- 'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
+- Xa xstrconst "xc99=none" AC99 \
+- unroll2 ip mp restrict
++tmpcflags=""
++for f in $cflags
+ do
+- # The first option we might strip will always have a space before it because
+- # we set -I$pkgincludedir as the first option
+- cflags=`echo "$cflags"|sed -e "s/ -$remove */ /g"`
++ case "${f}" in
++ -DDBUG_OFF) f="" ;;
++ -DSAFE_MUTEX) f="" ;;
++ -DUNIV_MUST_NOT_INLINE) f="" ;;
++ -DFORCE_INIT_OF_VARS) f="" ;;
++ -DEXTRA_DEBUG) f="" ;;
++ -DHAVE_purify) f="" ;;
++ -[ID]*) tmpcflags="${tmpcflags} ${f}" ;;
++ -[Ll]*)
++ libs="${libs} ${f}"
++ libs_r="${libs_r} ${f}"
++ embedded_libs="${embedded_libs} ${f}"
++ ;;
++ esac
+ done
+-cflags=`echo "$cflags"|sed -e 's/ *\$//'`
++cflags="${tmpcflags# }"
+
+ # Same for --libs(_r)
+-for remove in lmtmalloc static-libcxa i-static static-intel
++for remove in lmtmalloc static-libcxa i-static static-intel lprobes_mysql
+ do
+ # We know the strings starts with a space
+ libs=`echo "$libs"|sed -e "s/ -$remove */ /g"`
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-08-23 18:56 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-08-23 18:56 UTC (permalink / raw
To: gentoo-commits
commit: 75392d66acaf6a89370097ebe82e8879520be350
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Fri Aug 23 17:25:34 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Fri Aug 23 18:51:53 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=75392d66
Remove upstream applied patch for 5.6.13 build and fix bug numbers
---
00000_index.txt | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3b18905..a751d0e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1505,17 +1505,17 @@
@patch 20002_all_mysql-va-list.patch
@ver 5.05.00.00 to 5.05.99.99
@pn mysql
-@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20002_all_mysql-va-list.patch
@ver 5.05.00.00 to 5.05.99.99
@pn percona-server
-@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20002_all_mysql-va-list-5.6.patch
-@ver 5.06.00.00 to 5.99.99.99
+@ver 5.06.00.00 to 5.06.12.99
@pn mysql
-@@ Bug 442000, upstream 62729 compilation failure on arm and possibly other arches where va_list is a struct or array.
+@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20003_all_fix-5.6-library.patch
@ver 5.06.00.00 to 5.06.11.99
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-10-09 19:30 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-10-09 19:30 UTC (permalink / raw
To: gentoo-commits
commit: 359a50b3ab16e1359bf46d850e344d19511e9b2d
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Wed Oct 9 19:27:17 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed Oct 9 19:27:17 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=359a50b3
Disable mysql_config patches for 5.5 until bug 449390 is decided
---
00000_index.txt | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 893a3d7..15f31d3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -240,16 +240,16 @@
@pn mariadb
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 10.00.99.99
-@pn mariadb
-@pn mariadb-galera
-@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-
-@patch 01050_all_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 5.05.99.99
-@pn mysql
-@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+#@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
+#@ver 5.05.00.00 to 10.00.99.99
+#@pn mariadb
+#@pn mariadb-galera
+#@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
+#@patch 01050_all_mysql_config_cleanup-5.5.patch
+#@ver 5.05.00.00 to 5.05.99.99
+#@pn mysql
+#@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-10-09 19:30 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-10-09 19:30 UTC (permalink / raw
To: gentoo-commits
commit: 68428843d4cdc26ce8c483a6f6c3f6186169dcd9
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Wed Oct 9 18:25:25 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed Oct 9 19:16:44 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=68428843
Filter out aggressive CFLAGS for USE=tokudb on mariadb
---
00000_index.txt | 12 +++++++++++
20004_all_mariadb-filter-tokudb-flags.patch | 31 +++++++++++++++++++++++++++++
2 files changed, 43 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index a751d0e..893a3d7 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1526,3 +1526,15 @@
@ver 5.07.00.00 to 5.99.99.99
@pn mysql
@@ Fix readline upstream bug 63130
+
+@patch 20004_all_mariadb-filter-tokudb-flags.patch
+@ver 5.05.33.00 to 5.99.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
+
+@patch 20004_all_mariadb-filter-tokudb-flags.patch
+@ver 10.00.05.00 to 10.99.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
diff --git a/20004_all_mariadb-filter-tokudb-flags.patch b/20004_all_mariadb-filter-tokudb-flags.patch
new file mode 100644
index 0000000..249f0bf
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags.patch
@@ -0,0 +1,31 @@
+diff -aurN mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -136,12 +136,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+@@ -172,8 +170,8 @@
+ endif ()
+
+ ## always want these
+-set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}")
+-set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}")
++set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
++set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
+
+ ## need to set -stdlib=libc++ to get real c++11 support on darwin
+ if (APPLE)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-12-10 18:24 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-12-10 18:24 UTC (permalink / raw
To: gentoo-commits
commit: 074fb5e267d2294f6a3375bf857dadb7f9ef5a60
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Dec 10 17:46:15 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue Dec 10 17:46:15 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=074fb5e2
Respin min/max patch for 5.1.73
---
00000_index.txt | 8 +-
07110_all_mysql_gcc-4.2_5.1.73.patch | 3839 ++++++++++++++++++++++++++++++++++
2 files changed, 3846 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 15f31d3..0524cfc 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -590,7 +590,13 @@
@@ FIXME: Testing patch - applies cleanly
@patch 07110_all_mysql_gcc-4.2_5.1.69.patch
-@ver 5.01.69.00 to 5.01.99.99
+@ver 5.01.69.00 to 5.01.72.99
+@pn mysql
+@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
+@@ FIXME: Testing patch - applies cleanly
+
+@patch 07110_all_mysql_gcc-4.2_5.1.73.patch
+@ver 5.01.73.00 to 5.01.99.99
@pn mysql
@@ Replace max() and min() macro with MYSQL_MIN() and MYSQL_MAX()
@@ FIXME: Testing patch - applies cleanly
diff --git a/07110_all_mysql_gcc-4.2_5.1.73.patch b/07110_all_mysql_gcc-4.2_5.1.73.patch
new file mode 100644
index 0000000..fcf5730
--- /dev/null
+++ b/07110_all_mysql_gcc-4.2_5.1.73.patch
@@ -0,0 +1,3839 @@
+X-Gentoo-Bug: 280843
+X-Upstream-Bug: 30866
+X-Gentoo-Bug-URL: http://bugs.gentoo.org/show_bug.cgi?id=280843
+X-Upstream-Bug-URL: http://bugs.mysql.com/bug.php?id=30866
+
+diff -ur mysql-orig/client/mysqlbinlog.cc mysql/client/mysqlbinlog.cc
+--- mysql-orig/client/mysqlbinlog.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqlbinlog.cc 2012-08-14 01:14:59.292197574 +0000
+@@ -1978,7 +1978,7 @@
+ my_off_t length,tmp;
+ for (length= start_position_mot ; length > 0 ; length-=tmp)
+ {
+- tmp=min(length,sizeof(buff));
++ tmp=MYSQL_MIN(length,sizeof(buff));
+ if (my_b_read(file, buff, (uint) tmp))
+ {
+ error("Failed reading from file.");
+diff -ur mysql-orig/client/mysql.cc mysql/client/mysql.cc
+--- mysql-orig/client/mysql.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -3334,9 +3334,9 @@
+ {
+ uint length= column_names ? field->name_length : 0;
+ if (quick)
+- length=max(length,field->length);
++ length=MYSQL_MAX(length,field->length);
+ else
+- length=max(length,field->max_length);
++ length=MYSQL_MAX(length,field->max_length);
+ if (length < 4 && !IS_NOT_NULL(field->flags))
+ length=4; // Room for "NULL"
+ field->max_length=length;
+@@ -3356,7 +3356,7 @@
+ field->name,
+ field->name + name_length);
+ uint display_length= field->max_length + name_length - numcells;
+- tee_fprintf(PAGER, " %-*s |",(int) min(display_length,
++ tee_fprintf(PAGER, " %-*s |",(int) MYSQL_MIN(display_length,
+ MAX_COLUMN_LENGTH),
+ field->name);
+ num_flag[off]= IS_NUM(field->type);
+diff -ur mysql-orig/client/mysqldump.c mysql/client/mysqldump.c
+--- mysql-orig/client/mysqldump.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqldump.c 2012-08-14 01:14:59.322198687 +0000
+@@ -849,7 +849,7 @@
+ &err_ptr, &err_len);
+ if (err_len)
+ {
+- strmake(buff, err_ptr, min(sizeof(buff) - 1, err_len));
++ strmake(buff, err_ptr, MYSQL_MIN(sizeof(buff) - 1, err_len));
+ fprintf(stderr, "Invalid mode to --compatible: %s\n", buff);
+ exit(1);
+ }
+@@ -4769,7 +4769,7 @@
+
+ for (; pos != end && *pos != ','; pos++) ;
+ var_len= (uint) (pos - start);
+- strmake(buff, start, min(sizeof(buff) - 1, var_len));
++ strmake(buff, start, MYSQL_MIN(sizeof(buff) - 1, var_len));
+ find= find_type(buff, lib, var_len);
+ if (!find)
+ {
+diff -ur mysql-orig/client/mysqltest.cc mysql/client/mysqltest.cc
+--- mysql-orig/client/mysqltest.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysqltest.cc 2012-08-14 01:14:59.322198687 +0000
+@@ -5666,9 +5666,9 @@
+ }
+ else if ((c == '{' &&
+ (!my_strnncoll_simple(charset_info, (const uchar*) "while", 5,
+- (uchar*) buf, min(5, p - buf), 0) ||
++ (uchar*) buf, MYSQL_MIN(5, p - buf), 0) ||
+ !my_strnncoll_simple(charset_info, (const uchar*) "if", 2,
+- (uchar*) buf, min(2, p - buf), 0))))
++ (uchar*) buf, MYSQL_MIN(2, p - buf), 0))))
+ {
+ /* Only if and while commands can be terminated by { */
+ *p++= c;
+diff -ur mysql-orig/client/mysql_upgrade.c mysql/client/mysql_upgrade.c
+--- mysql-orig/client/mysql_upgrade.c 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/mysql_upgrade.c 2012-08-14 01:14:59.332198575 +0000
+@@ -533,7 +533,7 @@
+ if ((value_end= strchr(value_start, '\n')) == NULL)
+ return 1; /* Unexpected result */
+
+- strncpy(value, value_start, min(FN_REFLEN, value_end-value_start));
++ strncpy(value, value_start, MYSQL_MIN(FN_REFLEN, value_end-value_start));
+ return 0;
+ }
+
+diff -ur mysql-orig/client/sql_string.cc mysql/client/sql_string.cc
+--- mysql-orig/client/sql_string.cc 2012-08-14 01:12:29.733435005 +0000
++++ mysql/client/sql_string.cc 2012-08-14 01:14:59.332198575 +0000
+@@ -665,7 +665,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -751,7 +751,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -768,7 +768,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+diff -ur mysql-orig/dbug/dbug.c mysql/dbug/dbug.c
+--- mysql-orig/dbug/dbug.c 2012-08-14 01:12:29.743434923 +0000
++++ mysql/dbug/dbug.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1205,7 +1205,7 @@
+ if (TRACING)
+ {
+ Indent(cs, cs->level + 1);
+- pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80);
++ pos= MYSQL_MIN(MYSQL_MAX(cs->level-cs->stack->sub_level,0)*INDENT,80);
+ }
+ else
+ {
+@@ -1690,7 +1690,7 @@
+ {
+ REGISTER int count;
+
+- indent= max(indent-1-cs->stack->sub_level,0)*INDENT;
++ indent= MYSQL_MAX(indent-1-cs->stack->sub_level,0)*INDENT;
+ for (count= 0; count < indent ; count++)
+ {
+ if ((count % INDENT) == 0)
+diff -ur mysql-orig/extra/yassl/src/ssl.cpp mysql/extra/yassl/src/ssl.cpp
+--- mysql-orig/extra/yassl/src/ssl.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/src/ssl.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -39,6 +39,7 @@
+ #include "file.hpp" // for TaoCrypt Source
+ #include "coding.hpp" // HexDecoder
+ #include "helpers.hpp" // for placement new hack
++#include "my_global.h"
+ #include <stdio.h>
+
+ #ifdef _WIN32
+@@ -114,7 +115,7 @@
+ // use file's salt for key derivation, but not real iv
+ TaoCrypt::Source source(info.iv, info.ivSz);
+ TaoCrypt::HexDecoder dec(source);
+- memcpy(info.iv, source.get_buffer(), min((uint)sizeof(info.iv),
++ memcpy(info.iv, source.get_buffer(), MYSQL_MIN((uint)sizeof(info.iv),
+ source.size()));
+ EVP_BytesToKey(info.name, "MD5", info.iv, (byte*)password,
+ passwordSz, 1, key, iv);
+diff -ur mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp mysql/extra/yassl/taocrypt/include/pwdbased.hpp
+--- mysql-orig/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/include/pwdbased.hpp 2012-08-14 01:14:59.332198575 +0000
+@@ -68,7 +68,7 @@
+ }
+ hmac.Final(buffer.get_buffer());
+
+- word32 segmentLen = min(dLen, buffer.size());
++ word32 segmentLen = MYSQL_MIN(dLen, buffer.size());
+ memcpy(derived, buffer.get_buffer(), segmentLen);
+
+ for (j = 1; j < iterations; j++) {
+diff -ur mysql-orig/extra/yassl/taocrypt/src/dh.cpp mysql/extra/yassl/taocrypt/src/dh.cpp
+--- mysql-orig/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/extra/yassl/taocrypt/src/dh.cpp 2012-08-14 01:14:59.332198575 +0000
+@@ -23,6 +23,7 @@
+ #include "runtime.hpp"
+ #include "dh.hpp"
+ #include "asn.hpp"
++#include "my_global.h"
+ #include <math.h>
+
+ namespace TaoCrypt {
+@@ -54,7 +55,7 @@
+ // Generate private value
+ void DH::GeneratePrivate(RandomNumberGenerator& rng, byte* priv)
+ {
+- Integer x(rng, Integer::One(), min(p_ - 1,
++ Integer x(rng, Integer::One(), MYSQL_MIN(p_ - 1,
+ Integer::Power2(2*DiscreteLogWorkFactor(p_.BitCount())) ) );
+ x.Encode(priv, p_.ByteCount());
+ }
+diff -ur mysql-orig/include/my_global.h mysql/include/my_global.h
+--- mysql-orig/include/my_global.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/include/my_global.h 2012-08-14 01:14:59.332198575 +0000
+@@ -586,10 +586,8 @@
+ #endif
+
+ /* Define some useful general macros */
+-#if !defined(max)
+-#define max(a, b) ((a) > (b) ? (a) : (b))
+-#define min(a, b) ((a) < (b) ? (a) : (b))
+-#endif
++#define MYSQL_MAX(a, b) ((a) > (b) ? (a) : (b))
++#define MYSQL_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+ #if !defined(HAVE_UINT)
+ #undef HAVE_UINT
+diff -ur mysql-orig/libmysql/libmysql.c mysql/libmysql/libmysql.c
+--- mysql-orig/libmysql/libmysql.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/libmysql/libmysql.c 2012-08-14 01:14:59.332198575 +0000
+@@ -1572,7 +1572,7 @@
+ my_net_set_read_timeout(net, CLIENT_NET_READ_TIMEOUT);
+ my_net_set_write_timeout(net, CLIENT_NET_WRITE_TIMEOUT);
+ net->retry_count= 1;
+- net->max_packet_size= max(net_buffer_length, max_allowed_packet);
++ net->max_packet_size= MYSQL_MAX(net_buffer_length, max_allowed_packet);
+ }
+
+ /*
+@@ -3622,7 +3622,7 @@
+ copy_length= end - start;
+ /* We've got some data beyond offset: copy up to buffer_length bytes */
+ if (param->buffer_length)
+- memcpy(buffer, start, min(copy_length, param->buffer_length));
++ memcpy(buffer, start, MYSQL_MIN(copy_length, param->buffer_length));
+ }
+ else
+ copy_length= 0;
+@@ -3855,9 +3855,9 @@
+ precisions. This will ensure that on the same machine you get the
+ same value as a string independent of the protocol you use.
+ */
+- sprintf(buff, "%-*.*g", (int) min(sizeof(buff)-1,
++ sprintf(buff, "%-*.*g", (int) MYSQL_MIN(sizeof(buff)-1,
+ param->buffer_length),
+- min(DBL_DIG, width), value);
++ MYSQL_MIN(DBL_DIG,width), value);
+ end= strcend(buff, ' ');
+ *end= 0;
+ }
+@@ -4175,7 +4175,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ *param->length= length;
+ *param->error= copy_length < length;
+@@ -4187,7 +4187,7 @@
+ uchar **row)
+ {
+ ulong length= net_field_length(row);
+- ulong copy_length= min(length, param->buffer_length);
++ ulong copy_length= MYSQL_MIN(length, param->buffer_length);
+ memcpy(param->buffer, (char *)*row, copy_length);
+ /* Add an end null if there is room in the buffer */
+ if (copy_length != param->buffer_length)
+diff -ur mysql-orig/libmysqld/lib_sql.cc mysql/libmysqld/lib_sql.cc
+--- mysql-orig/libmysqld/lib_sql.cc 2012-08-14 01:12:29.723435087 +0000
++++ mysql/libmysqld/lib_sql.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -844,7 +844,7 @@
+ is cleared between substatements, and mysqltest gets confused
+ */
+ thd->cur_data->embedded_info->warning_count=
+- (thd->spcont ? 0 : min(total_warn_count, 65535));
++ (thd->spcont ? 0 : MYSQL_MIN(total_warn_count, 65535));
+ return FALSE;
+ }
+
+diff -ur mysql-orig/mysys/array.c mysql/mysys/array.c
+--- mysql-orig/mysys/array.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/array.c 2012-08-14 01:14:59.372198019 +0000
+@@ -50,7 +50,7 @@
+ DBUG_ENTER("init_dynamic_array");
+ if (!alloc_increment)
+ {
+- alloc_increment=max((8192-MALLOC_OVERHEAD)/element_size,16);
++ alloc_increment=MYSQL_MAX((8192-MALLOC_OVERHEAD)/element_size,16);
+ if (init_alloc > 8 && alloc_increment > init_alloc * 2)
+ alloc_increment=init_alloc*2;
+ }
+@@ -344,7 +344,7 @@
+
+ void freeze_size(DYNAMIC_ARRAY *array)
+ {
+- uint elements=max(array->elements,1);
++ uint elements=MYSQL_MAX(array->elements,1);
+
+ /*
+ Do nothing if we are using a static buffer
+diff -ur mysql-orig/mysys/default.c mysql/mysys/default.c
+--- mysql-orig/mysys/default.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/default.c 2012-08-14 01:14:59.372198019 +0000
+@@ -796,7 +796,7 @@
+ for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
+ end[0]=0;
+
+- strmake(curr_gr, ptr, min((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
++ strmake(curr_gr, ptr, MYSQL_MIN((size_t) (end-ptr)+1, sizeof(curr_gr)-1));
+
+ /* signal that a new group is found */
+ opt_handler(handler_ctx, curr_gr, NULL);
+diff -ur mysql-orig/mysys/mf_format.c mysql/mysys/mf_format.c
+--- mysql-orig/mysys/mf_format.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_format.c 2012-08-14 01:14:59.372198019 +0000
+@@ -86,7 +86,7 @@
+ tmp_length= strlength(startpos);
+ DBUG_PRINT("error",("dev: '%s' ext: '%s' length: %u",dev,ext,
+ (uint) length));
+- (void) strmake(to,startpos,min(tmp_length,FN_REFLEN-1));
++ (void) strmake(to,startpos,MYSQL_MIN(tmp_length,FN_REFLEN-1));
+ }
+ else
+ {
+diff -ur mysql-orig/mysys/mf_iocache.c mysql/mysys/mf_iocache.c
+--- mysql-orig/mysys/mf_iocache.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/mf_iocache.c 2012-08-14 01:14:59.372198019 +0000
+@@ -1099,7 +1099,7 @@
+ */
+ while (write_length)
+ {
+- size_t copy_length= min(write_length, write_cache->buffer_length);
++ size_t copy_length= MYSQL_MIN(write_length, write_cache->buffer_length);
+ int __attribute__((unused)) rc;
+
+ rc= lock_io_cache(write_cache, write_cache->pos_in_file);
+@@ -1258,7 +1258,7 @@
+ TODO: figure out if the assert below is needed or correct.
+ */
+ DBUG_ASSERT(pos_in_file == info->end_of_file);
+- copy_len=min(Count, len_in_buff);
++ copy_len=MYSQL_MIN(Count, len_in_buff);
+ memcpy(Buffer, info->append_read_pos, copy_len);
+ info->append_read_pos += copy_len;
+ Count -= copy_len;
+@@ -1367,7 +1367,7 @@
+ }
+ #endif
+ /* Copy found bytes to buffer */
+- length=min(Count,read_length);
++ length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->read_pos,(size_t) length);
+ Buffer+=length;
+ Count-=length;
+@@ -1401,7 +1401,7 @@
+ if ((read_length=my_read(info->file,info->request_pos,
+ read_length, info->myflags)) == (size_t) -1)
+ return info->error= -1;
+- use_length=min(Count,read_length);
++ use_length=MYSQL_MIN(Count,read_length);
+ memcpy(Buffer,info->request_pos,(size_t) use_length);
+ info->read_pos=info->request_pos+Count;
+ info->read_end=info->request_pos+read_length;
+diff -ur mysql-orig/mysys/my_alloc.c mysql/mysys/my_alloc.c
+--- mysql-orig/mysys/my_alloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_alloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -214,7 +214,7 @@
+ { /* Time to alloc new block */
+ block_size= mem_root->block_size * (mem_root->block_num >> 2);
+ get_size= length+ALIGN_SIZE(sizeof(USED_MEM));
+- get_size= max(get_size, block_size);
++ get_size= MYSQL_MAX(get_size, block_size);
+
+ if (!(next = (USED_MEM*) my_malloc(get_size,MYF(MY_WME))))
+ {
+diff -ur mysql-orig/mysys/my_bitmap.c mysql/mysys/my_bitmap.c
+--- mysql-orig/mysys/my_bitmap.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_bitmap.c 2012-08-14 01:14:59.372198019 +0000
+@@ -425,7 +425,7 @@
+
+ DBUG_ASSERT(map->bitmap && map2->bitmap);
+
+- end= to+min(len,len2);
++ end= to+MYSQL_MIN(len,len2);
+ for (; to < end; to++, from++)
+ *to &= *from;
+
+diff -ur mysql-orig/mysys/my_compare.c mysql/mysys/my_compare.c
+--- mysql-orig/mysys/my_compare.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compare.c 2012-08-14 01:14:59.372198019 +0000
+@@ -30,7 +30,7 @@
+ static int compare_bin(uchar *a, uint a_length, uchar *b, uint b_length,
+ my_bool part_key, my_bool skip_end_space)
+ {
+- uint length= min(a_length,b_length);
++ uint length= MYSQL_MIN(a_length,b_length);
+ uchar *end= a+ length;
+ int flag;
+
+@@ -158,7 +158,7 @@
+ continue; /* To next key part */
+ }
+ }
+- end= a+ min(keyseg->length,key_length);
++ end= a+ MYSQL_MIN(keyseg->length,key_length);
+ next_key_length=key_length-keyseg->length;
+
+ switch ((enum ha_base_keytype) keyseg->type) {
+diff -ur mysql-orig/mysys/my_compress.c mysql/mysys/my_compress.c
+--- mysql-orig/mysys/my_compress.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_compress.c 2012-08-14 01:14:59.372198019 +0000
+@@ -244,7 +244,7 @@
+
+ if (ver != 1)
+ DBUG_RETURN(1);
+- if (!(data= my_malloc(max(orglen, complen), MYF(MY_WME))))
++ if (!(data= my_malloc(MYSQL_MAX(orglen, complen), MYF(MY_WME))))
+ DBUG_RETURN(2);
+ memcpy(data, pack_data + BLOB_HEADER, complen);
+
+diff -ur mysql-orig/mysys/my_conio.c mysql/mysys/my_conio.c
+--- mysql-orig/mysys/my_conio.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_conio.c 2012-08-14 01:14:59.372198019 +0000
+@@ -165,13 +165,13 @@
+ though it is known it should not be more than 64K
+ so we cut 64K and try first size of screen buffer
+ if it is still to large we cut half of it and try again
+- later we may want to cycle from min(clen, 65535) to allowed size
++ later we may want to cycle from MYSQL_MIN(clen, 65535) to allowed size
+ with small decrement to determine exact allowed buffer
+ */
+- clen= min(clen, 65535);
++ clen= MYSQL_MIN(clen, 65535);
+ do
+ {
+- clen= min(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
++ clen= MYSQL_MIN(clen, (size_t) csbi.dwSize.X*csbi.dwSize.Y);
+ if (!ReadConsole((HANDLE)my_coninpfh, (LPVOID)buffer, (DWORD) clen - 1, &plen_res,
+ NULL))
+ {
+diff -ur mysql-orig/mysys/my_file.c mysql/mysys/my_file.c
+--- mysql-orig/mysys/my_file.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_file.c 2012-08-14 01:14:59.372198019 +0000
+@@ -77,7 +77,7 @@
+ static uint set_max_open_files(uint max_file_limit)
+ {
+ /* We don't know the limit. Return best guess */
+- return min(max_file_limit, OS_FILE_LIMIT);
++ return MYSQL_MIN(max_file_limit, OS_FILE_LIMIT);
+ }
+ #endif
+
+@@ -99,7 +99,7 @@
+ DBUG_ENTER("my_set_max_open_files");
+ DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));
+
+- files= set_max_open_files(min(files, OS_FILE_LIMIT));
++ files= set_max_open_files(MYSQL_MIN(files, OS_FILE_LIMIT));
+ if (files <= MY_NFILE)
+ DBUG_RETURN(files);
+
+@@ -109,9 +109,9 @@
+
+ /* Copy any initialized files */
+ memcpy((char*) tmp, (char*) my_file_info,
+- sizeof(*tmp) * min(my_file_limit, files));
++ sizeof(*tmp) * MYSQL_MIN(my_file_limit, files));
+ bzero((char*) (tmp + my_file_limit),
+- max((int) (files- my_file_limit), 0)*sizeof(*tmp));
++ MYSQL_MAX((int) (files- my_file_limit), 0)*sizeof(*tmp));
+ my_free_open_file_info(); /* Free if already allocated */
+ my_file_info= tmp;
+ my_file_limit= files;
+diff -ur mysql-orig/mysys/my_getopt.c mysql/mysys/my_getopt.c
+--- mysql-orig/mysys/my_getopt.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_getopt.c 2012-08-14 01:14:59.372198019 +0000
+@@ -985,7 +985,7 @@
+ }
+ if (optp->max_value && num > (double) optp->max_value)
+ num= (double) optp->max_value;
+- return max(num, (double) optp->min_value);
++ return MYSQL_MAX(num, (double) optp->min_value);
+ }
+
+ /*
+diff -ur mysql-orig/mysys/my_static.h mysql/mysys/my_static.h
+--- mysql-orig/mysys/my_static.h 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/my_static.h 2012-08-14 01:14:59.372198019 +0000
+@@ -22,7 +22,7 @@
+ #include <signal.h>
+
+ #define MAX_SIGNALS 10 /* Max signals under a dont-allow */
+-#define MIN_KEYBLOCK (min(IO_SIZE,1024))
++#define MIN_KEYBLOCK (MYSQL_MIN(IO_SIZE,1024))
+ #define MAX_KEYBLOCK 8192 /* Max keyblocklength == 8*IO_SIZE */
+ #define MAX_BLOCK_TYPES MAX_KEYBLOCK/MIN_KEYBLOCK
+
+diff -ur mysql-orig/mysys/safemalloc.c mysql/mysys/safemalloc.c
+--- mysql-orig/mysys/safemalloc.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/safemalloc.c 2012-08-14 01:14:59.372198019 +0000
+@@ -250,7 +250,7 @@
+
+ if ((data= _mymalloc(size,filename,lineno,MyFlags))) /* Allocate new area */
+ {
+- size=min(size, irem->datasize); /* Move as much as possibly */
++ size=MYSQL_MIN(size, irem->datasize); /* Move as much as possibly */
+ memcpy((uchar*) data, ptr, (size_t) size); /* Copy old data */
+ _myfree(ptr, filename, lineno, 0); /* Free not needed area */
+ }
+diff -ur mysql-orig/mysys/stacktrace.c mysql/mysys/stacktrace.c
+--- mysql-orig/mysys/stacktrace.c 2012-08-14 01:12:29.713435171 +0000
++++ mysql/mysys/stacktrace.c 2012-08-14 01:14:59.372198019 +0000
+@@ -98,7 +98,7 @@
+ /* Read up to the maximum number of bytes. */
+ while (total)
+ {
+- count= min(sizeof(buf), total);
++ count= MYSQL_MIN(sizeof(buf), total);
+
+ if ((nbytes= pread(fd, buf, count, offset)) < 0)
+ {
+@@ -328,7 +328,7 @@
+
+ if (!stack_bottom || (uchar*) stack_bottom > (uchar*) &fp)
+ {
+- ulong tmp= min(0x10000,thread_stack);
++ ulong tmp= MYSQL_MIN(0x10000,thread_stack);
+ /* Assume that the stack starts at the previous even 65K */
+ stack_bottom= (uchar*) (((ulong) &fp + tmp) & ~(ulong) 0xFFFF);
+ my_safe_printf_stderr("Cannot determine thread, fp=%p, "
+diff -ur mysql-orig/server-tools/instance-manager/buffer.cc mysql/server-tools/instance-manager/buffer.cc
+--- mysql-orig/server-tools/instance-manager/buffer.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/buffer.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -86,8 +86,8 @@
+ if (position + len_arg >= buffer_size)
+ {
+ buffer= (uchar*) my_realloc(buffer,
+- min(MAX_BUFFER_SIZE,
+- max((uint) (buffer_size*1.5),
++ MYSQL_MIN(MAX_BUFFER_SIZE,
++ MYSQL_MAX((uint) (buffer_size*1.5),
+ position + len_arg)), MYF(0));
+ if (!(buffer))
+ goto err;
+diff -ur mysql-orig/server-tools/instance-manager/listener.cc mysql/server-tools/instance-manager/listener.cc
+--- mysql-orig/server-tools/instance-manager/listener.cc 2012-08-14 01:12:29.703435253 +0000
++++ mysql/server-tools/instance-manager/listener.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -106,7 +106,7 @@
+
+ /* II. Listen sockets and spawn childs */
+ for (i= 0; i < num_sockets; i++)
+- n= max(n, sockets[i]);
++ n= MYSQL_MAX(n, sockets[i]);
+ n++;
+
+ timeval tv;
+diff -ur mysql-orig/sql/debug_sync.cc mysql/sql/debug_sync.cc
+--- mysql-orig/sql/debug_sync.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/debug_sync.cc 2012-08-14 01:14:59.372198019 +0000
+@@ -1036,7 +1036,7 @@
+ DBUG_ASSERT(action);
+ DBUG_ASSERT(ds_control);
+
+- action->activation_count= max(action->hit_limit, action->execute);
++ action->activation_count= MYSQL_MAX(action->hit_limit, action->execute);
+ if (!action->activation_count)
+ {
+ debug_sync_remove_action(ds_control, action);
+diff -ur mysql-orig/sql/field.cc mysql/sql/field.cc
+--- mysql-orig/sql/field.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/field.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -55,7 +55,7 @@
+ #define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
+ #define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
+-((ulong) ((LL(1) << min(arg, 4) * 8) - LL(1)))
++((ulong) ((LL(1) << MYSQL_MIN(arg, 4) * 8) - LL(1)))
+
+ #define ASSERT_COLUMN_MARKED_FOR_READ DBUG_ASSERT(!table || (!table->read_set || bitmap_is_set(table->read_set, field_index)))
+ #define ASSERT_COLUMN_MARKED_FOR_WRITE DBUG_ASSERT(!table || (!table->write_set || bitmap_is_set(table->write_set, field_index)))
+@@ -2073,7 +2073,7 @@
+ tmp_uint=tmp_dec+(uint)(int_digits_end-int_digits_from);
+ else if (expo_sign_char == '-')
+ {
+- tmp_uint=min(exponent,(uint)(int_digits_end-int_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(int_digits_end-int_digits_from));
+ frac_digits_added_zeros=exponent-tmp_uint;
+ int_digits_end -= tmp_uint;
+ frac_digits_head_end=int_digits_end+tmp_uint;
+@@ -2081,7 +2081,7 @@
+ }
+ else // (expo_sign_char=='+')
+ {
+- tmp_uint=min(exponent,(uint)(frac_digits_end-frac_digits_from));
++ tmp_uint=MYSQL_MIN(exponent,(uint)(frac_digits_end-frac_digits_from));
+ int_digits_added_zeros=exponent-tmp_uint;
+ int_digits_tail_from=frac_digits_from;
+ frac_digits_from=frac_digits_from+tmp_uint;
+@@ -2506,7 +2506,7 @@
+ {
+ signed int overflow;
+
+- dec= min(dec, DECIMAL_MAX_SCALE);
++ dec= MYSQL_MIN(dec, DECIMAL_MAX_SCALE);
+
+ /*
+ If the value still overflows the field with the corrected dec,
+@@ -2522,7 +2522,7 @@
+ overflow= required_length - len;
+
+ if (overflow > 0)
+- dec= max(0, dec - overflow); // too long, discard fract
++ dec= MYSQL_MAX(0, dec - overflow); // too long, discard fract
+ else
+ /* Corrected value fits. */
+ len= required_length;
+@@ -3092,7 +3092,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,5*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,5*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -3304,7 +3304,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,7*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,7*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ short j;
+@@ -3521,7 +3521,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,10*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,10*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ long j= unsigned_flag ? (long) uint3korr(ptr) : sint3korr(ptr);
+@@ -3740,7 +3740,7 @@
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,12*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,12*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ int32 j;
+@@ -3981,7 +3981,7 @@
+ {
+ CHARSET_INFO *cs= &my_charset_bin;
+ uint length;
+- uint mlength=max(field_length+1,22*cs->mbmaxlen);
++ uint mlength=MYSQL_MAX(field_length+1,22*cs->mbmaxlen);
+ val_buffer->alloc(mlength);
+ char *to=(char*) val_buffer->ptr();
+ longlong j;
+@@ -4204,7 +4204,7 @@
+ #endif
+ memcpy_fixed((uchar*) &nr,ptr,sizeof(nr));
+
+- uint to_length=max(field_length,70);
++ uint to_length=MYSQL_MAX(field_length,70);
+ val_buffer->alloc(to_length);
+ char *to=(char*) val_buffer->ptr();
+
+@@ -6443,13 +6443,13 @@
+ calculate the maximum number of significant digits if the 'f'-format
+ would be used (+1 for decimal point if the number has a fractional part).
+ */
+- digits= max(1, (int) max_length - fractional);
++ digits= MYSQL_MAX(1, (int) max_length - fractional);
+ /*
+ If the exponent is negative, decrease digits by the number of leading zeros
+ after the decimal point that do not count as significant digits.
+ */
+ if (exp < 0)
+- digits= max(1, (int) digits + exp);
++ digits= MYSQL_MAX(1, (int) digits + exp);
+ /*
+ 'e'-format is used only if the exponent is less than -4 or greater than or
+ equal to the precision. In this case we need to adjust the number of
+@@ -6457,7 +6457,7 @@
+ We also have to reserve one additional character if abs(exp) >= 100.
+ */
+ if (exp >= (int) digits || exp < -4)
+- digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
++ digits= MYSQL_MAX(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+
+ /* Limit precision to DBL_DIG to avoid garbage past significant digits */
+ set_if_smaller(digits, DBL_DIG);
+@@ -6715,7 +6715,7 @@
+ uint max_length,
+ bool low_byte_first __attribute__((unused)))
+ {
+- uint length= min(field_length,max_length);
++ uint length= MYSQL_MIN(field_length,max_length);
+ uint local_char_length= max_length/field_charset->mbmaxlen;
+ if (length > local_char_length)
+ local_char_length= my_charpos(field_charset, from, from+length,
+@@ -7709,7 +7709,7 @@
+ from= tmpstr.ptr();
+ }
+
+- new_length= min(max_data_length(), field_charset->mbmaxlen * length);
++ new_length= MYSQL_MIN(max_data_length(), field_charset->mbmaxlen * length);
+ if (value.alloc(new_length))
+ goto oom_error;
+
+@@ -7869,7 +7869,7 @@
+ b_length=get_length(b_ptr);
+ if (b_length > max_length)
+ b_length=max_length;
+- diff=memcmp(a,b,min(a_length,b_length));
++ diff=memcmp(a,b,MYSQL_MIN(a_length,b_length));
+ return diff ? diff : (int) (a_length - b_length);
+ }
+
+@@ -8065,7 +8065,7 @@
+ length given is smaller than the actual length of the blob, we
+ just store the initial bytes of the blob.
+ */
+- store_length(to, packlength, min(length, max_length), low_byte_first);
++ store_length(to, packlength, MYSQL_MIN(length, max_length), low_byte_first);
+
+ /*
+ Store the actual blob data, which will occupy 'length' bytes.
+@@ -9112,7 +9112,7 @@
+ {
+ ASSERT_COLUMN_MARKED_FOR_READ;
+ char buff[sizeof(longlong)];
+- uint length= min(pack_length(), sizeof(longlong));
++ uint length= MYSQL_MIN(pack_length(), sizeof(longlong));
+ ulonglong bits= val_int();
+ mi_int8store(buff,bits);
+
+@@ -9198,7 +9198,7 @@
+ *buff++= bits;
+ length--;
+ }
+- uint data_length = min(length, bytes_in_rec);
++ uint data_length = MYSQL_MIN(length, bytes_in_rec);
+ memcpy(buff, ptr, data_length);
+ return data_length + 1;
+ }
+@@ -9326,7 +9326,7 @@
+ uchar bits= get_rec_bits(bit_ptr + (from - ptr), bit_ofs, bit_len);
+ *to++= bits;
+ }
+- length= min(bytes_in_rec, max_length - (bit_len > 0));
++ length= MYSQL_MIN(bytes_in_rec, max_length - (bit_len > 0));
+ memcpy(to, from, length);
+ return to + length;
+ }
+@@ -9783,7 +9783,7 @@
+ DBUG_ASSERT(MAX_DATETIME_COMPRESSED_WIDTH < UINT_MAX);
+ if (length != UINT_MAX) /* avoid overflow; is safe because of min() */
+ length= ((length+1)/2)*2;
+- length= min(length, MAX_DATETIME_COMPRESSED_WIDTH);
++ length= MYSQL_MIN(length, MAX_DATETIME_COMPRESSED_WIDTH);
+ }
+ flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ /*
+diff -ur mysql-orig/sql/filesort.cc mysql/sql/filesort.cc
+--- mysql-orig/sql/filesort.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/filesort.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -194,7 +194,7 @@
+ #ifdef CAN_TRUST_RANGE
+ if (select && select->quick && select->quick->records > 0L)
+ {
+- records=min((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
++ records=MYSQL_MIN((ha_rows) (select->quick->records*2+EXTRA_RECORDS*2),
+ table->file->stats.records)+EXTRA_RECORDS;
+ selected_records_file=0;
+ }
+@@ -217,14 +217,14 @@
+
+ memavl= thd->variables.sortbuff_size;
+ min_sort_memory=
+- max(MIN_SORT_MEMORY,
++ MYSQL_MAX(MIN_SORT_MEMORY,
+ ALIGN_SIZE(MERGEBUFF2 * (param.rec_length + sizeof(uchar*))));
+
+ while (memavl >= min_sort_memory)
+ {
+ ulong old_memavl;
+ ulong keys= memavl/(param.rec_length+sizeof(char*));
+- param.keys=(uint) min(records+1, keys);
++ param.keys=(uint) MYSQL_MIN(records+1, keys);
+
+ if (table_sort.sort_keys &&
+ table_sort.sort_keys_size != char_array_size(param.keys,
+@@ -1133,7 +1133,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= rec_length*count),buffpek->file_pos,MYF_RW))
+@@ -1396,7 +1396,7 @@
+ != -1 && error != 0);
+
+ end:
+- lastbuff->count= min(org_max_rows-max_rows, param->max_rows);
++ lastbuff->count= MYSQL_MIN(org_max_rows-max_rows, param->max_rows);
+ lastbuff->file_pos= to_start_filepos;
+ err:
+ delete_queue(&queue);
+diff -ur mysql-orig/sql/ha_ndbcluster.cc mysql/sql/ha_ndbcluster.cc
+--- mysql-orig/sql/ha_ndbcluster.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/ha_ndbcluster.cc 2012-08-14 01:14:59.382197947 +0000
+@@ -799,7 +799,7 @@
+
+ DBUG_PRINT("value", ("set blob ptr: 0x%lx len: %u",
+ (long) blob_ptr, blob_len));
+- DBUG_DUMP("value", blob_ptr, min(blob_len, 26));
++ DBUG_DUMP("value", blob_ptr, MYSQL_MIN(blob_len, 26));
+
+ if (set_blob_value)
+ *set_blob_value= TRUE;
+diff -ur mysql-orig/sql/handler.h mysql/sql/handler.h
+--- mysql-orig/sql/handler.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/handler.h 2012-08-14 01:14:59.382197947 +0000
+@@ -1607,15 +1607,15 @@
+ { return (HA_ERR_WRONG_COMMAND); }
+
+ uint max_record_length() const
+- { return min(HA_MAX_REC_LENGTH, max_supported_record_length()); }
++ { return MYSQL_MIN(HA_MAX_REC_LENGTH, max_supported_record_length()); }
+ uint max_keys() const
+- { return min(MAX_KEY, max_supported_keys()); }
++ { return MYSQL_MIN(MAX_KEY, max_supported_keys()); }
+ uint max_key_parts() const
+- { return min(MAX_REF_PARTS, max_supported_key_parts()); }
++ { return MYSQL_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
+ uint max_key_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ uint max_key_part_length() const
+- { return min(MAX_KEY_LENGTH, max_supported_key_part_length()); }
++ { return MYSQL_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+
+ virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+ virtual uint max_supported_keys() const { return 0; }
+diff -ur mysql-orig/sql/ha_partition.cc mysql/sql/ha_partition.cc
+--- mysql-orig/sql/ha_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/ha_partition.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -6138,7 +6138,7 @@
+ {
+ *first= bitmap_get_first_set(&(m_part_info->used_partitions));
+ *num_used_parts= bitmap_bits_set(&(m_part_info->used_partitions));
+- *check_min_num= min(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
++ *check_min_num= MYSQL_MIN(MAX_PARTS_FOR_OPTIMIZER_CALLS, *num_used_parts);
+ }
+
+
+diff -ur mysql-orig/sql/item_buff.cc mysql/sql/item_buff.cc
+--- mysql-orig/sql/item_buff.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_buff.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -61,7 +61,7 @@
+
+ Cached_item_str::Cached_item_str(THD *thd, Item *arg)
+ :item(arg),
+- value_max_length(min(arg->max_length, thd->variables.max_sort_length)),
++ value_max_length(MYSQL_MIN(arg->max_length, thd->variables.max_sort_length)),
+ value(value_max_length)
+ {}
+
+@@ -71,7 +71,7 @@
+ bool tmp;
+
+ if ((res=item->val_str(&tmp_value)))
+- res->length(min(res->length(), value_max_length));
++ res->length(MYSQL_MIN(res->length(), value_max_length));
+ if (null_value != item->null_value)
+ {
+ if ((null_value= item->null_value))
+diff -ur mysql-orig/sql/item.cc mysql/sql/item.cc
+--- mysql-orig/sql/item.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -76,7 +76,7 @@
+ Hybrid_type_traits_decimal::fix_length_and_dec(Item *item, Item *arg) const
+ {
+ item->decimals= arg->decimals;
+- item->max_length= min(arg->max_length + DECIMAL_LONGLONG_DIGITS,
++ item->max_length= MYSQL_MIN(arg->max_length + DECIMAL_LONGLONG_DIGITS,
+ DECIMAL_MAX_STR_LENGTH);
+ }
+
+@@ -444,9 +444,9 @@
+ {
+ uint prec=
+ my_decimal_length_to_precision(max_length, decimals, unsigned_flag);
+- return min(prec, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(prec, DECIMAL_MAX_PRECISION);
+ }
+- return min(max_length, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_length, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -752,7 +752,7 @@
+ &res_length);
+ }
+ else
+- name= sql_strmake(str, (name_length= min(length,MAX_ALIAS_NAME)));
++ name= sql_strmake(str, (name_length= MYSQL_MIN(length,MAX_ALIAS_NAME)));
+ }
+
+
+@@ -5417,7 +5417,7 @@
+ // following assert is redundant, because fixed=1 assigned in constructor
+ DBUG_ASSERT(fixed == 1);
+ char *end=(char*) str_value.ptr()+str_value.length(),
+- *ptr=end-min(str_value.length(),sizeof(longlong));
++ *ptr=end-MYSQL_MIN(str_value.length(),sizeof(longlong));
+
+ ulonglong value=0;
+ for (; ptr != end ; ptr++)
+@@ -5472,7 +5472,7 @@
+ void Item_hex_string::print(String *str, enum_query_type query_type)
+ {
+ char *end= (char*) str_value.ptr() + str_value.length(),
+- *ptr= end - min(str_value.length(), sizeof(longlong));
++ *ptr= end - MYSQL_MIN(str_value.length(), sizeof(longlong));
+ str->append("0x");
+ for (; ptr != end ; ptr++)
+ {
+@@ -7554,14 +7554,14 @@
+ /* fix variable decimals which always is NOT_FIXED_DEC */
+ if (Field::result_merge_type(fld_type) == INT_RESULT)
+ item_decimals= 0;
+- decimals= max(decimals, item_decimals);
++ decimals= MYSQL_MAX(decimals, item_decimals);
+ }
+ if (Field::result_merge_type(fld_type) == DECIMAL_RESULT)
+ {
+- decimals= min(max(decimals, item->decimals), DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(MYSQL_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
+ int item_int_part= item->decimal_int_part();
+- int item_prec = max(prev_decimal_int_part, item_int_part) + decimals;
+- int precision= min(item_prec, DECIMAL_MAX_PRECISION);
++ int item_prec = MYSQL_MAX(prev_decimal_int_part, item_int_part) + decimals;
++ int precision= MYSQL_MIN(item_prec, DECIMAL_MAX_PRECISION);
+ unsigned_flag&= item->unsigned_flag;
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+@@ -7592,7 +7592,7 @@
+ */
+ if (collation.collation != &my_charset_bin)
+ {
+- max_length= max(old_max_chars * collation.collation->mbmaxlen,
++ max_length= MYSQL_MAX(old_max_chars * collation.collation->mbmaxlen,
+ display_length(item) /
+ item->collation.collation->mbmaxlen *
+ collation.collation->mbmaxlen);
+@@ -7614,7 +7614,7 @@
+ {
+ int delta1= max_length_orig - decimals_orig;
+ int delta2= item->max_length - item->decimals;
+- max_length= max(delta1, delta2) + decimals;
++ max_length= MYSQL_MAX(delta1, delta2) + decimals;
+ if (fld_type == MYSQL_TYPE_FLOAT && max_length > FLT_DIG + 2)
+ {
+ max_length= MAX_FLOAT_STR_LENGTH;
+@@ -7632,7 +7632,7 @@
+ break;
+ }
+ default:
+- max_length= max(max_length, display_length(item));
++ max_length= MYSQL_MAX(max_length, display_length(item));
+ };
+ maybe_null|= item->maybe_null;
+ get_full_info(item);
+diff -ur mysql-orig/sql/item_cmpfunc.cc mysql/sql/item_cmpfunc.cc
+--- mysql-orig/sql/item_cmpfunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_cmpfunc.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -628,7 +628,7 @@
+ {
+ if ((*a)->decimals < NOT_FIXED_DEC && (*b)->decimals < NOT_FIXED_DEC)
+ {
+- precision= 5 / log_10[max((*a)->decimals, (*b)->decimals) + 1];
++ precision= 5 / log_10[MYSQL_MAX((*a)->decimals, (*b)->decimals) + 1];
+ if (func == &Arg_comparator::compare_real)
+ func= &Arg_comparator::compare_real_fixed;
+ else if (func == &Arg_comparator::compare_e_real)
+@@ -1315,7 +1315,7 @@
+ owner->null_value= 0;
+ uint res1_length= res1->length();
+ uint res2_length= res2->length();
+- int cmp= memcmp(res1->ptr(), res2->ptr(), min(res1_length,res2_length));
++ int cmp= memcmp(res1->ptr(), res2->ptr(), MYSQL_MIN(res1_length,res2_length));
+ return cmp ? cmp : (int) (res1_length - res2_length);
+ }
+ }
+@@ -2447,7 +2447,7 @@
+ {
+ agg_result_type(&hybrid_type, args, 2);
+ maybe_null=args[1]->maybe_null;
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ unsigned_flag= args[0]->unsigned_flag && args[1]->unsigned_flag;
+
+ if (hybrid_type == DECIMAL_RESULT || hybrid_type == INT_RESULT)
+@@ -2458,10 +2458,10 @@
+ int len1= args[1]->max_length - args[1]->decimals
+ - (args[1]->unsigned_flag ? 0 : 1);
+
+- max_length= max(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
++ max_length= MYSQL_MAX(len0, len1) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+
+ switch (hybrid_type) {
+ case STRING_RESULT:
+@@ -2485,9 +2485,9 @@
+ {
+ int arg0_int_part= args[0]->decimal_int_part();
+ int arg1_int_part= args[1]->decimal_int_part();
+- int max_int_part= max(arg0_int_part, arg1_int_part);
++ int max_int_part= MYSQL_MAX(arg0_int_part, arg1_int_part);
+ int precision= max_int_part + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -2615,7 +2615,7 @@
+ 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);
++ decimals= MYSQL_MAX(args[1]->decimals, args[2]->decimals);
+ unsigned_flag=args[1]->unsigned_flag && args[2]->unsigned_flag;
+
+ enum Item_result arg1_type=args[1]->result_type();
+@@ -2659,10 +2659,10 @@
+ int len2= args[2]->max_length - args[2]->decimals
+ - (args[2]->unsigned_flag ? 0 : 1);
+
+- max_length=max(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
++ max_length=MYSQL_MAX(len1, len2) + decimals + (unsigned_flag ? 0 : 1);
+ }
+ else
+- max_length= max(args[1]->max_length, args[2]->max_length);
++ max_length= MYSQL_MAX(args[1]->max_length, args[2]->max_length);
+ }
+
+
+@@ -2670,8 +2670,8 @@
+ {
+ int arg1_prec= args[1]->decimal_int_part();
+ int arg2_prec= args[2]->decimal_int_part();
+- int precision=max(arg1_prec,arg2_prec) + decimals;
+- return min(precision, DECIMAL_MAX_PRECISION);
++ int precision=MYSQL_MAX(arg1_prec,arg2_prec) + decimals;
++ return MYSQL_MIN(precision, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -3081,7 +3081,7 @@
+
+ if (else_expr_num != -1)
+ set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
+- return min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ return MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ }
+
+
+@@ -4979,7 +4979,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 && pattern[g] == pattern[g + plm1 - f])
+ g--;
+@@ -4998,7 +4998,7 @@
+ else
+ {
+ if (i < g)
+- g = i; // g = min(i, g)
++ g = i; // g = MYSQL_MIN(i, g)
+ f = i;
+ while (g >= 0 &&
+ likeconv(cs, pattern[g]) == likeconv(cs, pattern[g + plm1 - f]))
+@@ -5119,14 +5119,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) (uchar) text[i + j]] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+@@ -5150,14 +5150,14 @@
+ register const int v = plm1 - i;
+ turboShift = u - v;
+ bcShift = bmBc[(uint) likeconv(cs, text[i + j])] - plm1 + i;
+- shift = max(turboShift, bcShift);
+- shift = max(shift, bmGs[i]);
++ shift = MYSQL_MAX(turboShift, bcShift);
++ shift = MYSQL_MAX(shift, bmGs[i]);
+ if (shift == bmGs[i])
+- u = min(pattern_len - shift, v);
++ u = MYSQL_MIN(pattern_len - shift, v);
+ else
+ {
+ if (turboShift < bcShift)
+- shift = max(shift, u + 1);
++ shift = MYSQL_MAX(shift, u + 1);
+ u = 0;
+ }
+ j+= shift;
+diff -ur mysql-orig/sql/item_func.cc mysql/sql/item_func.cc
+--- mysql-orig/sql/item_func.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.cc 2012-08-14 01:14:59.392197867 +0000
+@@ -549,7 +549,7 @@
+ set_if_bigger(max_int_part, args[i]->decimal_int_part());
+ set_if_smaller(unsigned_flag, args[i]->unsigned_flag);
+ }
+- int precision= min(max_int_part + decimals, DECIMAL_MAX_PRECISION);
++ int precision= MYSQL_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1143,10 +1143,10 @@
+ */
+ void Item_func_additive_op::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
+ int arg1_int= args[0]->decimal_precision() - args[0]->decimals;
+ int arg2_int= args[1]->decimal_precision() - args[1]->decimals;
+- int precision= max(arg1_int, arg2_int) + 1 + decimals;
++ int precision= MYSQL_MAX(arg1_int, arg2_int) + 1 + decimals;
+
+ /* Integer operations keep unsigned_flag if one of arguments is unsigned */
+ if (result_type() == INT_RESULT)
+@@ -1256,9 +1256,9 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + args[1]->decimals, DECIMAL_MAX_SCALE);
+ uint est_prec = args[0]->decimal_precision() + args[1]->decimal_precision();
+- uint precision= min(est_prec, DECIMAL_MAX_PRECISION);
++ uint precision= MYSQL_MIN(est_prec, DECIMAL_MAX_PRECISION);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1306,7 +1306,7 @@
+
+ void Item_func_div::result_precision()
+ {
+- uint precision=min(args[0]->decimal_precision() +
++ uint precision=MYSQL_MIN(args[0]->decimal_precision() +
+ args[1]->decimals + prec_increment,
+ DECIMAL_MAX_PRECISION);
+
+@@ -1315,7 +1315,7 @@
+ unsigned_flag= args[0]->unsigned_flag | args[1]->unsigned_flag;
+ else
+ unsigned_flag= args[0]->unsigned_flag & args[1]->unsigned_flag;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision, decimals,
+ unsigned_flag);
+ }
+@@ -1329,7 +1329,7 @@
+ switch(hybrid_type) {
+ case REAL_RESULT:
+ {
+- decimals=max(args[0]->decimals,args[1]->decimals)+prec_increment;
++ decimals=MYSQL_MAX(args[0]->decimals,args[1]->decimals)+prec_increment;
+ set_if_smaller(decimals, NOT_FIXED_DEC);
+ uint tmp=float_length(decimals);
+ if (decimals == NOT_FIXED_DEC)
+@@ -1460,8 +1460,8 @@
+
+ void Item_func_mod::result_precision()
+ {
+- decimals= max(args[0]->decimals, args[1]->decimals);
+- max_length= max(args[0]->max_length, args[1]->max_length);
++ decimals= MYSQL_MAX(args[0]->decimals, args[1]->decimals);
++ max_length= MYSQL_MAX(args[0]->max_length, args[1]->max_length);
+ }
+
+
+@@ -1983,7 +1983,7 @@
+
+ if (args[0]->decimals == NOT_FIXED_DEC)
+ {
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ hybrid_type= REAL_RESULT;
+ return;
+@@ -1993,7 +1993,7 @@
+ case REAL_RESULT:
+ case STRING_RESULT:
+ hybrid_type= REAL_RESULT;
+- decimals= min(decimals_to_set, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals_to_set, NOT_FIXED_DEC);
+ max_length= float_length(decimals);
+ break;
+ case INT_RESULT:
+@@ -2010,13 +2010,13 @@
+ case DECIMAL_RESULT:
+ {
+ hybrid_type= DECIMAL_RESULT;
+- decimals_to_set= min(DECIMAL_MAX_SCALE, decimals_to_set);
++ decimals_to_set= MYSQL_MIN(DECIMAL_MAX_SCALE, decimals_to_set);
+ int decimals_delta= args[0]->decimals - decimals_to_set;
+ int precision= args[0]->decimal_precision();
+ int length_increase= ((decimals_delta <= 0) || truncate) ? 0:1;
+
+ precision-= decimals_delta - length_increase;
+- decimals= min(decimals_to_set, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(decimals_to_set, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -2117,7 +2117,7 @@
+ my_decimal val, *value= args[0]->val_decimal(&val);
+ longlong dec= args[1]->val_int();
+ if (dec >= 0 || args[1]->unsigned_flag)
+- dec= min((ulonglong) dec, decimals);
++ dec= MYSQL_MIN((ulonglong) dec, decimals);
+ else if (dec < INT_MIN)
+ dec= INT_MIN;
+
+@@ -2989,7 +2989,7 @@
+ free_udf(u_d);
+ DBUG_RETURN(TRUE);
+ }
+- func->max_length=min(initid.max_length,MAX_BLOB_WIDTH);
++ func->max_length=MYSQL_MIN(initid.max_length,MAX_BLOB_WIDTH);
+ func->maybe_null=initid.maybe_null;
+ const_item_cache=initid.const_item;
+ /*
+@@ -2998,7 +2998,7 @@
+ */
+ if (!const_item_cache && !used_tables_cache)
+ used_tables_cache= RAND_TABLE_BIT;
+- func->decimals=min(initid.decimals,NOT_FIXED_DEC);
++ func->decimals=MYSQL_MIN(initid.decimals,NOT_FIXED_DEC);
+ }
+ initialized=1;
+ if (error)
+diff -ur mysql-orig/sql/item_func.h mysql/sql/item_func.h
+--- mysql-orig/sql/item_func.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_func.h 2012-08-14 01:14:59.402197785 +0000
+@@ -421,6 +421,6 @@
+ const char *func_name() const { return "cast_as_unsigned"; }
+ void fix_length_and_dec()
+ {
+- max_length= min(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
++ max_length= MYSQL_MIN(args[0]->max_length,MY_INT64_NUM_DECIMAL_DIGITS);
+ }
+ longlong val_int();
+diff -ur mysql-orig/sql/item_strfunc.cc mysql/sql/item_strfunc.cc
+--- mysql-orig/sql/item_strfunc.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -389,7 +389,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -750,7 +750,7 @@
+ }
+ else
+ {
+- uint new_len = max(tmp_value.alloced_length() * 2, concat_len);
++ uint new_len = MYSQL_MAX(tmp_value.alloced_length() * 2, concat_len);
+
+ if (tmp_value.realloc(new_len))
+ goto null;
+@@ -1251,7 +1251,7 @@
+
+ length= res->charpos((int) length, (uint32) start);
+ tmp_length= res->length() - start;
+- length= min(length, tmp_length);
++ length= MYSQL_MIN(length, tmp_length);
+
+ if (!start && (longlong) res->length() == length)
+ return res;
+@@ -1271,7 +1271,7 @@
+ if (start < 0)
+ max_length= ((uint)(-start) > max_length) ? 0 : (uint)(-start);
+ else
+- max_length-= min((uint)(start - 1), max_length);
++ max_length-= MYSQL_MIN((uint)(start - 1), max_length);
+ }
+ if (arg_count == 3 && args[2]->const_item())
+ {
+@@ -1962,7 +1962,7 @@
+ if ((null_value= args[0]->null_value))
+ return 0; /* purecov: inspected */
+
+- if (tmp_value.alloc(max(res->length(), 4 * cs->mbminlen)))
++ if (tmp_value.alloc(MYSQL_MAX(res->length(), 4 * cs->mbminlen)))
+ return str; /* purecov: inspected */
+ char *to= (char *) tmp_value.ptr();
+ char *to_end= to + tmp_value.alloced_length();
+@@ -3114,11 +3114,11 @@
+
+ void Item_func_export_set::fix_length_and_dec()
+ {
+- uint length=max(args[1]->max_length,args[2]->max_length);
++ uint length=MYSQL_MAX(args[1]->max_length,args[2]->max_length);
+ uint sep_length=(arg_count > 3 ? args[3]->max_length : 1);
+ max_length=length*64+sep_length*63;
+
+- if (agg_arg_charsets(collation, args+1, min(4,arg_count)-1,
++ if (agg_arg_charsets(collation, args+1, MYSQL_MIN(4,arg_count)-1,
+ MY_COLL_ALLOW_CONV, 1))
+ return;
+ }
+@@ -3582,7 +3582,7 @@
+ /*
+ -1 so we won't make tv= uuid_time for nanoseq >= (tv - uuid_time)
+ */
+- ulong delta= min(nanoseq, (ulong) (tv - uuid_time -1));
++ ulong delta= MYSQL_MIN(nanoseq, (ulong) (tv - uuid_time -1));
+ tv-= delta;
+ nanoseq-= delta;
+ }
+diff -ur mysql-orig/sql/item_strfunc.h mysql/sql/item_strfunc.h
+--- mysql-orig/sql/item_strfunc.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_strfunc.h 2012-08-14 01:14:59.402197785 +0000
+@@ -709,7 +709,7 @@
+ collation.set(args[0]->collation);
+ ulonglong max_result_length= (ulonglong) args[0]->max_length * 2 +
+ 2 * collation.collation->mbmaxlen;
+- max_length= (uint32) min(max_result_length, MAX_BLOB_WIDTH);
++ max_length= (uint32) MYSQL_MIN(max_result_length, MAX_BLOB_WIDTH);
+ }
+ };
+
+diff -ur mysql-orig/sql/item_sum.cc mysql/sql/item_sum.cc
+--- mysql-orig/sql/item_sum.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/item_sum.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -1139,7 +1139,7 @@
+ AVG() will divide val by count. We need to reserve digits
+ after decimal point as the result can be fractional.
+ */
+- decimals= min(decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(decimals + prec_increment, NOT_FIXED_DEC);
+ }
+
+
+@@ -1202,16 +1202,16 @@
+ if (hybrid_type == DECIMAL_RESULT)
+ {
+ int precision= args[0]->decimal_precision() + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+- f_precision= min(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
++ f_precision= MYSQL_MIN(precision+DECIMAL_LONGLONG_DIGITS, DECIMAL_MAX_PRECISION);
+ f_scale= args[0]->decimals;
+ dec_bin_size= my_decimal_get_binary_size(f_precision, f_scale);
+ }
+ else {
+- decimals= min(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, NOT_FIXED_DEC);
+ max_length= args[0]->max_length + prec_increment;
+ }
+ }
+@@ -1402,13 +1402,13 @@
+ switch (args[0]->result_type()) {
+ case REAL_RESULT:
+ case STRING_RESULT:
+- decimals= min(args[0]->decimals + 4, NOT_FIXED_DEC);
++ decimals= MYSQL_MIN(args[0]->decimals + 4, NOT_FIXED_DEC);
+ break;
+ case INT_RESULT:
+ case DECIMAL_RESULT:
+ {
+ int precision= args[0]->decimal_precision()*2 + prec_increment;
+- decimals= min(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
++ decimals= MYSQL_MIN(args[0]->decimals + prec_increment, DECIMAL_MAX_SCALE);
+ max_length= my_decimal_precision_to_length_no_truncation(precision,
+ decimals,
+ unsigned_flag);
+@@ -3345,7 +3345,7 @@
+ syntax of this function). If there is no ORDER BY clause, we don't
+ create this tree.
+ */
+- init_tree(tree, (uint) min(thd->variables.max_heap_table_size,
++ init_tree(tree, (uint) MYSQL_MIN(thd->variables.max_heap_table_size,
+ thd->variables.sortbuff_size/16), 0,
+ tree_key_length,
+ group_concat_key_cmp_with_order , 0, NULL, (void*) this);
+diff -ur mysql-orig/sql/item_timefunc.cc mysql/sql/item_timefunc.cc
+--- mysql-orig/sql/item_timefunc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/item_timefunc.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -310,14 +310,14 @@
+ switch (*++ptr) {
+ /* Year */
+ case 'Y':
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ if ((int) (tmp-val) <= 2)
+ l_time->year= year_2000_handling(l_time->year);
+ val= tmp;
+ break;
+ case 'y':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ l_time->year= year_2000_handling(l_time->year);
+@@ -326,7 +326,7 @@
+ /* Month */
+ case 'm':
+ case 'c':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->month= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -343,15 +343,15 @@
+ /* Day */
+ case 'd':
+ case 'e':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+ case 'D':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->day= (int) my_strtoll10(val, &tmp, &error);
+ /* Skip 'st, 'nd, 'th .. */
+- val= tmp + min((int) (val_end-tmp), 2);
++ val= tmp + MYSQL_MIN((int) (val_end-tmp), 2);
+ break;
+
+ /* Hour */
+@@ -362,14 +362,14 @@
+ /* fall through */
+ case 'k':
+ case 'H':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->hour= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+
+ /* Minute */
+ case 'i':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->minute= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -377,7 +377,7 @@
+ /* Second */
+ case 's':
+ case 'S':
+- tmp= (char*) val + min(2, val_len);
++ tmp= (char*) val + MYSQL_MIN(2, val_len);
+ l_time->second= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -429,7 +429,7 @@
+ val= tmp;
+ break;
+ case 'j':
+- tmp= (char*) val + min(val_len, 3);
++ tmp= (char*) val + MYSQL_MIN(val_len, 3);
+ yearday= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -441,7 +441,7 @@
+ case 'u':
+ sunday_first_n_first_week_non_iso= (*ptr=='U' || *ptr== 'V');
+ strict_week_number= (*ptr=='V' || *ptr=='v');
+- tmp= (char*) val + min(val_len, 2);
++ tmp= (char*) val + MYSQL_MIN(val_len, 2);
+ if ((week_number= (int) my_strtoll10(val, &tmp, &error)) < 0 ||
+ (strict_week_number && !week_number) ||
+ week_number > 53)
+@@ -453,7 +453,7 @@
+ case 'X':
+ case 'x':
+ strict_week_number_year_type= (*ptr=='X');
+- tmp= (char*) val + min(4, val_len);
++ tmp= (char*) val + MYSQL_MIN(4, val_len);
+ strict_week_number_year= (int) my_strtoll10(val, &tmp, &error);
+ val= tmp;
+ break;
+@@ -598,7 +598,7 @@
+ err:
+ {
+ char buff[128];
+- strmake(buff, val_begin, min(length, sizeof(buff)-1));
++ strmake(buff, val_begin, MYSQL_MIN(length, sizeof(buff)-1));
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+ date_time_type, buff, "str_to_date");
+@@ -1830,7 +1830,7 @@
+ else
+ {
+ fixed_length=0;
+- max_length=min(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
++ max_length=MYSQL_MIN(arg1->max_length, MAX_BLOB_WIDTH) * 10 *
+ collation.collation->mbmaxlen;
+ set_if_smaller(max_length,MAX_BLOB_WIDTH);
+ }
+diff -ur mysql-orig/sql/key.cc mysql/sql/key.cc
+--- mysql-orig/sql/key.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/key.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -128,13 +128,13 @@
+ key_part->key_part_flag & HA_VAR_LENGTH_PART)
+ {
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ key_part->field->get_key_image(to_key, length, Field::itRAW);
+ to_key+= HA_KEY_BLOB_LENGTH;
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ Field *field= key_part->field;
+ CHARSET_INFO *cs= field->charset();
+ uint bytes= field->get_key_image(to_key, length, Field::itRAW);
+@@ -218,7 +218,7 @@
+ my_ptrdiff_t ptrdiff= to_record - field->table->record[0];
+ field->move_field_offset(ptrdiff);
+ key_length-= HA_KEY_BLOB_LENGTH;
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ old_map= dbug_tmp_use_all_columns(field->table, field->table->write_set);
+ field->set_key_image(from_key, length);
+ dbug_tmp_restore_column_map(field->table->write_set, old_map);
+@@ -227,7 +227,7 @@
+ }
+ else
+ {
+- length= min(key_length, key_part->length);
++ length= MYSQL_MIN(key_length, key_part->length);
+ /* skip the byte with 'uneven' bits, if used */
+ memcpy(to_record + key_part->offset, from_key + used_uneven_bits
+ , (size_t) length - used_uneven_bits);
+@@ -288,7 +288,7 @@
+ return 1;
+ continue;
+ }
+- length= min((uint) (key_end-key), store_length);
++ length= MYSQL_MIN((uint) (key_end-key), store_length);
+ if (!(key_part->key_type & (FIELDFLAG_NUMBER+FIELDFLAG_BINARY+
+ FIELDFLAG_PACK)))
+ {
+@@ -354,7 +354,7 @@
+ {
+ field->val_str(&tmp);
+ if (key_part->length < field->pack_length())
+- tmp.length(min(tmp.length(),key_part->length));
++ tmp.length(MYSQL_MIN(tmp.length(),key_part->length));
+ to->append(tmp);
+ }
+ else
+diff -ur mysql-orig/sql/log.cc mysql/sql/log.cc
+--- mysql-orig/sql/log.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log.cc 2012-08-14 01:14:59.402197785 +0000
+@@ -597,11 +597,11 @@
+ t.neg= 0;
+
+ /* fill in query_time field */
+- calc_time_from_sec(&t, (long) min(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(query_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[2]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* lock_time */
+- calc_time_from_sec(&t, (long) min(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
++ calc_time_from_sec(&t, (long) MYSQL_MIN(lock_time, (longlong) TIME_MAX_VALUE_SECONDS), 0);
+ if (table->field[3]->store_time(&t, MYSQL_TIMESTAMP_TIME))
+ goto err;
+ /* rows_sent */
+@@ -2432,7 +2432,7 @@
+ {
+ char *p= fn_ext(log_name);
+ uint length= (uint) (p - log_name);
+- strmake(buff, log_name, min(length, FN_REFLEN-1));
++ strmake(buff, log_name, MYSQL_MIN(length, FN_REFLEN-1));
+ return (const char*)buff;
+ }
+ return log_name;
+@@ -5238,7 +5238,7 @@
+ DBUG_ENTER("print_buffer_to_nt_eventlog");
+
+ /* Add ending CR/LF's to string, overwrite last chars if necessary */
+- strmov(buffptr+min(length, buffLen-5), "\r\n\r\n");
++ strmov(buffptr+MYSQL_MIN(length, buffLen-5), "\r\n\r\n");
+
+ setup_windows_event_source();
+ if ((event= RegisterEventSource(NULL,"MySQL")))
+diff -ur mysql-orig/sql/log_event.cc mysql/sql/log_event.cc
+--- mysql-orig/sql/log_event.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/log_event.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1099,7 +1099,7 @@
+ of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
+ "minimal" over the set {MySQL >=4.0}).
+ */
+- uint header_size= min(description_event->common_header_len,
++ uint header_size= MYSQL_MIN(description_event->common_header_len,
+ LOG_EVENT_MINIMAL_HEADER_LEN);
+
+ LOCK_MUTEX;
+@@ -2695,7 +2695,7 @@
+ be even bigger, but this will suffice to catch most corruption
+ errors that can lead to a crash.
+ */
+- if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
++ if (status_vars_len > MYSQL_MIN(data_len, MAX_SIZE_LOG_EVENT_STATUS))
+ {
+ DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
+ status_vars_len, data_len));
+@@ -5676,7 +5676,7 @@
+ char buf[UV_NAME_LEN_SIZE];
+ char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
+ UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
+- uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
++ uchar buf2[MYSQL_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
+ uint buf1_length;
+ ulong event_length;
+
+@@ -7426,7 +7426,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/log_event_old.cc mysql/sql/log_event_old.cc
+--- mysql-orig/sql/log_event_old.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/log_event_old.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -1434,7 +1434,7 @@
+ trigger false warnings.
+ */
+ #ifndef HAVE_purify
+- DBUG_DUMP("row_data", row_data, min(length, 32));
++ DBUG_DUMP("row_data", row_data, MYSQL_MIN(length, 32));
+ #endif
+
+ DBUG_ASSERT(m_rows_buf <= m_rows_cur);
+diff -ur mysql-orig/sql/mysqld.cc mysql/sql/mysqld.cc
+--- mysql-orig/sql/mysqld.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/mysqld.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -3241,7 +3241,7 @@
+ can't get max_connections*5 but still got no less than was
+ requested (value of wanted_files).
+ */
+- max_open_files= max(max(wanted_files, max_connections*5),
++ max_open_files= MYSQL_MAX(MYSQL_MAX(wanted_files, max_connections*5),
+ open_files_limit);
+ files= my_set_max_open_files(max_open_files);
+
+@@ -3253,15 +3253,15 @@
+ If we have requested too much file handles than we bring
+ max_connections in supported bounds.
+ */
+- max_connections= (ulong) min(files-10-TABLE_OPEN_CACHE_MIN*2,
++ max_connections= (ulong) MYSQL_MIN(files-10-TABLE_OPEN_CACHE_MIN*2,
+ max_connections);
+ /*
+ Decrease table_cache_size according to max_connections, but
+- not below TABLE_OPEN_CACHE_MIN. Outer min() ensures that we
++ not below TABLE_OPEN_CACHE_MIN. Outer MYSQL_MIN() ensures that we
+ never increase table_cache_size automatically (that could
+ happen if max_connections is decreased above).
+ */
+- table_cache_size= (ulong) min(max((files-10-max_connections)/2,
++ table_cache_size= (ulong) MYSQL_MIN(MYSQL_MAX((files-10-max_connections)/2,
+ TABLE_OPEN_CACHE_MIN),
+ table_cache_size);
+ DBUG_PRINT("warning",
+@@ -4947,7 +4947,7 @@
+ {
+ my_socket sock,new_sock;
+ uint error_count=0;
+- uint max_used_connection= (uint) (max(ip_sock,unix_sock)+1);
++ uint max_used_connection= (uint) (MYSQL_MAX(ip_sock,unix_sock)+1);
+ fd_set readFDs,clientFDs;
+ THD *thd;
+ struct sockaddr_in cAddr;
+diff -ur mysql-orig/sql/net_serv.cc mysql/sql/net_serv.cc
+--- mysql-orig/sql/net_serv.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/net_serv.cc 2012-08-14 01:14:59.412197702 +0000
+@@ -755,7 +755,7 @@
+ {
+ while (remain > 0)
+ {
+- size_t length= min(remain, net->max_packet);
++ size_t length= MYSQL_MIN(remain, net->max_packet);
+ if (net_safe_read(net, net->buff, length, alarmed))
+ DBUG_RETURN(1);
+ update_statistics(thd_increment_bytes_received(length));
+@@ -946,7 +946,7 @@
+ len=uint3korr(net->buff+net->where_b);
+ if (!len) /* End of big multi-packet */
+ goto end;
+- helping = max(len,*complen) + net->where_b;
++ helping = MYSQL_MAX(len,*complen) + net->where_b;
+ /* The necessary size of net->buff */
+ if (helping >= net->max_packet)
+ {
+diff -ur mysql-orig/sql/opt_range.cc mysql/sql/opt_range.cc
+--- mysql-orig/sql/opt_range.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -2347,7 +2347,7 @@
+ group_trp= get_best_group_min_max(¶m, tree);
+ if (group_trp)
+ {
+- param.table->quick_condition_rows= min(group_trp->records,
++ param.table->quick_condition_rows= MYSQL_MIN(group_trp->records,
+ head->file->stats.records);
+ if (group_trp->read_cost < best_read_time)
+ {
+@@ -3823,7 +3823,7 @@
+ {
+ imerge_trp->read_cost= imerge_cost;
+ imerge_trp->records= non_cpk_scan_records + cpk_scan_records;
+- imerge_trp->records= min(imerge_trp->records,
++ imerge_trp->records= MYSQL_MIN(imerge_trp->records,
+ param->table->file->stats.records);
+ imerge_trp->range_scans= range_scans;
+ imerge_trp->range_scans_end= range_scans + n_child_scans;
+@@ -7471,7 +7471,7 @@
+ param->table->quick_key_parts[key]=param->max_key_part+1;
+ param->table->quick_n_ranges[key]= param->n_ranges;
+ param->table->quick_condition_rows=
+- min(param->table->quick_condition_rows, records);
++ MYSQL_MIN(param->table->quick_condition_rows, records);
+ }
+ /*
+ Need to save quick_rows in any case as it is used when calculating
+@@ -7540,7 +7540,7 @@
+ uchar *tmp_min_key, *tmp_max_key;
+ uint8 save_first_null_comp= param->first_null_comp;
+
+- param->max_key_part=max(param->max_key_part,key_tree->part);
++ param->max_key_part=MYSQL_MAX(param->max_key_part,key_tree->part);
+ if (key_tree->left != &null_element)
+ {
+ /*
+@@ -8462,13 +8462,13 @@
+ /* Do not allocate the buffers twice. */
+ if (multi_range_length)
+ {
+- DBUG_ASSERT(multi_range_length == min(multi_range_count, ranges.elements));
++ DBUG_ASSERT(multi_range_length == MYSQL_MIN(multi_range_count, ranges.elements));
+ DBUG_RETURN(0);
+ }
+
+ /* Allocate the ranges array. */
+ DBUG_ASSERT(ranges.elements);
+- multi_range_length= min(multi_range_count, ranges.elements);
++ multi_range_length= MYSQL_MIN(multi_range_count, ranges.elements);
+ DBUG_ASSERT(multi_range_length > 0);
+ while (multi_range_length && ! (multi_range= (KEY_MULTI_RANGE*)
+ my_malloc(multi_range_length *
+@@ -8487,7 +8487,7 @@
+ /* Allocate the handler buffer if necessary. */
+ if (file->ha_table_flags() & HA_NEED_READ_RANGE_BUFFER)
+ {
+- mrange_bufsiz= min(multi_range_bufsiz,
++ mrange_bufsiz= MYSQL_MIN(multi_range_bufsiz,
+ ((uint)QUICK_SELECT_I::records + 1)* head->s->reclength);
+
+ while (mrange_bufsiz &&
+@@ -8568,7 +8568,7 @@
+ goto end;
+ }
+
+- uint count= min(multi_range_length, ranges.elements -
++ uint count= MYSQL_MIN(multi_range_length, ranges.elements -
+ (cur_range - (QUICK_RANGE**) ranges.buffer));
+ if (count == 0)
+ {
+@@ -9270,7 +9270,7 @@
+
+ TODO
+ - What happens if the query groups by the MIN/MAX field, and there is no
+- other field as in: "select min(a) from t1 group by a" ?
++ other field as in: "select MYSQL_MIN(a) from t1 group by a" ?
+ - We assume that the general correctness of the GROUP-BY query was checked
+ before this point. Is this correct, or do we have to check it completely?
+ - Lift the limitation in condition (B3), that is, make this access method
+@@ -9496,7 +9496,7 @@
+ cur_group_prefix_len+= cur_part->store_length;
+ used_key_parts_map.set_bit(key_part_nr);
+ ++cur_group_key_parts;
+- max_key_part= max(max_key_part,key_part_nr);
++ max_key_part= MYSQL_MAX(max_key_part,key_part_nr);
+ }
+ /*
+ Check that used key parts forms a prefix of the index.
+@@ -10132,9 +10132,9 @@
+ {
+ double blocks_per_group= (double) num_blocks / (double) num_groups;
+ p_overlap= (blocks_per_group * (keys_per_subgroup - 1)) / keys_per_group;
+- p_overlap= min(p_overlap, 1.0);
++ p_overlap= MYSQL_MIN(p_overlap, 1.0);
+ }
+- io_cost= (double) min(num_groups * (1 + p_overlap), num_blocks);
++ io_cost= (double) MYSQL_MIN(num_groups * (1 + p_overlap), num_blocks);
+ }
+ else
+ io_cost= (keys_per_group > keys_per_block) ?
+diff -ur mysql-orig/sql/opt_range.h mysql/sql/opt_range.h
+--- mysql-orig/sql/opt_range.h 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/opt_range.h 2012-08-14 01:14:59.422197616 +0000
+@@ -85,7 +85,7 @@
+ void make_min_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_min_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+@@ -123,7 +123,7 @@
+ void make_max_endpoint(key_range *kr, uint prefix_length,
+ key_part_map keypart_map) {
+ make_max_endpoint(kr);
+- kr->length= min(kr->length, prefix_length);
++ kr->length= MYSQL_MIN(kr->length, prefix_length);
+ kr->keypart_map&= keypart_map;
+ }
+
+diff -ur mysql-orig/sql/protocol.cc mysql/sql/protocol.cc
+--- mysql-orig/sql/protocol.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/protocol.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -168,7 +168,7 @@
+ pos+=2;
+
+ /* We can only return up to 65535 warnings in two bytes */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ int2store(pos, tmp);
+ pos+= 2;
+ }
+@@ -263,7 +263,7 @@
+ Don't send warn count during SP execution, as the warn_list
+ is cleared between substatements, and mysqltest gets confused
+ */
+- uint tmp= min(total_warn_count, 65535);
++ uint tmp= MYSQL_MIN(total_warn_count, 65535);
+ buff[0]= 254;
+ int2store(buff+1, tmp);
+ /*
+diff -ur mysql-orig/sql/rpl_record.cc mysql/sql/rpl_record.cc
+--- mysql-orig/sql/rpl_record.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/rpl_record.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -287,7 +287,7 @@
+ /*
+ throw away master's extra fields
+ */
+- uint max_cols= min(tabledef->size(), cols->n_bits);
++ uint max_cols= MYSQL_MIN(tabledef->size(), cols->n_bits);
+ for (; i < max_cols; i++)
+ {
+ if (bitmap_is_set(cols, i))
+diff -ur mysql-orig/sql/rpl_rli.cc mysql/sql/rpl_rli.cc
+--- mysql-orig/sql/rpl_rli.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_rli.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -690,7 +690,7 @@
+ ulong log_name_extension;
+ char log_name_tmp[FN_REFLEN]; //make a char[] from String
+
+- strmake(log_name_tmp, log_name->ptr(), min(log_name->length(), FN_REFLEN-1));
++ strmake(log_name_tmp, log_name->ptr(), MYSQL_MIN(log_name->length(), FN_REFLEN-1));
+
+ char *p= fn_ext(log_name_tmp);
+ char *p_end;
+@@ -700,7 +700,7 @@
+ goto err;
+ }
+ // Convert 0-3 to 4
+- log_pos= max(log_pos, BIN_LOG_HEADER_SIZE);
++ log_pos= MYSQL_MAX(log_pos, BIN_LOG_HEADER_SIZE);
+ /* p points to '.' */
+ log_name_extension= strtoul(++p, &p_end, 10);
+ /*
+diff -ur mysql-orig/sql/rpl_utility.cc mysql/sql/rpl_utility.cc
+--- mysql-orig/sql/rpl_utility.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -182,7 +182,7 @@
+ /*
+ We only check the initial columns for the tables.
+ */
+- uint const cols_to_check= min(table->s->fields, size());
++ uint const cols_to_check= MYSQL_MIN(table->s->fields, size());
+ int error= 0;
+ Relay_log_info const *rli= const_cast<Relay_log_info*>(rli_arg);
+
+diff -ur mysql-orig/sql/rpl_utility.h mysql/sql/rpl_utility.h
+--- mysql-orig/sql/rpl_utility.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/rpl_utility.h 2012-08-14 01:14:59.422197616 +0000
+@@ -315,7 +315,7 @@
+ do { \
+ char buf[256]; \
+ uint i; \
+- for (i = 0 ; i < min(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
++ for (i = 0 ; i < MYSQL_MIN(sizeof(buf) - 1, (BS)->n_bits) ; i++) \
+ buf[i] = bitmap_is_set((BS), i) ? '1' : '0'; \
+ buf[i] = '\0'; \
+ DBUG_PRINT((N), ((FRM), buf)); \
+diff -ur mysql-orig/sql/set_var.cc mysql/sql/set_var.cc
+--- mysql-orig/sql/set_var.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/set_var.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1849,7 +1849,7 @@
+ ¬_used));
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ }
+@@ -4034,7 +4034,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ goto err;
+ }
+ return FALSE;
+diff -ur mysql-orig/sql/slave.cc mysql/sql/slave.cc
+--- mysql-orig/sql/slave.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/slave.cc 2012-08-14 01:14:59.422197616 +0000
+@@ -1791,7 +1791,7 @@
+ special marker to say "consider we have caught up".
+ */
+ protocol->store((longlong)(mi->rli.last_master_timestamp ?
+- max(0, time_diff) : 0));
++ MYSQL_MAX(0, time_diff) : 0));
+ }
+ else
+ {
+@@ -2408,7 +2408,7 @@
+ exec_res= 0;
+ rli->cleanup_context(thd, 1);
+ /* chance for concurrent connection to get more locks */
+- safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
++ safe_sleep(thd, MYSQL_MIN(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
+ (CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
+ pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
+ rli->trans_retries++;
+@@ -4112,7 +4112,7 @@
+ relay_log_pos Current log pos
+ pending Number of bytes already processed from the event
+ */
+- rli->event_relay_log_pos= max(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
++ rli->event_relay_log_pos= MYSQL_MAX(rli->event_relay_log_pos, BIN_LOG_HEADER_SIZE);
+ my_b_seek(cur_log,rli->event_relay_log_pos);
+ DBUG_RETURN(cur_log);
+ }
+diff -ur mysql-orig/sql/spatial.h mysql/sql/spatial.h
+--- mysql-orig/sql/spatial.h 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/spatial.h 2012-08-14 01:14:59.432197532 +0000
+@@ -182,8 +182,8 @@
+ if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr))
+ return 0;
+
+- MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin),
+- min(xmax, mbr->xmax), min(ymax, mbr->ymax));
++ MBR intersection(MYSQL_MAX(xmin, mbr->xmin), MYSQL_MAX(ymin, mbr->ymin),
++ MYSQL_MIN(xmax, mbr->xmax), MYSQL_MIN(ymax, mbr->ymax));
+
+ return (d == intersection.dimension());
+ }
+diff -ur mysql-orig/sql/sp_head.cc mysql/sql/sp_head.cc
+--- mysql-orig/sql/sp_head.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sp_head.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -2481,7 +2481,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string(col3_caption,
+- max(m_defstr.length, 1024));
++ MYSQL_MAX(m_defstr.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+@@ -2682,7 +2682,7 @@
+ field_list.push_back(new Item_uint("Pos", 9));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Instruction",
+- max(buffer.length(), 1024)));
++ MYSQL_MAX(buffer.length(), 1024)));
+ if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
+ Protocol::SEND_EOF))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_acl.cc mysql/sql/sql_acl.cc
+--- mysql-orig/sql/sql_acl.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_acl.cc 2012-08-14 01:14:59.432197532 +0000
+@@ -824,7 +824,7 @@
+ chars= 128; // Marker that chars existed
+ }
+ }
+- sort= (sort << 8) + (wild_pos ? min(wild_pos, 127) : chars);
++ sort= (sort << 8) + (wild_pos ? MYSQL_MIN(wild_pos, 127) : chars);
+ }
+ va_end(args);
+ return sort;
+diff -ur mysql-orig/sql/sql_analyse.cc mysql/sql/sql_analyse.cc
+--- mysql-orig/sql/sql_analyse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_analyse.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -282,16 +282,16 @@
+ {
+ if (((longlong) info->ullval) < 0)
+ return 0; // Impossible to store as a negative number
+- ev_info->llval = -(longlong) max((ulonglong) -ev_info->llval,
++ ev_info->llval = -(longlong) MYSQL_MAX((ulonglong) -ev_info->llval,
+ info->ullval);
+- ev_info->min_dval = (double) -max(-ev_info->min_dval, info->dval);
++ ev_info->min_dval = (double) -MYSQL_MAX(-ev_info->min_dval, info->dval);
+ }
+ else // ulonglong is as big as bigint in MySQL
+ {
+ if ((check_ulonglong(num, info->integers) == DECIMAL_NUM))
+ return 0;
+- ev_info->ullval = (ulonglong) max(ev_info->ullval, info->ullval);
+- ev_info->max_dval = (double) max(ev_info->max_dval, info->dval);
++ ev_info->ullval = (ulonglong) MYSQL_MAX(ev_info->ullval, info->ullval);
++ ev_info->max_dval = (double) MYSQL_MAX(ev_info->max_dval, info->dval);
+ }
+ return 1;
+ } // get_ev_num_info
+@@ -1045,7 +1045,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &avg_val, sum+cur_sum, &num, prec_increment);
+ /* TODO remove this after decimal_div returns proper frac */
+ my_decimal_round(E_DEC_FATAL_ERROR, &avg_val,
+- min(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
++ MYSQL_MIN(sum[cur_sum].frac + prec_increment, DECIMAL_MAX_SCALE),
+ FALSE,&rounded_avg);
+ my_decimal2string(E_DEC_FATAL_ERROR, &rounded_avg, 0, 0, '0', s);
+ return s;
+@@ -1070,7 +1070,7 @@
+ my_decimal_div(E_DEC_FATAL_ERROR, &tmp, &sum2, &num, prec_increment);
+ my_decimal2double(E_DEC_FATAL_ERROR, &tmp, &std_sqr);
+ s->set_real(((double) std_sqr <= 0.0 ? 0.0 : sqrt(std_sqr)),
+- min(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
++ MYSQL_MIN(item->decimals + prec_increment, NOT_FIXED_DEC), my_thd_charset);
+
+ return s;
+ }
+@@ -1187,7 +1187,7 @@
+ func_items[8] = new Item_proc_string("Std", 255);
+ func_items[8]->maybe_null = 1;
+ func_items[9] = new Item_proc_string("Optimal_fieldtype",
+- max(64, output_str_length));
++ MYSQL_MAX(64, output_str_length));
+
+ for (uint i = 0; i < array_elements(func_items); i++)
+ field_list.push_back(func_items[i]);
+diff -ur mysql-orig/sql/sql_cache.cc mysql/sql/sql_cache.cc
+--- mysql-orig/sql/sql_cache.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_cache.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -1006,7 +1006,7 @@
+ }
+ last_result_block= header->result()->prev;
+ allign_size= ALIGN_SIZE(last_result_block->used);
+- len= max(query_cache.min_allocation_unit, allign_size);
++ len= MYSQL_MAX(query_cache.min_allocation_unit, allign_size);
+ if (last_result_block->length >= query_cache.min_allocation_unit + len)
+ query_cache.split_block(last_result_block,len);
+
+@@ -2451,7 +2451,7 @@
+ DBUG_ENTER("Query_cache::write_block_data");
+ DBUG_PRINT("qcache", ("data: %ld, header: %ld, all header: %ld",
+ data_len, header_len, all_headers_len));
+- Query_cache_block *block= allocate_block(max(align_len,
++ Query_cache_block *block= allocate_block(MYSQL_MAX(align_len,
+ min_allocation_unit),1, 0);
+ if (block != 0)
+ {
+@@ -2506,7 +2506,7 @@
+ ulong append_min = get_min_append_result_data_size();
+ if (last_block_free_space < data_len &&
+ append_next_free_block(last_block,
+- max(tail, append_min)))
++ MYSQL_MAX(tail, append_min)))
+ last_block_free_space = last_block->length - last_block->used;
+ // If no space in last block (even after join) allocate new block
+ if (last_block_free_space < data_len)
+@@ -2534,7 +2534,7 @@
+ // Now finally write data to the last block
+ if (success && last_block_free_space > 0)
+ {
+- ulong to_copy = min(data_len,last_block_free_space);
++ ulong to_copy = MYSQL_MIN(data_len,last_block_free_space);
+ DBUG_PRINT("qcache", ("use free space %lub at block 0x%lx to copy %lub",
+ last_block_free_space, (ulong)last_block, to_copy));
+ memcpy((uchar*) last_block + last_block->used, data, to_copy);
+@@ -2622,8 +2622,8 @@
+ if (queries_in_cache < QUERY_CACHE_MIN_ESTIMATED_QUERIES_NUMBER)
+ return min_result_data_size;
+ ulong avg_result = (query_cache_size - free_memory) / queries_in_cache;
+- avg_result = min(avg_result, query_cache_limit);
+- return max(min_result_data_size, avg_result);
++ avg_result = MYSQL_MIN(avg_result, query_cache_limit);
++ return MYSQL_MAX(min_result_data_size, avg_result);
+ }
+
+ inline ulong Query_cache::get_min_append_result_data_size()
+@@ -2655,7 +2655,7 @@
+ ulong len= data_len + all_headers_len;
+ ulong align_len= ALIGN_SIZE(len);
+
+- if (!(new_block= allocate_block(max(min_size, align_len),
++ if (!(new_block= allocate_block(MYSQL_MAX(min_size, align_len),
+ min_result_data_size == 0,
+ all_headers_len + min_result_data_size)))
+ {
+@@ -2664,7 +2664,7 @@
+ }
+
+ new_block->n_tables = 0;
+- new_block->used = min(len, new_block->length);
++ new_block->used = MYSQL_MIN(len, new_block->length);
+ new_block->type = Query_cache_block::RES_INCOMPLETE;
+ new_block->next = new_block->prev = new_block;
+ Query_cache_result *header = new_block->result();
+@@ -3087,7 +3087,7 @@
+ DBUG_PRINT("qcache", ("len %lu, not less %d, min %lu",
+ len, not_less,min));
+
+- if (len >= min(query_cache_size, query_cache_limit))
++ if (len >= MYSQL_MIN(query_cache_size, query_cache_limit))
+ {
+ DBUG_PRINT("qcache", ("Query cache hase only %lu memory and limit %lu",
+ query_cache_size, query_cache_limit));
+diff -ur mysql-orig/sql/sql_class.cc mysql/sql/sql_class.cc
+--- mysql-orig/sql/sql_class.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_class.cc 2012-08-14 01:14:59.442197450 +0000
+@@ -418,7 +418,7 @@
+ if (max_query_len < 1)
+ len= thd->query_length();
+ else
+- len= min(thd->query_length(), max_query_len);
++ len= MYSQL_MIN(thd->query_length(), max_query_len);
+ str.append('\n');
+ str.append(thd->query(), len);
+ }
+@@ -433,7 +433,7 @@
+ was reallocated to a larger buffer to be able to fit.
+ */
+ DBUG_ASSERT(buffer != NULL);
+- length= min(str.length(), length-1);
++ length= MYSQL_MIN(str.length(), length-1);
+ memcpy(buffer, str.c_ptr_quick(), length);
+ /* Make sure that the new string is null terminated */
+ buffer[length]= '\0';
+@@ -2116,7 +2116,7 @@
+ else
+ {
+ if (fixed_row_size)
+- used_length=min(res->length(),item->max_length);
++ used_length=MYSQL_MIN(res->length(),item->max_length);
+ else
+ used_length=res->length();
+ if ((result_type == STRING_RESULT || is_unsafe_field_sep) &&
+diff -ur mysql-orig/sql/sql_client.cc mysql/sql/sql_client.cc
+--- mysql-orig/sql/sql_client.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_client.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -34,7 +34,7 @@
+ (uint)global_system_variables.net_write_timeout);
+
+ net->retry_count= (uint) global_system_variables.net_retry_count;
+- net->max_packet_size= max(global_system_variables.net_buffer_length,
++ net->max_packet_size= MYSQL_MAX(global_system_variables.net_buffer_length,
+ global_system_variables.max_allowed_packet);
+ #endif
+ }
+diff -ur mysql-orig/sql/sql_connect.cc mysql/sql/sql_connect.cc
+--- mysql-orig/sql/sql_connect.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_connect.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -845,7 +845,7 @@
+ if (thd->main_security_ctx.host)
+ {
+ if (thd->main_security_ctx.host != my_localhost)
+- thd->main_security_ctx.host[min(strlen(thd->main_security_ctx.host),
++ thd->main_security_ctx.host[MYSQL_MIN(strlen(thd->main_security_ctx.host),
+ HOSTNAME_LENGTH)]= 0;
+ thd->main_security_ctx.host_or_ip= thd->main_security_ctx.host;
+ }
+diff -ur mysql-orig/sql/sql_parse.cc mysql/sql/sql_parse.cc
+--- mysql-orig/sql/sql_parse.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_parse.cc 2012-08-14 01:14:59.452197368 +0000
+@@ -5762,7 +5762,7 @@
+ return 1;
+ }
+ #ifndef DBUG_OFF
+- max_stack_used= max(max_stack_used, stack_used);
++ max_stack_used= MYSQL_MAX(max_stack_used, stack_used);
+ #endif
+ return 0;
+ }
+@@ -7293,7 +7293,7 @@
+ char command[80];
+ Lex_input_stream *lip= & thd->m_parser_state->m_lip;
+ strmake(command, lip->yylval->symbol.str,
+- min(lip->yylval->symbol.length, sizeof(command)-1));
++ MYSQL_MIN(lip->yylval->symbol.length, sizeof(command)-1));
+ my_error(ER_CANT_USE_OPTION_HERE, MYF(0), command);
+ return 1;
+ }
+diff -ur mysql-orig/sql/sql_partition.cc mysql/sql/sql_partition.cc
+--- mysql-orig/sql/sql_partition.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_partition.cc 2012-08-14 01:14:59.462197286 +0000
+@@ -4592,7 +4592,7 @@
+ */
+ start_part= 0;
+ end_part= new_total_partitions - (upper_2n + 1);
+- end_part= max(lower_2n - 1, end_part);
++ end_part= MYSQL_MAX(lower_2n - 1, end_part);
+ }
+ else if (new_total_partitions <= upper_2n)
+ {
+diff -ur mysql-orig/sql/sql_plugin.cc mysql/sql/sql_plugin.cc
+--- mysql-orig/sql/sql_plugin.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_plugin.cc 2012-08-14 01:14:59.472197202 +0000
+@@ -512,7 +512,7 @@
+ for (i=0;
+ (old=(struct st_mysql_plugin *)(ptr+i*sizeof_st_plugin))->info;
+ i++)
+- memcpy(cur+i, old, min(sizeof(cur[i]), sizeof_st_plugin));
++ memcpy(cur+i, old, MYSQL_MIN(sizeof(cur[i]), sizeof_st_plugin));
+
+ sym= cur;
+ }
+@@ -2131,7 +2131,7 @@
+ &error, &error_len, ¬_used);
+ if (error_len)
+ {
+- strmake(buff, error, min(sizeof(buff) - 1, error_len));
++ strmake(buff, error, MYSQL_MIN(sizeof(buff) - 1, error_len));
+ strvalue= buff;
+ goto err;
+ }
+diff -ur mysql-orig/sql/sql_prepare.cc mysql/sql/sql_prepare.cc
+--- mysql-orig/sql/sql_prepare.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_prepare.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -249,7 +249,7 @@
+ int2store(buff+5, columns);
+ int2store(buff+7, stmt->param_count);
+ buff[9]= 0; // Guard against a 4.1 client
+- tmp= min(stmt->thd->total_warn_count, 65535);
++ tmp= MYSQL_MIN(stmt->thd->total_warn_count, 65535);
+ int2store(buff+10, tmp);
+
+ /*
+diff -ur mysql-orig/sql/sql_profile.cc mysql/sql/sql_profile.cc
+--- mysql-orig/sql/sql_profile.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_profile.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -254,7 +254,7 @@
+ uint query_length_arg)
+ {
+ /* Truncate to avoid DoS attacks. */
+- uint length= min(MAX_QUERY_LENGTH, query_length_arg);
++ uint length= MYSQL_MIN(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+diff -ur mysql-orig/sql/sql_repl.cc mysql/sql/sql_repl.cc
+--- mysql-orig/sql/sql_repl.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_repl.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -1299,12 +1299,12 @@
+ {
+ /*
+ Sometimes mi->rli.master_log_pos == 0 (it happens when the SQL thread is
+- not initialized), so we use a max().
++ not initialized), so we use a MYSQL_MAX().
+ What happens to mi->rli.master_log_pos during the initialization stages
+ of replication is not 100% clear, so we guard against problems using
+ max().
+ */
+- mi->master_log_pos = max(BIN_LOG_HEADER_SIZE,
++ mi->master_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE,
+ mi->rli.group_master_log_pos);
+ strmake(mi->master_log_name, mi->rli.group_master_log_name,
+ sizeof(mi->master_log_name)-1);
+@@ -1478,7 +1478,7 @@
+ LEX_MASTER_INFO *lex_mi= &thd->lex->mi;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows event_count, limit_start, limit_end;
+- my_off_t pos = max(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
++ my_off_t pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, lex_mi->pos); // user-friendly
+ char search_file_name[FN_REFLEN], *name;
+ const char *log_file_name = lex_mi->log_file_name;
+ pthread_mutex_t *log_lock = mysql_bin_log.get_log_lock();
+@@ -1750,14 +1750,14 @@
+ DBUG_RETURN(0);
+
+ for (block_len= (uint) (my_b_get_bytes_in_buffer(file)); block_len > 0;
+- buffer += min(block_len, max_event_size),
+- block_len -= min(block_len, max_event_size))
++ buffer += MYSQL_MIN(block_len, max_event_size),
++ block_len -= MYSQL_MIN(block_len, max_event_size))
+ {
+ lf_info->last_pos_in_file= my_b_get_pos_in_file(file);
+ if (lf_info->wrote_create_file)
+ {
+ Append_block_log_event a(lf_info->thd, lf_info->thd->db, buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&a))
+ DBUG_RETURN(1);
+@@ -1766,7 +1766,7 @@
+ {
+ Begin_load_query_log_event b(lf_info->thd, lf_info->thd->db,
+ buffer,
+- min(block_len, max_event_size),
++ MYSQL_MIN(block_len, max_event_size),
+ lf_info->log_delayed);
+ if (mysql_bin_log.write(&b))
+ DBUG_RETURN(1);
+diff -ur mysql-orig/sql/sql_select.cc mysql/sql/sql_select.cc
+--- mysql-orig/sql/sql_select.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_select.cc 2012-08-14 01:14:59.482197120 +0000
+@@ -3022,7 +3022,7 @@
+ This is can't be to high as otherwise we are likely to use
+ table scan.
+ */
+- s->worst_seeks= min((double) s->found_records / 10,
++ s->worst_seeks= MYSQL_MIN((double) s->found_records / 10,
+ (double) s->read_time*3);
+ if (s->worst_seeks < 2.0) // Fix for small tables
+ s->worst_seeks=2.0;
+@@ -3958,7 +3958,7 @@
+ uint and_level,i,found_eq_constant;
+ KEY_FIELD *key_fields, *end, *field;
+ uint sz;
+- uint m= max(select_lex->max_equal_elems,1);
++ uint m= MYSQL_MAX(select_lex->max_equal_elems,1);
+
+ /*
+ We use the same piece of memory to store both KEY_FIELD
+@@ -3981,7 +3981,7 @@
+ can be not more than select_lex->max_equal_elems such
+ substitutions.
+ */
+- sz= max(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
++ sz= MYSQL_MAX(sizeof(KEY_FIELD),sizeof(SARGABLE_PARAM))*
+ (((thd->lex->current_select->cond_count+1)*2 +
+ thd->lex->current_select->between_count)*m+1);
+ if (!(key_fields=(KEY_FIELD*) thd->alloc(sz)))
+@@ -4144,7 +4144,7 @@
+ if (map == 1) // Only one table
+ {
+ TABLE *tmp_table=join->all_tables[tablenr];
+- keyuse->ref_table_rows= max(tmp_table->file->stats.records, 100);
++ keyuse->ref_table_rows= MYSQL_MAX(tmp_table->file->stats.records, 100);
+ }
+ }
+ /*
+@@ -4464,7 +4464,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ }
+ else
+@@ -4631,7 +4631,7 @@
+ tmp= record_count*(tmp+keys_per_block-1)/keys_per_block;
+ }
+ else
+- tmp= record_count*min(tmp,s->worst_seeks);
++ tmp= record_count*MYSQL_MIN(tmp,s->worst_seeks);
+ }
+ else
+ tmp= best_time; // Do nothing
+@@ -5581,7 +5581,7 @@
+ {
+ uint blob_length=(uint) (join_tab->table->file->stats.mean_rec_length-
+ (join_tab->table->s->reclength- rec_length));
+- rec_length+=(uint) max(4,blob_length);
++ rec_length+=(uint) MYSQL_MAX(4,blob_length);
+ }
+ join_tab->used_fields=fields;
+ join_tab->used_fieldlength=rec_length;
+@@ -10488,7 +10488,7 @@
+ share->max_rows= ~(ha_rows) 0;
+ else
+ share->max_rows= (ha_rows) (((share->db_type() == heap_hton) ?
+- min(thd->variables.tmp_table_size,
++ MYSQL_MIN(thd->variables.tmp_table_size,
+ thd->variables.max_heap_table_size) :
+ thd->variables.tmp_table_size) /
+ share->reclength);
+@@ -13708,7 +13708,7 @@
+ index entry.
+ */
+ index_scan_time= select_limit/rec_per_key *
+- min(rec_per_key, table->file->scan_time());
++ MYSQL_MIN(rec_per_key, table->file->scan_time());
+ if ((ref_key < 0 && is_covering) ||
+ (ref_key < 0 && (group || table->force_index)) ||
+ index_scan_time < read_time)
+@@ -13720,7 +13720,7 @@
+ if (table->quick_keys.is_set(nr))
+ quick_records= table->quick_rows[nr];
+ if (best_key < 0 ||
+- (select_limit <= min(quick_records,best_records) ?
++ (select_limit <= MYSQL_MIN(quick_records,best_records) ?
+ keyinfo->key_parts < best_key_parts :
+ quick_records < best_records))
+ {
+@@ -14416,7 +14416,7 @@
+ count++;
+ if (!sortorder)
+ sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
+- (max(count, *length) + 1));
++ (MYSQL_MAX(count, *length) + 1));
+ pos= sort= sortorder;
+
+ if (!pos)
+@@ -14538,7 +14538,7 @@
+ cache->length=length+blobs*sizeof(char*);
+ cache->blobs=blobs;
+ *blob_ptr=0; /* End sequentel */
+- size=max(thd->variables.join_buff_size, cache->length);
++ size=MYSQL_MAX(thd->variables.join_buff_size, cache->length);
+ if (!(cache->buff=(uchar*) my_malloc(size,MYF(0))))
+ DBUG_RETURN(1); /* Don't use cache */ /* purecov: inspected */
+ cache->end=cache->buff+size;
+diff -ur mysql-orig/sql/sql_show.cc mysql/sql/sql_show.cc
+--- mysql-orig/sql/sql_show.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_show.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -753,7 +753,7 @@
+ {
+ field_list.push_back(new Item_empty_string("View",NAME_CHAR_LEN));
+ field_list.push_back(new Item_empty_string("Create View",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ field_list.push_back(new Item_empty_string("character_set_client",
+ MY_CS_NAME_SIZE));
+ field_list.push_back(new Item_empty_string("collation_connection",
+@@ -764,7 +764,7 @@
+ field_list.push_back(new Item_empty_string("Table",NAME_CHAR_LEN));
+ // 1024 is for not to confuse old clients
+ field_list.push_back(new Item_empty_string("Create Table",
+- max(buffer.length(),1024)));
++ MYSQL_MAX(buffer.length(),1024)));
+ }
+
+ if (protocol->send_fields(&field_list,
+@@ -1875,7 +1875,7 @@
+ pthread_mutex_lock(&tmp->LOCK_thd_data);
+ if (tmp->query())
+ {
+- uint length= min(max_query_length, tmp->query_length());
++ uint length= MYSQL_MIN(max_query_length, tmp->query_length());
+ thd_info->query= (char*) thd->strmake(tmp->query(),length);
+ }
+ pthread_mutex_unlock(&tmp->LOCK_thd_data);
+@@ -2006,7 +2006,7 @@
+ if (tmp->query())
+ {
+ table->field[7]->store(tmp->query(),
+- min(PROCESS_LIST_INFO_WIDTH,
++ MYSQL_MIN(PROCESS_LIST_INFO_WIDTH,
+ tmp->query_length()), cs);
+ table->field[7]->set_notnull();
+ }
+@@ -3276,7 +3276,7 @@
+ for (ptr=tables->table->field; (field= *ptr) ; ptr++)
+ {
+ star_table_open_method=
+- min(star_table_open_method,
++ MYSQL_MIN(star_table_open_method,
+ schema_table->fields_info[field_indx].open_method);
+ if (bitmap_is_set(tables->table->read_set, field->field_index))
+ {
+@@ -7095,7 +7095,7 @@
+
+ Item_empty_string *stmt_fld=
+ new Item_empty_string("SQL Original Statement",
+- max(trg_sql_original_stmt.length, 1024));
++ MYSQL_MAX(trg_sql_original_stmt.length, 1024));
+
+ stmt_fld->maybe_null= TRUE;
+
+diff -ur mysql-orig/sql/sql_string.cc mysql/sql/sql_string.cc
+--- mysql-orig/sql/sql_string.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_string.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -700,7 +700,7 @@
+ {
+ if (Alloced_length < str_length + space_needed)
+ {
+- if (realloc(Alloced_length + max(space_needed, grow_by) - 1))
++ if (realloc(Alloced_length + MYSQL_MAX(space_needed, grow_by) - 1))
+ return TRUE;
+ }
+ return FALSE;
+@@ -786,7 +786,7 @@
+
+ int stringcmp(const String *s,const String *t)
+ {
+- uint32 s_len=s->length(),t_len=t->length(),len=min(s_len,t_len);
++ uint32 s_len=s->length(),t_len=t->length(),len=MYSQL_MIN(s_len,t_len);
+ int cmp= memcmp(s->ptr(), t->ptr(), len);
+ return (cmp) ? cmp : (int) (s_len - t_len);
+ }
+@@ -803,7 +803,7 @@
+ }
+ if (to->realloc(from_length))
+ return from; // Actually an error
+- if ((to->str_length=min(from->str_length,from_length)))
++ if ((to->str_length=MYSQL_MIN(from->str_length,from_length)))
+ memcpy(to->Ptr,from->Ptr,to->str_length);
+ to->str_charset=from->str_charset;
+ return to;
+@@ -1004,7 +1004,7 @@
+
+ if (to_cs == &my_charset_bin)
+ {
+- res= min(min(nchars, to_length), from_length);
++ res= MYSQL_MIN(MYSQL_MIN(nchars, to_length), from_length);
+ memmove(to, from, res);
+ *from_end_pos= from + res;
+ *well_formed_error_pos= NULL;
+@@ -1190,7 +1190,7 @@
+ char *t= to;
+ char *t_end= to + to_len - 1; // '- 1' is for the '\0' at the end
+ const char *f= from;
+- const char *f_end= from + (nbytes ? min(from_len, nbytes) : from_len);
++ const char *f_end= from + (nbytes ? MYSQL_MIN(from_len, nbytes) : from_len);
+ char *dots= to; // last safe place to append '...'
+
+ if (!f || t == t_end)
+diff -ur mysql-orig/sql/sql_table.cc mysql/sql/sql_table.cc
+--- mysql-orig/sql/sql_table.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/sql_table.cc 2012-08-14 01:14:59.492197038 +0000
+@@ -3276,7 +3276,7 @@
+ if ((length=column->length) > max_key_length ||
+ length > file->max_key_part_length())
+ {
+- length=min(max_key_length, file->max_key_part_length());
++ length=MYSQL_MIN(max_key_length, file->max_key_part_length());
+ if (key->type == Key::MULTIPLE)
+ {
+ /* not a critical problem */
+diff -ur mysql-orig/sql/sql_yacc.cc mysql/sql/sql_yacc.cc
+--- mysql-orig/sql/sql_yacc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.cc 2012-08-14 01:14:59.502196954 +0000
+@@ -16217,7 +16217,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ break;
+
+@@ -16237,7 +16237,7 @@
+ {
+ Lex->mi.relay_log_pos = (yyvsp[(3) - (3)].ulong_num);
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ break;
+
+diff -ur mysql-orig/sql/sql_yacc.yy mysql/sql/sql_yacc.yy
+--- mysql-orig/sql/sql_yacc.yy 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/sql_yacc.yy 2012-08-14 01:14:59.512196872 +0000
+@@ -1807,7 +1807,7 @@
+ from 0" (4 in fact), unspecified means "don't change the position
+ (keep the preceding value)").
+ */
+- Lex->mi.pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
++ Lex->mi.pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.pos);
+ }
+ | RELAY_LOG_FILE_SYM EQ TEXT_STRING_sys
+ {
+@@ -1817,7 +1817,7 @@
+ {
+ Lex->mi.relay_log_pos = $3;
+ /* Adjust if < BIN_LOG_HEADER_SIZE (same comment as Lex->mi.pos) */
+- Lex->mi.relay_log_pos = max(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
++ Lex->mi.relay_log_pos = MYSQL_MAX(BIN_LOG_HEADER_SIZE, Lex->mi.relay_log_pos);
+ }
+ ;
+
+diff -ur mysql-orig/sql/thr_malloc.cc mysql/sql/thr_malloc.cc
+--- mysql-orig/sql/thr_malloc.cc 2012-08-14 01:12:29.423437567 +0000
++++ mysql/sql/thr_malloc.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -132,7 +132,7 @@
+ if ((from_cs == &my_charset_bin) || (to_cs == &my_charset_bin))
+ {
+ // Safety if to_cs->mbmaxlen > 0
+- new_length= min(arg_length, max_res_length);
++ new_length= MYSQL_MIN(arg_length, max_res_length);
+ memcpy(pos, str, new_length);
+ }
+ else
+diff -ur mysql-orig/sql/tztime.cc mysql/sql/tztime.cc
+--- mysql-orig/sql/tztime.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/tztime.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -169,7 +169,7 @@
+ uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
+ TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
+ #ifdef ABBR_ARE_USED
+- max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
++ MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
+ #endif
+ sizeof(LS_INFO) * TZ_MAX_LEAPS];
+ } u;
+@@ -398,7 +398,7 @@
+ Let us choose end_t as point before next time type change or leap
+ second correction.
+ */
+- end_t= min((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
++ end_t= MYSQL_MIN((next_trans_idx < sp->timecnt) ? sp->ats[next_trans_idx] - 1:
+ MY_TIME_T_MAX,
+ (next_leap_idx < sp->leapcnt) ?
+ sp->lsis[next_leap_idx].ls_trans - 1: MY_TIME_T_MAX);
+@@ -1825,7 +1825,7 @@
+ uchar types[TZ_MAX_TIMES];
+ TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
+ #ifdef ABBR_ARE_USED
+- char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
++ char chars[MYSQL_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
+ #endif
+ /*
+ Used as a temporary tz_info until we decide that we actually want to
+diff -ur mysql-orig/sql/unireg.cc mysql/sql/unireg.cc
+--- mysql-orig/sql/unireg.cc 2012-08-14 01:12:29.413437640 +0000
++++ mysql/sql/unireg.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -498,7 +498,7 @@
+ }
+ cfield->row=(uint8) row;
+ cfield->col=(uint8) (length+1);
+- cfield->sc_length=(uint8) min(cfield->length,cols-(length+2));
++ cfield->sc_length=(uint8) MYSQL_MIN(cfield->length,cols-(length+2));
+ }
+ length=(uint) (pos-start_screen);
+ int2store(start_screen,length);
+@@ -718,7 +718,7 @@
+ DBUG_RETURN(1);
+ }
+ /* Hack to avoid bugs with small static rows in MySQL */
+- reclength=max(file->min_record_length(table_options),reclength);
++ reclength=MYSQL_MAX(file->min_record_length(table_options),reclength);
+ if (info_length+(ulong) create_fields.elements*FCOMP+288+
+ n_length+int_length+com_length > 65535L || int_count > 255)
+ {
+diff -ur mysql-orig/sql-common/client.c mysql/sql-common/client.c
+--- mysql-orig/sql-common/client.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/client.c 2012-08-14 01:14:59.512196872 +0000
+@@ -730,7 +730,7 @@
+ }
+
+ (void) strmake(net->last_error,(char*) pos,
+- min((uint) len,(uint) sizeof(net->last_error)-1));
++ MYSQL_MIN((uint) len,(uint) sizeof(net->last_error)-1));
+ }
+ else
+ set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate);
+@@ -2113,7 +2113,7 @@
+ {
+ IF_DBUG(char ipaddr[18];)
+ memcpy(&sock_addr.sin_addr, hp->h_addr_list[i],
+- min(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
++ MYSQL_MIN(sizeof(sock_addr.sin_addr), (size_t) hp->h_length));
+ DBUG_PRINT("info",("Trying %s...",
+ (my_inet_ntoa(sock_addr.sin_addr, ipaddr), ipaddr)));
+ status= my_connect(sock, (struct sockaddr *) &sock_addr,
+diff -ur mysql-orig/sql-common/my_time.c mysql/sql-common/my_time.c
+--- mysql-orig/sql-common/my_time.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/sql-common/my_time.c 2012-08-14 01:14:59.512196872 +0000
+@@ -251,7 +251,7 @@
+ 2003-03-03 20:00:20 AM
+ 20:00:20.000000 AM 03-03-2000
+ */
+- i= max((uint) format_position[0], (uint) format_position[1]);
++ i= MYSQL_MAX((uint) format_position[0], (uint) format_position[1]);
+ set_if_bigger(i, (uint) format_position[2]);
+ allow_space= ((1 << i) | (1 << format_position[6]));
+ allow_space&= (1 | 2 | 4 | 8);
+diff -ur mysql-orig/storage/csv/ha_tina.cc mysql/storage/csv/ha_tina.cc
+--- mysql-orig/storage/csv/ha_tina.cc 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/csv/ha_tina.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -1195,7 +1195,7 @@
+ if (closest_hole == chain_ptr) /* no more chains */
+ *end_pos= file_buff->end();
+ else
+- *end_pos= min(file_buff->end(),
++ *end_pos= MYSQL_MIN(file_buff->end(),
+ closest_hole->begin);
+ return (closest_hole != chain_ptr) && (*end_pos == closest_hole->begin);
+ }
+@@ -1431,7 +1431,7 @@
+ /* write repaired file */
+ while (1)
+ {
+- write_end= min(file_buff->end(), current_position);
++ write_end= MYSQL_MIN(file_buff->end(), current_position);
+ if ((write_end - write_begin) &&
+ (my_write(repair_file, (uchar*)file_buff->ptr(),
+ (size_t) (write_end - write_begin), MYF_RW)))
+diff -ur mysql-orig/storage/example/ha_example.h mysql/storage/example/ha_example.h
+--- mysql-orig/storage/example/ha_example.h 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/example/ha_example.h 2012-08-14 01:14:59.512196872 +0000
+@@ -112,14 +112,14 @@
+ max_supported_key_parts(), uint max_supported_key_length()
+ to make sure that the storage engine can handle the data it is about to
+ send. Return *real* limits of your storage engine here; MySQL will do
+- min(your_limits, MySQL_limits) automatically.
++ MYSQL_MIN(your_limits, MySQL_limits) automatically.
+ */
+ uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
+
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -130,7 +130,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+@@ -141,7 +141,7 @@
+ /** @brief
+ unireg.cc will call this to make sure that the storage engine can handle
+ the data it is about to send. Return *real* limits of your storage engine
+- here; MySQL will do min(your_limits, MySQL_limits) automatically.
++ here; MySQL will do MYSQL_MIN(your_limits, MySQL_limits) automatically.
+
+ @details
+ There is no need to implement ..._key_... methods if your engine doesn't
+diff -ur mysql-orig/storage/federated/ha_federated.cc mysql/storage/federated/ha_federated.cc
+--- mysql-orig/storage/federated/ha_federated.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/federated/ha_federated.cc 2012-08-14 01:14:59.512196872 +0000
+@@ -546,7 +546,7 @@
+ size_t buf_len;
+ DBUG_ENTER("ha_federated parse_url_error");
+
+- buf_len= min(table->s->connect_string.length,
++ buf_len= MYSQL_MIN(table->s->connect_string.length,
+ FEDERATED_QUERY_BUFFER_SIZE-1);
+ strmake(buf, table->s->connect_string.str, buf_len);
+ my_error(error_num, MYF(0), buf);
+@@ -1291,7 +1291,7 @@
+ {
+ Field *field= key_part->field;
+ uint store_length= key_part->store_length;
+- uint part_length= min(store_length, length);
++ uint part_length= MYSQL_MIN(store_length, length);
+ needs_quotes= field->str_needs_quotes();
+ DBUG_DUMP("key, start of loop", ptr, length);
+
+diff -ur mysql-orig/storage/heap/hp_create.c mysql/storage/heap/hp_create.c
+--- mysql-orig/storage/heap/hp_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_create.c 2012-08-14 01:14:59.512196872 +0000
+@@ -230,7 +230,7 @@
+ {
+ uint i,recbuffer,records_in_block;
+
+- max_records= max(min_records,max_records);
++ max_records= MYSQL_MAX(min_records,max_records);
+ if (!max_records)
+ max_records= 1000; /* As good as quess as anything */
+ recbuffer= (uint) (reclength + sizeof(uchar**) - 1) & ~(sizeof(uchar**) - 1);
+diff -ur mysql-orig/storage/heap/hp_test2.c mysql/storage/heap/hp_test2.c
+--- mysql-orig/storage/heap/hp_test2.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/heap/hp_test2.c 2012-08-14 01:14:59.512196872 +0000
+@@ -138,7 +138,7 @@
+
+ for (i=0 ; i < recant ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*5,MAX_RECORDS));
+ make_record(record,n1,n2,n3,"Pos",write_count);
+
+ if (heap_write(file,record))
+@@ -219,7 +219,7 @@
+ printf("- Update\n");
+ for (i=0 ; i < write_count/10 ; i++)
+ {
+- n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
++ n1=rnd(1000); n2=rnd(100); n3=rnd(MYSQL_MIN(recant*2,MAX_RECORDS));
+ make_record(record2, n1, n2, n3, "XXX", update);
+ if (rnd(2) == 1)
+ {
+diff -ur mysql-orig/storage/innobase/include/ut0byte.h mysql/storage/innobase/include/ut0byte.h
+--- mysql-orig/storage/innobase/include/ut0byte.h 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/innobase/include/ut0byte.h 2012-08-14 01:14:59.522196790 +0000
+@@ -87,7 +87,7 @@
+ dulint
+ ut_dulint_get_max(
+ /*==============*/
+- /* out: max(a, b) */
++ /* out: MYSQL_MAX(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+@@ -96,7 +96,7 @@
+ dulint
+ ut_dulint_get_min(
+ /*==============*/
+- /* out: min(a, b) */
++ /* out: MYSQL_MIN(a, b) */
+ dulint a, /* in: dulint */
+ dulint b); /* in: dulint */
+ /***********************************************************
+diff -ur mysql-orig/storage/innodb_plugin/dict/dict0dict.c mysql/storage/innodb_plugin/dict/dict0dict.c
+--- mysql-orig/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/dict/dict0dict.c 2012-08-14 01:14:59.522196790 +0000
+@@ -4898,7 +4898,7 @@
+
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+@@ -4908,7 +4908,7 @@
+ const char* name) /*!< in: name of the index to find */
+ {
+ dict_index_t* index;
+- dict_index_t* min_index; /* Index with matching name and min(id) */
++ dict_index_t* min_index; /* Index with matching name and MYSQL_MIN(id) */
+
+ min_index = NULL;
+ index = dict_table_get_first_index(table);
+diff -ur mysql-orig/storage/innodb_plugin/include/dict0dict.h mysql/storage/innodb_plugin/include/dict0dict.h
+--- mysql-orig/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/innodb_plugin/include/dict0dict.h 2012-08-14 01:14:59.552196542 +0000
+@@ -1115,7 +1115,7 @@
+ const char* name); /*!< in: name of the index to find */
+ /**********************************************************************//**
+ In case there is more than one index with the same name return the index
+-with the min(id).
++with the MYSQL_MIN(id).
+ @return index, NULL if does not exist */
+ UNIV_INTERN
+ dict_index_t*
+diff -ur mysql-orig/storage/myisam/ft_boolean_search.c mysql/storage/myisam/ft_boolean_search.c
+--- mysql-orig/storage/myisam/ft_boolean_search.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/ft_boolean_search.c 2012-08-14 01:14:59.552196542 +0000
+@@ -48,9 +48,9 @@
+ three subexpressions (including the top-level one),
+ every one has its own max_docid, updated by its plus word.
+ but for the search word6 uses
+- max(word1.max_docid, word3.max_docid, word5.max_docid),
++ MYSQL_MAX(word1.max_docid, word3.max_docid, word5.max_docid),
+ while word4 uses, accordingly,
+- max(word1.max_docid, word3.max_docid).
++ MYSQL_MAX(word1.max_docid, word3.max_docid).
+ */
+
+ #define FT_CORE
+diff -ur mysql-orig/storage/myisam/ha_myisam.cc mysql/storage/myisam/ha_myisam.cc
+--- mysql-orig/storage/myisam/ha_myisam.cc 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/ha_myisam.cc 2012-08-14 01:14:59.552196542 +0000
+@@ -1546,7 +1546,7 @@
+ {
+ DBUG_ENTER("ha_myisam::start_bulk_insert");
+ THD *thd= current_thd;
+- ulong size= min(thd->variables.read_buff_size,
++ ulong size= MYSQL_MIN(thd->variables.read_buff_size,
+ (ulong) (table->s->avg_row_length*rows));
+ DBUG_PRINT("info",("start_bulk_insert: rows %lu size %lu",
+ (ulong) rows, size));
+diff -ur mysql-orig/storage/myisam/mi_cache.c mysql/storage/myisam/mi_cache.c
+--- mysql-orig/storage/myisam/mi_cache.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_cache.c 2012-08-14 01:14:59.572196376 +0000
+@@ -61,7 +61,7 @@
+ (my_off_t) (info->read_end - info->request_pos))
+ {
+ in_buff_pos=info->request_pos+(uint) offset;
+- in_buff_length= min(length, (size_t) (info->read_end-in_buff_pos));
++ in_buff_length= MYSQL_MIN(length, (size_t) (info->read_end-in_buff_pos));
+ memcpy(buff,info->request_pos+(uint) offset,(size_t) in_buff_length);
+ if (!(length-=in_buff_length))
+ DBUG_RETURN(0);
+diff -ur mysql-orig/storage/myisam/mi_check.c mysql/storage/myisam/mi_check.c
+--- mysql-orig/storage/myisam/mi_check.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_check.c 2012-08-14 01:14:59.572196376 +0000
+@@ -2175,7 +2175,7 @@
+ ulong buff_length;
+ DBUG_ENTER("filecopy");
+
+- buff_length=(ulong) min(param->write_buffer_length,length);
++ buff_length=(ulong) MYSQL_MIN(param->write_buffer_length,length);
+ if (!(buff=my_malloc(buff_length,MYF(0))))
+ {
+ buff=tmp_buff; buff_length=IO_SIZE;
+@@ -2331,7 +2331,7 @@
+ init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0);
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ length=share->base.min_block_length;
+ else
+@@ -2420,7 +2420,7 @@
+ (see _create_index_by_sort)
+ */
+ sort_info.max_records= 10 *
+- max(param->sort_buffer_length, MIN_SORT_BUFFER) /
++ MYSQL_MAX(param->sort_buffer_length, MIN_SORT_BUFFER) /
+ sort_param.key_length;
+ }
+
+@@ -2784,7 +2784,7 @@
+ my_seek(param->read_cache.file,0L,MY_SEEK_END,MYF(0));
+
+ if (share->data_file_type == DYNAMIC_RECORD)
+- rec_length=max(share->base.min_pack_length+1,share->base.min_block_length);
++ rec_length=MYSQL_MAX(share->base.min_pack_length+1,share->base.min_block_length);
+ else if (share->data_file_type == COMPRESSED_RECORD)
+ rec_length=share->base.min_block_length;
+ else
+@@ -3982,7 +3982,7 @@
+ ft_buf->buf=ft_buf->lastkey+a_len;
+ /*
+ 32 is just a safety margin here
+- (at least max(val_len, sizeof(nod_flag)) should be there).
++ (at least MYSQL_MAX(val_len, sizeof(nod_flag)) should be there).
+ May be better performance could be achieved if we'd put
+ (sort_info->keyinfo->block_length-32)/XXX
+ instead.
+diff -ur mysql-orig/storage/myisam/mi_create.c mysql/storage/myisam/mi_create.c
+--- mysql-orig/storage/myisam/mi_create.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_create.c 2012-08-14 01:14:59.572196376 +0000
+@@ -439,8 +439,8 @@
+ block_length= (keydef->block_length ?
+ my_round_up_to_next_power(keydef->block_length) :
+ myisam_block_size);
+- block_length= max(block_length, MI_MIN_KEY_BLOCK_LENGTH);
+- block_length= min(block_length, MI_MAX_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MAX(block_length, MI_MIN_KEY_BLOCK_LENGTH);
++ block_length= MYSQL_MIN(block_length, MI_MAX_KEY_BLOCK_LENGTH);
+
+ keydef->block_length= (uint16) MI_BLOCK_SIZE(length-real_length_diff,
+ pointer,MI_MAX_KEYPTR_SIZE,
+@@ -529,7 +529,7 @@
+ got from MYI file header (see also myisampack.c:save_state)
+ */
+ share.base.key_reflength=
+- mi_get_pointer_length(max(ci->key_file_length,tmp),3);
++ mi_get_pointer_length(MYSQL_MAX(ci->key_file_length,tmp),3);
+ share.base.keys= share.state.header.keys= keys;
+ share.state.header.uniques= uniques;
+ share.state.header.fulltext_keys= fulltext_keys;
+@@ -567,7 +567,7 @@
+ share.base.min_block_length=
+ (share.base.pack_reclength+3 < MI_EXTEND_BLOCK_LENGTH &&
+ ! share.base.blobs) ?
+- max(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
++ MYSQL_MAX(share.base.pack_reclength,MI_MIN_BLOCK_LENGTH) :
+ MI_EXTEND_BLOCK_LENGTH;
+ if (! (flags & HA_DONT_TOUCH_DATA))
+ share.state.create_time= (long) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/mi_dynrec.c mysql/storage/myisam/mi_dynrec.c
+--- mysql-orig/storage/myisam/mi_dynrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_dynrec.c 2012-08-14 01:14:59.572196376 +0000
+@@ -882,7 +882,7 @@
+ uint tmp=MY_ALIGN(reclength - length + 3 +
+ test(reclength >= 65520L),MI_DYN_ALIGN_SIZE);
+ /* Don't create a block bigger than MI_MAX_BLOCK_LENGTH */
+- tmp= min(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
++ tmp= MYSQL_MIN(length+tmp, MI_MAX_BLOCK_LENGTH)-length;
+ /* Check if we can extend this block */
+ if (block_info.filepos + block_info.block_len ==
+ info->state->data_file_length &&
+diff -ur mysql-orig/storage/myisam/mi_extra.c mysql/storage/myisam/mi_extra.c
+--- mysql-orig/storage/myisam/mi_extra.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_extra.c 2012-08-14 01:14:59.572196376 +0000
+@@ -101,7 +101,7 @@
+ cache_size= (extra_arg ? *(ulong*) extra_arg :
+ my_default_record_cache_size);
+ if (!(init_io_cache(&info->rec_cache,info->dfile,
+- (uint) min(info->state->data_file_length+1,
++ (uint) MYSQL_MIN(info->state->data_file_length+1,
+ cache_size),
+ READ_CACHE,0L,(pbool) (info->lock_type != F_UNLCK),
+ MYF(share->write_flag & MY_WAIT_IF_FULL))))
+diff -ur mysql-orig/storage/myisam/mi_open.c mysql/storage/myisam/mi_open.c
+--- mysql-orig/storage/myisam/mi_open.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_open.c 2012-08-14 01:14:59.582196294 +0000
+@@ -330,7 +330,7 @@
+ strmov(share->index_file_name, index_name);
+ strmov(share->data_file_name, data_name);
+
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ {
+ HA_KEYSEG *pos=share->keyparts;
+ uint32 ftkey_nr= 1;
+@@ -503,7 +503,7 @@
+ share->base.margin_key_file_length=(share->base.max_key_file_length -
+ (keys ? MI_INDEX_BLOCK_MARGIN *
+ share->blocksize * keys : 0));
+- share->blocksize=min(IO_SIZE,myisam_block_size);
++ share->blocksize=MYSQL_MIN(IO_SIZE,myisam_block_size);
+ share->data_file_type=STATIC_RECORD;
+ if (share->options & HA_OPTION_COMPRESS_RECORD)
+ {
+@@ -716,10 +716,10 @@
+ if (length == (ulong) -1)
+ {
+ if (info->s->options & HA_OPTION_COMPRESS_RECORD)
+- length= max(info->s->base.pack_reclength, info->s->max_pack_length);
++ length= MYSQL_MAX(info->s->base.pack_reclength, info->s->max_pack_length);
+ else
+ length= info->s->base.pack_reclength;
+- length= max(length, info->s->base.max_key_length);
++ length= MYSQL_MAX(length, info->s->base.max_key_length);
+ /* Avoid unnecessary realloc */
+ if (newptr && length == old_length)
+ return newptr;
+diff -ur mysql-orig/storage/myisam/mi_packrec.c mysql/storage/myisam/mi_packrec.c
+--- mysql-orig/storage/myisam/mi_packrec.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/mi_packrec.c 2012-08-14 01:14:59.582196294 +0000
+@@ -686,7 +686,7 @@
+ return OFFSET_TABLE_SIZE;
+ }
+ length2= find_longest_bitstream(next, end) + 1;
+- length=max(length,length2);
++ length=MYSQL_MAX(length,length2);
+ }
+ return length;
+ }
+@@ -1401,7 +1401,7 @@
+ info->filepos=filepos+head_length;
+ if (file > 0)
+ {
+- info->offset=min(info->rec_len, ref_length - head_length);
++ info->offset=MYSQL_MIN(info->rec_len, ref_length - head_length);
+ memcpy(*rec_buff_p, header + head_length, info->offset);
+ }
+ return 0;
+diff -ur mysql-orig/storage/myisam/mi_test1.c mysql/storage/myisam/mi_test1.c
+--- mysql-orig/storage/myisam/mi_test1.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test1.c 2012-08-14 01:14:59.582196294 +0000
+@@ -438,7 +438,7 @@
+ uint tmp;
+ uchar *ptr;;
+ sprintf((char*) blob_record,"... row: %d", rownr);
+- strappend((char*) blob_record,max(MAX_REC_LENGTH-rownr,10),' ');
++ strappend((char*) blob_record,MYSQL_MAX(MAX_REC_LENGTH-rownr,10),' ');
+ tmp=strlen((char*) blob_record);
+ int4store(pos,tmp);
+ ptr=blob_record;
+diff -ur mysql-orig/storage/myisam/mi_test2.c mysql/storage/myisam/mi_test2.c
+--- mysql-orig/storage/myisam/mi_test2.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/mi_test2.c 2012-08-14 01:14:59.582196294 +0000
+@@ -603,7 +603,7 @@
+ goto err;
+
+ bmove(read_record2,read_record,reclength);
+- for (i=min(2,keys) ; i-- > 0 ;)
++ for (i=MYSQL_MIN(2,keys) ; i-- > 0 ;)
+ {
+ if (mi_rsame(file,read_record2,(int) i)) goto err;
+ if (memcmp(read_record,read_record2,reclength) != 0)
+diff -ur mysql-orig/storage/myisam/myisamlog.c mysql/storage/myisam/myisamlog.c
+--- mysql-orig/storage/myisam/myisamlog.c 2012-08-14 01:12:29.653435667 +0000
++++ mysql/storage/myisam/myisamlog.c 2012-08-14 01:14:59.582196294 +0000
+@@ -92,7 +92,7 @@
+ log_filename=myisam_log_filename;
+ get_options(&argc,&argv);
+ /* Number of MyISAM files we can have open at one time */
+- max_files= (my_set_max_open_files(min(max_files,8))-6)/2;
++ max_files= (my_set_max_open_files(MYSQL_MIN(max_files,8))-6)/2;
+ if (update)
+ printf("Trying to %s MyISAM files according to log '%s'\n",
+ (recover ? "recover" : "update"),log_filename);
+diff -ur mysql-orig/storage/myisam/myisampack.c mysql/storage/myisam/myisampack.c
+--- mysql-orig/storage/myisam/myisampack.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/myisampack.c 2012-08-14 01:14:59.582196294 +0000
+@@ -1240,7 +1240,7 @@
+ {
+ if (huff_counts->field_length > 2 &&
+ huff_counts->empty_fields + (records - huff_counts->empty_fields)*
+- (1+max_bit(max(huff_counts->max_pre_space,
++ (1+max_bit(MYSQL_MAX(huff_counts->max_pre_space,
+ huff_counts->max_end_space))) <
+ records * max_bit(huff_counts->field_length))
+ {
+@@ -3002,7 +3002,7 @@
+ if (mrg->src_file_has_indexes_disabled)
+ {
+ isam_file->s->state.state.key_file_length=
+- max(isam_file->s->state.state.key_file_length, new_length);
++ MYSQL_MAX(isam_file->s->state.state.key_file_length, new_length);
+ }
+ state.dellink= HA_OFFSET_ERROR;
+ state.version=(ulong) time((time_t*) 0);
+diff -ur mysql-orig/storage/myisam/rt_mbr.c mysql/storage/myisam/rt_mbr.c
+--- mysql-orig/storage/myisam/rt_mbr.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/rt_mbr.c 2012-08-14 01:14:59.582196294 +0000
+@@ -325,8 +325,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -338,8 +338,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = min(amin, bmin); \
+- amax = max(amax, bmax); \
++ amin = MYSQL_MIN(amin, bmin); \
++ amax = MYSQL_MAX(amax, bmax); \
+ store_func(c, amin); \
+ store_func(c+len, amax); \
+ }
+@@ -417,8 +417,8 @@
+ bmin = korr_func(b); \
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -431,8 +431,8 @@
+ get_func(bmin, b); \
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+- amin = max(amin, bmin); \
+- amax = min(amax, bmax); \
++ amin = MYSQL_MAX(amin, bmin); \
++ amax = MYSQL_MIN(amax, bmax); \
+ if (amin >= amax) \
+ return 0; \
+ res *= amax - amin; \
+@@ -508,7 +508,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_AREA_INC_GET(type, get_func, len)\
+@@ -519,7 +519,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_area *= (((double)amax) - ((double)amin)); \
+- loc_ab_area *= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ loc_ab_area *= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+@@ -604,7 +604,7 @@
+ amax = korr_func(a+len); \
+ bmax = korr_func(b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ #define RT_PERIM_INC_GET(type, get_func, len)\
+@@ -615,7 +615,7 @@
+ get_func(amax, a+len); \
+ get_func(bmax, b+len); \
+ a_perim+= (((double)amax) - ((double)amin)); \
+- *ab_perim+= ((double)max(amax, bmax) - (double)min(amin, bmin)); \
++ *ab_perim+= ((double)MYSQL_MAX(amax, bmax) - (double)MYSQL_MIN(amin, bmin)); \
+ }
+
+ /*
+diff -ur mysql-orig/storage/myisam/sort.c mysql/storage/myisam/sort.c
+--- mysql-orig/storage/myisam/sort.c 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisam/sort.c 2012-08-14 01:14:59.582196294 +0000
+@@ -131,7 +131,7 @@
+ sort_keys= (uchar **) NULL; error= 1;
+ maxbuffer=1;
+
+- memavl= max(sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sortbuff_size, MIN_SORT_BUFFER);
+ records= info->sort_info->max_records;
+ sort_length= info->key_length;
+ LINT_INIT(keys);
+@@ -348,7 +348,7 @@
+ bzero((char*) &sort_param->unique, sizeof(sort_param->unique));
+ sort_keys= (uchar **) NULL;
+
+- memavl= max(sort_param->sortbuff_size, MIN_SORT_BUFFER);
++ memavl= MYSQL_MAX(sort_param->sortbuff_size, MIN_SORT_BUFFER);
+ idx= (uint)sort_param->sort_info->max_records;
+ sort_length= sort_param->key_length;
+ maxbuffer= 1;
+@@ -822,7 +822,7 @@
+ register uint count;
+ uint length;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ if (my_pread(fromfile->file,(uchar*) buffpek->base,
+ (length= sort_length*count),buffpek->file_pos,MYF_RW))
+@@ -843,7 +843,7 @@
+ uint idx;
+ uchar *buffp;
+
+- if ((count=(uint) min((ha_rows) buffpek->max_keys,buffpek->count)))
++ if ((count=(uint) MYSQL_MIN((ha_rows) buffpek->max_keys,buffpek->count)))
+ {
+ buffp = buffpek->base;
+
+diff -ur mysql-orig/storage/myisammrg/ha_myisammrg.cc mysql/storage/myisammrg/ha_myisammrg.cc
+--- mysql-orig/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:12:29.643435749 +0000
++++ mysql/storage/myisammrg/ha_myisammrg.cc 2012-08-14 01:14:59.582196294 +0000
+@@ -965,7 +965,7 @@
+ memcpy((char*) table->key_info[0].rec_per_key,
+ (char*) mrg_info.rec_per_key,
+ sizeof(table->key_info[0].rec_per_key[0]) *
+- min(file->keys, table->s->key_parts));
++ MYSQL_MIN(file->keys, table->s->key_parts));
+ }
+ }
+ if (flag & HA_STATUS_ERRKEY)
+diff -ur mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp mysql/storage/ndb/src/common/portlib/NdbTCP.cpp
+--- mysql-orig/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:12:29.673435501 +0000
++++ mysql/storage/ndb/src/common/portlib/NdbTCP.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,7 +30,7 @@
+ &tmp_errno);
+ if (hp)
+ {
+- memcpy(dst, hp->h_addr, min(sizeof(*dst), (size_t) hp->h_length));
++ memcpy(dst, hp->h_addr, MYSQL_MIN(sizeof(*dst), (size_t) hp->h_length));
+ my_gethostbyname_r_free();
+ return 0; //DBUG_RETURN(0);
+ }
+diff -ur mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+--- mysql-orig/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:12:29.683435419 +0000
++++ mysql/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -212,7 +212,7 @@
+ }
+ }
+ // return values
+- par.m_depth = 1 + max(cpar[0].m_depth, cpar[1].m_depth);
++ par.m_depth = 1 + MYSQL_MAX(cpar[0].m_depth, cpar[1].m_depth);
+ par.m_occup = node.getOccup();
+ for (unsigned i = 0; i <= 1; i++) {
+ if (node.getLink(i) == NullTupLoc)
+diff -ur mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp mysql/storage/ndb/src/ndbapi/NdbBlob.cpp
+--- mysql-orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:12:29.693435335 +0000
++++ mysql/storage/ndb/src/ndbapi/NdbBlob.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -1523,7 +1523,7 @@
+ }
+ // these buffers are always used
+ theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
+- thePackKeyBuf.alloc(max(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
++ thePackKeyBuf.alloc(MYSQL_MAX(theTable->m_keyLenInWords, theAccessTable->m_keyLenInWords) << 2);
+ theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
+ theHead = (Head*)theHeadInlineBuf.data;
+ theInlineData = theHeadInlineBuf.data + sizeof(Head);
+diff -ur mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp mysql/storage/ndb/test/ndbapi/testIndexStat.cpp
+--- mysql-orig/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/ndbapi/testIndexStat.cpp 2012-08-14 01:14:59.582196294 +0000
+@@ -30,10 +30,10 @@
+ * 0. baseline with same options as handler
+ */
+
+-#undef min
+-#undef max
+-#define min(a, b) ((a) <= (b) ? (a) : (b))
+-#define max(a, b) ((a) >= (b) ? (a) : (b))
++#undef MYSQL_MIN
++#undef MYSQL_MAX
++#define MYSQL_MIN(a, b) ((a) <= (b) ? (a) : (b))
++#define MYSQL_MAX(a, b) ((a) >= (b) ? (a) : (b))
+
+ inline NdbOut&
+ NdbOut::operator<<(double x)
+@@ -784,13 +784,13 @@
+ uint
+ Range::minattrs() const
+ {
+- return min(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MIN(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ uint
+ Range::maxattrs() const
+ {
+- return max(bnd[0].val.numattrs, bnd[1].val.numattrs);
++ return MYSQL_MAX(bnd[0].val.numattrs, bnd[1].val.numattrs);
+ }
+
+ int
+@@ -856,8 +856,8 @@
+ lim[i] = lo;
+ }
+ // the range
+- const int lo = max(lim[0], 0);
+- const int hi = min(lim[1], (int)g_sortcount - 1);
++ const int lo = MYSQL_MAX(lim[0], 0);
++ const int hi = MYSQL_MIN(lim[1], (int)g_sortcount - 1);
+ if (! g_opts.nochecks) {
+ int curr = -1;
+ for (i = 0; i < (int)g_sortcount; i++) {
+diff -ur mysql-orig/storage/ndb/test/src/getarg.c mysql/storage/ndb/test/src/getarg.c
+--- mysql-orig/storage/ndb/test/src/getarg.c 2012-08-14 01:12:29.663435583 +0000
++++ mysql/storage/ndb/test/src/getarg.c 2012-08-14 01:14:59.582196294 +0000
+@@ -65,8 +65,8 @@
+
+ #define ISFLAG(X) ((X).type == arg_flag || (X).type == arg_negative_flag)
+
+-#ifndef max
+-#define max(a, b) (a) > (b) ? (a) : (b)
++#ifndef MYSQL_MAX
++#define MYSQL_MAX(a, b) (a) > (b) ? (a) : (b)
+ #endif
+
+ #ifdef HAVE___PROGNAME
+@@ -306,7 +306,7 @@
+ }
+ if (args[i].long_name && args[i].short_name)
+ len += 2; /* ", " */
+- max_len = max(max_len, len);
++ max_len = MYSQL_MAX(max_len, len);
+ }
+ if (extra_string) {
+ col = check_column(stderr, col, strlen(extra_string) + 1, columns);
+diff -ur mysql-orig/strings/ctype-big5.c mysql/strings/ctype-big5.c
+--- mysql-orig/strings/ctype-big5.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-big5.c 2012-08-14 01:14:59.592196210 +0000
+@@ -254,7 +254,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+ return res ? res : (int)((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -267,7 +267,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_big5_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-bin.c mysql/strings/ctype-bin.c
+--- mysql-orig/strings/ctype-bin.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-bin.c 2012-08-14 01:14:59.592196210 +0000
+@@ -82,7 +82,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -133,7 +133,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -177,7 +177,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -406,7 +406,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, 0);
+ return dstlen;
+@@ -419,7 +419,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen,srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-gbk.c mysql/strings/ctype-gbk.c
+--- mysql-orig/strings/ctype-gbk.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-gbk.c 2012-08-14 01:14:59.592196210 +0000
+@@ -2617,7 +2617,7 @@
+ const uchar *b, size_t b_length,
+ my_bool b_is_prefix)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+ return res ? res : (int) ((b_is_prefix ? length : a_length) - b_length);
+ }
+@@ -2628,7 +2628,7 @@
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference)
+ {
+- size_t length= min(a_length, b_length);
++ size_t length= MYSQL_MIN(a_length, b_length);
+ int res= my_strnncoll_gbk_internal(&a, &b, length);
+
+ #ifndef VARCHAR_WITH_DIFF_ENDSPACE_ARE_DIFFERENT_FOR_UNIQUE
+diff -ur mysql-orig/strings/ctype-mb.c mysql/strings/ctype-mb.c
+--- mysql-orig/strings/ctype-mb.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-mb.c 2012-08-14 01:14:59.592196210 +0000
+@@ -369,7 +369,7 @@
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix)
+ {
+- size_t len=min(slen,tlen);
++ size_t len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : (int) ((t_is_prefix ? len : slen) - tlen);
+ }
+@@ -413,7 +413,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -452,7 +452,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dest != src)
+- memcpy(dest, src, min(dstlen, srclen));
++ memcpy(dest, src, MYSQL_MIN(dstlen, srclen));
+ if (dstlen > srclen)
+ bfill(dest + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-simple.c mysql/strings/ctype-simple.c
+--- mysql-orig/strings/ctype-simple.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-simple.c 2012-08-14 01:14:59.592196210 +0000
+@@ -161,7 +161,7 @@
+ diff_if_only_endspace_difference= 0;
+ #endif
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (map[*a++] != map[*b++])
+@@ -875,7 +875,7 @@
+ val= new_val;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ memcpy(dst, p, len);
+ return len+sign;
+ }
+@@ -929,7 +929,7 @@
+ long_val= quo;
+ }
+
+- len= min(len, (size_t) (e-p));
++ len= MYSQL_MIN(len, (size_t) (e-p));
+ cnv:
+ memcpy(dst, p, len);
+ return len+sign;
+@@ -1160,7 +1160,7 @@
+ {
+ size_t nbytes= (size_t) (end-start);
+ *error= 0;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+diff -ur mysql-orig/strings/ctype-tis620.c mysql/strings/ctype-tis620.c
+--- mysql-orig/strings/ctype-tis620.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-tis620.c 2012-08-14 01:14:59.592196210 +0000
+@@ -583,7 +583,7 @@
+ a_length= thai2sortable(a, a_length);
+ b_length= thai2sortable(b, b_length);
+
+- end= a + (length= min(a_length, b_length));
++ end= a + (length= MYSQL_MIN(a_length, b_length));
+ while (a < end)
+ {
+ if (*a++ != *b++)
+@@ -640,7 +640,7 @@
+ const uchar *src, size_t srclen)
+ {
+ size_t dstlen= len;
+- len= (size_t) (strmake((char*) dest, (char*) src, min(len, srclen)) -
++ len= (size_t) (strmake((char*) dest, (char*) src, MYSQL_MIN(len, srclen)) -
+ (char*) dest);
+ len= thai2sortable(dest, len);
+ if (dstlen > len)
+diff -ur mysql-orig/strings/ctype-uca.c mysql/strings/ctype-uca.c
+--- mysql-orig/strings/ctype-uca.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-uca.c 2012-08-14 01:14:59.592196210 +0000
+@@ -7569,7 +7569,7 @@
+ {
+ char tail[30];
+ size_t len= lexem->end - lexem->prev;
+- strmake (tail, lexem->prev, (size_t) min(len, sizeof(tail)-1));
++ strmake (tail, lexem->prev, (size_t) MYSQL_MIN(len, sizeof(tail)-1));
+ errstr[errsize-1]= '\0';
+ my_snprintf(errstr,errsize-1,"%s at '%s'", txt, tail);
+ }
+diff -ur mysql-orig/strings/ctype-ucs2.c mysql/strings/ctype-ucs2.c
+--- mysql-orig/strings/ctype-ucs2.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-ucs2.c 2012-08-14 01:14:59.602196128 +0000
+@@ -280,7 +280,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc = uni_plane[s[0]] ? (int) uni_plane[s[0]][s[1]].sort :
+ (((int) s[0]) << 8) + (int) s[1];
+@@ -1332,7 +1332,7 @@
+ size_t nbytes= ((size_t) (e-b)) & ~(size_t) 1;
+ *error= 0;
+ nchars*= 2;
+- return min(nbytes, nchars);
++ return MYSQL_MIN(nbytes, nchars);
+ }
+
+
+@@ -1426,7 +1426,7 @@
+ se= s + slen;
+ te= t + tlen;
+
+- for (minlen= min(slen, tlen); minlen; minlen-= 2)
++ for (minlen= MYSQL_MIN(slen, tlen); minlen; minlen-= 2)
+ {
+ int s_wc= s[0] * 256 + s[1];
+ int t_wc= t[0] * 256 + t[1];
+@@ -1473,7 +1473,7 @@
+ const uchar *src, size_t srclen)
+ {
+ if (dst != src)
+- memcpy(dst,src,srclen= min(dstlen,srclen));
++ memcpy(dst,src,srclen= MYSQL_MIN(dstlen,srclen));
+ if (dstlen > srclen)
+ cs->cset->fill(cs, (char*) dst + srclen, dstlen - srclen, ' ');
+ return dstlen;
+diff -ur mysql-orig/strings/ctype-utf8.c mysql/strings/ctype-utf8.c
+--- mysql-orig/strings/ctype-utf8.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/ctype-utf8.c 2012-08-14 01:14:59.602196128 +0000
+@@ -2114,7 +2114,7 @@
+ const uchar *t, const uchar *te)
+ {
+ int slen= (int) (se-s), tlen= (int) (te-t);
+- int len=min(slen,tlen);
++ int len=MYSQL_MIN(slen,tlen);
+ int cmp= memcmp(s,t,len);
+ return cmp ? cmp : slen-tlen;
+ }
+diff -ur mysql-orig/strings/decimal.c mysql/strings/decimal.c
+--- mysql-orig/strings/decimal.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/decimal.c 2012-08-14 01:14:59.602196128 +0000
+@@ -405,7 +405,7 @@
+ for (; frac>0; frac-=DIG_PER_DEC1)
+ {
+ dec1 x=*buf++;
+- for (i=min(frac, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(frac, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/DIG_MASK;
+ *s1++='0'+(uchar)y;
+@@ -428,7 +428,7 @@
+ for (buf=buf0+ROUND_UP(intg); intg>0; intg-=DIG_PER_DEC1)
+ {
+ dec1 x=*--buf;
+- for (i=min(intg, DIG_PER_DEC1); i; i--)
++ for (i=MYSQL_MIN(intg, DIG_PER_DEC1); i; i--)
+ {
+ dec1 y=x/10;
+ *--s='0'+(uchar)(x-y*10);
+@@ -1531,8 +1531,8 @@
+
+ if (to != from)
+ {
+- dec1 *p0= buf0+intg0+max(frac1, frac0);
+- dec1 *p1= buf1+intg0+max(frac1, frac0);
++ dec1 *p0= buf0+intg0+MYSQL_MAX(frac1, frac0);
++ dec1 *p1= buf1+intg0+MYSQL_MAX(frac1, frac0);
+
+ DBUG_ASSERT(p0 - buf0 <= len);
+ DBUG_ASSERT(p1 - buf1 <= len);
+@@ -1543,7 +1543,7 @@
+ buf0=to->buf;
+ buf1=to->buf;
+ to->sign=from->sign;
+- to->intg=min(intg0, len)*DIG_PER_DEC1;
++ to->intg=MYSQL_MIN(intg0, len)*DIG_PER_DEC1;
+ }
+
+ if (frac0 > frac1)
+@@ -1645,7 +1645,7 @@
+ scale=frac0*DIG_PER_DEC1;
+ error=E_DEC_TRUNCATED; /* XXX */
+ }
+- for (buf1=to->buf+intg0+max(frac0,0); buf1 > to->buf; buf1--)
++ for (buf1=to->buf+intg0+MYSQL_MAX(frac0,0); buf1 > to->buf; buf1--)
+ {
+ buf1[0]=buf1[-1];
+ }
+@@ -1664,7 +1664,7 @@
+ /* making 'zero' with the proper scale */
+ dec1 *p0= to->buf + frac0 + 1;
+ to->intg=1;
+- to->frac= max(scale, 0);
++ to->frac= MYSQL_MAX(scale, 0);
+ to->sign= 0;
+ for (buf1= to->buf; buf1<p0; buf1++)
+ *buf1= 0;
+@@ -1713,11 +1713,11 @@
+ {
+ switch (op) {
+ case '-':
+- return ROUND_UP(max(from1->intg, from2->intg)) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '+':
+- return ROUND_UP(max(from1->intg, from2->intg)+1) +
+- ROUND_UP(max(from1->frac, from2->frac));
++ return ROUND_UP(MYSQL_MAX(from1->intg, from2->intg)+1) +
++ ROUND_UP(MYSQL_MAX(from1->frac, from2->frac));
+ case '*':
+ return ROUND_UP(from1->intg+from2->intg)+
+ ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
+@@ -1732,7 +1732,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
+- frac0=max(frac1, frac2), intg0=max(intg1, intg2), error;
++ frac0=MYSQL_MAX(frac1, frac2), intg0=MYSQL_MAX(intg1, intg2), error;
+ dec1 *buf1, *buf2, *buf0, *stop, *stop2, x, carry;
+
+ sanity(to);
+@@ -1757,7 +1757,7 @@
+ buf0=to->buf+intg0+frac0;
+
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg0*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1768,7 +1768,7 @@
+ set_if_smaller(intg2, intg0);
+ }
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN(frac) */
+ if (frac1 > frac2)
+ {
+ buf1=from1->buf+intg1+frac1;
+@@ -1786,14 +1786,14 @@
+ while (buf1 > stop)
+ *--buf0=*--buf1;
+
+- /* part 2 - min(frac) ... min(intg) */
++ /* part 2 - MYSQL_MIN(frac) ... MYSQL_MIN(intg) */
+ carry=0;
+ while (buf1 > stop2)
+ {
+ ADD(*--buf0, *--buf1, *--buf2, carry);
+ }
+
+- /* part 3 - min(intg) ... max(intg) */
++ /* part 3 - MYSQL_MIN(intg) ... MYSQL_MAX(intg) */
+ buf1= intg1 > intg2 ? ((stop=from1->buf)+intg1-intg2) :
+ ((stop=from2->buf)+intg2-intg1) ;
+ while (buf1 > stop)
+@@ -1814,7 +1814,7 @@
+ {
+ int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
+ frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac);
+- int frac0=max(frac1, frac2), error;
++ int frac0=MYSQL_MAX(frac1, frac2), error;
+ dec1 *buf1, *buf2, *buf0, *stop1, *stop2, *start1, *start2, carry=0;
+
+ /* let carry:=1 if from2 > from1 */
+@@ -1889,7 +1889,7 @@
+ FIX_INTG_FRAC_ERROR(to->len, intg1, frac0, error);
+ buf0=to->buf+intg1+frac0;
+
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ to->intg=intg1*DIG_PER_DEC1;
+ if (unlikely(error))
+ {
+@@ -1900,7 +1900,7 @@
+ }
+ carry=0;
+
+- /* part 1 - max(frac) ... min (frac) */
++ /* part 1 - MYSQL_MAX(frac) ... MYSQL_MIN (frac) */
+ if (frac1 > frac2)
+ {
+ buf1=start1+intg1+frac1;
+@@ -1924,7 +1924,7 @@
+ }
+ }
+
+- /* part 2 - min(frac) ... intg2 */
++ /* part 2 - MYSQL_MIN(frac) ... intg2 */
+ while (buf2 > start2)
+ {
+ SUB(*--buf0, *--buf1, *--buf2, carry);
+@@ -2187,11 +2187,11 @@
+ {
+ /* we're calculating N1 % N2.
+ The result will have
+- frac=max(frac1, frac2), as for subtraction
++ frac=MYSQL_MAX(frac1, frac2), as for subtraction
+ intg=intg2
+ */
+ to->sign=from1->sign;
+- to->frac=max(from1->frac, from2->frac);
++ to->frac=MYSQL_MAX(from1->frac, from2->frac);
+ frac0=0;
+ }
+ else
+@@ -2315,7 +2315,7 @@
+ /*
+ now the result is in tmp1, it has
+ intg=prec1-frac1
+- frac=max(frac1, frac2)=to->frac
++ frac=MYSQL_MAX(frac1, frac2)=to->frac
+ */
+ if (dcarry)
+ *--start1=dcarry;
+@@ -2353,7 +2353,7 @@
+ }
+ DBUG_ASSERT(intg0 <= ROUND_UP(from2->intg));
+ stop1=start1+frac0+intg0;
+- to->intg=min(intg0*DIG_PER_DEC1, from2->intg);
++ to->intg=MYSQL_MIN(intg0*DIG_PER_DEC1, from2->intg);
+ }
+ if (unlikely(intg0+frac0 > to->len))
+ {
+diff -ur mysql-orig/strings/my_vsnprintf.c mysql/strings/my_vsnprintf.c
+--- mysql-orig/strings/my_vsnprintf.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/my_vsnprintf.c 2012-08-14 01:14:59.602196128 +0000
+@@ -143,7 +143,7 @@
+ /* If %#d syntax was used, we have to pre-zero/pre-space the string */
+ if (store_start == buff)
+ {
+- length= min(length, to_length);
++ length= MYSQL_MIN(length, to_length);
+ if (res_length < length)
+ {
+ size_t diff= (length- res_length);
+diff -ur mysql-orig/strings/str2int.c mysql/strings/str2int.c
+--- mysql-orig/strings/str2int.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/strings/str2int.c 2012-08-14 01:14:59.602196128 +0000
+@@ -84,7 +84,7 @@
+ machines all, if +|n| is representable, so is -|n|, but on
+ twos complement machines the converse is not true. So the
+ "maximum" representable number has a negative representative.
+- Limit is set to min(-|lower|,-|upper|); this is the "largest"
++ Limit is set to MYSQL_MIN(-|lower|,-|upper|); this is the "largest"
+ number we are concerned with. */
+
+ /* Calculate Limit using Scale as a scratch variable */
+diff -ur mysql-orig/vio/viosocket.c mysql/vio/viosocket.c
+--- mysql-orig/vio/viosocket.c 2012-08-14 01:12:29.723435087 +0000
++++ mysql/vio/viosocket.c 2012-08-14 01:14:59.602196128 +0000
+@@ -79,7 +79,7 @@
+
+ if (vio->read_pos < vio->read_end)
+ {
+- rc= min((size_t) (vio->read_end - vio->read_pos), size);
++ rc= MYSQL_MIN((size_t) (vio->read_end - vio->read_pos), size);
+ memcpy(buf, vio->read_pos, rc);
+ vio->read_pos+= rc;
+ /*
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2013-12-12 15:25 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2013-12-12 15:25 UTC (permalink / raw
To: gentoo-commits
commit: 1477b8961894eccd115c16dbaa4548bb0eadb82e
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Dec 12 15:24:50 2013 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Dec 12 15:24:50 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1477b896
Fix bad Makefile.am references in unittest/my_decimal
---
00000_index.txt | 5 +++++
20005_all_mysql-unittest-5.1.73.patch | 19 +++++++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 0524cfc..98fcae7 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1544,3 +1544,8 @@
@pn mariadb
@pn mariadb-galera
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
+
+@patch 20005_all_mysql-unittest-5.1.73.patch
+@ver 5.01.73.00 to 5.01.99.99
+@pn mysql
+@@ Fix poor Makefile.am references in unittest/my_decimal
diff --git a/20005_all_mysql-unittest-5.1.73.patch b/20005_all_mysql-unittest-5.1.73.patch
new file mode 100644
index 0000000..59cef0d
--- /dev/null
+++ b/20005_all_mysql-unittest-5.1.73.patch
@@ -0,0 +1,19 @@
+--- a/unittest/my_decimal/Makefile.am 2013-12-12 09:37:48.508314567 -0500
++++ b/unittest/my_decimal/Makefile.am 2013-12-12 09:38:28.187519854 -0500
+@@ -18,11 +18,11 @@
+ AM_CPPFLAGS += -I$(top_srcdir)/sql
+
+ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a \
+- $(top_builddir)/dbug/libdbug.a \
+- $(top_builddir)/mysys/libmysys.a \
+- $(top_builddir)/strings/libmystrings.a
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la \
++ $(top_builddir)/dbug/libdbug.la \
++ $(top_builddir)/mysys/libmysys.la \
++ $(top_builddir)/strings/libmystrings.la
+
+ my_decimal_t_SOURCES = my_decimal-t.cc
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-18 22:40 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-18 22:40 UTC (permalink / raw
To: gentoo-commits
commit: abe99de571cf27c23342469bc717711ae1213f0e
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Fri Jan 17 00:37:45 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sat Jan 18 22:34:58 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=abe99de5
Split client and embedded libs.
Add a patch based on Brian Evan's patch to address libutils.cmake.
---
00000_index.txt | 5 ++
20006_all_cmake_elib.patch | 129 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 134 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 98fcae7..f1c6274 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1549,3 +1549,8 @@
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
@@ Fix poor Makefile.am references in unittest/my_decimal
+
+@patch 20006_all_cmake_elib.patch
+@ver 5.05.32.00 to 5.05.32.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
diff --git a/20006_all_cmake_elib.patch b/20006_all_cmake_elib.patch
new file mode 100644
index 0000000..a3c3f38
--- /dev/null
+++ b/20006_all_cmake_elib.patch
@@ -0,0 +1,129 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-17 13:01:56.248694769 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-17 13:02:26.515695920 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ # - INSTALL_SYSCONFDIR (config files. Usually /etc or nothing)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -119,6 +120,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -180,6 +184,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "bin")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -207,6 +212,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -238,7 +244,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-17 13:01:56.248694769 -0100
++++ mysql/cmake/libutils.cmake 2014-01-17 13:19:22.283734547 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-17 13:01:56.247694769 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-17 13:17:10.427729533 -0100
+@@ -329,7 +329,7 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-17 13:01:56.048694761 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-17 13:18:03.210731540 -0100
+@@ -134,7 +134,7 @@
+ ENDFOREACH()
+
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -142,7 +142,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -161,7 +161,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-18 23:47 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-18 23:47 UTC (permalink / raw
To: gentoo-commits
commit: 445859d4b3390cea7ba542613bb8a891323adc9b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 18 23:41:50 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Sat Jan 18 23:41:50 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=445859d4
Bump cmake_elib patch to mariadb-5.5.33 and higher.
---
00000_index.txt | 7 +++-
...ch => 20006_all_cmake_elib-mariadb-5.5.32.patch | 0
...ch => 20006_all_cmake_elib-mariadb-5.5.33.patch | 39 +++++++++++-----------
3 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index f1c6274..4659487 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1550,7 +1550,12 @@
@pn mysql
@@ Fix poor Makefile.am references in unittest/my_decimal
-@patch 20006_all_cmake_elib.patch
+@patch 20006_all_cmake_elib-mariad-5.5.32.patch
@ver 5.05.32.00 to 5.05.32.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-mariad-5.5.33.patch
+@ver 5.05.33.00 to 5.05.99.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
diff --git a/20006_all_cmake_elib.patch b/20006_all_cmake_elib-mariadb-5.5.32.patch
similarity index 100%
copy from 20006_all_cmake_elib.patch
copy to 20006_all_cmake_elib-mariadb-5.5.32.patch
diff --git a/20006_all_cmake_elib.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
similarity index 81%
rename from 20006_all_cmake_elib.patch
rename to 20006_all_cmake_elib-mariadb-5.5.33.patch
index a3c3f38..50abfe9 100644
--- a/20006_all_cmake_elib.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -1,9 +1,9 @@
diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
---- mysql-old/cmake/install_layout.cmake 2014-01-17 13:01:56.248694769 -0100
-+++ mysql/cmake/install_layout.cmake 2014-01-17 13:02:26.515695920 -0100
-@@ -43,7 +43,8 @@
- # - INSTALL_SCRIPTDIR (several scripts, rarely used)
- # - INSTALL_SYSCONFDIR (config files. Usually /etc or nothing)
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
#
-# - INSTALL_LIBDIR (directory with client end embedded libraries)
+# - INSTALL_LIBDIR (directory with client libraries)
@@ -11,7 +11,7 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
# - INSTALL_PLUGINDIR (directory for plugins)
#
# - INSTALL_INCLUDEDIR (directory for MySQL headers)
-@@ -119,6 +120,7 @@
+@@ -120,6 +121,7 @@
SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
#
SET(INSTALL_LIBDIR_STANDALONE "lib")
@@ -19,7 +19,7 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
#
SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
-@@ -148,9 +150,11 @@
+@@ -150,9 +152,11 @@
#
IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
SET(INSTALL_LIBDIR_RPM "lib64")
@@ -31,15 +31,15 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
ENDIF()
#
-@@ -180,6 +184,7 @@
- SET(INSTALL_SCRIPTDIR_DEB "bin")
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
#
SET(INSTALL_LIBDIR_DEB "lib")
+SET(INSTALL_ELIBDIR_DEB "lib")
SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
#
SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
-@@ -207,6 +212,7 @@
+@@ -210,6 +215,7 @@
SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
#
SET(INSTALL_LIBDIR_SVR4 "lib")
@@ -47,18 +47,19 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
#
SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
-@@ -238,7 +244,7 @@
+@@ -241,7 +247,7 @@
# Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
# will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
# layout is chosen)
--FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF
-+FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
CACHE STRING "${var} installation directory" ${FORCE})
+Only in mysql/cmake: install_layout.cmake.orig
diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
---- mysql-old/cmake/libutils.cmake 2014-01-17 13:01:56.248694769 -0100
-+++ mysql/cmake/libutils.cmake 2014-01-17 13:19:22.283734547 -0100
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
@@ -211,10 +211,11 @@
# [linklib1 .... linklibN]
# [EXPORTS exported_func1 .... exportedFuncN]
@@ -86,8 +87,8 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
---- mysql-old/libmysql/CMakeLists.txt 2014-01-17 13:01:56.247694769 -0100
-+++ mysql/libmysql/CMakeLists.txt 2014-01-17 13:17:10.427729533 -0100
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
@@ -329,7 +329,7 @@
# Merge several convenience libraries into one big mysqlclient
@@ -98,8 +99,8 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
# Visual Studio users need debug static library for debug projects
IF(MSVC)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
---- mysql-old/libmysqld/CMakeLists.txt 2014-01-17 13:01:56.048694761 -0100
-+++ mysql/libmysqld/CMakeLists.txt 2014-01-17 13:18:03.210731540 -0100
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
@@ -134,7 +134,7 @@
ENDFOREACH()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-19 2:11 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-01-19 2:11 UTC (permalink / raw
To: gentoo-commits
commit: 409e347ddf0b6741375f940c01fe44ed17143428
Author: Brian Evans <grknight <AT> lavabit <DOT> com>
AuthorDate: Sun Jan 19 02:03:20 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Sun Jan 19 02:03:20 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=409e347d
Fix typo in patch name
---
00000_index.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 4659487..6cdb68a 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1550,12 +1550,12 @@
@pn mysql
@@ Fix poor Makefile.am references in unittest/my_decimal
-@patch 20006_all_cmake_elib-mariad-5.5.32.patch
+@patch 20006_all_cmake_elib-mariadb-5.5.32.patch
@ver 5.05.32.00 to 5.05.32.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
-@patch 20006_all_cmake_elib-mariad-5.5.33.patch
+@patch 20006_all_cmake_elib-mariadb-5.5.33.patch
@ver 5.05.33.00 to 5.05.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-20 1:04 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-20 1:04 UTC (permalink / raw
To: gentoo-commits
commit: 1e0a0674899f9e794a77f0fd23215d730bb0db4e
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 00:59:01 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 00:59:01 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1e0a0674
Rework cmake_elib patch for mysql-5.5.35.
---
20006_all_cmake_elib-mysql-5.5.35.patch | 132 ++++++++++++++++++++++++++++++++
1 file changed, 132 insertions(+)
diff --git a/20006_all_cmake_elib-mysql-5.5.35.patch b/20006_all_cmake_elib-mysql-5.5.35.patch
new file mode 100644
index 0000000..fe92583
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.5.35.patch
@@ -0,0 +1,132 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-19 20:22:12.883270532 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-19 20:30:54.488290367 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-19 20:22:12.883270532 -0100
++++ mysql/cmake/libutils.cmake 2014-01-19 20:33:38.821296616 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ ENDMACRO()
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-19 20:22:12.882270532 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-19 20:29:18.944286734 -0100
+@@ -165,7 +165,7 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-19 20:22:12.757270527 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-19 20:35:39.362301200 -0100
+@@ -127,7 +127,7 @@
+ ENDFOREACH()
+
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,11 +135,13 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
++
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(MSVC AND NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}
+- COMPONENT Embedded)
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-20 1:08 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-20 1:08 UTC (permalink / raw
To: gentoo-commits
commit: b1a44474a980a99f21f66127088a336f3562ab6b
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 01:03:22 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 01:03:22 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=b1a44474
Actually add the patch to mysql-5.5.35.
---
00000_index.txt | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 6cdb68a..d3c4941 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1559,3 +1559,8 @@
@ver 5.05.33.00 to 5.05.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-mysql-5.5.35.patch
+@ver 5.05.35.00 to 5.05.99.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-20 1:35 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-20 1:35 UTC (permalink / raw
To: gentoo-commits
commit: fa30d8a6927b22d55104d8a18fd75d5ce8f98644
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 01:29:45 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 01:29:45 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=fa30d8a6
Update cmake_elib patch for mysql to fit the patch order.
---
20006_all_cmake_elib-mysql-5.5.35.patch | 33 ++++++++++++++++++---------------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/20006_all_cmake_elib-mysql-5.5.35.patch b/20006_all_cmake_elib-mysql-5.5.35.patch
index fe92583..adcff93 100644
--- a/20006_all_cmake_elib-mysql-5.5.35.patch
+++ b/20006_all_cmake_elib-mysql-5.5.35.patch
@@ -1,6 +1,6 @@
diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
---- mysql-old/cmake/install_layout.cmake 2014-01-19 20:22:12.883270532 -0100
-+++ mysql/cmake/install_layout.cmake 2014-01-19 20:30:54.488290367 -0100
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
@@ -43,7 +43,8 @@
# - INSTALL_SBINDIR (directory with mysqld)
# - INSTALL_SCRIPTDIR (several scripts, rarely used)
@@ -57,8 +57,8 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
CACHE STRING "${var} installation directory" ${FORCE})
diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
---- mysql-old/cmake/libutils.cmake 2014-01-19 20:22:12.883270532 -0100
-+++ mysql/cmake/libutils.cmake 2014-01-19 20:33:38.821296616 -0100
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
@@ -40,6 +40,8 @@
# - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
# [EXPORTS exported_func1 .... exported_func_N]
@@ -89,10 +89,11 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+ ENDIF()
ENDIF()
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
- ENDMACRO()
+
+Only in mysql/cmake: libutils.cmake.orig
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
---- mysql-old/libmysql/CMakeLists.txt 2014-01-19 20:22:12.882270532 -0100
-+++ mysql/libmysql/CMakeLists.txt 2014-01-19 20:29:18.944286734 -0100
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
@@ -165,7 +165,7 @@
# Merge several convenience libraries into one big mysqlclient
@@ -103,8 +104,8 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
---- mysql-old/libmysqld/CMakeLists.txt 2014-01-19 20:22:12.757270527 -0100
-+++ mysql/libmysqld/CMakeLists.txt 2014-01-19 20:35:39.362301200 -0100
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
@@ -127,7 +127,7 @@
ENDFOREACH()
@@ -114,19 +115,21 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
# Visual Studio users need debug static library
IF(MSVC)
-@@ -135,11 +135,13 @@
+@@ -135,12 +135,14 @@
ENDIF()
IF(UNIX)
- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
+ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
-+
${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
ENDIF()
- IF(MSVC AND NOT DISABLE_SHARED)
- MERGE_LIBRARIES(libmysqld SHARED ${LIBS} EXPORTS ${CLIENT_API_FUNCTIONS}
-- COMPONENT Embedded)
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
+ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
+
- ENDIF()
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+Only in mysql/libmysqld: CMakeLists.txt.rej
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-20 2:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-01-20 2:05 UTC (permalink / raw
To: gentoo-commits
commit: 1f0915eba7095c4b16d9b2e17a941ba1686b6d63
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Jan 20 02:02:54 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon Jan 20 02:04:41 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1f0915eb
Respin tokudb patch for 10.0.7
---
00000_index.txt | 8 ++++-
20004_all_mariadb-filter-tokudb-flags-10.0.7.patch | 42 ++++++++++++++++++++++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index d3c4941..972c386 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1540,7 +1540,13 @@
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
@patch 20004_all_mariadb-filter-tokudb-flags.patch
-@ver 10.00.05.00 to 10.99.99.99
+@ver 10.00.05.00 to 10.00.06.99
+@pn mariadb
+@pn mariadb-galera
+@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
+
+@patch 20004_all_mariadb-filter-tokudb-flags-10.0.7.patch
+@ver 10.00.07.00 to 10.99.99.99
@pn mariadb
@pn mariadb-galera
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
diff --git a/20004_all_mariadb-filter-tokudb-flags-10.0.7.patch b/20004_all_mariadb-filter-tokudb-flags-10.0.7.patch
new file mode 100644
index 0000000..5e640a7
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags-10.0.7.patch
@@ -0,0 +1,42 @@
+--- mysql.orig/storage/tokudb/CMakeLists.txt 2014-01-16 16:23:26.731243149 -0500
++++ mysql/storage/tokudb/CMakeLists.txt 2014-01-16 16:26:29.197327097 -0500
+@@ -58,8 +58,6 @@
+ SET(TOKUDB_SOURCES ha_tokudb.cc)
+ MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
+ LINK_LIBRARIES tokufractaltree_static tokuportability_static ${ZLIB_LIBRARY} stdc++)
+-SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
+-SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
+
+ SET(CPACK_RPM_server_PACKAGE_OBSOLETES
+ "${CPACK_RPM_server_PACKAGE_OBSOLETES} MariaDB-tokudb-engine < 10.0.5" PARENT_SCOPE)
+diff -aurN mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -136,12 +136,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+@@ -172,8 +170,8 @@
+ endif ()
+
+ ## always want these
+-set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}")
+-set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}")
++set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
++set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
+
+ ## need to set -stdlib=libc++ to get real c++11 support on darwin
+ if (APPLE)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-20 14:03 Jorge Manuel B. S. Vicetto
0 siblings, 0 replies; 300+ messages in thread
From: Jorge Manuel B. S. Vicetto @ 2014-01-20 14:03 UTC (permalink / raw
To: gentoo-commits
commit: ab2b0e6c6aa303a121c06396ca9c03ad226dd830
Author: Jorge Manuel B. S. Vicetto (jmbsvicetto) <jmbsvicetto <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 13:53:59 2014 +0000
Commit: Jorge Manuel B. S. Vicetto <jmbsvicetto <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 13:58:10 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ab2b0e6c
Clean-up cmake_elib patch files.
---
20006_all_cmake_elib-mariadb-5.5.33.patch | 1 -
20006_all_cmake_elib-mysql-5.5.35.patch | 2 --
2 files changed, 3 deletions(-)
diff --git a/20006_all_cmake_elib-mariadb-5.5.33.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
index 50abfe9..fbb51a7 100644
--- a/20006_all_cmake_elib-mariadb-5.5.33.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -56,7 +56,6 @@ diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
CACHE STRING "${var} installation directory" ${FORCE})
-Only in mysql/cmake: install_layout.cmake.orig
diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
+++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
diff --git a/20006_all_cmake_elib-mysql-5.5.35.patch b/20006_all_cmake_elib-mysql-5.5.35.patch
index adcff93..0f332e8 100644
--- a/20006_all_cmake_elib-mysql-5.5.35.patch
+++ b/20006_all_cmake_elib-mysql-5.5.35.patch
@@ -90,7 +90,6 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
ENDIF()
SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
-Only in mysql/cmake: libutils.cmake.orig
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
@@ -132,4 +131,3 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client library
# hence the same version)
-Only in mysql/libmysqld: CMakeLists.txt.rej
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-23 0:14 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-01-23 0:14 UTC (permalink / raw
To: gentoo-commits
commit: 916d01948c83d066d91ce18fa8f7d945761750ed
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Jan 23 00:13:51 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Jan 23 00:13:51 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=916d0194
Respin elib patch for percona, mysql 5.6 and mariadb 10.0
---
00000_index.txt | 20 +++++
20006_all_cmake_elib-mariadb-10.0.7.patch | 1 +
20006_all_cmake_elib-mysql-5.6.15.patch | 132 +++++++++++++++++++++++++++++
20006_all_cmake_elib-percona-5.5.35.patch | 133 ++++++++++++++++++++++++++++++
20006_all_cmake_elib-percona-5.6.15.patch | 132 +++++++++++++++++++++++++++++
5 files changed, 418 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 972c386..096c746 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1570,3 +1570,23 @@
@ver 5.05.35.00 to 5.05.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-mysql-5.6.15.patch
+@ver 5.06.15.00 to 5.05.99.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-percona-5.5.35.patch
+@ver 5.05.35.00 to 5.05.99.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-percona-5.6.15.patch
+@ver 5.06.15.00 to 5.06.99.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20006_all_cmake_elib-mariadb-10.0.7.patch
+@ver 10.00.07.00 to 10.00.99.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
diff --git a/20006_all_cmake_elib-mariadb-10.0.7.patch b/20006_all_cmake_elib-mariadb-10.0.7.patch
new file mode 120000
index 0000000..fe5632d
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.7.patch
@@ -0,0 +1 @@
+20006_all_cmake_elib-mariadb-5.5.33.patch
\ No newline at end of file
diff --git a/20006_all_cmake_elib-mysql-5.6.15.patch b/20006_all_cmake_elib-mysql-5.6.15.patch
new file mode 100644
index 0000000..5dd5f0c
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.6.15.patch
@@ -0,0 +1,132 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -165,6 +165,6 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -127,7 +127,7 @@
+ ENDFOREACH()
+
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
diff --git a/20006_all_cmake_elib-percona-5.5.35.patch b/20006_all_cmake_elib-percona-5.5.35.patch
new file mode 100644
index 0000000..8662c5e
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.5.35.patch
@@ -0,0 +1,133 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -165,7 +165,7 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -127,7 +127,7 @@
+ ENDFOREACH()
+
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
diff --git a/20006_all_cmake_elib-percona-5.6.15.patch b/20006_all_cmake_elib-percona-5.6.15.patch
new file mode 100644
index 0000000..cb37a3a
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.15.patch
@@ -0,0 +1,132 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -165,6 +165,6 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -127,7 +127,7 @@
+ ENDFOREACH()
+
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-01-23 3:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-01-23 3:40 UTC (permalink / raw
To: gentoo-commits
commit: 52dfc0b901b41071be6faa21c61c4254284e7ccc
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Jan 23 03:40:29 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Jan 23 03:40:29 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=52dfc0b9
MySQL 5.7 only uses dev-libs/libedit now
---
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 096c746..0826118 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1529,7 +1529,7 @@
@@ Fix bad references to zlib and readline upstream bugs 68277 and 63130
@patch 20003_all_fix-5.7-library.patch
-@ver 5.07.00.00 to 5.99.99.99
+@ver 5.07.00.00 to 5.07.02.99
@pn mysql
@@ Fix readline upstream bug 63130
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-02-24 14:57 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-02-24 14:57 UTC (permalink / raw
To: gentoo-commits
commit: 99d968181b12d7783228a21ea7a420038a33baa5
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Feb 24 14:57:11 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon Feb 24 14:57:11 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=99d96818
Respin minimal patch for 5.5.36
---
00000_index.txt | 8 ++--
..._all_fix-minimal-build-cmake-mysql-5.5.36.patch | 50 ++++++++++++++++++++++
2 files changed, 55 insertions(+), 3 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 0826118..dd77021 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1474,12 +1474,14 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
-@ver 5.05.29.00 to 5.05.99.99
+@ver 5.05.29.00 to 5.05.35.99
@pn mysql
+@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
-@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.29.patch
-@ver 5.05.29.00 to 5.05.99.99
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch
+@ver 5.05.36.00 to 5.05.99.99
+@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch b/20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch
new file mode 100644
index 0000000..561b19e
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch
@@ -0,0 +1,50 @@
+--- CMakeLists.orig.txt 2013-01-18 16:58:34.701624830 -0500
++++ CMakeLists.txt 2013-01-18 17:00:51.479636903 -0500
+@@ -294,7 +294,11 @@
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+@@ -307,10 +311,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -319,19 +320,18 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
+ ADD_SUBDIRECTORY(packaging/rpm-uln)
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+ ENDIF()
+
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
++
+ INCLUDE(cmake/abi_check.cmake)
+ INCLUDE(cmake/tags.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-02-26 18:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-02-26 18:37 UTC (permalink / raw
To: gentoo-commits
commit: 52ab5580cc39d07a9d3eecdce9b0e7f405db6459
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed Feb 26 18:37:30 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed Feb 26 18:37:30 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=52ab5580
Remove Werror from mysql and percona-server cmake
---
00000_index.txt | 12 ++++++++++++
20007_all_cmake-debug-werror-5.6.patch | 18 ++++++++++++++++++
20007_all_cmake-debug-werror.patch | 15 +++++++++++++++
3 files changed, 45 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index dd77021..719a590 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1592,3 +1592,15 @@
@ver 10.00.07.00 to 10.00.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+
+@patch 20007_all_cmake-debug-werror.patch
+@ver 5.05.32.00 to 5.05.99.99
+@pn mysql
+@pn percona-server
+@@ Remove -Werror from USE="debug" builds
+
+@patch 20007_all_cmake-debug-werror-5.6.patch
+@ver 5.06.00.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ Remove -Werror from USE="debug" builds
diff --git a/20007_all_cmake-debug-werror-5.6.patch b/20007_all_cmake-debug-werror-5.6.patch
new file mode 100644
index 0000000..be119f6
--- /dev/null
+++ b/20007_all_cmake-debug-werror-5.6.patch
@@ -0,0 +1,18 @@
+Gentoo-Bug: 494332
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=494332
+
+--- a/CMakeLists.txt 2014-02-26 13:32:49.779760325 -0500
++++ a/CMakeLists.txt 2014-02-26 13:33:27.208957243 -0500
+@@ -166,11 +166,7 @@
+ # Whether the maintainer mode compiler options should be enabled.
+ IF(MYSQL_MAINTAINER_MODE)
+ IF(CMAKE_C_COMPILER_ID MATCHES "GNU")
+- IF(WITH_INNODB_MEMCACHED)
+ SET_MYSQL_MAINTAINER_GNU_C_OPTIONS_NO_WERROR()
+- ELSE()
+- SET_MYSQL_MAINTAINER_GNU_C_OPTIONS()
+- ENDIF()
+ ENDIF()
+ IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
+ SET_MYSQL_MAINTAINER_GNU_CXX_OPTIONS()
+
diff --git a/20007_all_cmake-debug-werror.patch b/20007_all_cmake-debug-werror.patch
new file mode 100644
index 0000000..9f44808
--- /dev/null
+++ b/20007_all_cmake-debug-werror.patch
@@ -0,0 +1,15 @@
+Gentoo-Bug: 494332
+Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=494332
+
+--- a/cmake/maintainer.cmake
++++ b/cmake/maintainer.cmake
+@@ -18,7 +18,7 @@
+ # Setup GCC (GNU C compiler) warning options.
+ MACRO(SET_MYSQL_MAINTAINER_GNU_C_OPTIONS)
+ SET(MY_MAINTAINER_WARNINGS
+- "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror")
++ "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing")
+ CHECK_C_COMPILER_FLAG("-Wdeclaration-after-statement"
+ HAVE_DECLARATION_AFTER_STATEMENT)
+ IF(HAVE_DECLARATION_AFTER_STATEMENT)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-04 15:33 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-04 15:33 UTC (permalink / raw
To: gentoo-commits
commit: 2c174fd98adb34416ccfdfa5e91c754dee20c7bc
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Mar 4 14:30:05 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue Mar 4 15:33:01 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=2c174fd9
Add static libs install based on condition
---
00000_index.txt | 9 ++++++-
20006_all_cmake_elib-mariadb-5.5.33.patch | 32 ++++++++++++++++++++++--
20006_all_cmake_elib-mysql-5.5.35.patch | 35 +++++++++++++++++++++++---
20006_all_cmake_elib-mysql-5.6.15.patch | 41 ++++++++++++++++++++++++++++---
20006_all_cmake_elib-percona-5.5.35.patch | 37 +++++++++++++++++++++++++---
20006_all_cmake_elib-percona-5.6.15.patch | 41 ++++++++++++++++++++++++++++---
6 files changed, 177 insertions(+), 18 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 719a590..359a77c 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1562,36 +1562,43 @@
@ver 5.05.32.00 to 5.05.32.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-5.5.33.patch
@ver 5.05.33.00 to 5.05.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.5.35.patch
@ver 5.05.35.00 to 5.05.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.6.15.patch
-@ver 5.06.15.00 to 5.05.99.99
+@ver 5.06.15.00 to 5.06.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.5.35.patch
@ver 5.05.35.00 to 5.05.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.6.15.patch
@ver 5.06.15.00 to 5.06.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.7.patch
@ver 10.00.07.00 to 10.00.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20007_all_cmake-debug-werror.patch
@ver 5.05.32.00 to 5.05.99.99
diff --git a/20006_all_cmake_elib-mariadb-5.5.33.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
index fbb51a7..516abbd 100644
--- a/20006_all_cmake_elib-mariadb-5.5.33.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -88,15 +88,33 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
-@@ -329,7 +329,7 @@
+@@ -327,9 +327,14 @@
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
# Merge several convenience libraries into one big mysqlclient
# and link them together into shared library.
-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library for debug projects
IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
@@ -127,3 +145,13 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ logger_service.c)
+
+ ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
diff --git a/20006_all_cmake_elib-mysql-5.5.35.patch b/20006_all_cmake_elib-mysql-5.5.35.patch
index 0f332e8..9d478cc 100644
--- a/20006_all_cmake_elib-mysql-5.5.35.patch
+++ b/20006_all_cmake_elib-mysql-5.5.35.patch
@@ -93,15 +93,33 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
-@@ -165,7 +165,7 @@
-
+@@ -163,9 +163,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
# Merge several convenience libraries into one big mysqlclient
# and link them together into shared library.
-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
@@ -131,3 +149,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client library
# hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
diff --git a/20006_all_cmake_elib-mysql-5.6.15.patch b/20006_all_cmake_elib-mysql-5.6.15.patch
index 5dd5f0c..735cfa8 100644
--- a/20006_all_cmake_elib-mysql-5.6.15.patch
+++ b/20006_all_cmake_elib-mysql-5.6.15.patch
@@ -93,14 +93,36 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
-@@ -165,6 +165,6 @@
-
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
# Merge several convenience libraries into one big mysqlclient
-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
-
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
@@ -130,3 +152,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client library
# hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
diff --git a/20006_all_cmake_elib-percona-5.5.35.patch b/20006_all_cmake_elib-percona-5.5.35.patch
index 8662c5e..65f53a5 100644
--- a/20006_all_cmake_elib-percona-5.5.35.patch
+++ b/20006_all_cmake_elib-percona-5.5.35.patch
@@ -93,15 +93,33 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
-@@ -165,7 +165,7 @@
-
+@@ -163,9 +163,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
# Merge several convenience libraries into one big mysqlclient
# and link them together into shared library.
-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
-
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
@@ -131,3 +149,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client library
# hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
diff --git a/20006_all_cmake_elib-percona-5.6.15.patch b/20006_all_cmake_elib-percona-5.6.15.patch
index cb37a3a..69987af 100644
--- a/20006_all_cmake_elib-percona-5.6.15.patch
+++ b/20006_all_cmake_elib-percona-5.6.15.patch
@@ -93,14 +93,36 @@ diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
+++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
-@@ -165,6 +165,6 @@
-
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
# Merge several convenience libraries into one big mysqlclient
-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR})
-
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
@@ -130,3 +152,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client library
# hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-10 20:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-10 20:02 UTC (permalink / raw
To: gentoo-commits
commit: d6639476c960c995eef16ad260a362d555e49e0e
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Mar 10 20:02:15 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon Mar 10 20:02:15 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d6639476
Add static-libs install to patches for embedded as well
---
20006_all_cmake_elib-mariadb-5.5.33.patch | 28 ++++++++++++----------------
20006_all_cmake_elib-mysql-5.5.35.patch | 10 ++++++++--
20006_all_cmake_elib-mysql-5.6.15.patch | 10 ++++++++--
20006_all_cmake_elib-percona-5.5.35.patch | 10 ++++++++--
20006_all_cmake_elib-percona-5.6.15.patch | 10 ++++++++--
5 files changed, 44 insertions(+), 24 deletions(-)
diff --git a/20006_all_cmake_elib-mariadb-5.5.33.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
index 516abbd..33e902b 100644
--- a/20006_all_cmake_elib-mariadb-5.5.33.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -118,16 +118,22 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
-@@ -134,7 +134,7 @@
+@@ -133,8 +133,13 @@
+ ENDIF()
ENDFOREACH()
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
-+ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
- # Visual Studio users need debug static library
- IF(MSVC)
-@@ -142,7 +142,7 @@
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
ENDIF()
IF(UNIX)
@@ -136,7 +142,7 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
ENDIF()
-@@ -161,7 +161,7 @@
+@@ -163,7 +168,7 @@
IF(NOT DISABLE_SHARED)
MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
@@ -145,13 +151,3 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
---- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
-+++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
-@@ -26,4 +26,6 @@
- logger_service.c)
-
- ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
--INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
-+IF(ENABLE_STATIC_LIBS)
-+ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
-+ENDIF()
diff --git a/20006_all_cmake_elib-mysql-5.5.35.patch b/20006_all_cmake_elib-mysql-5.5.35.patch
index 9d478cc..2946025 100644
--- a/20006_all_cmake_elib-mysql-5.5.35.patch
+++ b/20006_all_cmake_elib-mysql-5.5.35.patch
@@ -123,12 +123,18 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
-@@ -127,7 +127,7 @@
+@@ -126,8 +126,13 @@
+ ENDIF()
ENDFOREACH()
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
-+ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library
IF(MSVC)
diff --git a/20006_all_cmake_elib-mysql-5.6.15.patch b/20006_all_cmake_elib-mysql-5.6.15.patch
index 735cfa8..66b7280 100644
--- a/20006_all_cmake_elib-mysql-5.6.15.patch
+++ b/20006_all_cmake_elib-mysql-5.6.15.patch
@@ -126,12 +126,18 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
-@@ -127,7 +127,7 @@
+@@ -126,8 +126,13 @@
+ ENDIF()
ENDFOREACH()
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
-+ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library
IF(MSVC)
diff --git a/20006_all_cmake_elib-percona-5.5.35.patch b/20006_all_cmake_elib-percona-5.5.35.patch
index 65f53a5..1d41852 100644
--- a/20006_all_cmake_elib-percona-5.5.35.patch
+++ b/20006_all_cmake_elib-percona-5.5.35.patch
@@ -123,12 +123,18 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
-@@ -127,7 +127,7 @@
+@@ -126,8 +126,13 @@
+ ENDIF()
ENDFOREACH()
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
-+ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library
IF(MSVC)
diff --git a/20006_all_cmake_elib-percona-5.6.15.patch b/20006_all_cmake_elib-percona-5.6.15.patch
index 69987af..d805b2c 100644
--- a/20006_all_cmake_elib-percona-5.6.15.patch
+++ b/20006_all_cmake_elib-percona-5.6.15.patch
@@ -126,12 +126,18 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
+++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
-@@ -127,7 +127,7 @@
+@@ -126,8 +126,13 @@
+ ENDIF()
ENDFOREACH()
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
-+ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library
IF(MSVC)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-11 14:55 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-11 14:55 UTC (permalink / raw
To: gentoo-commits
commit: 6f5a24bc5f79392fe9c445811c2f141fb2dd95c0
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Mar 11 14:55:18 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue Mar 11 14:55:18 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=6f5a24bc
Change index for mysql-5.6.16
---
00000_index.txt | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 359a77c..caf38d0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1606,8 +1606,14 @@
@pn percona-server
@@ Remove -Werror from USE="debug" builds
+@patch 20007_all_cmake-debug-werror.patch
+@ver 5.06.16.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ Remove -Werror from USE="debug" builds
+
@patch 20007_all_cmake-debug-werror-5.6.patch
-@ver 5.06.00.00 to 5.06.99.99
+@ver 5.06.00.00 to 5.06.15.99
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-11 14:59 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-11 14:59 UTC (permalink / raw
To: gentoo-commits
commit: 48606dd7de830c27ccc103e5ae3f0ca0e53c69b2
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Mar 11 14:59:44 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue Mar 11 14:59:44 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=48606dd7
Respin patch for mysql-5.6.16
---
00000_index.txt | 8 ++++----
20007_all_cmake-debug-werror-5.6.16.patch | 11 +++++++++++
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index caf38d0..e56fbae 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1606,14 +1606,14 @@
@pn percona-server
@@ Remove -Werror from USE="debug" builds
-@patch 20007_all_cmake-debug-werror.patch
-@ver 5.06.16.00 to 5.06.99.99
+@patch 20007_all_cmake-debug-werror-5.6.patch
+@ver 5.06.00.00 to 5.06.15.99
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
-@patch 20007_all_cmake-debug-werror-5.6.patch
-@ver 5.06.00.00 to 5.06.15.99
+@patch 20007_all_cmake-debug-werror-5.6.16.patch
+@ver 5.06.16.00 to 5.06.99.99
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
diff --git a/20007_all_cmake-debug-werror-5.6.16.patch b/20007_all_cmake-debug-werror-5.6.16.patch
new file mode 100644
index 0000000..3c461bd
--- /dev/null
+++ b/20007_all_cmake-debug-werror-5.6.16.patch
@@ -0,0 +1,11 @@
+--- maintainer.cmake.orig 2014-03-11 10:57:45.184755333 -0400
++++ maintainer.cmake 2014-03-11 10:58:03.584364026 -0400
+@@ -18,7 +18,7 @@
+ # Setup GCC (GNU C compiler) warning options.
+ MACRO(SET_MYSQL_MAINTAINER_GNU_C_OPTIONS)
+ SET(MY_MAINTAINER_WARNINGS
+- "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing -Werror")
++ "-Wall -Wextra -Wunused -Wwrite-strings -Wno-strict-aliasing")
+
+ CHECK_C_COMPILER_FLAG("-Wdeclaration-after-statement"
+ HAVE_DECLARATION_AFTER_STATEMENT)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-11 15:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-11 15:02 UTC (permalink / raw
To: gentoo-commits
commit: 5f3459dfa1406108ca1a500739c7afbc899f4df4
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Mar 11 15:02:45 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue Mar 11 15:02:45 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=5f3459df
Fix cmake-debug-werror-5.6.16 patch paths
---
20007_all_cmake-debug-werror-5.6.16.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/20007_all_cmake-debug-werror-5.6.16.patch b/20007_all_cmake-debug-werror-5.6.16.patch
index 3c461bd..32cadbc 100644
--- a/20007_all_cmake-debug-werror-5.6.16.patch
+++ b/20007_all_cmake-debug-werror-5.6.16.patch
@@ -1,5 +1,5 @@
---- maintainer.cmake.orig 2014-03-11 10:57:45.184755333 -0400
-+++ maintainer.cmake 2014-03-11 10:58:03.584364026 -0400
+--- a/cmake/maintainer.cmake 2014-03-11 10:57:45.184755333 -0400
++++ b/cmake/maintainer.cmake 2014-03-11 10:58:03.584364026 -0400
@@ -18,7 +18,7 @@
# Setup GCC (GNU C compiler) warning options.
MACRO(SET_MYSQL_MAINTAINER_GNU_C_OPTIONS)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-27 17:45 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-27 17:45 UTC (permalink / raw
To: gentoo-commits
commit: 54d6cda99c49d9ccde3e566d0e0f5513c4d1a25b
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Mar 27 17:42:48 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Mar 27 17:42:48 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=54d6cda9
Respin patch for mysql-5.5.37
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
00000_index.txt | 8 +-
20006_all_cmake_elib-mysql-5.5.37.patch | 172 ++++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index e56fbae..e1c4075 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1571,7 +1571,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.5.35.patch
-@ver 5.05.35.00 to 5.05.99.99
+@ver 5.05.35.00 to 5.05.36.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mysql-5.5.37.patch
+@ver 5.05.37.00 to 5.05.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mysql-5.5.37.patch b/20006_all_cmake_elib-mysql-5.5.37.patch
new file mode 100644
index 0000000..a56805c
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.5.37.patch
@@ -0,0 +1,172 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -163,9 +163,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -196,9 +196,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-31 17:48 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-31 17:48 UTC (permalink / raw
To: gentoo-commits
commit: 0e9135d87a5b68b668414b4ff2af4df479f62a17
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Mar 31 17:48:41 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon Mar 31 17:48:41 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=0e9135d8
Respin elib patches for new percona versions
---
00000_index.txt | 16 ++-
20006_all_cmake_elib-percona-5.5.36.patch | 168 +++++++++++++++++++++++++++++
20006_all_cmake_elib-percona-5.6.16.patch | 173 ++++++++++++++++++++++++++++++
3 files changed, 355 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index e1c4075..94ed5c3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1589,13 +1589,25 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.5.35.patch
-@ver 5.05.35.00 to 5.05.99.99
+@ver 5.05.35.00 to 5.05.35.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.5.36.patch
+@ver 5.05.36.00 to 5.05.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.6.15.patch
-@ver 5.06.15.00 to 5.06.99.99
+@ver 5.06.15.00 to 5.06.15.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.6.16.patch
+@ver 5.06.16.00 to 5.06.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-percona-5.5.36.patch b/20006_all_cmake_elib-percona-5.5.36.patch
new file mode 100644
index 0000000..1536fc2
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.5.36.patch
@@ -0,0 +1,168 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -163,9 +163,14 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -186,7 +191,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a perconaserverclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a perconaserverclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
diff --git a/20006_all_cmake_elib-percona-5.6.16.patch b/20006_all_cmake_elib-percona-5.6.16.patch
new file mode 100644
index 0000000..608daad
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.16.patch
@@ -0,0 +1,173 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} $INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -210,10 +215,12 @@
+ ENDIF()
+
+ IF(UNIX)
+- GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ GET_TARGET_NAME(perconaserverclient lib_name)\
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-03-31 18:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-03-31 18:05 UTC (permalink / raw
To: gentoo-commits
commit: c6fec9cf21f30d91c9b00711f501bada8f37b9f7
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Mar 31 18:05:23 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon Mar 31 18:05:23 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c6fec9cf
Fix bad percona patch for 5.6.16
---
20006_all_cmake_elib-percona-5.6.16.patch | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/20006_all_cmake_elib-percona-5.6.16.patch b/20006_all_cmake_elib-percona-5.6.16.patch
index 608daad..b1a2a0b 100644
--- a/20006_all_cmake_elib-percona-5.6.16.patch
+++ b/20006_all_cmake_elib-percona-5.6.16.patch
@@ -104,19 +104,18 @@ diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+
# Merge several convenience libraries into one big perconaserverclient
-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
-+MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} $INSTALL_STATIC_LIBS})
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
# Visual Studio users need debug static library for debug projects
INSTALL_DEBUG_SYMBOLS(clientlib)
-@@ -210,10 +215,12 @@
+@@ -210,9 +215,11 @@
ENDIF()
IF(UNIX)
-- GET_TARGET_NAME(perconaserverclient lib_name)
+ GET_TARGET_NAME(perconaserverclient lib_name)
- INSTALL_SYMLINK(perconaserverclient
- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
- ${INSTALL_LIBDIR} Development)
-+ GET_TARGET_NAME(perconaserverclient lib_name)\
+ IF(ENABLE_STATIC_LIBS)
+ INSTALL_SYMLINK(perconaserverclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-10 15:29 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-10 15:29 UTC (permalink / raw
To: gentoo-commits
commit: ca6691d526b69992959fdcc342acc684a5003ae2
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Apr 10 15:27:58 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Apr 10 15:27:58 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ca6691d5
Backport tzinfo fix from MariaDB. Bug 491176
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
00000_index.txt | 6 ++
20008_all_mysql-tzinfo-symlink.patch | 103 +++++++++++++++++++++++++++++++++++
2 files changed, 109 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 94ed5c3..17cac9f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1635,3 +1635,9 @@
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
+
+@patch 20008_all_mysql-tzinfo-symlink.patch
+@ver 5.05.36.00 to 5.99.99.99
+@pn mysql
+@pn percona-server
+@@ Backport tzinfo symlink fix from MariaDB bug 491176
diff --git a/20008_all_mysql-tzinfo-symlink.patch b/20008_all_mysql-tzinfo-symlink.patch
new file mode 100644
index 0000000..5b7a524
--- /dev/null
+++ b/20008_all_mysql-tzinfo-symlink.patch
@@ -0,0 +1,103 @@
+=== modified file 'sql/tztime.cc'
+--- sql/tztime.cc 2013-05-07 11:05:09 +0000
++++ sql/tztime.cc 2013-11-13 15:16:35 +0000
+@@ -2494,7 +2494,7 @@
+
+ */
+ my_bool
+-scan_tz_dir(char * name_end)
++scan_tz_dir(char * name_end, uint symlink_recursion_level)
+ {
+ MY_DIR *cur_dir;
+ char *name_end_tmp;
+@@ -2514,7 +2514,32 @@
+
+ if (MY_S_ISDIR(cur_dir->dir_entry[i].mystat->st_mode))
+ {
+- if (scan_tz_dir(name_end_tmp))
++ my_bool is_symlink;
++ if ((is_symlink= my_is_symlink(fullname)) &&
++ symlink_recursion_level > 0)
++ {
++ /*
++ The timezone definition data in some Linux distributions
++ (e.g. the "timezone-data-2013f" package in Gentoo)
++ may have synlimks like:
++ /usr/share/zoneinfo/posix/ -> /usr/share/zoneinfo/,
++ so the same timezone files are available under two names
++ (e.g. "CET" and "posix/CET").
++
++ We allow one level of symlink recursion for backward
++ compatibility with earlier timezone data packages that have
++ duplicate copies of the same timezone files inside the root
++ directory and the "posix" subdirectory (instead of symlinking).
++ This makes "posix/CET" still available, but helps to avoid
++ following such symlinks infinitely:
++ /usr/share/zoneinfo/posix/posix/posix/.../posix/
++ */
++ fflush(stdout);
++ fprintf(stderr, "Warning: Skipping directory '%s': "
++ "to avoid infinite symlink recursion.\n", fullname);
++ continue;
++ }
++ if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink))
+ {
+ my_dirend(cur_dir);
+ return 1;
+@@ -2526,14 +2551,20 @@
+ if (!tz_load(fullname, &tz_info, &tz_storage))
+ print_tz_as_sql(root_name_end + 1, &tz_info);
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr,
+ "Warning: Unable to load '%s' as time zone. Skipping it.\n",
+ fullname);
++ }
+ free_root(&tz_storage, MYF(0));
+ }
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr, "Warning: '%s' is not regular file or directory\n",
+ fullname);
++ }
+ }
+ }
+
+@@ -2566,8 +2597,9 @@
+ printf("TRUNCATE TABLE time_zone_transition;\n");
+ printf("TRUNCATE TABLE time_zone_transition_type;\n");
+
+- if (scan_tz_dir(root_name_end))
++ if (scan_tz_dir(root_name_end, 0))
+ {
++ fflush(stdout);
+ fprintf(stderr, "There were fatal errors during processing "
+ "of zoneinfo directory\n");
+ return 1;
+@@ -2586,6 +2618,7 @@
+ {
+ if (tz_load(argv[2], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2595,6 +2628,7 @@
+ {
+ if (tz_load(argv[1], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2604,6 +2638,7 @@
+ free_root(&tz_storage, MYF(0));
+ }
+
++ my_end(0);
+ return 0;
+ }
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-17 19:45 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-17 19:45 UTC (permalink / raw
To: gentoo-commits
commit: 2866c44052f745e4cdd7d7b10ee4f2360aeaa658
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Thu Apr 17 18:58:39 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Thu Apr 17 18:58:39 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=2866c440
Renable mysql_config patch for testing
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
00000_index.txt | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 17cac9f..dc34ce8 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -240,16 +240,16 @@
@pn mariadb
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-#@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-#@ver 5.05.00.00 to 10.00.99.99
-#@pn mariadb
-#@pn mariadb-galera
-#@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-
-#@patch 01050_all_mysql_config_cleanup-5.5.patch
-#@ver 5.05.00.00 to 5.05.99.99
-#@pn mysql
-#@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
+@ver 5.05.00.00 to 10.00.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
+@patch 01050_all_mysql_config_cleanup-5.5.patch
+@ver 5.05.00.00 to 5.05.99.99
+@pn mysql
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-18 15:28 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-18 15:28 UTC (permalink / raw
To: gentoo-commits
commit: 6f0435c30079826df1d7fcbf3e6419ef2a3043b9
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Fri Apr 18 15:28:00 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Fri Apr 18 15:28:00 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=6f0435c3
Fix myodbc compilation due to missing symbol
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
00000_index.txt | 7 +++++++
20009_all_mariadb_myodbc_symbol_fix.patch | 10 ++++++++++
2 files changed, 17 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index dc34ce8..883b33d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1641,3 +1641,10 @@
@pn mysql
@pn percona-server
@@ Backport tzinfo symlink fix from MariaDB bug 491176
+
+@patch 20009_all_mariadb_myodbc_symbol_fix.patch
+@ver 5.05.37.00 to 10.99.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Export missing symbol my_charset_latin1
+@@ MariaDB bug MDEV-6131
diff --git a/20009_all_mariadb_myodbc_symbol_fix.patch b/20009_all_mariadb_myodbc_symbol_fix.patch
new file mode 100644
index 0000000..1ae1c8e
--- /dev/null
+++ b/20009_all_mariadb_myodbc_symbol_fix.patch
@@ -0,0 +1,10 @@
+--- a/libmysql/CMakeLists.txt 2014-04-18 11:23:20.792196748 -0400
++++ b/libmysql/CMakeLists.txt 2014-04-18 11:01:32.743379333 -0400
+@@ -261,6 +261,7 @@
+ mysql_get_charset
+ mysql_get_charset_by_csname
+ mysql_net_realloc
++ my_charset_latin1
+
+ # PHP's mysqli.so requires this (via the ER() macro)
+ mysql_client_errors
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-23 16:22 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-23 16:22 UTC (permalink / raw
To: gentoo-commits
commit: 3cc8988d513b07c32a26334c00c29d6dd141da3b
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed Apr 23 16:20:11 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed Apr 23 16:20:11 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=3cc8988d
Respin minimal patch for mysql 5.6
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
00000_index.txt | 6 ++++
20001_all_fix-minimal-build-cmake-mysql-5.6.patch | 41 +++++++++++++++++++++++
2 files changed, 47 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 883b33d..45589ac 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1485,6 +1485,12 @@
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.patch
+@ver 5.06.17.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
@ver 5.05.00.00 to 5.05.26.99
@pn mariadb
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.6.patch b/20001_all_fix-minimal-build-cmake-mysql-5.6.patch
new file mode 100644
index 0000000..55cdbdd
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.6.patch
@@ -0,0 +1,41 @@
+--- a/CMakeLists.txt 2014-04-23 12:12:15.373173849 -0400
++++ b/CMakeLists.txt 2014-04-23 12:14:45.448393844 -0400
+@@ -454,6 +454,14 @@
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(support-files)
++ADD_SUBDIRECTORY(scripts)
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
+
+ IF(WITH_UNIT_TESTS)
+ ADD_SUBDIRECTORY(unittest)
+@@ -470,10 +478,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -482,12 +487,7 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-26 0:57 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-26 0:57 UTC (permalink / raw
To: gentoo-commits
commit: d2a5ec77e428e6a0413c7fcbe6e6bc7e2e6f6667
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat Apr 26 00:57:35 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Sat Apr 26 00:57:35 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d2a5ec77
Fix embedded library location in ELIB patches for 5.5
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
20006_all_cmake_elib-mariadb-5.5.33.patch | 49 +++++++++++++++++++++++++++++++
20006_all_cmake_elib-mysql-5.5.37.patch | 49 +++++++++++++++++++++++++++++++
2 files changed, 98 insertions(+)
diff --git a/20006_all_cmake_elib-mariadb-5.5.33.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
index 33e902b..ae6447f 100644
--- a/20006_all_cmake_elib-mariadb-5.5.33.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -151,3 +151,52 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- a/mysql/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ b/mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- a/mysql/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ b/mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- a/mysql/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ b/mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
diff --git a/20006_all_cmake_elib-mysql-5.5.37.patch b/20006_all_cmake_elib-mysql-5.5.37.patch
index a56805c..d712067 100644
--- a/20006_all_cmake_elib-mysql-5.5.37.patch
+++ b/20006_all_cmake_elib-mysql-5.5.37.patch
@@ -170,3 +170,52 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
+ENDIF()
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- a/mysql/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ b/mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- a/mysql/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ b/mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- a/mysql/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ b/mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-26 1:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-26 1:26 UTC (permalink / raw
To: gentoo-commits
commit: c70f878ff23d999347f96d312ead0c8c56851684
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat Apr 26 01:25:54 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Sat Apr 26 01:25:54 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c70f878f
Fix embedded library location in ELIB patches for 5.5
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
20006_all_cmake_elib-mariadb-5.5.33.patch | 12 ++++++------
20006_all_cmake_elib-mysql-5.5.37.patch | 12 ++++++------
2 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/20006_all_cmake_elib-mariadb-5.5.33.patch b/20006_all_cmake_elib-mariadb-5.5.33.patch
index ae6447f..5658444 100644
--- a/20006_all_cmake_elib-mariadb-5.5.33.patch
+++ b/20006_all_cmake_elib-mariadb-5.5.33.patch
@@ -152,8 +152,8 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
---- a/mysql/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
-+++ b/mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
@@ -198,6 +198,7 @@
SET(scriptdir ${prefix}/${INSTALL_BINDIR})
SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
@@ -163,8 +163,8 @@ diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
SET(localstatedir ${prefix}/data)
ELSE()
diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
---- a/mysql/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
-+++ b/mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+--- mysql-old/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
@@ -190,9 +190,10 @@
else
{
@@ -178,8 +178,8 @@ diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
my $flags;
diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
---- a/mysql/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
-+++ b/mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
@@ -91,6 +91,10 @@
plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
diff --git a/20006_all_cmake_elib-mysql-5.5.37.patch b/20006_all_cmake_elib-mysql-5.5.37.patch
index d712067..1f328c2 100644
--- a/20006_all_cmake_elib-mysql-5.5.37.patch
+++ b/20006_all_cmake_elib-mysql-5.5.37.patch
@@ -171,8 +171,8 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+ENDIF()
diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
---- a/mysql/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
-+++ b/mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
@@ -198,6 +198,7 @@
SET(scriptdir ${prefix}/${INSTALL_BINDIR})
SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
@@ -182,8 +182,8 @@ diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
SET(localstatedir ${prefix}/data)
ELSE()
diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
---- a/mysql/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
-+++ b/mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+--- mysql-old/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
@@ -190,9 +190,10 @@
else
{
@@ -197,8 +197,8 @@ diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
my $flags;
diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
---- a/mysql/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
-+++ b/mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
@@ -91,6 +91,10 @@
plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-04-26 3:53 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-04-26 3:53 UTC (permalink / raw
To: gentoo-commits
commit: 67e9c375faa7e02492a170f856cb140f32d27e1f
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat Apr 26 03:53:23 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Sat Apr 26 03:53:23 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=67e9c375
Fix embedded library location in ELIB patches for overlay only ebuilds
Signed-off-by: Brian Evans <grknight <AT> tuffmail.com>
---
20006_all_cmake_elib-mariadb-10.0.7.patch | 188 +++++++++++++++++++++++++++++-
20006_all_cmake_elib-mysql-5.6.15.patch | 34 ++++++
20006_all_cmake_elib-percona-5.5.36.patch | 34 ++++++
20006_all_cmake_elib-percona-5.6.16.patch | 34 ++++++
4 files changed, 289 insertions(+), 1 deletion(-)
diff --git a/20006_all_cmake_elib-mariadb-10.0.7.patch b/20006_all_cmake_elib-mariadb-10.0.7.patch
deleted file mode 120000
index fe5632d..0000000
--- a/20006_all_cmake_elib-mariadb-10.0.7.patch
+++ /dev/null
@@ -1 +0,0 @@
-20006_all_cmake_elib-mariadb-5.5.33.patch
\ No newline at end of file
diff --git a/20006_all_cmake_elib-mariadb-10.0.7.patch b/20006_all_cmake_elib-mariadb-10.0.7.patch
new file mode 100644
index 0000000..9b02ee5
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.7.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
diff --git a/20006_all_cmake_elib-mysql-5.6.15.patch b/20006_all_cmake_elib-mysql-5.6.15.patch
index 66b7280..6e009ea 100644
--- a/20006_all_cmake_elib-mysql-5.6.15.patch
+++ b/20006_all_cmake_elib-mysql-5.6.15.patch
@@ -169,3 +169,37 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
+ENDIF()
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -206,6 +206,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
diff --git a/20006_all_cmake_elib-percona-5.5.36.patch b/20006_all_cmake_elib-percona-5.5.36.patch
index 1536fc2..2160b0e 100644
--- a/20006_all_cmake_elib-percona-5.5.36.patch
+++ b/20006_all_cmake_elib-percona-5.5.36.patch
@@ -166,3 +166,37 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
+ENDIF()
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -192,6 +192,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
diff --git a/20006_all_cmake_elib-percona-5.6.16.patch b/20006_all_cmake_elib-percona-5.6.16.patch
index b1a2a0b..6bdc2b2 100644
--- a/20006_all_cmake_elib-percona-5.6.16.patch
+++ b/20006_all_cmake_elib-percona-5.6.16.patch
@@ -170,3 +170,37 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
+ENDIF()
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -192,6 +192,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-06 19:29 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-06 19:29 UTC (permalink / raw
To: gentoo-commits
commit: 19f09808ad93aa2941ed4aab515b66b8b4563e21
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue May 6 19:29:46 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue May 6 19:29:46 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=19f09808
Respon elib patch for percona 5.5.37
---
00000_index.txt | 8 +-
20006_all_cmake_elib-percona-5.5.37.patch | 200 ++++++++++++++++++++++++++++++
2 files changed, 207 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 45589ac..3111ac7 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1601,7 +1601,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.5.36.patch
-@ver 5.05.36.00 to 5.05.99.99
+@ver 5.05.36.00 to 5.05.36.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.5.37.patch
+@ver 5.05.37.00 to 5.05.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-percona-5.5.37.patch b/20006_all_cmake_elib-percona-5.5.37.patch
new file mode 100644
index 0000000..557f932
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.5.37.patch
@@ -0,0 +1,200 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -163,9 +163,14 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -194,7 +194,7 @@
+ ENDMACRO()
+ ENDIF()
+
+-IF(UNIX)
++IF(UNIX AND ENABLE_STATIC_LIBS)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+ INSTALL_SYMLINK(perconaserverclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -192,6 +192,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-06 19:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-06 19:37 UTC (permalink / raw
To: gentoo-commits
commit: 7d93bfc0691a5cd825edd54876e6d6ad95222dd9
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue May 6 19:37:28 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Tue May 6 19:37:28 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=7d93bfc0
Small fix to last patch
---
20006_all_cmake_elib-percona-5.5.37.patch | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/20006_all_cmake_elib-percona-5.5.37.patch b/20006_all_cmake_elib-percona-5.5.37.patch
index 557f932..5bc5d97 100644
--- a/20006_all_cmake_elib-percona-5.5.37.patch
+++ b/20006_all_cmake_elib-percona-5.5.37.patch
@@ -190,11 +190,11 @@ diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
if [ -f "$basedir/include/mysql/mysql.h" ]; then
pkgincludedir="$basedir/include/mysql"
@@ -113,7 +117,7 @@
- libs=" $ldflags -L$pkglibdir -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs=" $ldflags @RPATH_OPTION@ -L$pkglibdir -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
- libs_r=" $ldflags -L$pkglibdir -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
--embedded_libs=" $ldflags -L$pkglibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
-+embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
if [ -r "$pkglibdir/libmygcc.a" ]; then
# When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-12 18:16 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-12 18:16 UTC (permalink / raw
To: gentoo-commits
commit: 840585ed77b204d9731ec2259ccef4a32c63ca28
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 12 18:15:28 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon May 12 18:15:28 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=840585ed
Respin patch for mariadb 10.0.11
---
00000_index.txt | 8 +-
20006_all_cmake_elib-mariadb-10.0.11.patch | 187 +++++++++++++++++++++++++++++
2 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3111ac7..4a1d471 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1625,7 +1625,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.7.patch
-@ver 10.00.07.00 to 10.00.99.99
+@ver 10.00.07.00 to 10.10.99.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
+@ver 10.00.11.00 to 10.10.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mariadb-10.0.11.patch b/20006_all_cmake_elib-mariadb-10.0.11.patch
new file mode 100644
index 0000000..5281bf5
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.11.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-12 18:19 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-12 18:19 UTC (permalink / raw
To: gentoo-commits
commit: 60766180cefff3b43d4d20d0a82496a2d334cb1a
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 12 18:19:25 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Mon May 12 18:19:25 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=60766180
Fix index
---
00000_index.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 4a1d471..9cb418b 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1625,13 +1625,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.7.patch
-@ver 10.00.07.00 to 10.10.99.99
+@ver 10.00.07.00 to 10.00.10.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
-@ver 10.00.11.00 to 10.10.99.99
+@ver 10.00.11.00 to 10.00.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-14 0:52 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-14 0:52 UTC (permalink / raw
To: gentoo-commits
commit: aa902e1b4ae3e98d6c8d87a6d8af160e4fa6fe2e
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed May 14 00:52:18 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed May 14 00:52:18 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=aa902e1b
fix bison3 on mysql 5.1.xx
---
00000_index.txt | 5 +++++
20010_all_mysql51-bison3.patch | 43 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 9cb418b..b40707d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1666,3 +1666,8 @@
@pn mariadb-galera
@@ Export missing symbol my_charset_latin1
@@ MariaDB bug MDEV-6131
+
+@patch 20010_all_mysql-bison3.patch
+@ver 5.01.73.00 to 5.01.99.99
+@pn mysql
+@@ Fix Bison 3 compatibility
diff --git a/20010_all_mysql51-bison3.patch b/20010_all_mysql51-bison3.patch
new file mode 100644
index 0000000..78d0faf
--- /dev/null
+++ b/20010_all_mysql51-bison3.patch
@@ -0,0 +1,43 @@
+X-Upstream-Patch-URL: https://bazaar.launchpad.net/~percona-core/percona-server/5.1/revision/611
+=== modified file 'Percona-Server/sql/sql_yacc.yy'
+--- Percona-Server/sql/sql_yacc.yy 2013-06-03 03:53:55 +0000
++++ Percona-Server/sql/sql_yacc.yy 2014-04-23 09:26:47 +0000
+@@ -27,8 +27,6 @@
+ ** The type will be void*, so it must be cast to (THD*) when used.
+ ** Use the YYTHD macro for this.
+ */
+-#define YYPARSE_PARAM yythd
+-#define YYLEX_PARAM yythd
+ #define YYTHD ((THD *)yythd)
+ #define YYLIP (& YYTHD->m_parser_state->m_lip)
+
+@@ -64,7 +62,7 @@
+ ulong val= *(F); \
+ if (my_yyoverflow((B), (D), &val)) \
+ { \
+- yyerror((char*) (A)); \
++ yyerror(yythd, (char*) (A)); \
+ return 2; \
+ } \
+ else \
+@@ -159,7 +157,7 @@
+ to abort from the parser.
+ */
+
+-void MYSQLerror(const char *s)
++void MYSQLerror(void *yythd, const char *s)
+ {
+ THD *thd= current_thd;
+
+@@ -675,7 +673,9 @@
+ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
+ %}
+
+-%pure_parser /* We have threads */
++%pure-parser /* We have threads */
++%parse-param { void *yythd }
++%lex-param { void *yythd }
+ /*
+ Currently there are 169 shift/reduce conflicts.
+ We should not introduce new conflicts any more.
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-05-14 0:58 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-05-14 0:58 UTC (permalink / raw
To: gentoo-commits
commit: 5cee59c415f7cb02bed0e1009f162d4cccb6bbee
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed May 14 00:58:08 2014 +0000
Commit: Brian Evans <grknight <AT> lavabit <DOT> com>
CommitDate: Wed May 14 00:58:08 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=5cee59c4
Fix index
---
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index b40707d..48b6ab1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1667,7 +1667,7 @@
@@ Export missing symbol my_charset_latin1
@@ MariaDB bug MDEV-6131
-@patch 20010_all_mysql-bison3.patch
+@patch 20010_all_mysql51-bison3.patch
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
@@ Fix Bison 3 compatibility
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-07-28 22:54 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-07-28 22:54 UTC (permalink / raw
To: gentoo-commits
commit: 316964138f9cdba7450affbead89fa91b4587302
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Jul 28 22:52:04 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Mon Jul 28 22:52:04 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=31696413
Fix runtime symbols of myodbc
---
00000_index.txt | 14 +++++++++++++-
20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch | 15 +++++++++++++++
20009_all_mysql_myodbc_symbol_fix-5.5.38.patch | 12 ++++++++++++
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 48b6ab1..4f167a1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1661,12 +1661,24 @@
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@patch 20009_all_mariadb_myodbc_symbol_fix.patch
-@ver 5.05.37.00 to 10.99.99.99
+@ver 5.05.37.00 to 5.05.37.99
@pn mariadb
@pn mariadb-galera
@@ Export missing symbol my_charset_latin1
@@ MariaDB bug MDEV-6131
+@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
+@ver 5.05.38.00 to 5.07.99.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
+@ver 5.05.38.00 to 10.99.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Export missing symbols at runtime
+
@patch 20010_all_mysql51-bison3.patch
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
diff --git a/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch b/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
new file mode 100644
index 0000000..d43e234
--- /dev/null
+++ b/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
@@ -0,0 +1,15 @@
+diff -aurwN mysql.orig/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql.orig/libmysql/CMakeLists.txt 2014-07-27 22:21:41.711342411 -0400
++++ mysql/libmysql/CMakeLists.txt 2014-07-27 22:26:15.558596434 -0400
+@@ -325,6 +325,11 @@
+ strmake
+ strmake_root
+ strxmov
++ my_thread_end_wait_time
++ insert_dynamic
++ delete_dynamic_element
++ my_qsort
++ allocate_dynamic
+
+ # pam_mysql.so
+ make_scrambled_password
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch b/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
new file mode 100644
index 0000000..80b24ef
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
@@ -0,0 +1,12 @@
+diff -auwrN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2014-07-27 22:03:27.806254846 -0400
++++ b/libmysql/CMakeLists.txt 2014-07-27 22:05:08.400521754 -0400
+@@ -131,6 +131,8 @@
+ mysql_set_character_set
+ mysql_get_character_set_info
+ mysql_stmt_next_result
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-07-28 23:43 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-07-28 23:43 UTC (permalink / raw
To: gentoo-commits
commit: 99fe52498d9660aee37dca6c3d32de895c43a5dd
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Jul 28 23:43:41 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Mon Jul 28 23:43:41 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=99fe5249
Respin last patch for MySQL 5.6
---
00000_index.txt | 8 +++++++-
20009_all_mysql_myodbc_symbol_fix-5.6.patch | 12 ++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 4f167a1..ac7bcb0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1668,7 +1668,13 @@
@@ MariaDB bug MDEV-6131
@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
-@ver 5.05.38.00 to 5.07.99.99
+@ver 5.05.38.00 to 5.05.99.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
+@ver 5.06.00.00 to 5.07.99.99
@pn mysql
@pn percona-server
@@ Export missing symbols
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.6.patch b/20009_all_mysql_myodbc_symbol_fix-5.6.patch
new file mode 100644
index 0000000..f081d64
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.6.patch
@@ -0,0 +1,12 @@
+diff -auwrN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2014-07-27 22:03:27.806254846 -0400
++++ b/libmysql/CMakeLists.txt 2014-07-27 22:05:08.400521754 -0400
+@@ -138,6 +138,8 @@
+ mysql_load_plugin_v
+ mysql_options4
+ mysql_plugin_options
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-07-29 18:41 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-07-29 18:41 UTC (permalink / raw
To: gentoo-commits
commit: 9490a24afb658277ba94d95d49f3f1d16723e1e0
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 29 18:40:18 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Tue Jul 29 18:40:56 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=9490a24a
Respin ELIB patch for percona 5.6.19
---
00000_index.txt | 8 +-
20006_all_cmake_elib-percona-5.6.19.patch | 206 ++++++++++++++++++++++++++++++
2 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index ac7bcb0..e9fb4a5 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1619,7 +1619,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.6.16.patch
-@ver 5.06.16.00 to 5.06.99.99
+@ver 5.06.16.00 to 5.06.18.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.6.19.patch
+@ver 5.06.19.00 to 5.06.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-percona-5.6.19.patch b/20006_all_cmake_elib-percona-5.6.19.patch
new file mode 100644
index 0000000..65c348b
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.19.patch
@@ -0,0 +1,206 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -210,9 +215,11 @@
+ ENDIF()
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -192,6 +192,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-05 18:17 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-05 18:17 UTC (permalink / raw
To: gentoo-commits
commit: 1b691ba4118d040ec73d7ef7984f0f79c73e4532
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 1 19:49:51 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Fri Aug 1 19:49:51 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1b691ba4
Respin minimal patches for new MySQL versions
---
00000_index.txt | 16 ++++++-
..._all_fix-minimal-build-cmake-mysql-5.5.39.patch | 49 ++++++++++++++++++++++
..._all_fix-minimal-build-cmake-mysql-5.6.20.patch | 16 +++++++
3 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index e9fb4a5..7051194 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1480,13 +1480,25 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch
-@ver 5.05.36.00 to 5.05.99.99
+@ver 5.05.36.00 to 5.05.38.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
+@ver 5.05.39.00 to 5.05.99.99
@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.patch
-@ver 5.06.17.00 to 5.06.99.99
+@ver 5.06.17.00 to 5.06.19.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
+@ver 5.06.20.00 to 5.06.99.99
@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch b/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
new file mode 100644
index 0000000..cbd9598
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
@@ -0,0 +1,49 @@
+--- CMakeLists.orig.txt 2013-01-18 16:58:34.701624830 -0500
++++ CMakeLists.txt 2013-01-18 17:00:51.479636903 -0500
+@@ -294,7 +294,11 @@
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+@@ -307,10 +311,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -319,18 +320,17 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+ ENDIF()
+
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
++
+ INCLUDE(cmake/abi_check.cmake)
+ INCLUDE(cmake/tags.cmake)
+
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch b/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
new file mode 100644
index 0000000..8bee332
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
@@ -0,0 +1,16 @@
+diff -aurwN mysql.orig/CMakeLists.txt mysql/CMakeLists.txt
+--- mysql.orig/CMakeLists.txt 2014-07-18 11:48:39.000000000 -0400
++++ mysql/CMakeLists.txt 2014-08-01 12:54:52.612732241 -0400
+@@ -512,11 +512,11 @@
+ # scripts/mysql_config depends on client and server targets loaded above.
+ # It is referenced by some of the directories below, so we insert it here.
+ ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+ ADD_SUBDIRECTORY(sql-bench)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-11 23:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-11 23:05 UTC (permalink / raw
To: gentoo-commits
commit: fa1d8943e262c1f47feed3b30553e92a4cf82ed5
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Aug 11 22:47:07 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Mon Aug 11 22:47:07 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=fa1d8943
Fix minimal builds on MariaDB 10.0.13
---
00000_index.txt | 6 ++++++
20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch | 16 ++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 7051194..c184471 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1508,6 +1508,12 @@
@pn mariadb
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
+@ver 10.00.13.00 to 10.99.99.99
+@pn mariadb
+@@ Fix the minimal build by reordering CMakeLists.txt
+@@ Fixes MDEV-6562
+
@patch 21000_all_sql-5.1.62.patch
@ver 5.01.62.00 to 5.01.64.99
@pn mariadb
diff --git a/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch b/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
new file mode 100644
index 0000000..99a46fd
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
@@ -0,0 +1,16 @@
+=== modified file 'CMakeLists.txt'
+--- a/CMakeLists.txt 2014-08-07 16:06:56 +0000
++++ b/CMakeLists.txt 2014-08-11 21:43:29 +0000
+@@ -466,7 +466,10 @@
+ ADD_SUBDIRECTORY(packaging/solaris)
+
+ IF(NOT CMAKE_CROSSCOMPILING)
+- SET(EXPORTED comp_err comp_sql factorial gen_lex_hash)
++ SET(EXPORTED comp_err comp_sql factorial)
++ IF(NOT WITHOUT_SERVER)
++ SET(EXPORTED ${EXPORTED} gen_lex_hash)
++ ENDIF()
+ # minimal target to build only binaries for export
+ ADD_CUSTOM_TARGET(import_executables DEPENDS ${EXPORTED})
+ EXPORT(TARGETS ${EXPORTED} FILE ${CMAKE_BINARY_DIR}/import_executables.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-17 23:19 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-17 23:19 UTC (permalink / raw
To: gentoo-commits
commit: ddbb7641cebcbf956e6cc58cd81372be3d2f257a
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Aug 17 23:16:01 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Sun Aug 17 23:19:22 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ddbb7641
Fix bad comparision of void to ulong on hppa
---
00000_index.txt | 7 +++++++
20011_all_mariadb-hppa-unsigned-long.patch | 11 +++++++++++
2 files changed, 18 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index c184471..425ec04 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1713,3 +1713,10 @@
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
@@ Fix Bison 3 compatibility
+
+@patch 20011_all_mariadb-hppa-unsigned-long.patch
+@ver 5.05.39.00 to 5.05.99.99
+@ver 10.00.13.00 to 10.00.99.99
+@pn mariadb
+@@ Fix bad comparision of void to ulong
+@@ Gentoo bug 520092 MDEV-6595
diff --git a/20011_all_mariadb-hppa-unsigned-long.patch b/20011_all_mariadb-hppa-unsigned-long.patch
new file mode 100644
index 0000000..5f5b841
--- /dev/null
+++ b/20011_all_mariadb-hppa-unsigned-long.patch
@@ -0,0 +1,11 @@
+--- a/storage/xtradb/os/os0stacktrace.c
++++ b/storage/xtradb/os/os0stacktrace.c
+@@ -85,7 +85,7 @@
+ caller_address = (void*) uc->uc_mcontext.gregs[REG_RIP] ;
+ #elif defined(__hppa__)
+ ucontext_t* uc = (ucontext_t*) ucontext;
+- caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0x3UL ;
++ caller_address = (void*) (uc->uc_mcontext.sc_iaoq[0] & ~0x3UL) ;
+ #elif (defined (__ppc__)) || (defined (__powerpc__))
+ ucontext_t* uc = (ucontext_t*) ucontext;
+ caller_address = (void*) uc->uc_mcontext.regs->nip ;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-17 23:32 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-17 23:32 UTC (permalink / raw
To: gentoo-commits
commit: 22bf230ec6ebf561d6dc9eeb9f9209c9746f7d57
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Aug 17 23:31:39 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Sun Aug 17 23:31:39 2014 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=22bf230e
Fix bad comparision of void to ulong on hppa for 10.0.13
---
00000_index.txt | 5 +++++
20011_all_mariadb-hppa-unsigned-long-10.0.13.patch | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 425ec04..eb30088 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1716,6 +1716,11 @@
@patch 20011_all_mariadb-hppa-unsigned-long.patch
@ver 5.05.39.00 to 5.05.99.99
+@pn mariadb
+@@ Fix bad comparision of void to ulong
+@@ Gentoo bug 520092 MDEV-6595
+
+@patch 20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
@ver 10.00.13.00 to 10.00.99.99
@pn mariadb
@@ Fix bad comparision of void to ulong
diff --git a/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch b/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
new file mode 100644
index 0000000..b076f05
--- /dev/null
+++ b/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
@@ -0,0 +1,11 @@
+--- a/storage/xtradb/os/os0stacktrace.cc
++++ b/storage/xtradb/os/os0stacktrace.cc
+@@ -85,7 +85,7 @@
+ caller_address = (void*) uc->uc_mcontext.gregs[REG_RIP] ;
+ #elif defined(__hppa__)
+ ucontext_t* uc = (ucontext_t*) ucontext;
+- caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0x3UL ;
++ caller_address = (void*) (uc->uc_mcontext.sc_iaoq[0] & ~0x3UL) ;
+ #elif (defined (__ppc__)) || (defined (__powerpc__))
+ ucontext_t* uc = (ucontext_t*) ucontext;
+ caller_address = (void*) uc->uc_mcontext.regs->nip ;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 20:21 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2014-08-18 20:21 UTC (permalink / raw
To: gentoo-commits
commit: 316964138f9cdba7450affbead89fa91b4587302
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Jul 28 22:52:04 2014 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jul 28 22:52:04 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=31696413
Fix runtime symbols of myodbc
---
00000_index.txt | 14 +++++++++++++-
20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch | 15 +++++++++++++++
20009_all_mysql_myodbc_symbol_fix-5.5.38.patch | 12 ++++++++++++
3 files changed, 40 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 48b6ab1..4f167a1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1661,12 +1661,24 @@
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@patch 20009_all_mariadb_myodbc_symbol_fix.patch
-@ver 5.05.37.00 to 10.99.99.99
+@ver 5.05.37.00 to 5.05.37.99
@pn mariadb
@pn mariadb-galera
@@ Export missing symbol my_charset_latin1
@@ MariaDB bug MDEV-6131
+@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
+@ver 5.05.38.00 to 5.07.99.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
+@ver 5.05.38.00 to 10.99.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Export missing symbols at runtime
+
@patch 20010_all_mysql51-bison3.patch
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
diff --git a/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch b/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
new file mode 100644
index 0000000..d43e234
--- /dev/null
+++ b/20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
@@ -0,0 +1,15 @@
+diff -aurwN mysql.orig/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql.orig/libmysql/CMakeLists.txt 2014-07-27 22:21:41.711342411 -0400
++++ mysql/libmysql/CMakeLists.txt 2014-07-27 22:26:15.558596434 -0400
+@@ -325,6 +325,11 @@
+ strmake
+ strmake_root
+ strxmov
++ my_thread_end_wait_time
++ insert_dynamic
++ delete_dynamic_element
++ my_qsort
++ allocate_dynamic
+
+ # pam_mysql.so
+ make_scrambled_password
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch b/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
new file mode 100644
index 0000000..80b24ef
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
@@ -0,0 +1,12 @@
+diff -auwrN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2014-07-27 22:03:27.806254846 -0400
++++ b/libmysql/CMakeLists.txt 2014-07-27 22:05:08.400521754 -0400
+@@ -131,6 +131,8 @@
+ mysql_set_character_set
+ mysql_get_character_set_info
+ mysql_stmt_next_result
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 20:21 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2014-08-18 20:21 UTC (permalink / raw
To: gentoo-commits
commit: 99fe52498d9660aee37dca6c3d32de895c43a5dd
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Jul 28 23:43:41 2014 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Mon Jul 28 23:43:41 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=99fe5249
Respin last patch for MySQL 5.6
---
00000_index.txt | 8 +++++++-
20009_all_mysql_myodbc_symbol_fix-5.6.patch | 12 ++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 4f167a1..ac7bcb0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1668,7 +1668,13 @@
@@ MariaDB bug MDEV-6131
@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
-@ver 5.05.38.00 to 5.07.99.99
+@ver 5.05.38.00 to 5.05.99.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
+@ver 5.06.00.00 to 5.07.99.99
@pn mysql
@pn percona-server
@@ Export missing symbols
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.6.patch b/20009_all_mysql_myodbc_symbol_fix-5.6.patch
new file mode 100644
index 0000000..f081d64
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.6.patch
@@ -0,0 +1,12 @@
+diff -auwrN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2014-07-27 22:03:27.806254846 -0400
++++ b/libmysql/CMakeLists.txt 2014-07-27 22:05:08.400521754 -0400
+@@ -138,6 +138,8 @@
+ mysql_load_plugin_v
+ mysql_options4
+ mysql_plugin_options
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 20:21 Robin H. Johnson
0 siblings, 0 replies; 300+ messages in thread
From: Robin H. Johnson @ 2014-08-18 20:21 UTC (permalink / raw
To: gentoo-commits
commit: 9490a24afb658277ba94d95d49f3f1d16723e1e0
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jul 29 18:40:18 2014 +0000
Commit: Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Tue Jul 29 18:40:56 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=9490a24a
Respin ELIB patch for percona 5.6.19
---
00000_index.txt | 8 +-
20006_all_cmake_elib-percona-5.6.19.patch | 206 ++++++++++++++++++++++++++++++
2 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index ac7bcb0..e9fb4a5 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1619,7 +1619,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.6.16.patch
-@ver 5.06.16.00 to 5.06.99.99
+@ver 5.06.16.00 to 5.06.18.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.6.19.patch
+@ver 5.06.19.00 to 5.06.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-percona-5.6.19.patch b/20006_all_cmake_elib-percona-5.6.19.patch
new file mode 100644
index 0000000..65c348b
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.19.patch
@@ -0,0 +1,206 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -210,9 +215,11 @@
+ ENDIF()
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -192,6 +192,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 23:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-18 23:37 UTC (permalink / raw
To: gentoo-commits
commit: 22bf230ec6ebf561d6dc9eeb9f9209c9746f7d57
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Aug 17 23:31:39 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Sun Aug 17 23:31:39 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=22bf230e
Fix bad comparision of void to ulong on hppa for 10.0.13
---
00000_index.txt | 5 +++++
20011_all_mariadb-hppa-unsigned-long-10.0.13.patch | 11 +++++++++++
2 files changed, 16 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 425ec04..eb30088 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1716,6 +1716,11 @@
@patch 20011_all_mariadb-hppa-unsigned-long.patch
@ver 5.05.39.00 to 5.05.99.99
+@pn mariadb
+@@ Fix bad comparision of void to ulong
+@@ Gentoo bug 520092 MDEV-6595
+
+@patch 20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
@ver 10.00.13.00 to 10.00.99.99
@pn mariadb
@@ Fix bad comparision of void to ulong
diff --git a/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch b/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
new file mode 100644
index 0000000..b076f05
--- /dev/null
+++ b/20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
@@ -0,0 +1,11 @@
+--- a/storage/xtradb/os/os0stacktrace.cc
++++ b/storage/xtradb/os/os0stacktrace.cc
+@@ -85,7 +85,7 @@
+ caller_address = (void*) uc->uc_mcontext.gregs[REG_RIP] ;
+ #elif defined(__hppa__)
+ ucontext_t* uc = (ucontext_t*) ucontext;
+- caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0x3UL ;
++ caller_address = (void*) (uc->uc_mcontext.sc_iaoq[0] & ~0x3UL) ;
+ #elif (defined (__ppc__)) || (defined (__powerpc__))
+ ucontext_t* uc = (ucontext_t*) ucontext;
+ caller_address = (void*) uc->uc_mcontext.regs->nip ;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 23:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-18 23:37 UTC (permalink / raw
To: gentoo-commits
commit: ddbb7641cebcbf956e6cc58cd81372be3d2f257a
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Aug 17 23:16:01 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Sun Aug 17 23:19:22 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ddbb7641
Fix bad comparision of void to ulong on hppa
---
00000_index.txt | 7 +++++++
20011_all_mariadb-hppa-unsigned-long.patch | 11 +++++++++++
2 files changed, 18 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index c184471..425ec04 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1713,3 +1713,10 @@
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
@@ Fix Bison 3 compatibility
+
+@patch 20011_all_mariadb-hppa-unsigned-long.patch
+@ver 5.05.39.00 to 5.05.99.99
+@ver 10.00.13.00 to 10.00.99.99
+@pn mariadb
+@@ Fix bad comparision of void to ulong
+@@ Gentoo bug 520092 MDEV-6595
diff --git a/20011_all_mariadb-hppa-unsigned-long.patch b/20011_all_mariadb-hppa-unsigned-long.patch
new file mode 100644
index 0000000..5f5b841
--- /dev/null
+++ b/20011_all_mariadb-hppa-unsigned-long.patch
@@ -0,0 +1,11 @@
+--- a/storage/xtradb/os/os0stacktrace.c
++++ b/storage/xtradb/os/os0stacktrace.c
+@@ -85,7 +85,7 @@
+ caller_address = (void*) uc->uc_mcontext.gregs[REG_RIP] ;
+ #elif defined(__hppa__)
+ ucontext_t* uc = (ucontext_t*) ucontext;
+- caller_address = (void*) uc->uc_mcontext.sc_iaoq[0] & ~0x3UL ;
++ caller_address = (void*) (uc->uc_mcontext.sc_iaoq[0] & ~0x3UL) ;
+ #elif (defined (__ppc__)) || (defined (__powerpc__))
+ ucontext_t* uc = (ucontext_t*) ucontext;
+ caller_address = (void*) uc->uc_mcontext.regs->nip ;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 23:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-18 23:37 UTC (permalink / raw
To: gentoo-commits
commit: fa1d8943e262c1f47feed3b30553e92a4cf82ed5
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Aug 11 22:47:07 2014 +0000
Commit: Brian Evans <grknight <AT> tuffmail <DOT> com>
CommitDate: Mon Aug 11 22:47:07 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=fa1d8943
Fix minimal builds on MariaDB 10.0.13
---
00000_index.txt | 6 ++++++
20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch | 16 ++++++++++++++++
2 files changed, 22 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 7051194..c184471 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1508,6 +1508,12 @@
@pn mariadb
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
+@ver 10.00.13.00 to 10.99.99.99
+@pn mariadb
+@@ Fix the minimal build by reordering CMakeLists.txt
+@@ Fixes MDEV-6562
+
@patch 21000_all_sql-5.1.62.patch
@ver 5.01.62.00 to 5.01.64.99
@pn mariadb
diff --git a/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch b/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
new file mode 100644
index 0000000..99a46fd
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
@@ -0,0 +1,16 @@
+=== modified file 'CMakeLists.txt'
+--- a/CMakeLists.txt 2014-08-07 16:06:56 +0000
++++ b/CMakeLists.txt 2014-08-11 21:43:29 +0000
+@@ -466,7 +466,10 @@
+ ADD_SUBDIRECTORY(packaging/solaris)
+
+ IF(NOT CMAKE_CROSSCOMPILING)
+- SET(EXPORTED comp_err comp_sql factorial gen_lex_hash)
++ SET(EXPORTED comp_err comp_sql factorial)
++ IF(NOT WITHOUT_SERVER)
++ SET(EXPORTED ${EXPORTED} gen_lex_hash)
++ ENDIF()
+ # minimal target to build only binaries for export
+ ADD_CUSTOM_TARGET(import_executables DEPENDS ${EXPORTED})
+ EXPORT(TARGETS ${EXPORTED} FILE ${CMAKE_BINARY_DIR}/import_executables.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-08-18 23:37 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-08-18 23:37 UTC (permalink / raw
To: gentoo-commits
commit: 1b691ba4118d040ec73d7ef7984f0f79c73e4532
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 1 19:49:51 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Aug 1 19:49:51 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=1b691ba4
Respin minimal patches for new MySQL versions
---
00000_index.txt | 16 ++++++-
..._all_fix-minimal-build-cmake-mysql-5.5.39.patch | 49 ++++++++++++++++++++++
..._all_fix-minimal-build-cmake-mysql-5.6.20.patch | 16 +++++++
3 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index e9fb4a5..7051194 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1480,13 +1480,25 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.36.patch
-@ver 5.05.36.00 to 5.05.99.99
+@ver 5.05.36.00 to 5.05.38.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
+@ver 5.05.39.00 to 5.05.99.99
@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.patch
-@ver 5.06.17.00 to 5.06.99.99
+@ver 5.06.17.00 to 5.06.19.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
+@ver 5.06.20.00 to 5.06.99.99
@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch b/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
new file mode 100644
index 0000000..cbd9598
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
@@ -0,0 +1,49 @@
+--- CMakeLists.orig.txt 2013-01-18 16:58:34.701624830 -0500
++++ CMakeLists.txt 2013-01-18 17:00:51.479636903 -0500
+@@ -294,7 +294,11 @@
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+@@ -307,10 +311,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -319,18 +320,17 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+ ENDIF()
+
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
++
+ INCLUDE(cmake/abi_check.cmake)
+ INCLUDE(cmake/tags.cmake)
+
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch b/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
new file mode 100644
index 0000000..8bee332
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
@@ -0,0 +1,16 @@
+diff -aurwN mysql.orig/CMakeLists.txt mysql/CMakeLists.txt
+--- mysql.orig/CMakeLists.txt 2014-07-18 11:48:39.000000000 -0400
++++ mysql/CMakeLists.txt 2014-08-01 12:54:52.612732241 -0400
+@@ -512,11 +512,11 @@
+ # scripts/mysql_config depends on client and server targets loaded above.
+ # It is referenced by some of the directories below, so we insert it here.
+ ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+ ADD_SUBDIRECTORY(sql-bench)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-09-03 19:11 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-09-03 19:11 UTC (permalink / raw
To: gentoo-commits
commit: deb9160c3477d0557d23ca2374178d67988b29fc
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Sep 3 19:11:32 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Sep 3 19:11:32 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=deb9160c
Apply mariadb patches to mariadb-galera as well
---
00000_index.txt | 3 +++
1 file changed, 3 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index eb30088..95944b3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1511,6 +1511,7 @@
@patch 20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
@ver 10.00.13.00 to 10.99.99.99
@pn mariadb
+@pn mariadb-galera
@@ Fix the minimal build by reordering CMakeLists.txt
@@ Fixes MDEV-6562
@@ -1657,6 +1658,7 @@
@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
@ver 10.00.11.00 to 10.00.99.99
@pn mariadb
+@pn mariadb-galera
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
@@ -1723,5 +1725,6 @@
@patch 20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
@ver 10.00.13.00 to 10.00.99.99
@pn mariadb
+@pn mariadb-galera
@@ Fix bad comparision of void to ulong
@@ Gentoo bug 520092 MDEV-6595
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-09-09 18:03 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-09-09 18:03 UTC (permalink / raw
To: gentoo-commits
commit: ab382ddf18bf4b11d20bd8b07026b602720ce4ae
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 9 18:03:14 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Sep 9 18:03:14 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ab382ddf
Adjust index for fixes committed upstream
---
00000_index.txt | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 95944b3..269a589 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1509,7 +1509,7 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mariadb-10.0.13.patch
-@ver 10.00.13.00 to 10.99.99.99
+@ver 10.00.13.00 to 10.00.13.99
@pn mariadb
@pn mariadb-galera
@@ Fix the minimal build by reordering CMakeLists.txt
@@ -1717,13 +1717,13 @@
@@ Fix Bison 3 compatibility
@patch 20011_all_mariadb-hppa-unsigned-long.patch
-@ver 5.05.39.00 to 5.05.99.99
+@ver 5.05.39.00 to 5.05.39.99
@pn mariadb
@@ Fix bad comparision of void to ulong
@@ Gentoo bug 520092 MDEV-6595
@patch 20011_all_mariadb-hppa-unsigned-long-10.0.13.patch
-@ver 10.00.13.00 to 10.00.99.99
+@ver 10.00.13.00 to 10.00.13.99
@pn mariadb
@pn mariadb-galera
@@ Fix bad comparision of void to ulong
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-09 14:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-09 14:50 UTC (permalink / raw
To: gentoo-commits
commit: e8739c87d7879529c68b0902ff6859d4806e92e5
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Oct 9 14:47:09 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Oct 9 14:47:09 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=e8739c87
Add new patch for mariadb 5.5.40
---
00000_index.txt | 8 +-
20006_all_cmake_elib-mariadb-5.5.40.patch | 202 ++++++++++++++++++++++++++++++
2 files changed, 209 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 269a589..b82c694 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1590,7 +1590,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-5.5.33.patch
-@ver 5.05.33.00 to 5.05.99.99
+@ver 5.05.33.00 to 5.05.39.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-5.5.40.patch
+@ver 5.05.40.00 to 5.05.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mariadb-5.5.40.patch b/20006_all_cmake_elib-mariadb-5.5.40.patch
new file mode 100644
index 0000000..7109578
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-5.5.40.patch
@@ -0,0 +1,202 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- mysql-old/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-17 14:20 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-17 14:20 UTC (permalink / raw
To: gentoo-commits
commit: a67fbb36cf3d44a90396f49a1db5fde57bd968fb
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Oct 17 14:19:37 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Oct 17 14:19:37 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=a67fbb36
Fix header include error for bug 525644 wrt MDEV-6862
---
00000_index.txt | 7 +++++++
| 12 ++++++++++++
2 files changed, 19 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index b82c694..610392e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1734,3 +1734,10 @@
@pn mariadb-galera
@@ Fix bad comparision of void to ulong
@@ Gentoo bug 520092 MDEV-6595
+
+@patch 20012_all_mariadb-debug-header.patch
+@ver 5.05.40.00 to 5.05.40.99
+@pn mariadb
+@pn mariadb-galera
+@@ Fix bad header #error which breaks other builds
+@@ Gentoo bug 525644 MDEV-6862
--git a/20012_all_mariadb-debug-header.patch b/20012_all_mariadb-debug-header.patch
new file mode 100644
index 0000000..2791a9b
--- /dev/null
+++ b/20012_all_mariadb-debug-header.patch
@@ -0,0 +1,12 @@
+diff -aurN mysql.orig/config.h.cmake mysql/config.h.cmake
+--- mysql.orig/config.h.cmake 2014-10-08 09:19:51.000000000 -0400
++++ mysql/config.h.cmake 2014-10-17 09:51:33.617709631 -0400
+@@ -650,7 +650,7 @@
+
+ __GLIBC__ is defined in <features.h>
+ */
+-#ifdef __GLIBC__
++#if 0
+ #error <my_config.h> MUST be included first!
+ #endif
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-18 0:15 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-18 0:15 UTC (permalink / raw
To: gentoo-commits
commit: 41e22794bda04788b5d39e2b8e1f13603523e2ad
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat Oct 18 00:13:45 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Oct 18 00:13:45 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=41e22794
Respin mysql_config cleanup for 5.6
---
00000_index.txt | 6 ++++
01050_all_mysql_config_cleanup-5.6.patch | 58 ++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 610392e..0027586 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -251,6 +251,12 @@
@pn mysql
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mysql_config_cleanup-5.6.patch
+@ver 5.06.00.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
@pn mysql
diff --git a/01050_all_mysql_config_cleanup-5.6.patch b/01050_all_mysql_config_cleanup-5.6.patch
new file mode 100644
index 0000000..183f164
--- /dev/null
+++ b/01050_all_mysql_config_cleanup-5.6.patch
@@ -0,0 +1,58 @@
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-17 19:37:06.511549907 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-17 19:53:44.458132867 -0400
+@@ -125,22 +125,42 @@
+ cxxflags="-I$pkgincludedir @CXXFLAGS@ " #note: end space!
+ include="-I$pkgincludedir"
+
+-# Remove some options that a client doesn't have to care about
+-for remove in DDBUG_OFF DSAFE_MUTEX DFORCE_INIT_OF_VARS \
+- DEXTRA_DEBUG DHAVE_purify O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
+- 'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
+- unroll2 ip mp restrict
++tmpcflags=""
++for f in $cflags
+ do
+- # The first option we might strip will always have a space before it because
+- # we set -I$pkgincludedir as the first option
+- cflags=`echo "$cflags"|sed -e "s/ -$remove */ /g"`
+- cxxflags=`echo "$cxxflags"|sed -e "s/ -$remove */ /g"`
++ case "${f}" in
++ -DDBUG_OFF) f="" ;;
++ -DSAFE_MUTEX) f="" ;;
++ -DUNIV_MUST_NOT_INLINE) f="" ;;
++ -DFORCE_INIT_OF_VARS) f="" ;;
++ -DEXTRA_DEBUG) f="" ;;
++ -DHAVE_purify) f="" ;;
++ -[ID]*) tmpcflags="${tmpcflags} ${f}" ;;
++ -[Ll]*)
++ libs="${libs} ${f}"
++ libs_r="${libs_r} ${f}"
++ embedded_libs="${embedded_libs} ${f}"
++ ;;
++ esac
+ done
+-cflags=`echo "$cflags"|sed -e 's/ *\$//'`
+-cxxflags=`echo "$cxxflags"|sed -e 's/ *\$//'`
++cflags="${tmpcflags# }"
++tmpcxxflags=""
++for f in $cxxflags
++do
++ case "${f}" in
++ -DDBUG_OFF) f="" ;;
++ -DSAFE_MUTEX) f="" ;;
++ -DUNIV_MUST_NOT_INLINE) f="" ;;
++ -DFORCE_INIT_OF_VARS) f="" ;;
++ -DEXTRA_DEBUG) f="" ;;
++ -DHAVE_purify) f="" ;;
++ -[ID]*) tmpcxxflags="${tmpcxxflags} ${f}" ;;
++ esac
++done
++cxxflags="${tmpcxxflags# }"
+
+ # Same for --libs(_r)
+-for remove in lmtmalloc static-libcxa i-static static-intel
++for remove in lmtmalloc static-libcxa i-static static-intel lprobes_mysql
+ do
+ # We know the strings starts with a space
+ libs=`echo "$libs"|sed -e "s/ -$remove */ /g"`
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-19 19:21 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-19 19:21 UTC (permalink / raw
To: gentoo-commits
commit: f47d3e000fbd71427ed613cf9cbb27ca119ec6f1
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Oct 19 19:21:45 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Oct 19 19:21:45 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=f47d3e00
Fix embedded lib paths for mysql_config in 5.6/10.0 series
---
20006_all_cmake_elib-mariadb-10.0.11.patch | 16 ++++++++--------
20006_all_cmake_elib-mysql-5.6.15.patch | 14 +++++++-------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/20006_all_cmake_elib-mariadb-10.0.11.patch b/20006_all_cmake_elib-mariadb-10.0.11.patch
index 5281bf5..e07a4c9 100644
--- a/20006_all_cmake_elib-mariadb-10.0.11.patch
+++ b/20006_all_cmake_elib-mariadb-10.0.11.patch
@@ -154,14 +154,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
+++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
-@@ -198,6 +198,7 @@
- SET(scriptdir ${prefix}/${INSTALL_BINDIR})
- SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
- SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
+SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
- IF(INSTALL_LAYOUT MATCHES "STANDALONE")
- SET(localstatedir ${prefix}/data)
- ELSE()
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
+++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
@@ -181,7 +181,7 @@ diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
-+embedded_libs=" $ldflags -L$elibdir -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
if [ -r "$pkglibdir/libmygcc.a" ]; then
# When linking against the static library with a different version of GCC
diff --git a/20006_all_cmake_elib-mysql-5.6.15.patch b/20006_all_cmake_elib-mysql-5.6.15.patch
index 6e009ea..e1b1c4a 100644
--- a/20006_all_cmake_elib-mysql-5.6.15.patch
+++ b/20006_all_cmake_elib-mysql-5.6.15.patch
@@ -172,14 +172,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
+++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
-@@ -206,6 +206,7 @@
- SET(scriptdir ${prefix}/${INSTALL_BINDIR})
- SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
- SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
+SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
- IF(INSTALL_LAYOUT MATCHES "STANDALONE")
- SET(localstatedir ${prefix}/data)
- ELSE()
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
+++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-19 19:27 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-19 19:27 UTC (permalink / raw
To: gentoo-commits
commit: ad7a16616962a6966c891348ca50395b89884484
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Oct 19 19:27:15 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Oct 19 19:27:15 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ad7a1661
Fix tokudb unique key false positive wrt bug 525912
---
00000_index.txt | 8 ++++++++
20013_all_mariadb-tokudb-variable.patch | 12 ++++++++++++
2 files changed, 20 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 0027586..f2f7826 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1747,3 +1747,11 @@
@pn mariadb-galera
@@ Fix bad header #error which breaks other builds
@@ Gentoo bug 525644 MDEV-6862
+
+@patch 20013_all_mariadb-tokudb-variable.patch
+@ver 5.05.39.00 to 5.05.99.99
+@ver 10.00.13.00 to 10.00.99.99
+@pn mariadb
+@pn mariadb-galera
+@@ Fix bad header #error which breaks other builds
+@@ Gentoo bug 525192 MDEV-6863
diff --git a/20013_all_mariadb-tokudb-variable.patch b/20013_all_mariadb-tokudb-variable.patch
new file mode 100644
index 0000000..7e7298a
--- /dev/null
+++ b/20013_all_mariadb-tokudb-variable.patch
@@ -0,0 +1,12 @@
+diff -urN a/storage/tokudb/ft-index/ft/ft-ops.cc b/storage/tokudb/ft-index/ft/ft-ops.cc
+--- a/storage/tokudb/ft-index/ft/ft-ops.cc 2014-09-24 23:29:47.000000000 +0100
++++ b/storage/tokudb/ft-index/ft/ft-ops.cc 2014-10-12 19:21:39.060499831 +0100
+@@ -2237,7 +2237,7 @@
+ nullptr, nullptr, nullptr
+ );
+ *target_childnum = childnum;
+- if (r == 0 && !le_latest_is_del(leftmost_le)) {
++ if (r == 0 && !le_latest_is_del(target_le)) {
+ *nondeleted_key_found = true;
+ }
+ }
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-21 17:41 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-21 17:41 UTC (permalink / raw
To: gentoo-commits
commit: 3f1fe4af81a297bf479b86646e11f4bee8f690cf
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 21 17:41:03 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Oct 21 17:41:03 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=3f1fe4af
Respin elib patch for percona to correct embedded lib paths
---
20006_all_cmake_elib-percona-5.6.19.patch | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/20006_all_cmake_elib-percona-5.6.19.patch b/20006_all_cmake_elib-percona-5.6.19.patch
index 65c348b..6f53e5c 100644
--- a/20006_all_cmake_elib-percona-5.6.19.patch
+++ b/20006_all_cmake_elib-percona-5.6.19.patch
@@ -173,14 +173,14 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
+++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
-@@ -192,6 +192,7 @@
- SET(scriptdir ${prefix}/${INSTALL_BINDIR})
- SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
- SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
+SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
- IF(INSTALL_LAYOUT MATCHES "STANDALONE")
- SET(localstatedir ${prefix}/data)
- ELSE()
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
+++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-22 19:12 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-22 19:12 UTC (permalink / raw
To: gentoo-commits
commit: 9586b0e19e60f8a7dacc9f2312cbcded06986457
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 22 19:12:28 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 22 19:12:28 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=9586b0e1
Patches for maridb-10.1.x
---
00000_index.txt | 9 +++-
20014_all_mariadb-innodb-compression.patch | 71 ++++++++++++++++++++++++++++++
2 files changed, 78 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index f2f7826..eebd9d1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -241,7 +241,7 @@
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 10.00.99.99
+@ver 5.05.00.00 to 10.99.99.99
@pn mariadb
@pn mariadb-galera
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@@ -1668,7 +1668,7 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
-@ver 10.00.11.00 to 10.00.99.99
+@ver 10.00.11.00 to 10.99.99.99
@pn mariadb
@pn mariadb-galera
@@ Add ELIBPATH to split client and embedded libs
@@ -1755,3 +1755,8 @@
@pn mariadb-galera
@@ Fix bad header #error which breaks other builds
@@ Gentoo bug 525192 MDEV-6863
+
+@patch 20014_all_mariadb-innodb-compression.patch
+@ver 10.01.01.00 to 10.99.99.99
+@pn mariadb
+@@ Remove magic dependencies on lz4 and lzo
diff --git a/20014_all_mariadb-innodb-compression.patch b/20014_all_mariadb-innodb-compression.patch
new file mode 100644
index 0000000..b045c8a
--- /dev/null
+++ b/20014_all_mariadb-innodb-compression.patch
@@ -0,0 +1,71 @@
+diff -aruN mysql.orig/cmake/lz4.cmake mysql/cmake/lz4.cmake
+--- mysql.orig/cmake/lz4.cmake 2014-10-15 18:53:42.000000000 -0400
++++ mysql/cmake/lz4.cmake 2014-10-22 13:27:29.084405469 -0400
+@@ -12,8 +12,12 @@
+ # this program; if not, write to the Free Software Foundation, Inc.,
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
++OPTION(WITH_INNODB_LZ4 "Enable lz4 compression on InnoDB/XtraDB" ON)
++
+ MACRO (MYSQL_CHECK_LZ4)
+
++IF (WITH_INNODB_LZ4)
++
+ CHECK_INCLUDE_FILES(lz4.h HAVE_LZ4_H)
+ CHECK_LIBRARY_EXISTS(lz4 LZ4_compress_limitedOutput "" HAVE_LZ4_SHARED_LIB)
+
+@@ -21,10 +25,11 @@
+ ADD_DEFINITIONS(-DHAVE_LZ4=1)
+ LINK_LIBRARIES(lz4)
+ ENDIF()
++ENDIF()
+ ENDMACRO()
+
+ MACRO (MYSQL_CHECK_LZ4_STATIC)
+-
++IF (WITH_INNODB_LZ4)
+ CHECK_INCLUDE_FILES(lz4.h HAVE_LZ4_H)
+ CHECK_LIBRARY_EXISTS(liblz4.a LZ4_compress_limitedOutput "" HAVE_LZ4_LIB)
+
+@@ -32,4 +37,5 @@
+ ADD_DEFINITIONS(-DHAVE_LZ4=1)
+ LINK_LIBRARIES(liblz4.a)
+ ENDIF()
+-ENDMACRO()
+\ No newline at end of file
++ENDIF()
++ENDMACRO()
+diff -aruN mysql.orig/cmake/lzo.cmake mysql/cmake/lzo.cmake
+--- mysql.orig/cmake/lzo.cmake 2014-10-15 18:53:42.000000000 -0400
++++ mysql/cmake/lzo.cmake 2014-10-22 13:28:37.622202579 -0400
+@@ -12,8 +12,10 @@
+ # this program; if not, write to the Free Software Foundation, Inc.,
+ # 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+-MACRO (MYSQL_CHECK_LZO_STATIC)
++OPTION(WITH_INNODB_LZO "Enable lzo compression on InnoDB/XtraDB" ON)
+
++MACRO (MYSQL_CHECK_LZO_STATIC)
++IF(WITH_INNODB_LZO)
+ CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H)
+ CHECK_LIBRARY_EXISTS(liblzo2.a lzo1x_1_compress "" HAVE_LZO_LIB)
+
+@@ -21,10 +23,11 @@
+ ADD_DEFINITIONS(-DHAVE_LZO=1)
+ LINK_LIBRARIES(liblzo2.a)
+ ENDIF()
++ENDIF()
+ ENDMACRO()
+
+ MACRO (MYSQL_CHECK_LZO)
+-
++IF(WITH_INNODB_LZO)
+ CHECK_INCLUDE_FILES(lzo/lzo1x.h HAVE_LZO_H)
+ CHECK_LIBRARY_EXISTS(lzo2 lzo1x_1_compress "" HAVE_LZO_SHARED_LIB)
+
+@@ -32,4 +35,5 @@
+ ADD_DEFINITIONS(-DHAVE_LZO=1)
+ LINK_LIBRARIES(lzo2)
+ ENDIF()
++ENDIF()
+ ENDMACRO()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-22 20:44 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-22 20:44 UTC (permalink / raw
To: gentoo-commits
commit: e6578baaa5ece0891c361d66a002930a9cca0cff
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 22 20:43:41 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 22 20:43:41 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=e6578baa
Respin patches for MariaDB 10.1
---
00000_index.txt | 10 +-
20006_all_cmake_elib-mariadb-10.1.1.patch | 187 ++++++++++++++++++++++++++++++
2 files changed, 195 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index eebd9d1..f4811aa 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -241,7 +241,7 @@
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 10.99.99.99
+@ver 5.05.00.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@@ -1668,12 +1668,18 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
-@ver 10.00.11.00 to 10.99.99.99
+@ver 10.00.11.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
+@patch 20006_all_cmake_elib-mariadb-10.1.1.patch
+@ver 10.01.01.00 to 10.99.99.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
@patch 20007_all_cmake-debug-werror.patch
@ver 5.05.32.00 to 5.05.99.99
@pn mysql
diff --git a/20006_all_cmake_elib-mariadb-10.1.1.patch b/20006_all_cmake_elib-mariadb-10.1.1.patch
new file mode 100644
index 0000000..69d95bd
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.1.1.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-10-25 2:42 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-10-25 2:42 UTC (permalink / raw
To: gentoo-commits
commit: 98ba1e33ae957b70ac94eca60a5721db16268bcc
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat Oct 25 02:42:21 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Oct 25 02:42:21 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=98ba1e33
Fix mariadb 10.1 pkgconfig location
---
00000_index.txt | 5 +++++
20015_all_mariadb-pkgconfig-location.patch | 12 ++++++++++++
2 files changed, 17 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index f4811aa..92da09a 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1766,3 +1766,8 @@
@ver 10.01.01.00 to 10.99.99.99
@pn mariadb
@@ Remove magic dependencies on lz4 and lzo
+
+@patch 20015_all_mariadb-pkgconfig-location.patch
+@ver 10.01.01.00 to 10.99.99.99
+@pn mariadb
+@@ Allow mariadb.pc to be installed in libdir instead of sharedir
diff --git a/20015_all_mariadb-pkgconfig-location.patch b/20015_all_mariadb-pkgconfig-location.patch
new file mode 100644
index 0000000..24e391e
--- /dev/null
+++ b/20015_all_mariadb-pkgconfig-location.patch
@@ -0,0 +1,12 @@
+diff -aruN mysql.orig/support-files/CMakeLists.txt mysql/support-files/CMakeLists.txt
+--- mysql.orig/support-files/CMakeLists.txt 2014-10-24 22:18:52.144297645 -0400
++++ mysql/support-files/CMakeLists.txt 2014-10-24 22:37:51.303410675 -0400
+@@ -62,7 +62,7 @@
+ ENDIF()
+
+ CONFIGURE_FILE(mariadb.pc.in ${CMAKE_CURRENT_BINARY_DIR}/mariadb.pc @ONLY)
+- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mariadb.pc DESTINATION ${INSTALL_SHAREDIR}/pkgconfig COMPONENT Development)
++ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/mariadb.pc DESTINATION ${INSTALL_LIBDIR}/pkgconfig COMPONENT Development)
+
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-11-25 13:47 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-11-25 13:47 UTC (permalink / raw
To: gentoo-commits
commit: 4187d3193894c36d07d35788cfc8a6aaf95ff296
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 25 13:46:20 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 25 13:47:08 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=4187d319
Respin patch for mariadb-10.0.15
---
00000_index.txt | 9 +-
20006_all_cmake_elib-mariadb-10.0.15.patch | 187 +++++++++++++++++++++++++++++
2 files changed, 195 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 92da09a..987305e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1668,7 +1668,14 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.0.11.patch
-@ver 10.00.11.00 to 10.00.99.99
+@ver 10.00.11.00 to 10.00.14.99
+@pn mariadb
+@pn mariadb-galera
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-10.0.15.patch
+@ver 10.00.15.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ Add ELIBPATH to split client and embedded libs
diff --git a/20006_all_cmake_elib-mariadb-10.0.15.patch b/20006_all_cmake_elib-mariadb-10.0.15.patch
new file mode 100644
index 0000000..769a24e
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.15.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-11-25 13:51 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-11-25 13:51 UTC (permalink / raw
To: gentoo-commits
commit: b3fdf4237fbc58dfb4b1fe7476a61cf0ea64ed31
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 25 13:51:16 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 25 13:51:16 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=b3fdf423
Set max version as patch fixed upstream
---
00000_index.txt | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 987305e..1235f87 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1762,8 +1762,8 @@
@@ Gentoo bug 525644 MDEV-6862
@patch 20013_all_mariadb-tokudb-variable.patch
-@ver 5.05.39.00 to 5.05.99.99
-@ver 10.00.13.00 to 10.00.99.99
+@ver 5.05.39.00 to 5.05.40.99
+@ver 10.00.13.00 to 10.14.99.99
@pn mariadb
@pn mariadb-galera
@@ Fix bad header #error which breaks other builds
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-11-25 13:52 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-11-25 13:52 UTC (permalink / raw
To: gentoo-commits
commit: 756417f0dd39af940bc3c087cf542f039b207c66
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 25 13:52:26 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 25 13:52:26 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=756417f0
Typo in version
---
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1235f87..43f86ac 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1763,7 +1763,7 @@
@patch 20013_all_mariadb-tokudb-variable.patch
@ver 5.05.39.00 to 5.05.40.99
-@ver 10.00.13.00 to 10.14.99.99
+@ver 10.00.13.00 to 10.00.14.99
@pn mariadb
@pn mariadb-galera
@@ Fix bad header #error which breaks other builds
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-11-25 14:15 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-11-25 14:15 UTC (permalink / raw
To: gentoo-commits
commit: 06fe15f3ea19c6cf37da960aab196433e787ebb1
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 25 14:15:45 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 25 14:15:45 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=06fe15f3
Respin mysql_config patch for mariadb 10.0.15
---
00000_index.txt | 10 ++++-
...0_all_mariadb_mysql_config_cleanup-5.5.41.patch | 45 ++++++++++++++++++++++
2 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 43f86ac..0d78670 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -241,7 +241,15 @@
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 01050_all_mariadb_mysql_config_cleanup-5.5.patch
-@ver 5.05.00.00 to 10.00.99.99
+@ver 5.05.00.00 to 5.05.40.99
+@ver 10.00.00.00 to 10.00.14.99
+@pn mariadb
+@pn mariadb-galera
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
+@patch 01050_all_mariadb_mysql_config_cleanup-5.5.41.patch
+@ver 5.05.41.00 to 5.05.99.99
+@ver 10.00.15.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
diff --git a/01050_all_mariadb_mysql_config_cleanup-5.5.41.patch b/01050_all_mariadb_mysql_config_cleanup-5.5.41.patch
new file mode 100644
index 0000000..f97c4cb
--- /dev/null
+++ b/01050_all_mariadb_mysql_config_cleanup-5.5.41.patch
@@ -0,0 +1,45 @@
+--- mysql.old/scripts/mysql_config.sh 2013-05-02 20:30:14.000000000 -0400
++++ mysql.new/scripts/mysql_config.sh 2013-05-02 20:32:36.000000000 -0400
+@@ -128,25 +128,29 @@
+ cflags="$include @CFLAGS@ " #note: end space!
+
+ # Remove some options that a client doesn't have to care about
+-# FIXME until we have a --cxxflags, we need to remove -Xa
+-# and -xstrconst to make --cflags usable for Sun Forte C++
+-# FIXME until we have a --cxxflags, we need to remove -AC99
+-# to make --cflags usable for HP C++ (aCC)
+-for remove in DDBUG_OFF DSAFE_MUTEX DUNIV_MUST_NOT_INLINE DFORCE_INIT_OF_VARS \
+- DEXTRA_DEBUG DHAVE_valgrind O 'O[0-9]' 'xO[0-9]' 'W[-A-Za-z]*' \
+- 'mtune=[-A-Za-z0-9]*' 'mcpu=[-A-Za-z0-9]*' 'march=[-A-Za-z0-9]*' \
+- Xa xstrconst "xc99=none" AC99 'W[-A-Za-z]*=[-A-Za-z0-9]*' \
+- unroll2 ip mp restrict
++tmpcflags=""
++for f in $cflags
+ do
+- # The first option we might strip will always have a space before it because
+- # we set -I$pkgincludedir as the first option
+- cflags=`echo "$cflags"|sed -e ':again' -e "s/ -$remove */ /g" -e 't again'`
++ case "${f}" in
++ -DDBUG_OFF) f="" ;;
++ -DSAFE_MUTEX) f="" ;;
++ -DUNIV_MUST_NOT_INLINE) f="" ;;
++ -DFORCE_INIT_OF_VARS) f="" ;;
++ -DEXTRA_DEBUG) f="" ;;
++ -DHAVE_valgrind) f="" ;;
++ -[ID]*) tmpcflags="${tmpcflags} ${f}" ;;
++ -[Ll]*)
++ libs="${libs} ${f}"
++ libs_r="${libs_r} ${f}"
++ embedded_libs="${embedded_libs} ${f}"
++ ;;
++ esac
+ done
+-cflags=`echo "$cflags"|sed -e 's/ *\$//'`
++cflags="${tmpcflags# }"
+
+ # Same for --libs(_r)
+-for remove in lmtmalloc static-libcxa i-static static-intel
++for remove in lmtmalloc static-libcxa i-static static-intel lprobes_mysql
+ do
+ # We know the strings starts with a space
+ libs=`echo "$libs"|sed -e "s/ -$remove */ /g"`
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-03 18:16 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-03 18:16 UTC (permalink / raw
To: gentoo-commits
commit: adaf967411084dda2f8cd7339f26cbda72f4cc51
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 3 18:16:03 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Dec 3 18:16:03 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=adaf9674
Respin patch for dev-db/mysql-5.6.22
---
00000_index.txt | 8 +-
20006_all_cmake_elib-mysql-5.6.22.patch | 205 ++++++++++++++++++++++++++++++++
2 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 0d78670..d66dffa 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1628,7 +1628,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.6.15.patch
-@ver 5.06.15.00 to 5.06.99.99
+@ver 5.06.15.00 to 5.06.21.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mysql-5.6.22.patch
+@ver 5.06.22.00 to 5.06.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mysql-5.6.22.patch b/20006_all_cmake_elib-mysql-5.6.22.patch
new file mode 100644
index 0000000..0b47cfc
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.6.22.patch
@@ -0,0 +1,205 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-03 18:22 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-03 18:22 UTC (permalink / raw
To: gentoo-commits
commit: 7d7d290a70003c4e366c04b4c9268fb678317a92
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 3 18:22:13 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Dec 3 18:22:13 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=7d7d290a
Respin Werror patch for dev-db/mysql-5.6.22
---
00000_index.txt | 8 +++++++-
20007_all_cmake-debug-werror-5.6.22.patch | 17 +++++++++++++++++
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index d66dffa..ccf19c0 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1714,7 +1714,13 @@
@@ Remove -Werror from USE="debug" builds
@patch 20007_all_cmake-debug-werror-5.6.16.patch
-@ver 5.06.16.00 to 5.06.99.99
+@ver 5.06.16.00 to 5.06.21.99
+@pn mysql
+@pn percona-server
+@@ Remove -Werror from USE="debug" builds
+
+@patch 20007_all_cmake-debug-werror-5.6.22.patch
+@ver 5.06.22.00 to 5.06.99.99
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
diff --git a/20007_all_cmake-debug-werror-5.6.22.patch b/20007_all_cmake-debug-werror-5.6.22.patch
new file mode 100644
index 0000000..80613ea
--- /dev/null
+++ b/20007_all_cmake-debug-werror-5.6.22.patch
@@ -0,0 +1,17 @@
+diff -aurN a/cmake/maintainer.cmake b/cmake/maintainer.cmake
+--- a/cmake/maintainer.cmake 2014-11-21 00:39:51.000000000 -0500
++++ b/cmake/maintainer.cmake 2014-12-03 13:19:50.893380789 -0500
+@@ -34,13 +34,6 @@
+ "${MY_CXX_WARNING_FLAGS} -Wno-null-conversion -Wno-unused-private-field")
+ ENDIF()
+
+-# Turn on Werror (warning => error) when using maintainer mode.
+-IF(MYSQL_MAINTAINER_MODE)
+- SET(MY_C_WARNING_FLAGS "${MY_C_WARNING_FLAGS} -Werror")
+- SET(MY_CXX_WARNING_FLAGS "${MY_CXX_WARNING_FLAGS} -Werror")
+- SET(COMPILE_FLAG_WERROR 1)
+-ENDIF()
+-
+ # Set warning flags for GCC/Clang
+ IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_C_WARNING_FLAGS}")
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-03 19:04 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-03 19:04 UTC (permalink / raw
To: gentoo-commits
commit: ccf74a2d22ed7ef2f5628329c45aa1dd4724218b
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 3 19:03:50 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Dec 3 19:03:50 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=ccf74a2d
Respin minimal patch for mysql-5.5.41
---
00000_index.txt | 8 +++-
..._all_fix-minimal-build-cmake-mysql-5.5.41.patch | 50 ++++++++++++++++++++++
2 files changed, 57 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index ccf19c0..e4103c2 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1500,7 +1500,13 @@
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.39.patch
-@ver 5.05.39.00 to 5.05.99.99
+@ver 5.05.39.00 to 5.05.40.99
+@pn mysql
+@pn percona-server
+@@ Fix the minimal build by reordering CMakeLists.txt
+
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
+@ver 5.05.41.00 to 5.05.99.99
@pn mysql
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch b/20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
new file mode 100644
index 0000000..d069732
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
@@ -0,0 +1,50 @@
+diff -aurN mysql.orig/CMakeLists.txt mysql/CMakeLists.txt
+--- mysql.orig/CMakeLists.txt 2014-11-04 02:49:52.000000000 -0500
++++ mysql/CMakeLists.txt 2014-12-03 13:46:18.534238953 -0500
+@@ -376,6 +376,11 @@
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
++ADD_SUBDIRECTORY(client)
++ADD_SUBDIRECTORY(libservices)
++ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(sql/share)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+@@ -389,10 +394,7 @@
+ ADD_SUBDIRECTORY(extra)
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+- ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql)
+- ADD_SUBDIRECTORY(sql/share)
+- ADD_SUBDIRECTORY(libservices)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
+ ADD_SUBDIRECTORY(libmysqld)
+@@ -401,12 +403,7 @@
+
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+- ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql-bench)
+- IF(UNIX)
+- ADD_SUBDIRECTORY(man)
+- ENDIF()
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
+@@ -414,6 +411,10 @@
+ ADD_SUBDIRECTORY(packaging/rpm-sles)
+ ENDIF()
+
++IF(UNIX)
++ ADD_SUBDIRECTORY(man)
++ENDIF()
++
+ INCLUDE(cmake/abi_check.cmake)
+ INCLUDE(cmake/tags.cmake)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-03 19:36 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-03 19:36 UTC (permalink / raw
To: gentoo-commits
commit: 32ef36aaaec9505fd270ed39982f0be5eea5b9e1
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Dec 3 19:36:42 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Dec 3 19:36:42 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=32ef36aa
Update patch index for werror for mysql-5.5.41
---
00000_index.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index e4103c2..527ffe3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1708,7 +1708,7 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20007_all_cmake-debug-werror.patch
-@ver 5.05.32.00 to 5.05.99.99
+@ver 5.05.32.00 to 5.05.40.99
@pn mysql
@pn percona-server
@@ Remove -Werror from USE="debug" builds
@@ -1726,6 +1726,7 @@
@@ Remove -Werror from USE="debug" builds
@patch 20007_all_cmake-debug-werror-5.6.22.patch
+@ver 5.05.41.00 to 5.05.99.99
@ver 5.06.22.00 to 5.06.99.99
@pn mysql
@pn percona-server
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-09 23:20 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-09 23:20 UTC (permalink / raw
To: gentoo-commits
commit: 2f91fb1c6692d8906b8e39ea779dff931b27b27b
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Tue Dec 9 23:20:12 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Dec 9 23:20:32 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=2f91fb1c
Respin elib patch for 10.1.2
---
00000_index.txt | 8 +-
20006_all_cmake_elib-mariadb-10.1.2.patch | 187 ++++++++++++++++++++++++++++++
2 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 527ffe3..8174521 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1702,7 +1702,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.1.1.patch
-@ver 10.01.01.00 to 10.99.99.99
+@ver 10.01.01.00 to 10.01.01.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-10.1.2.patch
+@ver 10.01.02.00 to 10.99.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mariadb-10.1.2.patch b/20006_all_cmake_elib-mariadb-10.1.2.patch
new file mode 100644
index 0000000..4edf5a6
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.1.2.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-15 1:44 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-15 1:44 UTC (permalink / raw
To: gentoo-commits
commit: c4a66f0ac469a3aae6b552633e07191132aaabe7
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Dec 15 01:43:56 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Dec 15 01:43:56 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=c4a66f0a
Add patch for mariadb-10.0.15 with critical replication bug and non-atomic arch compile fix
---
00000_index.txt | 7 +
..._mariadb-parallel-replication-fix-10.0.15.patch | 213 +++++++++++++++++++++
2 files changed, 220 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 8174521..c96910e 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1811,3 +1811,10 @@
@ver 10.01.01.00 to 10.99.99.99
@pn mariadb
@@ Allow mariadb.pc to be installed in libdir instead of sharedir
+
+@patch 20016_all_mariadb-parallel-replication-fix-10.0.15.patch
+@ver 10.00.15.00 to 10.00.15.99
+@pn mariadb
+@pn mariadb-galera
+@@ Fix build on sparc and other arches with no atomics
+@@ Also fix critical replication bug discovered shortly after release
diff --git a/20016_all_mariadb-parallel-replication-fix-10.0.15.patch b/20016_all_mariadb-parallel-replication-fix-10.0.15.patch
new file mode 100644
index 0000000..54a0169
--- /dev/null
+++ b/20016_all_mariadb-parallel-replication-fix-10.0.15.patch
@@ -0,0 +1,213 @@
+=== modified file 'mysql-test/suite/rpl/r/rpl_parallel.result'
+--- mysql-test/suite/rpl/r/rpl_parallel.result 2014-11-13 09:31:20 +0000
++++ mysql-test/suite/rpl/r/rpl_parallel.result 2014-12-01 12:53:57 +0000
+@@ -972,6 +972,54 @@
+ SET GLOBAL slave_parallel_threads=0;
+ SET GLOBAL slave_parallel_threads=10;
+ include/start_slave.inc
++*** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave ***
++INSERT INTO t2 VALUES (40);
++include/stop_slave.inc
++CHANGE MASTER TO master_use_gtid=no;
++SET @old_dbug= @@GLOBAL.debug_dbug;
++SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100";
++SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger";
++SET GLOBAL slave_parallel_threads=0;
++SET GLOBAL slave_parallel_threads=10;
++INSERT INTO t2 VALUES (41);
++INSERT INTO t2 VALUES (42);
++DELETE FROM t2 WHERE a=40;
++INSERT INTO t2 VALUES (43);
++INSERT INTO t2 VALUES (44);
++FLUSH LOGS;
++INSERT INTO t2 VALUES (45);
++SET gtid_seq_no=100;
++INSERT INTO t2 VALUES (46);
++BEGIN;
++SELECT * FROM t2 WHERE a=40 FOR UPDATE;
++a
++40
++include/start_slave.inc
++SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100';
++STOP SLAVE;
++SET debug_sync= 'now WAIT_FOR wait_for_done_waiting';
++ROLLBACK;
++include/wait_for_slave_sql_to_stop.inc
++SELECT * FROM t2 WHERE a >= 40 ORDER BY a;
++a
++41
++42
++include/start_slave.inc
++SELECT * FROM t2 WHERE a >= 40 ORDER BY a;
++a
++41
++42
++43
++44
++45
++46
++include/stop_slave.inc
++SET GLOBAL debug_dbug=@old_dbug;
++SET DEBUG_SYNC= 'RESET';
++SET GLOBAL slave_parallel_threads=0;
++SET GLOBAL slave_parallel_threads=10;
++CHANGE MASTER TO master_use_gtid=slave_pos;
++include/start_slave.inc
+ include/stop_slave.inc
+ SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+ include/start_slave.inc
+
+=== modified file 'mysql-test/suite/rpl/t/rpl_parallel.test'
+--- mysql-test/suite/rpl/t/rpl_parallel.test 2014-11-13 09:31:20 +0000
++++ mysql-test/suite/rpl/t/rpl_parallel.test 2014-12-01 12:53:57 +0000
+@@ -1535,6 +1535,99 @@
+ --source include/start_slave.inc
+
+
++--echo *** MDEV-7237: Parallel replication: incorrect relaylog position after stop/start the slave ***
++--connection server_1
++INSERT INTO t2 VALUES (40);
++--save_master_pos
++
++--connection server_2
++--sync_with_master
++--source include/stop_slave.inc
++CHANGE MASTER TO master_use_gtid=no;
++SET @old_dbug= @@GLOBAL.debug_dbug;
++# This DBUG injection causes a DEBUG_SYNC signal "scheduled_gtid_0_x_100" when
++# GTID 0-1-100 has been scheduled for and fetched by a worker thread.
++SET GLOBAL debug_dbug="+d,rpl_parallel_scheduled_gtid_0_x_100";
++# This DBUG injection causes a DEBUG_SYNC signal "wait_for_done_waiting" when
++# STOP SLAVE has signalled all worker threads to stop.
++SET GLOBAL debug_dbug="+d,rpl_parallel_wait_for_done_trigger";
++# Reset worker threads to make DBUG setting catch on.
++SET GLOBAL slave_parallel_threads=0;
++SET GLOBAL slave_parallel_threads=10;
++
++
++--connection server_1
++# Setup some transaction for the slave to replicate.
++INSERT INTO t2 VALUES (41);
++INSERT INTO t2 VALUES (42);
++DELETE FROM t2 WHERE a=40;
++INSERT INTO t2 VALUES (43);
++INSERT INTO t2 VALUES (44);
++# Force the slave to switch to a new relay log file.
++FLUSH LOGS;
++INSERT INTO t2 VALUES (45);
++# Inject a GTID 0-1-100, which will trigger a DEBUG_SYNC signal when this
++# transaction has been fetched by a worker thread.
++SET gtid_seq_no=100;
++INSERT INTO t2 VALUES (46);
++--save_master_pos
++
++--connection con_temp2
++# Temporarily block the DELETE on a=40 from completing.
++BEGIN;
++SELECT * FROM t2 WHERE a=40 FOR UPDATE;
++
++
++--connection server_2
++--source include/start_slave.inc
++
++# The DBUG injection set above will make the worker thread signal the following
++# debug_sync when the GTID 0-1-100 has been reached by a worker thread.
++# Thus, at this point, the SQL driver thread has reached the next
++# relay log file name, while a worker thread is still processing a
++# transaction in the previous relay log file, blocked on the SELECT FOR
++# UPDATE.
++SET debug_sync= 'now WAIT_FOR scheduled_gtid_0_x_100';
++# At this point, the SQL driver thread is in the new relay log file, while
++# the DELETE from the old relay log file is not yet complete. We will stop
++# the slave at this point. The bug was that the DELETE statement would
++# update the slave position to the _new_ relay log file name instead of
++# its own old file name. Thus, by stoping and restarting the slave at this
++# point, we would get an error at restart due to incorrect position. (If
++# we would let the slave catch up before stopping, the incorrect position
++# would be corrected by a later transaction).
++
++send STOP SLAVE;
++
++--connection con_temp2
++# Wait for STOP SLAVE to have proceeded sufficiently that it has signalled
++# all worker threads to stop; this ensures that we will stop after the DELETE
++# transaction (and not after a later transaction that might have been able
++# to set a fixed position).
++SET debug_sync= 'now WAIT_FOR wait_for_done_waiting';
++# Now release the row lock that was blocking the replication of DELETE.
++ROLLBACK;
++
++--connection server_2
++reap;
++--source include/wait_for_slave_sql_to_stop.inc
++SELECT * FROM t2 WHERE a >= 40 ORDER BY a;
++# Now restart the slave. With the bug present, this would start at an
++# incorrect relay log position, causing relay log read error (or if unlucky,
++# silently skip a number of events).
++--source include/start_slave.inc
++--sync_with_master
++SELECT * FROM t2 WHERE a >= 40 ORDER BY a;
++--source include/stop_slave.inc
++SET GLOBAL debug_dbug=@old_dbug;
++SET DEBUG_SYNC= 'RESET';
++SET GLOBAL slave_parallel_threads=0;
++SET GLOBAL slave_parallel_threads=10;
++CHANGE MASTER TO master_use_gtid=slave_pos;
++--source include/start_slave.inc
++
++
++# Clean up.
+ --connection server_2
+ --source include/stop_slave.inc
+ SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+
+=== modified file 'sql/rpl_parallel.cc'
+--- sql/rpl_parallel.cc 2014-11-17 11:42:02 +0000
++++ sql/rpl_parallel.cc 2014-12-01 12:53:57 +0000
+@@ -631,6 +631,14 @@
+ PSI_stage_info old_stage;
+ uint64 wait_count;
+
++ DBUG_EXECUTE_IF("rpl_parallel_scheduled_gtid_0_x_100", {
++ if (rgi->current_gtid.domain_id == 0 &&
++ rgi->current_gtid.seq_no == 100) {
++ debug_sync_set_action(thd,
++ STRING_WITH_LEN("now SIGNAL scheduled_gtid_0_x_100"));
++ }
++ });
++
+ in_event_group= true;
+ /*
+ If the standalone flag is set, then this event group consists of a
+@@ -1131,9 +1131,9 @@
+ inuse_relaylog *ir= accumulated_ir_last;
+ if (ir)
+ {
+- my_atomic_rwlock_wrlock(&ir->rli->inuse_relaylog_atomic_lock);
++ my_atomic_rwlock_wrlock(&ir->inuse_relaylog_atomic_lock);
+ my_atomic_add64(&ir->dequeued_count, accumulated_ir_count);
+- my_atomic_rwlock_wrunlock(&ir->rli->inuse_relaylog_atomic_lock);
++ my_atomic_rwlock_wrunlock(&ir->inuse_relaylog_atomic_lock);
+ accumulated_ir_count= 0;
+ accumulated_ir_last= NULL;
+ }
+
+
+=== modified file 'sql/rpl_rli.cc'
+--- sql/rpl_rli.cc 2014-11-25 11:19:48 +0000
++++ sql/rpl_rli.cc 2014-12-01 12:53:57 +0000
+@@ -986,11 +986,11 @@
+ if (rgi->is_parallel_exec)
+ {
+ /* In case of parallel replication, do not update the position backwards. */
+- int cmp= strcmp(group_relay_log_name, event_relay_log_name);
++ int cmp= strcmp(group_relay_log_name, rgi->event_relay_log_name);
+ if (cmp < 0)
+ {
+ group_relay_log_pos= rgi->future_event_relay_log_pos;
+- strmake_buf(group_relay_log_name, event_relay_log_name);
++ strmake_buf(group_relay_log_name, rgi->event_relay_log_name);
+ notify_group_relay_log_name_update();
+ } else if (cmp == 0 && group_relay_log_pos < rgi->future_event_relay_log_pos)
+ group_relay_log_pos= rgi->future_event_relay_log_pos;
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2014-12-15 2:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2014-12-15 2:02 UTC (permalink / raw
To: gentoo-commits
commit: 2e2fc2d9bae78de6c0d085070605f2464cdce1f3
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Mon Dec 15 02:02:30 2014 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Dec 15 02:02:30 2014 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=2e2fc2d9
Note upstream bug
---
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index c96910e..db297e1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1817,4 +1817,4 @@
@pn mariadb
@pn mariadb-galera
@@ Fix build on sparc and other arches with no atomics
-@@ Also fix critical replication bug discovered shortly after release
+@@ Also fix critical replication bug discovered shortly after release MDEV-7237
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-01-13 18:54 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-01-13 18:54 UTC (permalink / raw
To: gentoo-commits
commit: a4789f8c21de537c56fc6f52397dc1e8927dc788
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jan 13 18:53:38 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Jan 13 18:53:38 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=a4789f8c
Respin patch for percona 5.6.22
---
00000_index.txt | 8 +-
20006_all_cmake_elib-percona-5.6.22.patch | 206 ++++++++++++++++++++++++++++++
2 files changed, 213 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index db297e1..49b7d42 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1676,7 +1676,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-percona-5.6.19.patch
-@ver 5.06.19.00 to 5.06.99.99
+@ver 5.06.19.00 to 5.06.21.99
+@pn percona-server
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-percona-5.6.22.patch
+@ver 5.06.22.00 to 5.06.99.99
@pn percona-server
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-percona-5.6.22.patch b/20006_all_cmake_elib-percona-5.6.22.patch
new file mode 100644
index 0000000..5b88bbf
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.22.patch
@@ -0,0 +1,206 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -210,9 +215,11 @@
+ ENDIF()
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-01-27 13:51 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-01-27 13:51 UTC (permalink / raw
To: gentoo-commits
commit: 2eaaa54428187bab4c9cc39ea9a9d09df73b9d62
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jan 27 13:50:49 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Jan 27 13:50:49 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=2eaaa544
Add patch to Fix detection of >=openssl-1.0.2 wrt bug 537872
---
00000_index.txt | 9 +++++++++
20017_all_mysql-openssl-cmake-detection.patch | 12 ++++++++++++
2 files changed, 21 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 49b7d42..58e74cd 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1824,3 +1824,12 @@
@pn mariadb-galera
@@ Fix build on sparc and other arches with no atomics
@@ Also fix critical replication bug discovered shortly after release MDEV-7237
+
+@patch 20017_all_mysql-openssl-cmake-detection.patch
+@ver 5.06.00.00 to 5.07.99.99
+@pn mysql
+@pn percona-server
+@@ Fix detection of OpenSSL 1.0.2
+@@ Bug 537872
+@@ Upstream bug 75622
+
diff --git a/20017_all_mysql-openssl-cmake-detection.patch b/20017_all_mysql-openssl-cmake-detection.patch
new file mode 100644
index 0000000..3a5f53e
--- /dev/null
+++ b/20017_all_mysql-openssl-cmake-detection.patch
@@ -0,0 +1,12 @@
+diff -aurN a/cmake/ssl.cmake b/cmake/ssl.cmake
+--- a/cmake/ssl.cmake 2014-11-21 00:39:51.000000000 -0500
++++ b/cmake/ssl.cmake 2015-01-27 08:45:36.771744344 -0500
+@@ -166,7 +166,7 @@
+ # Encoded as MNNFFPPS: major minor fix patch status
+ FILE(STRINGS "${OPENSSL_INCLUDE_DIR}/openssl/opensslv.h"
+ OPENSSL_VERSION_NUMBER
+- REGEX "^#define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x[0-9].*"
++ REGEX "^#[\t ]*define[\t ]+OPENSSL_VERSION_NUMBER[\t ]+0x[0-9].*"
+ )
+ STRING(REGEX REPLACE
+ "^.*OPENSSL_VERSION_NUMBER[\t ]+0x([0-9]).*$" "\\1"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-02-10 15:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-02-10 15:02 UTC (permalink / raw
To: gentoo-commits
commit: d850256c5094cfcd8110d6ae2dc89d0b93e023c8
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 10 15:02:07 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Feb 10 15:02:07 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d850256c
Add patch references for dev-db/mysql-cluster-7.3.x
---
00000_index.txt | 42 ++++-
20006_all_cmake_elib-mysql-cluster-5.6.22.patch | 198 ++++++++++++++++++++++++
2 files changed, 236 insertions(+), 4 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 58e74cd..6d761f3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -265,6 +265,11 @@
@pn percona-server
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mysql_config_cleanup-5.6.patch
+@ver 7.03.00.00 to 7.03.99.99
+@pn mysql-cluster
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
@patch 02000_all_query-logging-bypass-4.1.19.patch
@ver 4.01.14.00 to 4.01.99.99
@pn mysql
@@ -1523,6 +1528,11 @@
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
+@ver 7.03.07.00 to 7.03.99.99
+@pn mysql-cluster
+@@ Fix the minimal build by reordering CMakeLists.txt
+
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
@ver 5.05.00.00 to 5.05.26.99
@pn mariadb
@@ -1558,10 +1568,6 @@
@patch 20002_all_mysql-va-list.patch
@ver 5.05.00.00 to 5.05.99.99
@pn mysql
-@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
-
-@patch 20002_all_mysql-va-list.patch
-@ver 5.05.00.00 to 5.05.99.99
@pn percona-server
@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
@@ -1645,6 +1651,12 @@
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
+@patch 20006_all_cmake_elib-mysql-cluster-5.6.22.patch
+@ver 7.03.08.00 to 7.03.99.99
+@pn mysql-cluster
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
@patch 20006_all_cmake_elib-percona-5.5.35.patch
@ver 5.05.35.00 to 5.05.35.99
@pn percona-server
@@ -1744,12 +1756,22 @@
@pn percona-server
@@ Remove -Werror from USE="debug" builds
+@patch 20007_all_cmake-debug-werror-5.6.22.patch
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Remove -Werror from USE="debug" builds
+
@patch 20008_all_mysql-tzinfo-symlink.patch
@ver 5.05.36.00 to 5.99.99.99
@pn mysql
@pn percona-server
@@ Backport tzinfo symlink fix from MariaDB bug 491176
+@patch 20008_all_mysql-tzinfo-symlink.patch
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Backport tzinfo symlink fix from MariaDB bug 491176
+
@patch 20009_all_mariadb_myodbc_symbol_fix.patch
@ver 5.05.37.00 to 5.05.37.99
@pn mariadb
@@ -1769,6 +1791,11 @@
@pn percona-server
@@ Export missing symbols
+@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Export missing symbols
+
@patch 20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
@ver 5.05.38.00 to 10.99.99.99
@pn mariadb
@@ -1833,3 +1860,10 @@
@@ Bug 537872
@@ Upstream bug 75622
+@patch 20017_all_mysql-openssl-cmake-detection.patch
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Fix detection of OpenSSL 1.0.2
+@@ Bug 537872
+@@ Upstream bug 75622
+
diff --git a/20006_all_cmake_elib-mysql-cluster-5.6.22.patch b/20006_all_cmake_elib-mysql-cluster-5.6.22.patch
new file mode 100644
index 0000000..bc48b9b
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-cluster-5.6.22.patch
@@ -0,0 +1,198 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,8 +135,8 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(MSVC AND NOT DISABLE_SHARED)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-02-10 17:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-02-10 17:50 UTC (permalink / raw
To: gentoo-commits
commit: d981fbf98cc870f30fb26f38ae2e96bedffcf965
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 10 17:47:47 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Feb 10 17:47:47 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=d981fbf9
Adjust patches for mysql-cluster-7.2.x
---
00000_index.txt | 35 +++-
20006_all_cmake_elib-mysql-cluster-5.5.37.patch | 221 ++++++++++++++++++++++++
2 files changed, 254 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 6d761f3..f1c2852 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -259,6 +259,11 @@
@pn mysql
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+@patch 01050_all_mysql_config_cleanup-5.5.patch
+@ver 7.02.00.00 to 7.02.99.99
+@pn mysql-cluster
+@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
+
@patch 01050_all_mysql_config_cleanup-5.6.patch
@ver 5.06.00.00 to 5.06.99.99
@pn mysql
@@ -346,6 +351,11 @@
@@ Take libmysqld to be a proper shared library.
@patch 02040_all_embedded-library-shared-5.5.10.patch
+@ver 7.02.01.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Take libmysqld to be a proper shared library.
+
+@patch 02040_all_embedded-library-shared-5.5.10.patch
@ver 5.05.10.00 to 5.07.99.99
@pn percona-server
@@ Take libmysqld to be a proper shared library.
@@ -1516,6 +1526,11 @@
@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
+@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
+@ver 7.02.19.00 to 7.02.99.99
+@pn mysql-cluster
+@@ Fix the minimal build by reordering CMakeLists.txt
+
@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.patch
@ver 5.06.17.00 to 5.06.19.99
@pn mysql
@@ -1571,6 +1586,11 @@
@pn percona-server
@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
+@patch 20002_all_mysql-va-list.patch
+@ver 7.02.01.00 to 7.02.99.99
+@pn mysql-cluster
+@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
+
@patch 20002_all_mysql-va-list-5.6.patch
@ver 5.06.00.00 to 5.06.12.99
@pn mysql
@@ -1639,6 +1659,12 @@
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
+@patch 20006_all_cmake_elib-mysql-cluster-5.5.37.patch
+@ver 7.02.16.00 to 7.02.99.99
+@pn mysql-cluster
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
@patch 20006_all_cmake_elib-mysql-5.6.15.patch
@ver 5.06.15.00 to 5.06.21.99
@pn mysql
@@ -1757,7 +1783,7 @@
@@ Remove -Werror from USE="debug" builds
@patch 20007_all_cmake-debug-werror-5.6.22.patch
-@ver 7.03.00.00 to 7.99.99.99
+@ver 7.02.19.00 to 7.99.99.99
@pn mysql-cluster
@@ Remove -Werror from USE="debug" builds
@@ -1768,7 +1794,7 @@
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@patch 20008_all_mysql-tzinfo-symlink.patch
-@ver 7.03.00.00 to 7.99.99.99
+@ver 7.02.16.00 to 7.99.99.99
@pn mysql-cluster
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@@ -1785,6 +1811,11 @@
@pn percona-server
@@ Export missing symbols
+@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
+@ver 7.02.18.00 to 7.02.99.99
+@pn mysql-cluster
+@@ Export missing symbols
+
@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
@ver 5.06.00.00 to 5.07.99.99
@pn mysql
diff --git a/20006_all_cmake_elib-mysql-cluster-5.5.37.patch b/20006_all_cmake_elib-mysql-cluster-5.5.37.patch
new file mode 100644
index 0000000..7951588
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-cluster-5.5.37.patch
@@ -0,0 +1,221 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -163,9 +163,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -196,9 +196,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -149,12 +149,14 @@
+ # to handle. So, for now, we just disable it for those builds.
+ #
+ IF(UNIX AND NOT INSTALL_LAYOUT MATCHES "SVR4")
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- mysql-old/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-02-10 17:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-02-10 17:50 UTC (permalink / raw
To: gentoo-commits
commit: a0d3d0ac6c9c8b10f715c5ae5a0e7d342392c64a
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Feb 10 17:50:27 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Feb 10 17:50:27 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=a0d3d0ac
Fix multilib compile of libndbclient due to missing WITHOUT_SERVER check
---
00000_index.txt | 5 +++++
30000_all_mysql-cluster-multilib-property.patch | 14 ++++++++++++++
2 files changed, 19 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index f1c2852..11046cb 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1898,3 +1898,8 @@
@@ Bug 537872
@@ Upstream bug 75622
+@patch 30000_all_mysql-cluster-multilib-property.patch
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
+@@ Fix property added to something not built with WITHOUT_SERVER
+
diff --git a/30000_all_mysql-cluster-multilib-property.patch b/30000_all_mysql-cluster-multilib-property.patch
new file mode 100644
index 0000000..c4cc2d4
--- /dev/null
+++ b/30000_all_mysql-cluster-multilib-property.patch
@@ -0,0 +1,14 @@
+diff -aurN a/storage/ndb/CMakeLists.txt b/storage/ndb/CMakeLists.txt
+--- a/storage/ndb/CMakeLists.txt 2015-02-10 12:21:44.502545905 -0500
++++ b/storage/ndb/CMakeLists.txt 2015-02-10 12:30:53.985233768 -0500
+@@ -145,7 +145,9 @@
+ # Add HAVE_NDB_BINLOG to the list of compile definitions used when compiling
+ # the ndbcluster plugin library(NOTE! there is also ndbcluster_embedded which
+ # is compiled without this define)
+-NDB_ADD_TARGET_PROPERTY(ndbcluster COMPILE_DEFINITIONS "HAVE_NDB_BINLOG")
++IF(NOT WITHOUT_SERVER)
++ NDB_ADD_TARGET_PROPERTY(ndbcluster COMPILE_DEFINITIONS "HAVE_NDB_BINLOG")
++ENDIF()
+
+ IF(CMAKE_SIZEOF_VOID_P EQUAL 4)
+ MESSAGE(STATUS "Building NDB 32-bit")
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-03-04 3:35 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-03-04 3:35 UTC (permalink / raw
To: gentoo-commits
commit: be6b12df249e2cac67adb14072ab45a3d40f79d9
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed Mar 4 03:10:27 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Mar 4 03:10:27 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=be6b12df
Update index for new 10.1 beta including a patch
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 11046cb..3e1287d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1867,7 +1867,7 @@
@@ Gentoo bug 525192 MDEV-6863
@patch 20014_all_mariadb-innodb-compression.patch
-@ver 10.01.01.00 to 10.99.99.99
+@ver 10.01.01.00 to 10.01.02.99
@pn mariadb
@@ Remove magic dependencies on lz4 and lzo
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-03-04 3:35 git@oystercatcher mirror+tproxy
0 siblings, 0 replies; 300+ messages in thread
From: git@oystercatcher mirror+tproxy @ 2015-03-04 3:35 UTC (permalink / raw
To: gentoo-commits
commit: be6b12df249e2cac67adb14072ab45a3d40f79d9
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Wed Mar 4 03:10:27 2015 +0000
Commit: git@oystercatcher mirror+tproxy <git <AT> oystercatcher <DOT> gentoo <DOT> org>
CommitDate: Wed Mar 4 03:10:27 2015 +0000
URL: http://sources.gentoo.org/gitweb/?p=proj/mysql-extras.git;a=commit;h=be6b12df
Update index for new 10.1 beta including a patch
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 11046cb..3e1287d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1867,7 +1867,7 @@
@@ Gentoo bug 525192 MDEV-6863
@patch 20014_all_mariadb-innodb-compression.patch
-@ver 10.01.01.00 to 10.99.99.99
+@ver 10.01.01.00 to 10.01.02.99
@pn mariadb
@@ Remove magic dependencies on lz4 and lzo
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-03-10 20:43 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-03-10 20:43 UTC (permalink / raw
To: gentoo-commits
commit: 5f9a1f024556d0b98739e37e27c07c7fb5db7f0a
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Mar 10 20:42:50 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Mar 10 20:43:17 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=5f9a1f02
Respin 2 patches for mysql-5.7.6_alpha
00000_index.txt | 16 +++-
20008_all_mysql-tzinfo-symlink-5.7.6.patch | 101 ++++++++++++++++++++++++++
20009_all_mysql_myodbc_symbol_fix-5.7.6.patch | 12 +++
3 files changed, 127 insertions(+), 2 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3e1287d..1f4e3a1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1788,7 +1788,13 @@
@@ Remove -Werror from USE="debug" builds
@patch 20008_all_mysql-tzinfo-symlink.patch
-@ver 5.05.36.00 to 5.99.99.99
+@ver 5.05.36.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ Backport tzinfo symlink fix from MariaDB bug 491176
+
+@patch 20008_all_mysql-tzinfo-symlink-5.7.6.patch
+@ver 5.07.00.00 to 5.99.99.99
@pn mysql
@pn percona-server
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@@ -1817,7 +1823,13 @@
@@ Export missing symbols
@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
-@ver 5.06.00.00 to 5.07.99.99
+@ver 5.06.00.00 to 5.06.99.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mysql_myodbc_symbol_fix-5.7.6.patch
+@ver 5.07.00.00 to 5.99.99.99
@pn mysql
@pn percona-server
@@ Export missing symbols
diff --git a/20008_all_mysql-tzinfo-symlink-5.7.6.patch b/20008_all_mysql-tzinfo-symlink-5.7.6.patch
new file mode 100644
index 0000000..1c1ce35
--- /dev/null
+++ b/20008_all_mysql-tzinfo-symlink-5.7.6.patch
@@ -0,0 +1,101 @@
+--- a/sql/tztime.cc 2015-02-26 09:51:45.000000000 -0500
++++ b/sql/tztime.cc 2015-03-10 11:15:19.434545224 -0400
+@@ -2504,7 +2504,7 @@
+
+ */
+ my_bool
+-scan_tz_dir(char * name_end)
++scan_tz_dir(char * name_end, uint symlink_recursion_level)
+ {
+ MY_DIR *cur_dir;
+ char *name_end_tmp;
+@@ -2524,7 +2524,32 @@
+
+ if (MY_S_ISDIR(cur_dir->dir_entry[i].mystat->st_mode))
+ {
+- if (scan_tz_dir(name_end_tmp))
++ my_bool is_symlink;
++ if ((is_symlink= my_is_symlink(fullname)) &&
++ symlink_recursion_level > 0)
++ {
++ /*
++ The timezone definition data in some Linux distributions
++ (e.g. the "timezone-data-2013f" package in Gentoo)
++ may have synlimks like:
++ /usr/share/zoneinfo/posix/ -> /usr/share/zoneinfo/,
++ so the same timezone files are available under two names
++ (e.g. "CET" and "posix/CET").
++
++ We allow one level of symlink recursion for backward
++ compatibility with earlier timezone data packages that have
++ duplicate copies of the same timezone files inside the root
++ directory and the "posix" subdirectory (instead of symlinking).
++ This makes "posix/CET" still available, but helps to avoid
++ following such symlinks infinitely:
++ /usr/share/zoneinfo/posix/posix/posix/.../posix/
++ */
++ fflush(stdout);
++ fprintf(stderr, "Warning: Skipping directory '%s': "
++ "to avoid infinite symlink recursion.\n", fullname);
++ continue;
++ }
++ if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink))
+ {
+ my_dirend(cur_dir);
+ return 1;
+@@ -2536,14 +2561,20 @@
+ if (!tz_load(fullname, &tz_info, &tz_storage))
+ print_tz_as_sql(root_name_end + 1, &tz_info);
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr,
+ "Warning: Unable to load '%s' as time zone. Skipping it.\n",
+ fullname);
++ }
+ free_root(&tz_storage, MYF(0));
+ }
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr, "Warning: '%s' is not regular file or directory\n",
+ fullname);
++ }
+ }
+ }
+
+@@ -2577,8 +2608,9 @@
+ printf("TRUNCATE TABLE time_zone_transition_type;\n");
+
+ printf("START TRANSACTION;\n");
+- if (scan_tz_dir(root_name_end))
++ if (scan_tz_dir(root_name_end, 0))
+ {
++ fflush(stdout);
+ fprintf(stderr, "There were fatal errors during processing "
+ "of zoneinfo directory\n");
+ return 1;
+@@ -2593,6 +2625,7 @@
+ {
+ if (tz_load(argv[2], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2602,6 +2635,7 @@
+ {
+ if (tz_load(argv[1], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2613,6 +2647,7 @@
+ free_root(&tz_storage, MYF(0));
+ }
+
++ my_end(0);
+ return 0;
+ }
+
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.7.6.patch b/20009_all_mysql_myodbc_symbol_fix-5.7.6.patch
new file mode 100644
index 0000000..a4a5f45
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.7.6.patch
@@ -0,0 +1,12 @@
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-02-26 09:51:43.000000000 -0500
++++ b/libmysql/CMakeLists.txt 2015-03-10 10:47:52.759629219 -0400
+@@ -155,6 +155,8 @@
+ # will have a FR to replace this for decent name/functionality and document it.
+ my_load_defaults
+ handle_options
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Undocumented Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-04-10 18:53 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-04-10 18:53 UTC (permalink / raw
To: gentoo-commits
commit: 714611538698605df492f7789276d5be081d4da3
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Apr 10 18:52:47 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Apr 10 18:52:47 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=71461153
Update patch index max for OpenSSL version detection
00000_index.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1f4e3a1..288889f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1896,7 +1896,8 @@
@@ Also fix critical replication bug discovered shortly after release MDEV-7237
@patch 20017_all_mysql-openssl-cmake-detection.patch
-@ver 5.06.00.00 to 5.07.99.99
+@ver 5.06.00.00 to 5.06.23.99
+@ver 5.07.00.00 to 5.07.06.99
@pn mysql
@pn percona-server
@@ Fix detection of OpenSSL 1.0.2
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-05-09 18:16 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-05-09 18:16 UTC (permalink / raw
To: gentoo-commits
commit: 34b51a42aacb35757a8d67f7f3f85085b6625aee
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sat May 9 18:15:58 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat May 9 18:15:58 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=34b51a42
Apply important fix to mariadb-5.5.43 for MDEV-8115
00000_index.txt | 6 +++
200018_all_mariadb-upgrade-crash-5.5.43.patch | 61 +++++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 288889f..a330532 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1916,3 +1916,9 @@
@pn mysql-cluster
@@ Fix property added to something not built with WITHOUT_SERVER
+@patch 200018_all_mariadb-upgrade-crash-5.5.43.patch
+@ver 5.05.43.00 to 5.05.43.99
+@pn mariadb
+@pn mariadb-galera
+@@ Fix crash of mysql_upgrade and the REPAIR VIEW command
+@@ Upstream MDEV-8115
diff --git a/200018_all_mariadb-upgrade-crash-5.5.43.patch b/200018_all_mariadb-upgrade-crash-5.5.43.patch
new file mode 100644
index 0000000..6ada096
--- /dev/null
+++ b/200018_all_mariadb-upgrade-crash-5.5.43.patch
@@ -0,0 +1,61 @@
+From 0014bdc7eef141dcd66930e853242b3be4960831 Mon Sep 17 00:00:00 2001
+From: Sergei Golubchik <serg@mariadb.org>
+Date: Thu, 7 May 2015 22:18:34 +0200
+Subject: [PATCH] MDEV-8115 mysql_upgrade crashes the server with REPAIR VIEW
+
+on REPAIR don't do table-specific stuff for views
+(because even if the view has a temp table opened for it,
+it's not opened all the way down the engine. In particular,
+Aria crashes in maria_status() because MARIA_HA* info - that is
+table->table->file->file - is NULL)
+---
+ mysql-test/r/repair.result | 7 +++++++
+ mysql-test/t/repair.test | 9 +++++++++
+ sql/sql_admin.cc | 2 +-
+ 3 files changed, 17 insertions(+), 1 deletion(-)
+
+diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result
+index 52ae9c3..51c3374 100644
+--- a/mysql-test/r/repair.result
++++ b/mysql-test/r/repair.result
+@@ -207,3 +207,10 @@ check table t1;
+ Table Op Msg_type Msg_text
+ test.t1 check status OK
+ drop table t1;
++create table t1 (a blob);
++create view v1 as select * from t1;
++repair view v1;
++Table Op Msg_type Msg_text
++test.v1 repair status OK
++drop view v1;
++drop table t1;
+diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test
+index 337b73f..f625965 100644
+--- a/mysql-test/t/repair.test
++++ b/mysql-test/t/repair.test
+@@ -208,3 +208,12 @@ repair table t1 use_frm;
+ select count(*) from t1;
+ check table t1;
+ drop table t1;
++
++#
++# MDEV-8115 mysql_upgrade crashes the server with REPAIR VIEW
++#
++create table t1 (a blob);
++create view v1 as select * from t1;
++repair view v1;
++drop view v1;
++drop table t1;
+diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
+index 44057b6..9827c67 100644
+--- a/sql/sql_admin.cc
++++ b/sql/sql_admin.cc
+@@ -901,7 +901,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
+ break;
+ }
+ }
+- if (table->table)
++ if (table->table && !table->view)
+ {
+ if (table->table->s->tmp_table)
+ {
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-07-10 19:09 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-07-10 19:09 UTC (permalink / raw
To: gentoo-commits
commit: 08efa23c59b97d725eba2543356e8010a83aef15
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 10 19:11:45 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Jul 10 19:11:45 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=08efa23c
Update index for ssl version detection patch on dev-db/mysql-cluster
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index a330532..d322641 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1905,7 +1905,7 @@
@@ Upstream bug 75622
@patch 20017_all_mysql-openssl-cmake-detection.patch
-@ver 7.03.00.00 to 7.99.99.99
+@ver 7.03.00.00 to 7.03.08.99
@pn mysql-cluster
@@ Fix detection of OpenSSL 1.0.2
@@ Bug 537872
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-07-17 17:04 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-07-17 17:04 UTC (permalink / raw
To: gentoo-commits
commit: 5b0cd9168dd9c8f1171d4c228c7b3f0965b37554
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Jul 17 17:07:01 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Jul 17 17:07:01 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=5b0cd916
Add patches to split server, client library and tools
00000_index.txt | 20 ++++
..._mariadb-10.0.20-without-clientlibs-tools.patch | 117 +++++++++++++++++++
...b-galera-10.0.20-without-clientlibs-tools.patch | 120 ++++++++++++++++++++
...all_mysql-5.6.25-without-clientlibs-tools.patch | 125 +++++++++++++++++++++
...na-server-5.6.25-without-clientlibs-tools.patch | 125 +++++++++++++++++++++
5 files changed, 507 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index d322641..64dbfb3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1922,3 +1922,23 @@
@pn mariadb-galera
@@ Fix crash of mysql_upgrade and the REPAIR VIEW command
@@ Upstream MDEV-8115
+
+@patch 20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
+@ver 10.00.20.00 to 10.00.99.99
+@pn mariadb
+@@ Split building of client libraries, server and client tools
+
+@patch 20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
+@ver 10.00.20.00 to 10.00.99.99
+@pn mariadb-galera
+@@ Split building of client libraries, server and client tools
+
+@patch 20018_all_mysql-5.6.25-without-clientlibs-tools.patch
+@ver 5.06.25.00 to 5.06.99.99
+@pn mysql
+@@ Split building of client libraries, server and client tools
+
+@patch 20018_all_percona-server-5.6.25-without-clientlibs-tools.patch
+@ver 5.06.25.00 to 5.06.99.99
+@pn percona-server
+@@ Split building of client libraries, server and client tools
diff --git a/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
new file mode 100644
index 0000000..7b759f3
--- /dev/null
+++ b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
@@ -0,0 +1,117 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,24 +392,35 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(support-files)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,12 +54,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
diff --git a/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch b/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
new file mode 100644
index 0000000..85e9786
--- /dev/null
+++ b/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
@@ -0,0 +1,120 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,27 +392,38 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
+ IF(WITH_WSREP)
+ ADD_SUBDIRECTORY(wsrep)
+ ENDIF()
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(support-files)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,12 +54,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
diff --git a/20018_all_mysql-5.6.25-without-clientlibs-tools.patch b/20018_all_mysql-5.6.25-without-clientlibs-tools.patch
new file mode 100644
index 0000000..35e60de
--- /dev/null
+++ b/20018_all_mysql-5.6.25-without-clientlibs-tools.patch
@@ -0,0 +1,125 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
++++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
+@@ -405,8 +405,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+
+@@ -436,7 +434,10 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -462,7 +463,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -470,11 +470,20 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -59,15 +59,16 @@
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+-
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+ TARGET_LINK_LIBRARIES(resolveip mysys mysys_ssl)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
++++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
+@@ -217,14 +217,14 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(mysqlclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
++++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
+@@ -347,7 +347,6 @@
+ SET(mysql_config_COMPONENT COMPONENT Development)
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_zap
+@@ -360,6 +359,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
diff --git a/20018_all_percona-server-5.6.25-without-clientlibs-tools.patch b/20018_all_percona-server-5.6.25-without-clientlibs-tools.patch
new file mode 100644
index 0000000..d6d21ad
--- /dev/null
+++ b/20018_all_percona-server-5.6.25-without-clientlibs-tools.patch
@@ -0,0 +1,125 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
++++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
+@@ -405,8 +405,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+
+@@ -436,7 +434,10 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -462,7 +463,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -470,11 +470,20 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -59,15 +59,16 @@
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+-
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+ TARGET_LINK_LIBRARIES(resolveip mysys mysys_ssl)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
++++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
+@@ -217,14 +217,14 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(perconaserverclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
++++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
+@@ -347,7 +347,6 @@
+ SET(mysql_config_COMPONENT COMPONENT Development)
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_zap
+@@ -360,6 +359,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-07-29 18:46 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-07-29 18:46 UTC (permalink / raw
To: gentoo-commits
commit: 15411faa29239bfb13a6f6760afd331663d4899e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 29 18:49:20 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jul 29 18:49:20 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=15411faa
Fix deprecated perl array defined syntax for test suite in 5.5
00000_index.txt | 6 ++++++
20019_all_mysql-5.5-mtr-perl-deprecation.patch | 24 ++++++++++++++++++++++++
2 files changed, 30 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 64dbfb3..ac9894a 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1942,3 +1942,9 @@
@ver 5.06.25.00 to 5.06.99.99
@pn percona-server
@@ Split building of client libraries, server and client tools
+
+@patch 20019_all_mysql-5.5-mtr-perl-deprecation.patch
+@ver 5.05.45.00 to 5.05.99.99
+@pn mysql
+@@ Fix deprecated perl array defined syntax on mtr test script
+@@ Ported forward from mysql 5.6; Oracle bug 18145121
diff --git a/20019_all_mysql-5.5-mtr-perl-deprecation.patch b/20019_all_mysql-5.5-mtr-perl-deprecation.patch
new file mode 100644
index 0000000..de8434c
--- /dev/null
+++ b/20019_all_mysql-5.5-mtr-perl-deprecation.patch
@@ -0,0 +1,24 @@
+diff -aurN a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
+--- a/mysql-test/lib/mtr_cases.pm 2015-06-25 09:44:36.000000000 -0400
++++ b/mysql-test/lib/mtr_cases.pm 2015-07-29 14:44:05.964091000 -0400
+@@ -336,7 +336,7 @@
+ # Build a hash of disabled testcases for this suite
+ # ----------------------------------------------------------------------
+ my %disabled;
+- my @disabled_collection= @{$opt_skip_test_list} if defined @{$opt_skip_test_list};
++ my @disabled_collection= @{$opt_skip_test_list} if $opt_skip_test_list;
+ unshift (@disabled_collection, "$testdir/disabled.def");
+ for my $skip (@disabled_collection)
+ {
+diff -aurN a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
+--- a/mysql-test/mysql-test-run.pl 2015-06-25 09:44:36.000000000 -0400
++++ b/mysql-test/mysql-test-run.pl 2015-07-29 14:34:54.796091000 -0400
+@@ -490,7 +490,7 @@
+ }
+ }
+
+- if ( not defined @$completed ) {
++ if ( not @$completed ) {
+ mtr_error("Test suite aborted");
+ }
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-08-05 16:09 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-08-05 16:09 UTC (permalink / raw
To: gentoo-commits
commit: 1f3c6320b6bc23ca9b54bf81f9add0ae42e2e676
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 5 16:12:49 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Aug 5 16:12:49 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1f3c6320
Respin myodbc patch for mysql-5.7.8
00000_index.txt | 6 ++++++
20009_all_mysql_myodbc_symbol_fix-5.7.8.patch | 13 +++++++++++++
2 files changed, 19 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index ac9894a..6c3147d 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1829,6 +1829,12 @@
@@ Export missing symbols
@patch 20009_all_mysql_myodbc_symbol_fix-5.7.6.patch
+@ver 5.07.00.00 to 5.07.07.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mysql_myodbc_symbol_fix-5.7.8.patch
@ver 5.07.00.00 to 5.99.99.99
@pn mysql
@pn percona-server
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.7.8.patch b/20009_all_mysql_myodbc_symbol_fix-5.7.8.patch
new file mode 100644
index 0000000..a4be6a5
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.7.8.patch
@@ -0,0 +1,13 @@
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-02-26 09:51:43.000000000 -0500
++++ b/libmysql/CMakeLists.txt 2015-03-10 10:47:52.759629219 -0400
+@@ -155,7 +155,9 @@
+ # will have a FR to replace this for decent name/functionality and document it.
+ my_load_defaults
+ handle_options
+ mysql_get_parameters
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Undocumented Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-09-11 15:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-09-11 15:05 UTC (permalink / raw
To: gentoo-commits
commit: c1d63d61deb5d6e4ca2bab1e23168eec925ee52e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Sep 11 15:09:51 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Sep 11 15:09:51 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c1d63d61
Respin clientlibs patch for MariaDB 10.1
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 5 +
...l_mariadb-10.1.7-without-clientlibs-tools.patch | 115 +++++++++++++++++++++
2 files changed, 120 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 6c3147d..12049e8 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1934,6 +1934,11 @@
@pn mariadb
@@ Split building of client libraries, server and client tools
+@patch 20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
+@ver 10.01.07.00 to 10.01.99.99
+@pn mariadb
+@@ Split building of client libraries, server and client tools
+
@patch 20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
@ver 10.00.20.00 to 10.00.99.99
@pn mariadb-galera
diff --git a/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
new file mode 100644
index 0000000..702b0cb
--- /dev/null
+++ b/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
@@ -0,0 +1,115 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,22 +392,33 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,12 +54,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-10-19 17:25 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-10-19 17:25 UTC (permalink / raw
To: gentoo-commits
commit: 2dfb539af77753167996ef3d806896b6198315b5
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 19 17:14:19 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Oct 19 17:14:19 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=2dfb539a
Reroll 20006_all_cmake_elib patch for MariaDB 10.1.8
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 8 +-
20006_all_cmake_elib-mariadb-10.1.8.patch | 187 ++++++++++++++++++++++++++++++
2 files changed, 194 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 12049e8..49ec593 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1752,7 +1752,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-10.1.2.patch
-@ver 10.01.02.00 to 10.99.99.99
+@ver 10.01.02.00 to 10.01.07.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-10.1.8.patch
+@ver 10.01.08.00 to 10.99.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mariadb-10.1.8.patch b/20006_all_cmake_elib-mariadb-10.1.8.patch
new file mode 100644
index 0000000..2b5c0d9
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.1.8.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR
+ SYSTEMD_UNIT)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Development OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT Server)
++ COMPONENT Server OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-11-05 20:51 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-11-05 20:51 UTC (permalink / raw
To: gentoo-commits
commit: 222cedbc7ba9102c5e2b480ed3ef6d890d8a9f50
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Nov 5 20:50:57 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Nov 5 20:50:57 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=222cedbc
Add events_1 test patch wrt bug 564968
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 8 ++++++++
20020_all_mysql-5.6-events_1-bug-78899.patch | 24 ++++++++++++++++++++++++
2 files changed, 32 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 49ec593..436dc69 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -1965,3 +1965,11 @@
@pn mysql
@@ Fix deprecated perl array defined syntax on mtr test script
@@ Ported forward from mysql 5.6; Oracle bug 18145121
+
+@patch 20020_all_mysql-5.6-events_1-bug-78899.patch
+@ver 5.06.00.00 to 5.06.27.99
+@pn mysql
+@pn percona-server
+@@ Fix events_1 test for October 2015
+@@ Patch backported from mariadb
+@@ Bug 564968 Upstream bug 78899
diff --git a/20020_all_mysql-5.6-events_1-bug-78899.patch b/20020_all_mysql-5.6-events_1-bug-78899.patch
new file mode 100644
index 0000000..5fe4e3e
--- /dev/null
+++ b/20020_all_mysql-5.6-events_1-bug-78899.patch
@@ -0,0 +1,24 @@
+diff -rupN old/mysql/mysql-test/r/events_1.result new/mysql/mysql-test/r/events_1.result
+--- old/mysql/mysql-test/r/events_1.result 2015-09-14 17:49:16.000000000 +0200
++++ new/mysql/mysql-test/r/events_1.result 2015-10-29 20:53:40.748451431 +0100
+@@ -114,7 +114,7 @@ create table t_event3 (a int, b float);
+ drop event if exists event3;
+ Warnings:
+ Note 1305 Event event3 does not exist
+-create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
++create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
+ select count(*) from t_event3;
+ count(*)
+ 0
+diff -rupN old/mysql/mysql-test/t/events_1.test new/mysql/mysql-test/t/events_1.test
+--- old/mysql/mysql-test/t/events_1.test 2015-09-14 17:49:16.000000000 +0200
++++ new/mysql/mysql-test/t/events_1.test 2015-10-29 20:54:38.959698756 +0100
+@@ -125,7 +125,7 @@ drop event existant;
+
+ create table t_event3 (a int, b float);
+ drop event if exists event3;
+-create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20151010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
++create event event3 on schedule every 50 + 10 minute starts date_add("20100101", interval 5 minute) ends date_add("20251010", interval 5 day) comment "portokala_comment" DO insert into t_event3 values (unix_timestamp(), rand());
+ let $wait_condition=SELECT count(*)=0 from t_event3;
+ --source include/wait_condition.inc
+ select count(*) from t_event3;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-11-17 20:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-11-17 20:40 UTC (permalink / raw
To: gentoo-commits
commit: 3890257ea14a657bcd536d348369ec26f8313cc2
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 17 20:40:21 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 17 20:40:21 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3890257e
Add patches to index for mysql-cluster releases
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index c575c84..54f3e9f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -879,6 +879,12 @@
@@ Fix deprecated perl array defined syntax on mtr test script
@@ Ported forward from mysql 5.6; Oracle bug 18145121
+@patch 20019_all_mysql-5.5-mtr-perl-deprecation.patch
+@ver 7.02.00.00 to 7.02.99.99
+@pn mysql-cluster
+@@ Fix deprecated perl array defined syntax on mtr test script
+@@ Ported forward from mysql 5.6; Oracle bug 18145121
+
@patch 20020_all_mysql-5.6-events_1-bug-78899.patch
@ver 5.06.00.00 to 5.06.27.99
@pn mysql
@@ -886,3 +892,11 @@
@@ Fix events_1 test for October 2015
@@ Patch backported from mariadb
@@ Bug 564968 Upstream bug 78899
+
+@patch 20020_all_mysql-5.6-events_1-bug-78899.patch
+@ver 7.02.00.00 to 7.02.99.99
+@ver 7.03.00.00 to 7.03.12.99
+@pn mysql-cluster
+@@ Fix events_1 test for October 2015
+@@ Patch backported from mariadb
+@@ Bug 564968 Upstream bug 78899
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-11-23 16:43 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-11-23 16:43 UTC (permalink / raw
To: gentoo-commits
commit: 572718ce895485b442d048b6c310b1bb2e4465f6
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Nov 23 16:43:10 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Nov 23 16:43:10 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=572718ce
Respin TokuDB flag patch for 10.1.9
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 8 +++++-
20004_all_mariadb-filter-tokudb-flags-10.1.9.patch | 31 ++++++++++++++++++++++
2 files changed, 38 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 54f3e9f..dc126aa 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -532,7 +532,13 @@
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
@patch 20004_all_mariadb-filter-tokudb-flags-10.0.7.patch
-@ver 10.00.07.00 to 10.99.99.99
+@ver 10.00.07.00 to 10.01.08.99
+@pn mariadb
+@pn mariadb-galera
+@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
+
+@patch 20004_all_mariadb-filter-tokudb-flags-10.1.9.patch
+@ver 10.01.09.00 to 10.99.99.99
@pn mariadb
@pn mariadb-galera
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
diff --git a/20004_all_mariadb-filter-tokudb-flags-10.1.9.patch b/20004_all_mariadb-filter-tokudb-flags-10.1.9.patch
new file mode 100644
index 0000000..5156aee
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags-10.1.9.patch
@@ -0,0 +1,31 @@
+diff -aurN a/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- a/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ b/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -124,12 +124,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+@@ -158,8 +156,8 @@
+ endif ()
+
+ ## always want these
+-set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}")
+-set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}")
++set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
++set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
+
+ ## need to set -stdlib=libc++ to get real c++11 support on darwin
+ if (APPLE)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2015-12-22 21:38 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2015-12-22 21:38 UTC (permalink / raw
To: gentoo-commits
commit: 7d3a382385c3d95c4edb8a4736b2f01eaac156d6
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 22 21:38:00 2015 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Dec 22 21:38:00 2015 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7d3a3823
Respin tokudb CFLAGS patch for new MariaDB versions
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 17 +++++++--
...4_all_mariadb-filter-tokudb-flags-10.0.23.patch | 42 ++++++++++++++++++++++
...4_all_mariadb-filter-tokudb-flags-10.1.10.patch | 31 ++++++++++++++++
3 files changed, 87 insertions(+), 3 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index dc126aa..6b8eea9 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -532,17 +532,28 @@
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
@patch 20004_all_mariadb-filter-tokudb-flags-10.0.7.patch
-@ver 10.00.07.00 to 10.01.08.99
+@ver 10.00.07.00 to 10.00.22.99
+@ver 10.01.00.00 to 10.01.08.99
@pn mariadb
@pn mariadb-galera
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
-@patch 20004_all_mariadb-filter-tokudb-flags-10.1.9.patch
-@ver 10.01.09.00 to 10.99.99.99
+@patch 20004_all_mariadb-filter-tokudb-flags-10.0.23.patch
+@ver 10.00.23.00 to 10.00.99.99
@pn mariadb
@pn mariadb-galera
@@ Filter out -flto -fuse-linker-plugin -g and -Werror for tokudb
+@patch 20004_all_mariadb-filter-tokudb-flags-10.1.9.patch
+@ver 10.01.09.00 to 10.01.09.99
+@pn mariadb
+@@ Filter out -g and -Werror for tokudb
+
+@patch 20004_all_mariadb-filter-tokudb-flags-10.1.10.patch
+@ver 10.01.10.00 to 10.01.99.99
+@pn mariadb
+@@ Filter out -g and -Werror for tokudb
+
@patch 20005_all_mysql-unittest-5.1.73.patch
@ver 5.01.73.00 to 5.01.99.99
@pn mysql
diff --git a/20004_all_mariadb-filter-tokudb-flags-10.0.23.patch b/20004_all_mariadb-filter-tokudb-flags-10.0.23.patch
new file mode 100644
index 0000000..cc11566
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags-10.0.23.patch
@@ -0,0 +1,42 @@
+--- a/storage/tokudb/CMakeLists.txt 2014-01-16 16:23:26.731243149 -0500
++++ b/storage/tokudb/CMakeLists.txt 2014-01-16 16:26:29.197327097 -0500
+@@ -58,8 +58,6 @@
+ SET(TOKUDB_SOURCES ha_tokudb.cc)
+ MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
+ LINK_LIBRARIES tokufractaltree_static tokuportability_static ${ZLIB_LIBRARY} stdc++)
+-SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
+-SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
+
+ SET(CPACK_RPM_server_PACKAGE_OBSOLETES
+ "${CPACK_RPM_server_PACKAGE_OBSOLETES} MariaDB-tokudb-engine < 10.0.5" PARENT_SCOPE)
+diff -aurN mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -136,12 +136,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+@@ -172,8 +170,8 @@
+ endif ()
+
+ ## always want these
+-set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}")
+-set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}")
++set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
++set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
+
+ ## need to set -stdlib=libc++ to get real c++11 support on darwin
+ if (APPLE)
diff --git a/20004_all_mariadb-filter-tokudb-flags-10.1.10.patch b/20004_all_mariadb-filter-tokudb-flags-10.1.10.patch
new file mode 100644
index 0000000..49f9b5b
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags-10.1.10.patch
@@ -0,0 +1,31 @@
+diff -aurN a/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -124,12 +124,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3 -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+@@ -158,8 +156,8 @@
+ endif ()
+
+ ## always want these
+-set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}")
+-set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}")
++set(CMAKE_C_FLAGS "-Wall ${CMAKE_C_FLAGS}")
++set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
+
+ ## need to set -stdlib=libc++ to get real c++11 support on darwin
+ if (APPLE)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-01-21 13:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-01-21 13:50 UTC (permalink / raw
To: gentoo-commits
commit: 433f76ad475f15f199f1c996d77b661c68cca47a
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jan 21 13:50:12 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jan 21 13:50:12 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=433f76ad
Respin patch for 5.7.10
00000_index.txt | 8 +++++++-
20009_all_mysql_myodbc_symbol_fix-5.7.10.patch | 12 ++++++++++++
2 files changed, 19 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 6b8eea9..6281247 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -771,7 +771,13 @@
@@ Export missing symbols
@patch 20009_all_mysql_myodbc_symbol_fix-5.7.8.patch
-@ver 5.07.00.00 to 5.99.99.99
+@ver 5.07.08.00 to 5.07.09.99
+@pn mysql
+@pn percona-server
+@@ Export missing symbols
+
+@patch 20009_all_mysql_myodbc_symbol_fix-5.7.10.patch
+@ver 5.07.10.00 to 5.07.99.99
@pn mysql
@pn percona-server
@@ Export missing symbols
diff --git a/20009_all_mysql_myodbc_symbol_fix-5.7.10.patch b/20009_all_mysql_myodbc_symbol_fix-5.7.10.patch
new file mode 100644
index 0000000..a4a5f45
--- /dev/null
+++ b/20009_all_mysql_myodbc_symbol_fix-5.7.10.patch
@@ -0,0 +1,12 @@
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-02-26 09:51:43.000000000 -0500
++++ b/libmysql/CMakeLists.txt 2015-03-10 10:47:52.759629219 -0400
+@@ -155,6 +155,8 @@
+ # will have a FR to replace this for decent name/functionality and document it.
+ my_load_defaults
+ handle_options
++dynstr_append_os_quoted
++strfill
+
+ CACHE INTERNAL "Undocumented Functions exported by client API"
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-01-31 1:46 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-01-31 1:46 UTC (permalink / raw
To: gentoo-commits
commit: 7e90d6b00bb0b1031f06c9d4c86d9c4a0c8cf566
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Jan 31 01:46:43 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jan 31 01:46:43 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7e90d6b0
Add patch to mariadb for the new gssapi/kerberos auth plugin MDEV-9494
00000_index.txt | 5 +++++
20021_all_mariadb-10.1.11-kerberos-MDEV-9494.patch | 22 ++++++++++++++++++++++
2 files changed, 27 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 6281247..106fc24 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -923,3 +923,8 @@
@@ Fix events_1 test for October 2015
@@ Patch backported from mariadb
@@ Bug 564968 Upstream bug 78899
+
+@patch 20021_all_mariadb-10.1.11-kerberos-MDEV-9494
+@ver 10.01.11.00 to 10.01.11.99
+@pn mariadb
+@@ Fix server gssapi plugin compile with heimdal
diff --git a/20021_all_mariadb-10.1.11-kerberos-MDEV-9494.patch b/20021_all_mariadb-10.1.11-kerberos-MDEV-9494.patch
new file mode 100644
index 0000000..dad69e3
--- /dev/null
+++ b/20021_all_mariadb-10.1.11-kerberos-MDEV-9494.patch
@@ -0,0 +1,22 @@
+From 3d794d0ee8e0a5a7dfbd3b7de056c0a3ccb9aa81 Mon Sep 17 00:00:00 2001
+From: Vladislav Vaintroub <wlad@mariadb.com>
+Date: Wed, 6 Jan 2016 09:15:19 +0100
+Subject: [PATCH] MDEV9494 Fix build for Heimdal Kerberos
+
+---
+ plugin/auth_gssapi/gssapi_server.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/plugin/auth_gssapi/gssapi_server.cc b/plugin/auth_gssapi/gssapi_server.cc
+index d325b2a..ed042a0 100644
+--- a/plugin/auth_gssapi/gssapi_server.cc
++++ b/plugin/auth_gssapi/gssapi_server.cc
+@@ -58,7 +58,7 @@ static char* get_default_principal_name()
+ }
+
+ /* Check for entry in keytab */
+- if (krb5_kt_read_service_key(context, NULL, principal, 0, 0, &key))
++ if (krb5_kt_read_service_key(context, NULL, principal, 0, (krb5_enctype)0, &key))
+ {
+ sql_print_warning("GSSAPI plugin : default principal '%s' not found in keytab", unparsed_name);
+ goto cleanup;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-01-31 1:57 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-01-31 1:57 UTC (permalink / raw
To: gentoo-commits
commit: e7f24d9133fe40f709538c712a9888a8d519be23
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Sun Jan 31 01:57:28 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jan 31 01:57:28 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e7f24d91
Fix index file name from previous commit
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 106fc24..1750a53 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -924,7 +924,7 @@
@@ Patch backported from mariadb
@@ Bug 564968 Upstream bug 78899
-@patch 20021_all_mariadb-10.1.11-kerberos-MDEV-9494
+@patch 20021_all_mariadb-10.1.11-kerberos-MDEV-9494.patch
@ver 10.01.11.00 to 10.01.11.99
@pn mariadb
@@ Fix server gssapi plugin compile with heimdal
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-02-12 2:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-02-12 2:26 UTC (permalink / raw
To: gentoo-commits
commit: 490d855c9b2e6a1d537e5d86b5a6cea0aedf69e5
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Fri Feb 12 02:26:07 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Feb 12 02:26:07 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=490d855c
Respin embedded library patch for mysql-5.6.29
00000_index.txt | 8 +-
20006_all_cmake_elib-mysql-5.6.29.patch | 205 ++++++++++++++++++++++++++++++++
2 files changed, 212 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 1750a53..8f25b34 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -602,7 +602,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.6.22.patch
-@ver 5.06.22.00 to 5.06.99.99
+@ver 5.06.22.00 to 5.06.28.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mysql-5.6.29.patch
+@ver 5.06.29.00 to 5.06.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mysql-5.6.29.patch b/20006_all_cmake_elib-mysql-5.6.29.patch
new file mode 100644
index 0000000..038f08b
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.6.29.patch
@@ -0,0 +1,205 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+ libs_r="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-02-12 2:33 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-02-12 2:33 UTC (permalink / raw
To: gentoo-commits
commit: b241546359a7dd72ad607be0480b456bac12bad8
Author: Brian Evans <grknight <AT> tuffmail <DOT> com>
AuthorDate: Fri Feb 12 02:33:05 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Feb 12 02:33:05 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=b2415463
Fix bad patch from previous commit
20006_all_cmake_elib-mysql-5.6.29.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/20006_all_cmake_elib-mysql-5.6.29.patch b/20006_all_cmake_elib-mysql-5.6.29.patch
index 038f08b..0adb0ca 100644
--- a/20006_all_cmake_elib-mysql-5.6.29.patch
+++ b/20006_all_cmake_elib-mysql-5.6.29.patch
@@ -194,10 +194,10 @@ diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
pkgincludedir='@pkgincludedir@'
if [ -f "$basedir/include/mysql/mysql.h" ]; then
pkgincludedir="$basedir/include/mysql"
-@@ -113,7 +117,7 @@
+@@ -116,7 +116,7 @@
libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
- libs_r="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+ libs_r="$libs_r @QUOTED_CMAKE_C_LINK_FLAGS@"
-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-03-07 18:49 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-03-07 18:49 UTC (permalink / raw
To: gentoo-commits
commit: 2a8823a6dbfe001096b44cc6c0dd5785836fd188
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 7 18:49:37 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 7 18:49:37 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=2a8823a6
Respin patch for percona 5.6.29
20006_all_cmake_elib-percona-5.6.29.patch | 206 ++++++++++++++++++++++++++++++
1 file changed, 206 insertions(+)
diff --git a/20006_all_cmake_elib-percona-5.6.29.patch b/20006_all_cmake_elib-percona-5.6.29.patch
new file mode 100644
index 0000000..d229e81
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.29.patch
@@ -0,0 +1,206 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -210,9 +215,11 @@
+ ENDIF()
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 23:19:05.544375123 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-25 09:10:46.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 23:21:36.030085686 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -113,7 +117,7 @@
+ libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+ libs_r="$libs_r @QUOTED_CMAKE_C_LINK_FLAGS@"
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-03-07 18:54 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-03-07 18:54 UTC (permalink / raw
To: gentoo-commits
commit: 0b5e37a7b3bc634340279c48828ef0ac79cd4c72
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 7 18:54:07 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 7 18:54:07 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=0b5e37a7
Fix patch to work with -p1
20008_all_mysql-tzinfo-symlink.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/20008_all_mysql-tzinfo-symlink.patch b/20008_all_mysql-tzinfo-symlink.patch
index 5b7a524..2c2316b 100644
--- a/20008_all_mysql-tzinfo-symlink.patch
+++ b/20008_all_mysql-tzinfo-symlink.patch
@@ -1,6 +1,6 @@
=== modified file 'sql/tztime.cc'
---- sql/tztime.cc 2013-05-07 11:05:09 +0000
-+++ sql/tztime.cc 2013-11-13 15:16:35 +0000
+--- a/sql/tztime.cc 2013-05-07 11:05:09 +0000
++++ b/sql/tztime.cc 2013-11-13 15:16:35 +0000
@@ -2494,7 +2494,7 @@
*/
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-04-27 17:32 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-04-27 17:32 UTC (permalink / raw
To: gentoo-commits
commit: 34aaa33ab5930e40f746ac7c75d9c1fe5026839e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 27 17:32:00 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Apr 27 17:32:00 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=34aaa33a
Respin 2 patches for MySQL 5.7
20001_all_fix-minimal-build-cmake-mysql-5.7.patch | 15 +++++++++++++++
20007_all_cmake-debug-werror-5.7.patch | 16 ++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.7.patch b/20001_all_fix-minimal-build-cmake-mysql-5.7.patch
new file mode 100644
index 0000000..bf21da4
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.7.patch
@@ -0,0 +1,15 @@
+diff -aurwN mysql.orig/CMakeLists.txt mysql/CMakeLists.txt
+--- a/CMakeLists.txt 2014-07-18 11:48:39.000000000 -0400
++++ b/CMakeLists.txt 2014-08-01 12:54:52.612732241 -0400
+@@ -626,10 +626,10 @@
+ # scripts/mysql_config depends on client and server targets loaded above.
+ # It is referenced by some of the directories below, so we insert it here.
+ ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
diff --git a/20007_all_cmake-debug-werror-5.7.patch b/20007_all_cmake-debug-werror-5.7.patch
new file mode 100644
index 0000000..4321399
--- /dev/null
+++ b/20007_all_cmake-debug-werror-5.7.patch
@@ -0,0 +1,16 @@
+diff -aurN a/cmake/maintainer.cmake b/cmake/maintainer.cmake
+--- a/cmake/maintainer.cmake 2014-11-21 00:39:51.000000000 -0500
++++ b/cmake/maintainer.cmake 2014-12-03 13:19:50.893380789 -0500
+@@ -30,12 +30,6 @@
+ "${MY_CXX_WARNING_FLAGS} -Wno-null-conversion -Wno-unused-private-field")
+ ENDIF()
+
+-# Turn on Werror (warning => error) when using maintainer mode.
+-IF(MYSQL_MAINTAINER_MODE)
+- SET(MY_C_WARNING_FLAGS "${MY_C_WARNING_FLAGS} -Werror")
+- SET(MY_CXX_WARNING_FLAGS "${MY_CXX_WARNING_FLAGS} -Werror")
+-ENDIF()
+-
+ # Set warning flags for GCC/Clang
+ IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${MY_C_WARNING_FLAGS}")
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-04-27 18:06 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-04-27 18:06 UTC (permalink / raw
To: gentoo-commits
commit: c6601b758d82903807230a8a643d702be94d139c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 27 18:05:53 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Apr 27 18:05:53 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c6601b75
Respin elib patch for MySQL 5.7
20006_all_cmake_elib-mysql-5.7.patch | 191 +++++++++++++++++++++++++++++++++++
1 file changed, 191 insertions(+)
diff --git a/20006_all_cmake_elib-mysql-5.7.patch b/20006_all_cmake_elib-mysql-5.7.patch
new file mode 100644
index 0000000..7672f79
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.7.patch
@@ -0,0 +1,191 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -456,8 +456,8 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST
+ SECURE_FILE_PRIV SECURE_FILE_PRIV_EMBEDDED MYSQLKEYRING)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_CONVENIENCE_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -116,7 +116,7 @@
+ # Create options
+ libs="-L$pkglibdir@RPATH_OPTION@"
+ libs="$libs -l@LIBMYSQL_OS_OUTPUT_NAME@ @CONFIG_CLIENT_LIBS@"
+-embedded_libs="-L$pkglibdir@RPATH_OPTION@"
++embedded_libs="-L$elibdir@RPATH_OPTION@"
+ embedded_libs="$embedded_libs -l@LIBEMBED_OS_OUTPUT_NAME@ @CONFIG_EMBEDD_LIBS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@" libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-04-27 18:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-04-27 18:40 UTC (permalink / raw
To: gentoo-commits
commit: cd476d9bba41a299000797ad9cd2b0c326544cfa
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Apr 27 18:40:25 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Apr 27 18:40:25 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=cd476d9b
Respin clientlibs patch for MySQL 5.7
20018_all_mysql-5.7-without-clientlibs-tools.patch | 121 +++++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/20018_all_mysql-5.7-without-clientlibs-tools.patch b/20018_all_mysql-5.7-without-clientlibs-tools.patch
new file mode 100644
index 0000000..9bed7a5
--- /dev/null
+++ b/20018_all_mysql-5.7-without-clientlibs-tools.patch
@@ -0,0 +1,121 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
++++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
+@@ -405,8 +405,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+
+@@ -436,7 +434,10 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -462,7 +463,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -470,11 +470,20 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -59,15 +59,16 @@
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+-
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+-SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
++ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+ TARGET_LINK_LIBRARIES(resolveip mysys mysys_ssl)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
++++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
+@@ -217,6 +217,6 @@
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
++++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
+@@ -433,18 +433,21 @@
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+-
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-06-28 14:15 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-06-28 14:15 UTC (permalink / raw
To: gentoo-commits
commit: b06e91caea912826ed728ca86263472bb66c743f
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jun 28 14:15:30 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Jun 28 14:15:30 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=b06e91ca
Respin elib patch for mariadb 10.0.26
20006_all_cmake_elib-mariadb-10.0.26.patch | 187 +++++++++++++++++++++++++++++
1 file changed, 187 insertions(+)
diff --git a/20006_all_cmake_elib-mariadb-10.0.26.patch b/20006_all_cmake_elib-mariadb-10.0.26.patch
new file mode 100644
index 0000000..d3acc99
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.26.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-06-28 14:22 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-06-28 14:22 UTC (permalink / raw
To: gentoo-commits
commit: 8fdb292b01de6a9fa6bad1af0a015a8027b62663
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Jun 28 14:22:05 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Jun 28 14:22:05 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=8fdb292b
Respin elib patch for mariadb 10.0.26
20006_all_cmake_elib-mariadb-10.0.26.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/20006_all_cmake_elib-mariadb-10.0.26.patch b/20006_all_cmake_elib-mariadb-10.0.26.patch
index d3acc99..e52440d 100644
--- a/20006_all_cmake_elib-mariadb-10.0.26.patch
+++ b/20006_all_cmake_elib-mariadb-10.0.26.patch
@@ -146,8 +146,8 @@ diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
IF(NOT DISABLE_SHARED)
MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
-- COMPONENT ${COMPONENT_LIBMYSQLD})
-+ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
IF(UNIX)
# Name the shared library, handle versioning (provides same api as client
# library hence the same version)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-07-21 15:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-07-21 15:26 UTC (permalink / raw
To: gentoo-commits
commit: 63743a3eeb350f20f73d2e44a24bb2b9155a0deb
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 12:58:22 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 12:58:22 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=63743a3e
Respin patches for 10.1.16
20006_all_cmake_elib-mariadb-10.1.16.patch | 187 +++++++++++++++++++++
..._mariadb-10.1.16-without-clientlibs-tools.patch | 114 +++++++++++++
2 files changed, 301 insertions(+)
diff --git a/20006_all_cmake_elib-mariadb-10.1.16.patch b/20006_all_cmake_elib-mariadb-10.1.16.patch
new file mode 100644
index 0000000..6087a6b
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.1.16.patch
@@ -0,0 +1,187 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR
+ SYSTEMD_UNIT)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER})
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +167,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
new file mode 100644
index 0000000..db1988d
--- /dev/null
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -0,0 +1,114 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,22 +392,33 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,12 +54,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,6 +327,5 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ ${WSREP_BINARIES}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-07-21 15:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-07-21 15:26 UTC (permalink / raw
To: gentoo-commits
commit: bff314ec616ec12f105522231b7977785634b652
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 21 15:25:59 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jul 21 15:25:59 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=bff314ec
Respin patch for mariadb 5.5.50
00000_index.txt | 8 +-
20006_all_cmake_elib-mariadb-5.5.50.patch | 202 ++++++++++++++++++++++++++++++
2 files changed, 209 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 8f25b34..2702877 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -572,7 +572,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mariadb-5.5.40.patch
-@ver 5.05.40.00 to 5.05.99.99
+@ver 5.05.40.00 to 5.05.49.99
+@pn mariadb
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mariadb-5.5.50.patch
+@ver 5.05.50.00 to 5.05.99.99
@pn mariadb
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mariadb-5.5.50.patch b/20006_all_cmake_elib-mariadb-5.5.50.patch
new file mode 100644
index 0000000..7e334d1
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-5.5.50.patch
@@ -0,0 +1,202 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER})
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- mysql-old/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ mysql/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-08-18 17:20 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-08-18 17:20 UTC (permalink / raw
To: gentoo-commits
commit: 21b42c38bed537d2bc8d9af2df91ba668404d9e2
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 18 17:19:50 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Aug 18 17:19:50 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=21b42c38
Respin elib patch for 10.2.1
20006_all_cmake_elib-mariadb-10.2.1.patch | 188 ++++++++++++++++++++++++++++++
1 file changed, 188 insertions(+)
diff --git a/20006_all_cmake_elib-mariadb-10.2.1.patch b/20006_all_cmake_elib-mariadb-10.2.1.patch
new file mode 100644
index 0000000..32ae3af
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.2.1.patch
@@ -0,0 +1,188 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR
+ SYSTEMD_UNIT)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,11 +211,12 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ CMAKE_PARSE_ARGUMENTS(ARG
+ "STATIC;SHARED;MODULE;NOINSTALL"
+- "OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "EXPORTS"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER})
+
+@@ -144,7 +149,7 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+@@ -163,7 +167,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-08-18 17:25 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-08-18 17:25 UTC (permalink / raw
To: gentoo-commits
commit: 009f5a042196fb7d379070aed3fd8852c919dd96
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 18 17:25:12 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Aug 18 17:25:12 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=009f5a04
Respin clientlibs patch for MariaDB 10.2.1
...l_mariadb-10.2.1-without-clientlibs-tools.patch | 114 +++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/20018_all_mariadb-10.2.1-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.1-without-clientlibs-tools.patch
new file mode 100644
index 0000000..92c3d37
--- /dev/null
+++ b/20018_all_mariadb-10.2.1-without-clientlibs-tools.patch
@@ -0,0 +1,114 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,22 +392,33 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,12 +54,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,6 +327,5 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+@@ -341,6 +340,12 @@
+ ${WSREP_BINARIES}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-10-19 18:53 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-10-19 18:53 UTC (permalink / raw
To: gentoo-commits
commit: 44ff91e60b443c45de9d859c8a32718ae957e31e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 19 18:52:56 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 19 18:52:56 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=44ff91e6
Respin elib patch for dev-db/mysql-5.5.53
00000_index.txt | 8 +-
20006_all_cmake_elib-mysql-5.5.53.patch | 221 ++++++++++++++++++++++++++++++++
2 files changed, 228 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 2702877..c93ab02 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -590,7 +590,13 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-5.5.37.patch
-@ver 5.05.37.00 to 5.05.99.99
+@ver 5.05.37.00 to 5.05.52.99
+@pn mysql
+@@ Add ELIBPATH to split client and embedded libs
+@@ Also install static libs by ENABLE_STATIC_LIBS
+
+@patch 20006_all_cmake_elib-mysql-5.5.53.patch
+@ver 5.05.53.00 to 5.05.99.99
@pn mysql
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
diff --git a/20006_all_cmake_elib-mysql-5.5.53.patch b/20006_all_cmake_elib-mysql-5.5.53.patch
new file mode 100644
index 0000000..248a799
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.5.53.patch
@@ -0,0 +1,221 @@
+diff -ur a/cmake/install_layout.cmake b/cmake/install_layout.cmake
+--- a/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ b/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST
+ SECURE_FILE_PRIV SECURE_FILE_PRIV_EMBEDDED)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur a/cmake/libutils.cmake b/cmake/libutils.cmake
+--- a/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ b/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ b/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -163,9 +163,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -196,9 +196,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
+--- a/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ b/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- a/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ b/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ b/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -198,6 +198,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/mysql/scripts/mysql_config.pl.in b/mysql/scripts/mysql_config.pl.in
+--- a/scripts/mysql_config.pl.in 2014-04-15 07:02:39.000000000 -0400
++++ b/scripts/mysql_config.pl.in 2014-04-25 19:28:48.000000000 -0400
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/mysql/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- a/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ b/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-10-19 19:14 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2016-10-19 19:14 UTC (permalink / raw
To: gentoo-commits
commit: 508fae75554f607a0ac11b7c8aa57c538ef91ef2
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 19 19:14:40 2016 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 19 19:14:40 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=508fae75
Fix end version of perl fix for mysql 5.5
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
00000_index.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index c93ab02..8f3a4c3 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -915,7 +915,7 @@
@@ Split building of client libraries, server and client tools
@patch 20019_all_mysql-5.5-mtr-perl-deprecation.patch
-@ver 5.05.45.00 to 5.05.99.99
+@ver 5.05.45.00 to 5.05.52.99
@pn mysql
@@ Fix deprecated perl array defined syntax on mtr test script
@@ Ported forward from mysql 5.6; Oracle bug 18145121
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2016-12-03 20:41 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2016-12-03 20:41 UTC (permalink / raw
To: gentoo-commits
commit: 7a855728c48b023b75d9b96aeb0e5f844fe51f2d
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 30 23:43:06 2016 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Nov 30 23:43:06 2016 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7a855728
Respin elib patch for percona 5.6.34
20006_all_cmake_elib-percona-5.6.34.patch | 198 ++++++++++++++++++++++++++++++
1 file changed, 198 insertions(+)
diff --git a/20006_all_cmake_elib-percona-5.6.34.patch b/20006_all_cmake_elib-percona-5.6.34.patch
new file mode 100644
index 0000000..3969654
--- /dev/null
+++ b/20006_all_cmake_elib-percona-5.6.34.patch
@@ -0,0 +1,198 @@
+--- mysql-old/cmake/install_layout.cmake
++++ mysql/cmake/install_layout.cmake
+@@ -55,7 +55,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -156,6 +157,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -329,9 +331,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -394,6 +398,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -422,6 +427,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -454,7 +460,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST
+ SECURE_FILE_PRIV SECURE_FILE_PRIV_EMBEDDED)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+--- mysql-old/cmake/libutils.cmake
++++ mysql/cmake/libutils.cmake
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -215,7 +217,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -266,7 +268,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+--- mysql-old/libmysql/CMakeLists.txt
++++ mysql/libmysql/CMakeLists.txt
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -210,9 +215,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+- INSTALL_SYMLINK(perconaserverclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(perconaserverclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+--- mysql-old/libmysqld/CMakeLists.txt
++++ mysql/libmysqld/CMakeLists.txt
+@@ -115,8 +115,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -124,12 +129,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt
++++ mysql/libservices/CMakeLists.txt
+@@ -24,4 +24,6 @@
+ mysql_string_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+--- mysql-old/scripts/CMakeLists.txt
++++ mysql/scripts/CMakeLists.txt
+@@ -249,6 +249,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+--- mysql-old/scripts/mysql_config.sh
++++ mysql/scripts/mysql_config.sh
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -116,7 +120,7 @@
+ libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lperconaserverclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+ libs_r="$libs_r @QUOTED_CMAKE_C_LINK_FLAGS@"
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-01-29 1:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-01-29 1:26 UTC (permalink / raw
To: gentoo-commits
commit: 3e33db00d27d450361a6e443d9c555775572378e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 29 01:25:51 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jan 29 01:25:51 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3e33db00
Fix support for minizip in Mariadb ConnectSE
20022_all_mariadb-10.0.29-minizip.patch | 57 +++++++++++++++++++++++++++++++++
1 file changed, 57 insertions(+)
diff --git a/20022_all_mariadb-10.0.29-minizip.patch b/20022_all_mariadb-10.0.29-minizip.patch
new file mode 100644
index 0000000..12859d3
--- /dev/null
+++ b/20022_all_mariadb-10.0.29-minizip.patch
@@ -0,0 +1,57 @@
+diff -aruN a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt
+--- a/storage/connect/CMakeLists.txt 2017-01-11 20:45:20.000000000 -0500
++++ b/storage/connect/CMakeLists.txt 2017-01-22 21:11:15.000000000 -0500
+@@ -286,8 +286,13 @@
+ OPTION(CONNECT_WITH_ZIP "Compile CONNECT storage engine with ZIP support" ON)
+
+ IF(CONNECT_WITH_ZIP)
+- SET(CONNECT_SOURCES ${CONNECT_SOURCES} filamzip.cpp tabzip.cpp unzip.c ioapi.c zip.c
+- filamzip.h tabzip.h ioapi.h unzip.h zip.h)
++ SET(CONNECT_SOURCES ${CONNECT_SOURCES} filamzip.cpp tabzip.cpp filamzip.h tabzip.h)
++ pkg_check_modules(MINIZIP minizip)
++ if(MINIZIP_FOUND) # Use system version
++ add_definitions(-DMINIZIP_FOUND)
++ else()
++ SET(CONNECT_SOURCES ${CONNECT_SOURCES} unzip.c ioapi.c zip.c ioapi.h unzip.h zip.h)
++ endif(MINIZIP_FOUND)
+ add_definitions(-DZIP_SUPPORT -DNOCRYPT)
+ ENDIF(CONNECT_WITH_ZIP)
+
+@@ -311,5 +316,6 @@
+ COMPONENT connect-engine
+ RECOMPILE_FOR_EMBEDDED
+ LINK_LIBRARIES ${ZLIB_LIBRARY} ${XML_LIBRARY} ${ICONV_LIBRARY}
+- ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY})
++ ${ODBC_LIBRARY} ${JDBC_LIBRARY} ${IPHLPAPI_LIBRARY}
++ ${MINIZIP_LIBRARIES})
+
+diff -aruN a/storage/connect/filamzip.h b/storage/connect/filamzip.h
+--- a/storage/connect/filamzip.h 2017-01-11 20:45:20.000000000 -0500
++++ b/storage/connect/filamzip.h 2017-01-17 22:12:54.000000000 -0500
+@@ -10,7 +10,11 @@
+
+ #include "block.h"
+ #include "filamap.h"
++#ifdef MINIZIP_FOUND
++#include "minizip/unzip.h"
++#else
+ #include "unzip.h"
++#endif
+
+ #define DLLEXPORT extern "C"
+
+diff -aruN a/storage/connect/tabzip.h b/storage/connect/tabzip.h
+--- a/storage/connect/tabzip.h 2017-01-11 20:45:21.000000000 -0500
++++ b/storage/connect/tabzip.h 2017-01-17 22:13:18.000000000 -0500
+@@ -9,7 +9,11 @@
+ #include "block.h"
+ #include "colblk.h"
+ #include "xtable.h"
++#ifdef MINIZIP_FOUND
++#include "minizip/unzip.h"
++#else
+ #include "unzip.h"
++#endif
+
+ typedef class ZIPDEF *PZIPDEF;
+ typedef class TDBZIP *PTDBZIP;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-03-01 20:41 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2017-03-01 20:41 UTC (permalink / raw
To: gentoo-commits
commit: 83e075e9a297e8e1b0014f96969d477e053e2595
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 1 20:19:35 2017 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Mar 1 20:19:35 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=83e075e9
Add patch to mysql 5.5 branch for CVE-2017-3302
00000_index.txt | 6 ++
20023_all_mysql-5.5-CVE-2017-3302.patch | 142 ++++++++++++++++++++++++++++++++
2 files changed, 148 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 8f3a4c3..3c8627f 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -946,3 +946,9 @@
@ver 10.01.11.00 to 10.01.11.99
@pn mariadb
@@ Fix server gssapi plugin compile with heimdal
+
+@patch 20023_all_mysql-5.5-CVE-2017-3302.patch
+@ver 5.05.45.00 to 5.05.54.99
+@pn mysql
+@@ Fix use-after-free in mysql_prune_stmt_list
+@@ Back ported from mysql 5.6; Oracle bug 17512527
diff --git a/20023_all_mysql-5.5-CVE-2017-3302.patch b/20023_all_mysql-5.5-CVE-2017-3302.patch
new file mode 100644
index 0000000..23bff1a
--- /dev/null
+++ b/20023_all_mysql-5.5-CVE-2017-3302.patch
@@ -0,0 +1,142 @@
+From 1037977895aa4a145de16719df0a2375c71bbf26 Mon Sep 17 00:00:00 2001
+From: Nisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com>
+Date: Mon, 21 Jul 2014 21:21:15 +0530
+Subject: [PATCH] BUG#17512527: LIST HANDLING INCORRECT IN
+ MYSQL_PRUNE_STMT_LIST()
+
+Analysis:
+---------
+Invalid memory access maybe observed when using prepared statements if:
+a) The mysql client connection is lost after statement preparation
+ is complete and
+b) There is at least one statement which is in initialized state but
+ not prepared yet.
+
+When the client detects a closed connection, it calls end_server()
+to shutdown the connection. As part of the clean up, the
+mysql_prune_stmt_list() removes the statements which has transitioned
+beyond the initialized state and retains only the statements which
+are in a initialized state. During this processing, the initialized
+statements are moved from 'mysql->stmts' to a temporary 'pruned_list'.
+When moving the first 'INIT_DONE' element to the pruned_list,
+'element->next' is set to NULL. Hence the rest of the list is never
+traversed and the statements which have transitioned beyond the
+initialized state are never invalidated.
+
+When the mysql_stmt_close() is called for the statement which is not
+invalidated; the statements list is updated in order to remove the
+statement. This would end up accessing freed memory(freed by the
+mysql_stmt_close() for a previous statement in the list).
+
+Fix:
+---
+mysql_prune_stmt_list() called list_add() incorrectly to create a
+temporary list. The use case of list_add() is to add a single
+element to the front of the doubly linked list.
+mysql_prune_stmt_list() called list_add() by passing an entire
+list as the 'element'.
+
+mysql_prune_stmt_list() now uses list_delete() to remove the
+statement which has transitioned beyond the initialized phase.
+Thus the statement list would contain only elements where the
+the state of the statement is initialized.
+
+Note: Run the test with valgrind-mysqltest and leak-check=full
+option to see the invalid memory access.
+
+Back-ported to MySQL 5.5 branch by Balint Reczey
+
+Conflicts:
+ sql-common/client.c
+ tests/mysql_client_test.c
+---
+ sql-common/client.c | 11 +++++++----
+ tests/mysql_client_test.c | 41 +++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+), 4 deletions(-)
+
+diff --git a/sql-common/client.c b/sql-common/client.c
+index cd9b6a7..be60cc1 100644
+--- a/sql-common/client.c
++++ b/sql-common/client.c
+@@ -3790,12 +3790,15 @@ static void mysql_close_free(MYSQL *mysql)
+ */
+ static void mysql_prune_stmt_list(MYSQL *mysql)
+ {
+- LIST *element= mysql->stmts;
+- LIST *pruned_list= 0;
++ LIST *pruned_list= NULL;
+
+- for (; element; element= element->next)
++ while(mysql->stmts)
+ {
+- MYSQL_STMT *stmt= (MYSQL_STMT *) element->data;
++ LIST *element= mysql->stmts;
++ MYSQL_STMT *stmt;
++
++ mysql->stmts= list_delete(element, element);
++ stmt= (MYSQL_STMT *) element->data;
+ if (stmt->state != MYSQL_STMT_INIT_DONE)
+ {
+ stmt->mysql= 0;
+diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
+index e600d82..d3f3899 100644
+--- a/tests/mysql_client_test.c
++++ b/tests/mysql_client_test.c
+@@ -18648,6 +18648,46 @@ static void test_bug13001491()
+ myquery(rc);
+ }
+
++static void test_bug17512527()
++{
++ MYSQL *conn1, *conn2;
++ MYSQL_STMT *stmt1, *stmt2;
++ const char *stmt1_txt= "SELECT NOW();";
++ const char *stmt2_txt= "SELECT 1;";
++ unsigned long thread_id;
++ char query[MAX_TEST_QUERY_LENGTH];
++ int rc;
++
++ conn1= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1);
++ conn2= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 0);
++
++ stmt1 = mysql_stmt_init(conn1);
++ check_stmt(stmt1);
++ rc= mysql_stmt_prepare(stmt1, stmt1_txt, strlen(stmt1_txt));
++ check_execute(stmt1, rc);
++
++ thread_id= mysql_thread_id(conn1);
++ sprintf(query, "KILL %lu", thread_id);
++ if (thread_query(query))
++ exit(1);
++
++ /*
++ After the connection is killed, the connection is
++ re-established due to the reconnect flag.
++ */
++ stmt2 = mysql_stmt_init(conn1);
++ check_stmt(stmt2);
++
++ rc= mysql_stmt_prepare(stmt2, stmt2_txt, strlen(stmt2_txt));
++ check_execute(stmt1, rc);
++
++ mysql_stmt_close(stmt2);
++ mysql_stmt_close(stmt1);
++
++ mysql_close(conn1);
++ mysql_close(conn2);
++}
++
+
+ static struct my_tests_st my_tests[]= {
+ { "disable_query_logs", disable_query_logs },
+@@ -18911,6 +18951,7 @@ static struct my_tests_st my_tests[]= {
+ { "test_bug12337762", test_bug12337762 },
+ { "test_bug11754979", test_bug11754979 },
+ { "test_bug13001491", test_bug13001491 },
++ { "test_bug17512527", test_bug17512527},
+ { 0, 0 }
+ };
+
+--
+2.1.4
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-03-01 21:39 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-03-01 21:39 UTC (permalink / raw
To: gentoo-commits
commit: ffd476e16b8daf2752935b714f2b1add7c5b87fe
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 1 21:39:23 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Mar 1 21:39:23 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=ffd476e1
Respin elib patch for mysql 5.6.35
20006_all_cmake_elib-mysql-5.6.35.patch | 205 ++++++++++++++++++++++++++++++++
1 file changed, 205 insertions(+)
diff --git a/20006_all_cmake_elib-mysql-5.6.35.patch b/20006_all_cmake_elib-mysql-5.6.35.patch
new file mode 100644
index 0000000..de3df07
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-5.6.35.patch
@@ -0,0 +1,205 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -43,7 +43,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -117,6 +118,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -148,9 +150,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -178,6 +182,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -204,6 +209,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -234,7 +240,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST
+ SECURE_FILE_PRIV SECURE_FILE_PRIV_EMBEDDED)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-20 00:14:06.581799638 -0100
++++ mysql/cmake/libutils.cmake 2014-01-20 00:15:27.647802721 -0100
+@@ -40,6 +40,8 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
++
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -214,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -265,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-20 00:14:06.580799638 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-20 00:15:27.647802721 -0100
+@@ -179,8 +179,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ INSTALL_DEBUG_SYMBOLS(clientlib)
+@@ -211,9 +216,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-20 00:14:06.453799634 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-20 00:25:46.375826250 -0100
+@@ -126,8 +126,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -135,12 +135,14 @@
+ ENDIF()
+
+ IF(UNIX)
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+--- mysql-old/libservices/CMakeLists.txt 2014-02-06 14:35:25.162325748 -0500
++++ mysql/libservices/CMakeLists.txt 2014-02-06 14:36:20.051137978 -0500
+@@ -26,4 +26,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+
+diff -aurN mysql.old/scripts/CMakeLists.txt mysql/scripts/CMakeLists.txt
+--- mysql.old/scripts/CMakeLists.txt 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 22:46:35.000000000 -0400
+@@ -239,6 +239,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.old/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.old/scripts/mysql_config.sh 2014-03-14 15:07:28.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 22:48:26.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -116,7 +116,7 @@
+ libs="$libs @QUOTED_CMAKE_C_LINK_FLAGS@"
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+ libs_r="$libs_r @QUOTED_CMAKE_C_LINK_FLAGS@"
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+ embedded_libs="$embedded_libs @QUOTED_CMAKE_CXX_LINK_FLAGS@"
+
+ cflags="-I$pkgincludedir @CFLAGS@ " #note: end space!
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-03-10 14:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-03-10 14:26 UTC (permalink / raw
To: gentoo-commits
commit: 2ef169446e02036bf602c627666a9a3c2927232e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 10 14:26:01 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Mar 10 14:26:01 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=2ef16944
Add patch for mariadb to build without the server
20034_all_mariadb-10.0.30-fix-without-server.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20034_all_mariadb-10.0.30-fix-without-server.patch b/20034_all_mariadb-10.0.30-fix-without-server.patch
new file mode 100644
index 0000000..a207117
--- /dev/null
+++ b/20034_all_mariadb-10.0.30-fix-without-server.patch
@@ -0,0 +1,13 @@
+diff -aruN a/include/my_sys.h b/include/my_sys.h
+--- a/include/my_sys.h 2017-03-09 16:09:17.630156658 -0500
++++ b/include/my_sys.h 2017-03-09 16:05:43.560021093 -0500
+@@ -597,6 +597,9 @@
+ myf MyFlags);
+ extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
+ extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
++#ifndef PSI_file_key
++typedef unsigned int PSI_file_key;
++#endif
+ extern int my_handler_delete_with_symlink(PSI_file_key key, const char *name,
+ const char *ext, myf sync_dir);
+ extern size_t my_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags);
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-03-16 13:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-03-16 13:40 UTC (permalink / raw
To: gentoo-commits
commit: fd8bb417f9316429119f3fd4ac76278d66840c95
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 16 13:40:14 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Mar 16 13:40:14 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=fd8bb417
Add patch to fix building mariadb 10.1.22 under certain conditions MDEV-12261
20034_all_mariadb-10.1.22-MDEV-12261.patch | 234 +++++++++++++++++++++++++++++
1 file changed, 234 insertions(+)
diff --git a/20034_all_mariadb-10.1.22-MDEV-12261.patch b/20034_all_mariadb-10.1.22-MDEV-12261.patch
new file mode 100644
index 0000000..d94d8d1
--- /dev/null
+++ b/20034_all_mariadb-10.1.22-MDEV-12261.patch
@@ -0,0 +1,234 @@
+From 2c2bd8c1556b081fccd0fc3e010dc3ea2c38fffb Mon Sep 17 00:00:00 2001
+From: Sergei Golubchik <serg@mariadb.org>
+Date: Wed, 15 Mar 2017 11:46:54 +0100
+Subject: [PATCH] MDEV-12261 build failure without P_S
+
+restore mysql_file_delete_with_symlink() but let it use
+new my_handler_delete_with_symlink() mysys helper.
+---
+ include/my_sys.h | 3 +--
+ include/mysql/psi/mysql_file.h | 44 ++++++++++++++++++++++++++++++++++++++++
+ mysys/my_symlink2.c | 14 ++++++-------
+ sql/handler.cc | 2 +-
+ sql/sql_db.cc | 6 +++---
+ sql/table.cc | 2 +-
+ storage/maria/ma_delete_table.c | 8 ++++----
+ storage/myisam/mi_delete_table.c | 8 ++++----
+ 8 files changed, 64 insertions(+), 23 deletions(-)
+
+diff --git a/include/my_sys.h b/include/my_sys.h
+index 4e129cc..5b0a114 100644
+--- a/include/my_sys.h
++++ b/include/my_sys.h
+@@ -597,8 +597,7 @@ extern File my_create_with_symlink(const char *linkname, const char *filename,
+ myf MyFlags);
+ extern int my_rename_with_symlink(const char *from,const char *to,myf MyFlags);
+ extern int my_symlink(const char *content, const char *linkname, myf MyFlags);
+-extern int my_handler_delete_with_symlink(PSI_file_key key, const char *name,
+- const char *ext, myf sync_dir);
++extern int my_handler_delete_with_symlink(const char *filename, myf sync_dir);
+
+ extern size_t my_read(File Filedes,uchar *Buffer,size_t Count,myf MyFlags);
+ extern size_t my_pread(File Filedes,uchar *Buffer,size_t Count,my_off_t offset,
+diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
+index aca66bd..df94603 100644
+--- a/include/mysql/psi/mysql_file.h
++++ b/include/mysql/psi/mysql_file.h
+@@ -442,6 +442,20 @@
+ #endif
+
+ /**
++ @def mysql_file_delete_with_symlink(K, P1, P2, P3)
++ Instrumented delete with symbolic link.
++ @c mysql_file_delete_with_symlink is a replacement
++ for @c my_handler_delete_with_symlink.
++*/
++#ifdef HAVE_PSI_FILE_INTERFACE
++ #define mysql_file_delete_with_symlink(K, P1, P2, P3) \
++ inline_mysql_file_delete_with_symlink(K, __FILE__, __LINE__, P1, P2, P3)
++#else
++ #define mysql_file_delete_with_symlink(K, P1, P2, P3) \
++ inline_mysql_file_delete_with_symlink(P1, P2, P3)
++#endif
++
++/**
+ @def mysql_file_rename_with_symlink(K, P1, P2, P3)
+ Instrumented rename with symbolic link.
+ @c mysql_file_rename_with_symlink is a replacement
+@@ -1294,6 +1308,7 @@ inline_mysql_file_rename(
+ return result;
+ }
+
++
+ static inline File
+ inline_mysql_file_create_with_symlink(
+ #ifdef HAVE_PSI_FILE_INTERFACE
+@@ -1325,6 +1340,35 @@ inline_mysql_file_create_with_symlink(
+
+
+ static inline int
++inline_mysql_file_delete_with_symlink(
++#ifdef HAVE_PSI_FILE_INTERFACE
++ PSI_file_key key, const char *src_file, uint src_line,
++#endif
++ const char *name, const char *ext, myf flags)
++{
++ int result;
++ char fullname[FN_REFLEN];
++ fn_format(fullname, name, "", ext, MY_UNPACK_FILENAME | MY_APPEND_EXT);
++#ifdef HAVE_PSI_FILE_INTERFACE
++ struct PSI_file_locker *locker;
++ PSI_file_locker_state state;
++ locker= PSI_FILE_CALL(get_thread_file_name_locker)
++ (&state, key, PSI_FILE_DELETE, fullname, &locker);
++ if (likely(locker != NULL))
++ {
++ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
++ result= my_handler_delete_with_symlink(fullname, flags);
++ PSI_FILE_CALL(end_file_close_wait)(locker, result);
++ return result;
++ }
++#endif
++
++ result= my_handler_delete_with_symlink(fullname, flags);
++ return result;
++}
++
++
++static inline int
+ inline_mysql_file_rename_with_symlink(
+ #ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+diff --git a/mysys/my_symlink2.c b/mysys/my_symlink2.c
+index defcb59..c851468 100644
+--- a/mysys/my_symlink2.c
++++ b/mysys/my_symlink2.c
+@@ -170,22 +170,20 @@ int my_rename_with_symlink(const char *from, const char *to, myf MyFlags)
+ in this case both the symlink and the symlinked file are deleted,
+ but only if the symlinked file is not in the datadir.
+ */
+-int my_handler_delete_with_symlink(PSI_file_key key, const char *name,
+- const char *ext, myf sync_dir)
++int my_handler_delete_with_symlink(const char *filename, myf sync_dir)
+ {
+- char orig[FN_REFLEN], real[FN_REFLEN];
++ char real[FN_REFLEN];
+ int res= 0;
+ DBUG_ENTER("my_handler_delete_with_symlink");
+
+- fn_format(orig, name, "", ext, MY_UNPACK_FILENAME | MY_APPEND_EXT);
+- if (my_is_symlink(orig))
++ if (my_is_symlink(filename))
+ {
+ /*
+ Delete the symlinked file only if the symlink is not
+ pointing into datadir.
+ */
+- if (!(my_realpath(real, orig, MYF(0)) || mysys_test_invalid_symlink(real)))
+- res= mysql_file_delete(key, real, MYF(MY_NOSYMLINKS | sync_dir));
++ if (!(my_realpath(real, filename, MYF(0)) || mysys_test_invalid_symlink(real)))
++ res= my_delete(real, MYF(MY_NOSYMLINKS | sync_dir));
+ }
+- DBUG_RETURN(mysql_file_delete(key, orig, MYF(sync_dir)) || res);
++ DBUG_RETURN(my_delete(filename, MYF(sync_dir)) || res);
+ }
+diff --git a/sql/handler.cc b/sql/handler.cc
+index 7fa8afd..fc70ed5 100644
+--- a/sql/handler.cc
++++ b/sql/handler.cc
+@@ -3850,7 +3850,7 @@ int handler::delete_table(const char *name)
+
+ for (const char **ext=bas_ext(); *ext ; ext++)
+ {
+- if (my_handler_delete_with_symlink(key_file_misc, name, *ext, 0))
++ if (mysql_file_delete_with_symlink(key_file_misc, name, *ext, 0))
+ {
+ if (my_errno != ENOENT)
+ {
+diff --git a/sql/sql_db.cc b/sql/sql_db.cc
+index 3f43a33..6c8c384 100644
+--- a/sql/sql_db.cc
++++ b/sql/sql_db.cc
+@@ -815,7 +815,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
+ if there exists a table with the name 'db', so let's just do it
+ separately. We know this file exists and needs to be deleted anyway.
+ */
+- if (my_handler_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
++ if (mysql_file_delete_with_symlink(key_file_misc, path, "", MYF(0)) &&
+ my_errno != ENOENT)
+ {
+ my_error(EE_DELETE, MYF(0), path, my_errno);
+@@ -1119,7 +1119,7 @@ static bool find_db_tables_and_rm_known_files(THD *thd, MY_DIR *dirp,
+ We ignore ENOENT error in order to skip files that was deleted
+ by concurrently running statement like REPAIR TABLE ...
+ */
+- if (my_handler_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) &&
++ if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(0)) &&
+ my_errno != ENOENT)
+ {
+ my_error(EE_DELETE, MYF(0), filePath, my_errno);
+@@ -1235,7 +1235,7 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path)
+ continue;
+ }
+ strxmov(filePath, org_path, "/", file->name, NullS);
+- if (my_handler_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME)))
++ if (mysql_file_delete_with_symlink(key_file_misc, filePath, "", MYF(MY_WME)))
+ {
+ goto err;
+ }
+diff --git a/sql/table.cc b/sql/table.cc
+index 80d0e02..975d9d5 100644
+--- a/sql/table.cc
++++ b/sql/table.cc
+@@ -569,7 +569,7 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags)
+ {
+ DBUG_ASSERT(flags & GTS_TABLE);
+ DBUG_ASSERT(flags & GTS_USE_DISCOVERY);
+- my_handler_delete_with_symlink(key_file_frm, path, "", MYF(0));
++ mysql_file_delete_with_symlink(key_file_frm, path, "", MYF(0));
+ file= -1;
+ }
+ else
+diff --git a/storage/maria/ma_delete_table.c b/storage/maria/ma_delete_table.c
+index a9ab8e5..186075d 100644
+--- a/storage/maria/ma_delete_table.c
++++ b/storage/maria/ma_delete_table.c
+@@ -86,11 +86,11 @@ int maria_delete_table_files(const char *name, myf sync_dir)
+ {
+ DBUG_ENTER("maria_delete_table_files");
+
+- if (my_handler_delete_with_symlink(key_file_kfile, name, MARIA_NAME_IEXT, MYF(MY_WME | sync_dir)) ||
+- my_handler_delete_with_symlink(key_file_dfile, name, MARIA_NAME_DEXT, MYF(MY_WME | sync_dir)))
++ if (mysql_file_delete_with_symlink(key_file_kfile, name, MARIA_NAME_IEXT, MYF(MY_WME | sync_dir)) ||
++ mysql_file_delete_with_symlink(key_file_dfile, name, MARIA_NAME_DEXT, MYF(MY_WME | sync_dir)))
+ DBUG_RETURN(my_errno);
+
+- my_handler_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
+- my_handler_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
++ mysql_file_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
++ mysql_file_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
+ DBUG_RETURN(0);
+ }
+diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
+index 3422e6b..d766fb2 100644
+--- a/storage/myisam/mi_delete_table.c
++++ b/storage/myisam/mi_delete_table.c
+@@ -34,14 +34,14 @@ int mi_delete_table(const char *name)
+ check_table_is_closed(name,"delete");
+ #endif
+
+- if (my_handler_delete_with_symlink(mi_key_file_kfile, name, MI_NAME_IEXT, MYF(MY_WME)) ||
+- my_handler_delete_with_symlink(mi_key_file_dfile, name, MI_NAME_DEXT, MYF(MY_WME)))
++ if (mysql_file_delete_with_symlink(mi_key_file_kfile, name, MI_NAME_IEXT, MYF(MY_WME)) ||
++ mysql_file_delete_with_symlink(mi_key_file_dfile, name, MI_NAME_DEXT, MYF(MY_WME)))
+ DBUG_RETURN(my_errno);
+
+
+ // optionally present:
+- my_handler_delete_with_symlink(mi_key_file_dfile, name, ".OLD", MYF(0));
+- my_handler_delete_with_symlink(mi_key_file_dfile, name, ".TMD", MYF(0));
++ mysql_file_delete_with_symlink(mi_key_file_dfile, name, ".OLD", MYF(0));
++ mysql_file_delete_with_symlink(mi_key_file_dfile, name, ".TMD", MYF(0));
+
+ DBUG_RETURN(0);
+ }
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-03-16 13:55 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-03-16 13:55 UTC (permalink / raw
To: gentoo-commits
commit: d6738091bca29969dcc43c6a0edd006c1adcfb11
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 16 13:54:41 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Mar 16 13:54:41 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d6738091
Fix MDEV-12261 patch which does not completely apply
20034_all_mariadb-10.1.22-MDEV-12261.patch | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/20034_all_mariadb-10.1.22-MDEV-12261.patch b/20034_all_mariadb-10.1.22-MDEV-12261.patch
index d94d8d1..66ba7e3 100644
--- a/20034_all_mariadb-10.1.22-MDEV-12261.patch
+++ b/20034_all_mariadb-10.1.22-MDEV-12261.patch
@@ -193,7 +193,7 @@ diff --git a/storage/maria/ma_delete_table.c b/storage/maria/ma_delete_table.c
index a9ab8e5..186075d 100644
--- a/storage/maria/ma_delete_table.c
+++ b/storage/maria/ma_delete_table.c
-@@ -86,11 +86,11 @@ int maria_delete_table_files(const char *name, myf sync_dir)
+@@ -86,13 +86,13 @@
{
DBUG_ENTER("maria_delete_table_files");
@@ -203,10 +203,12 @@ index a9ab8e5..186075d 100644
+ mysql_file_delete_with_symlink(key_file_dfile, name, MARIA_NAME_DEXT, MYF(MY_WME | sync_dir)))
DBUG_RETURN(my_errno);
-- my_handler_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
-- my_handler_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
-+ mysql_file_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
-+ mysql_file_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
+ if (!temporary) {
+- my_handler_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
+- my_handler_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
++ mysql_file_delete_with_symlink(key_file_dfile, name, ".TMD", MYF(0));
++ mysql_file_delete_with_symlink(key_file_dfile, name, ".OLD", MYF(0));
+ }
DBUG_RETURN(0);
}
diff --git a/storage/myisam/mi_delete_table.c b/storage/myisam/mi_delete_table.c
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-05-29 2:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-05-29 2:02 UTC (permalink / raw
To: gentoo-commits
commit: df0498c18892a344fe861dff0444c1726b2695a9
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 29 02:02:39 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon May 29 02:02:39 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=df0498c1
Add mysql_st API regression patch for mariadb 10.2
20024_all_mariadb-10.2.6-mysql_st-regression.patch | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/20024_all_mariadb-10.2.6-mysql_st-regression.patch b/20024_all_mariadb-10.2.6-mysql_st-regression.patch
new file mode 100644
index 0000000..a78d0ff
--- /dev/null
+++ b/20024_all_mariadb-10.2.6-mysql_st-regression.patch
@@ -0,0 +1,12 @@
+diff -aurN a/libmariadb/include/mysql.h b/libmariadb/include/mysql.h
+--- a/libmariadb/include/mysql.h 2017-05-14 19:13:15.000000000 -0400
++++ b/libmariadb/include/mysql.h 2017-05-28 22:00:15.066047333 -0400
+@@ -342,7 +342,7 @@
+ struct st_mysql_options options;
+ enum mysql_status status;
+ my_bool free_me; /* If free in mysql_close */
+- my_bool unused_1;
++ my_bool reconnect;
+ char scramble_buff[20+ 1];
+ /* madded after 3.23.58 */
+ my_bool unused_2;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-06-28 17:21 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-06-28 17:21 UTC (permalink / raw
To: gentoo-commits
commit: 977694685a255462ead21692c2619290c1fa3abb
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jun 28 17:21:35 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jun 28 17:21:35 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=97769468
Respin without-libs-tools patch for MariaDB 10.2.6
...l_mariadb-10.2.6-without-clientlibs-tools.patch | 141 +++++++++++++++++++++
1 file changed, 141 insertions(+)
diff --git a/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch
new file mode 100644
index 0000000..0ddf031
--- /dev/null
+++ b/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch
@@ -0,0 +1,141 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/CMakeLists.txt 2017-06-28 13:14:25.686006673 -0400
+@@ -325,8 +325,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -363,28 +361,41 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ # mariadb_connector_c fetches submodules which is useful for plugins
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
++ENDIF()
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/extra/CMakeLists.txt 2017-06-28 12:54:14.972089739 -0400
+@@ -46,12 +46,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-06-28 13:08:17.185731795 -0400
+@@ -358,8 +358,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${mariadbclient_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS)
++ ADD_LIBRARY(mariadbclient STATIC ${mariadbclient_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+ TARGET_LINK_LIBRARIES(libmariadb ${SYSTEM_LIBS})
+
+@@ -379,7 +381,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "-Wl,--version-script=${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
++IF(ENABLE_STATIC_LIBS)
+ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -398,9 +402,11 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2017-05-14 19:13:18.000000000 -0400
++++ b/scripts/CMakeLists.txt 2017-06-28 12:56:23.774081970 -0400
+@@ -276,7 +276,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -288,6 +287,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-06-28 17:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-06-28 17:40 UTC (permalink / raw
To: gentoo-commits
commit: 7a0a7707d4f44865a4f33dfbecf37eb0195c8676
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jun 28 17:40:47 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jun 28 17:40:47 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7a0a7707
Enable static-lib building for 10.2.6-without-libs-tools when tools are built
20018_all_mariadb-10.2.6-without-clientlibs-tools.patch | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch
index 0ddf031..c063b76 100644
--- a/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.6-without-clientlibs-tools.patch
@@ -86,10 +86,10 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
-ADD_LIBRARY(mariadbclient STATIC ${mariadbclient_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
-+IF(ENABLE_STATIC_LIBS)
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ ADD_LIBRARY(mariadbclient STATIC ${mariadbclient_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
-+ENDIF(ENABLE_STATIC_LIBS)
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
TARGET_LINK_LIBRARIES(libmariadb ${SYSTEM_LIBS})
@@ -97,9 +97,9 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
TARGET_LINK_LIBRARIES (libmariadb "-Wl,--version-script=${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
ENDIF()
-+IF(ENABLE_STATIC_LIBS)
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
-+ENDIF(ENABLE_STATIC_LIBS)
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-06-28 18:47 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-06-28 18:47 UTC (permalink / raw
To: gentoo-commits
commit: 7885817ceeeac4deac019c594e3e0333dfb8ff93
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jun 28 18:46:48 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jun 28 18:46:48 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7885817c
Add patch for 10.2.6 GSSAPI detection via pkg-config
20025_all_mariadb-10.2.6-gssapi-detect.patch | 66 ++++++++++++++++++++++++++++
1 file changed, 66 insertions(+)
diff --git a/20025_all_mariadb-10.2.6-gssapi-detect.patch b/20025_all_mariadb-10.2.6-gssapi-detect.patch
new file mode 100644
index 0000000..b828a52
--- /dev/null
+++ b/20025_all_mariadb-10.2.6-gssapi-detect.patch
@@ -0,0 +1,66 @@
+diff -aurN a/libmariadb/cmake/FindGSSAPI.cmake b/libmariadb/cmake/FindGSSAPI.cmake
+--- a/libmariadb/cmake/FindGSSAPI.cmake 2017-05-14 19:13:15.000000000 -0400
++++ b/libmariadb/cmake/FindGSSAPI.cmake 2017-06-28 14:43:30.324029111 -0400
+@@ -46,6 +46,29 @@
+
+ else(GSSAPI_LIBS AND GSSAPI_FLAVOR)
+
++ find_package(PkgConfig)
++ IF(PKG_CONFIG_FOUND)
++ pkg_search_module(GSSAPI mit-krb5-gssapi)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "MIT")
++ ELSE()
++ pkg_search_module(GSSAPI heimdal-gssapi)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "HEIMDAL")
++ ENDIF()
++ ENDIF()
++ IF(GSSAPI_FOUND)
++ message(STATUS "Found GSSAPI: ${GSSAPI_LIBS}")
++
++ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "")
++ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "")
++ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "")
++
++ mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
++ RETURN()
++ ENDIF()
++ ENDIF(PKG_CONFIG_FOUND)
++
+ find_program(KRB5_CONFIG NAMES krb5-config PATHS
+ /opt/local/bin
+ /usr/lib/mit/bin/
+diff -aurN a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake b/plugin/auth_gssapi/cmake/FindGSSAPI.cmake
+--- a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake 2017-05-14 19:13:17.000000000 -0400
++++ b/plugin/auth_gssapi/cmake/FindGSSAPI.cmake 2017-06-28 14:42:30.307704810 -0400
+@@ -39,6 +39,29 @@
+
+ else(GSSAPI_LIBS AND GSSAPI_FLAVOR)
+
++ find_package(PkgConfig)
++ IF(PKG_CONFIG_FOUND)
++ pkg_search_module(GSSAPI mit-krb5-gssapi)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "MIT")
++ ELSE()
++ pkg_search_module(GSSAPI heimdal-gssapi)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "HEIMDAL")
++ ENDIF()
++ ENDIF()
++ IF(GSSAPI_FOUND)
++ message(STATUS "Found GSSAPI: ${GSSAPI_LIBS}")
++
++ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "")
++ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "")
++ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "")
++
++ mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
++ RETURN()
++ ENDIF()
++ ENDIF(PKG_CONFIG_FOUND)
++
+ find_program(KRB5_CONFIG NAMES krb5-config heimdal-krb5-config PATHS
+ /opt/local/bin
+ ONLY_CMAKE_FIND_ROOT_PATH # this is required when cross compiling with cmake 2.6 and ignored with cmake 2.4, Alex
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-19 1:08 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-19 1:08 UTC (permalink / raw
To: gentoo-commits
commit: 21dd13b194ced117eb6b025f1be320954712df53
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 19 01:08:22 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jul 19 01:08:22 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=21dd13b1
Adjust patch for 10.2.7
...l_mariadb-10.2.7-without-clientlibs-tools.patch | 144 +++++++++++++++++++++
1 file changed, 144 insertions(+)
diff --git a/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
new file mode 100644
index 0000000..9ff438d
--- /dev/null
+++ b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
@@ -0,0 +1,144 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/CMakeLists.txt 2017-06-28 13:14:25.686006673 -0400
+@@ -325,8 +325,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -363,28 +361,41 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ # mariadb_connector_c fetches submodules which is useful for plugins
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
++ENDIF()
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/extra/CMakeLists.txt 2017-06-28 12:54:14.972089739 -0400
+@@ -46,12 +46,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-06-28 13:08:17.185731795 -0400
+@@ -380,8 +380,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -379,7 +381,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "-Wl,--version-script=${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -398,9 +402,11 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2017-05-14 19:13:18.000000000 -0400
++++ b/scripts/CMakeLists.txt 2017-06-28 12:56:23.774081970 -0400
+@@ -276,7 +276,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -288,6 +287,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-07-18 20:36:19.699737005 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-07-18 20:49:58.260498557 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-19 1:08 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-19 1:08 UTC (permalink / raw
To: gentoo-commits
commit: 9e58ec2885d906c33006e4df0ec07de508afc2e4
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Jul 9 20:35:44 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jul 9 20:35:44 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=9e58ec28
Fix some variable detections for GSSAPI plugins
20025_all_mariadb-10.2.6-gssapi-detect.patch | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/20025_all_mariadb-10.2.6-gssapi-detect.patch b/20025_all_mariadb-10.2.6-gssapi-detect.patch
index b828a52..aeffff4 100644
--- a/20025_all_mariadb-10.2.6-gssapi-detect.patch
+++ b/20025_all_mariadb-10.2.6-gssapi-detect.patch
@@ -17,11 +17,11 @@ diff -aurN a/libmariadb/cmake/FindGSSAPI.cmake b/libmariadb/cmake/FindGSSAPI.cma
+ ENDIF()
+ ENDIF()
+ IF(GSSAPI_FOUND)
-+ message(STATUS "Found GSSAPI: ${GSSAPI_LIBS}")
++ message(STATUS "Found GSSAPI: ${GSSAPI_LIBRARIES}")
+
-+ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "")
-+ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "")
-+ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "")
++ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "" FORCE)
++ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "" FORCE)
++ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "" FORCE)
+
+ mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
+ RETURN()
@@ -50,11 +50,11 @@ diff -aurN a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake b/plugin/auth_gssapi/cmak
+ ENDIF()
+ ENDIF()
+ IF(GSSAPI_FOUND)
-+ message(STATUS "Found GSSAPI: ${GSSAPI_LIBS}")
++ message(STATUS "Found GSSAPI: ${GSSAPI_LIBRARIES}")
+
-+ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "")
-+ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "")
-+ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "")
++ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "" FORCE)
++ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "" FORCE)
++ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "" FORCE)
+
+ mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
+ RETURN()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-19 13:35 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-19 13:35 UTC (permalink / raw
To: gentoo-commits
commit: 7e790fc6dc1d92178aaf2299a370ab0d7d2d8b1c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 19 13:35:43 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jul 19 13:35:43 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7e790fc6
Respin tzinfo patch for 5.6.37
20008_all_mysql-tzinfo-symlink-5.6.37.patch | 103 ++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/20008_all_mysql-tzinfo-symlink-5.6.37.patch b/20008_all_mysql-tzinfo-symlink-5.6.37.patch
new file mode 100644
index 0000000..1c6ed0f
--- /dev/null
+++ b/20008_all_mysql-tzinfo-symlink-5.6.37.patch
@@ -0,0 +1,103 @@
+=== modified file 'sql/tztime.cc'
+--- a/sql/tztime.cc 2013-05-07 11:05:09 +0000
++++ b/sql/tztime.cc 2013-11-13 15:16:35 +0000
+@@ -2494,7 +2494,7 @@
+
+ */
+ my_bool
+-scan_tz_dir(char * name_end)
++scan_tz_dir(char * name_end, uint symlink_recursion_level)
+ {
+ MY_DIR *cur_dir;
+ char *name_end_tmp;
+@@ -2514,7 +2514,32 @@
+
+ if (MY_S_ISDIR(cur_dir->dir_entry[i].mystat->st_mode))
+ {
+- if (scan_tz_dir(name_end_tmp))
++ my_bool is_symlink;
++ if ((is_symlink= my_is_symlink(fullname, NULL)) &&
++ symlink_recursion_level > 0)
++ {
++ /*
++ The timezone definition data in some Linux distributions
++ (e.g. the "timezone-data-2013f" package in Gentoo)
++ may have synlimks like:
++ /usr/share/zoneinfo/posix/ -> /usr/share/zoneinfo/,
++ so the same timezone files are available under two names
++ (e.g. "CET" and "posix/CET").
++
++ We allow one level of symlink recursion for backward
++ compatibility with earlier timezone data packages that have
++ duplicate copies of the same timezone files inside the root
++ directory and the "posix" subdirectory (instead of symlinking).
++ This makes "posix/CET" still available, but helps to avoid
++ following such symlinks infinitely:
++ /usr/share/zoneinfo/posix/posix/posix/.../posix/
++ */
++ fflush(stdout);
++ fprintf(stderr, "Warning: Skipping directory '%s': "
++ "to avoid infinite symlink recursion.\n", fullname);
++ continue;
++ }
++ if (scan_tz_dir(name_end_tmp, symlink_recursion_level + is_symlink))
+ {
+ my_dirend(cur_dir);
+ return 1;
+@@ -2526,14 +2551,20 @@
+ if (!tz_load(fullname, &tz_info, &tz_storage))
+ print_tz_as_sql(root_name_end + 1, &tz_info);
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr,
+ "Warning: Unable to load '%s' as time zone. Skipping it.\n",
+ fullname);
++ }
+ free_root(&tz_storage, MYF(0));
+ }
+ else
++ {
++ fflush(stdout);
+ fprintf(stderr, "Warning: '%s' is not regular file or directory\n",
+ fullname);
++ }
+ }
+ }
+
+@@ -2566,8 +2597,9 @@
+ printf("TRUNCATE TABLE time_zone_transition;\n");
+ printf("TRUNCATE TABLE time_zone_transition_type;\n");
+
+- if (scan_tz_dir(root_name_end))
++ if (scan_tz_dir(root_name_end, 0))
+ {
++ fflush(stdout);
+ fprintf(stderr, "There were fatal errors during processing "
+ "of zoneinfo directory\n");
+ return 1;
+@@ -2586,6 +2618,7 @@
+ {
+ if (tz_load(argv[2], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2595,6 +2628,7 @@
+ {
+ if (tz_load(argv[1], &tz_info, &tz_storage))
+ {
++ fflush(stdout);
+ fprintf(stderr, "Problems with zoneinfo file '%s'\n", argv[2]);
+ return 1;
+ }
+@@ -2604,6 +2638,7 @@
+ free_root(&tz_storage, MYF(0));
+ }
+
++ my_end(0);
+ return 0;
+ }
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-19 16:30 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-19 16:30 UTC (permalink / raw
To: gentoo-commits
commit: 9d34c352e6f59d794f2b3b02eb805ce3c19cead2
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jul 19 16:29:45 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jul 19 16:29:45 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=9d34c352
Update index for last patch
00000_index.txt | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3c8627f..980ddd4 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -742,7 +742,15 @@
@@ Remove -Werror from USE="debug" builds
@patch 20008_all_mysql-tzinfo-symlink.patch
-@ver 5.05.36.00 to 5.06.99.99
+@ver 5.05.36.00 to 5.05.56.99
+@ver 5.06.00.00 to 5.06.36.99
+@pn mysql
+@pn percona-server
+@@ Backport tzinfo symlink fix from MariaDB bug 491176
+
+@patch 20008_all_mysql-tzinfo-symlink-5.6.37.patch
+@ver 5.05.57.00 to 5.05.99.99
+@ver 5.06.37.00 to 5.06.99.99
@pn mysql
@pn percona-server
@@ Backport tzinfo symlink fix from MariaDB bug 491176
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-27 0:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-27 0:26 UTC (permalink / raw
To: gentoo-commits
commit: cf640d262757be9d5137031102555569aa1ac48c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 27 00:25:18 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jul 27 00:25:18 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=cf640d26
Add missing section for clientlibs patch on mariadb-10.2.7
...all_mariadb-10.2.7-without-clientlibs-tools.patch | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
index 9ff438d..adcf12f 100644
--- a/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
@@ -115,6 +115,21 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
INSTALL(TARGETS libmariadb
COMPONENT SharedLibraries
DESTINATION ${INSTALL_LIBDIR})
+@@ -427,9 +427,11 @@
+
+ IF(WITH_MYSQLCOMPAT)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(WITH_STATIC_LIBS)
+ ENDIF()
+
+
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2017-05-14 19:13:18.000000000 -0400
+++ b/scripts/CMakeLists.txt 2017-06-28 12:56:23.774081970 -0400
@@ -139,6 +154,5 @@ diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
FOREACH(file ${BIN_SCRIPTS})
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
-diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
---- a/libmariadb/libmariadb/CMakeLists.txt 2017-07-18 20:36:19.699737005 -0400
-+++ b/libmariadb/libmariadb/CMakeLists.txt 2017-07-18 20:49:58.260498557 -0400
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-27 0:36 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-27 0:36 UTC (permalink / raw
To: gentoo-commits
commit: 6576db8b7f70c48f3f5a40462423172a432f577a
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jul 27 00:35:52 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jul 27 00:35:52 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=6576db8b
Add missing section for clientlibs patch on mariadb-10.2.7 part 2
...l_mariadb-10.2.7-without-clientlibs-tools.patch | 33 ++++++++++++----------
1 file changed, 18 insertions(+), 15 deletions(-)
diff --git a/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
index adcf12f..4ffeb99 100644
--- a/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.7-without-clientlibs-tools.patch
@@ -115,21 +115,6 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
INSTALL(TARGETS libmariadb
COMPONENT SharedLibraries
DESTINATION ${INSTALL_LIBDIR})
-@@ -427,9 +427,11 @@
-
- IF(WITH_MYSQLCOMPAT)
- create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
-- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
-- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
-- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
-+# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
-+ IF(ENABLE_STATIC_LIBS)
-+ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
-+# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
-+ ENDIF(WITH_STATIC_LIBS)
- ENDIF()
-
-
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2017-05-14 19:13:18.000000000 -0400
+++ b/scripts/CMakeLists.txt 2017-06-28 12:56:23.774081970 -0400
@@ -156,3 +141,21 @@ diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-07-26 20:26:17.094481997 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-07-26 20:31:47.042608316 -0400
+@@ -427,9 +427,11 @@
+
+ IF(WITH_MYSQLCOMPAT)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-29 1:00 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-29 1:00 UTC (permalink / raw
To: gentoo-commits
commit: bf71740dd17ac4858bea5145bac69e5bdf737c6e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sat Jul 29 01:00:10 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Jul 29 01:00:10 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=bf71740d
20025: Additionally add -krb5 to pkg-config
20025_all_mariadb-10.2.6-gssapi-detect.patch | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/20025_all_mariadb-10.2.6-gssapi-detect.patch b/20025_all_mariadb-10.2.6-gssapi-detect.patch
index aeffff4..7687e3d 100644
--- a/20025_all_mariadb-10.2.6-gssapi-detect.patch
+++ b/20025_all_mariadb-10.2.6-gssapi-detect.patch
@@ -7,11 +7,11 @@ diff -aurN a/libmariadb/cmake/FindGSSAPI.cmake b/libmariadb/cmake/FindGSSAPI.cma
+ find_package(PkgConfig)
+ IF(PKG_CONFIG_FOUND)
-+ pkg_search_module(GSSAPI mit-krb5-gssapi)
++ pkg_search_module(GSSAPI mit-krb5-gssapi mit-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "MIT")
+ ELSE()
-+ pkg_search_module(GSSAPI heimdal-gssapi)
++ pkg_search_module(GSSAPI heimdal-gssapi heimdal-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "HEIMDAL")
+ ENDIF()
@@ -40,11 +40,11 @@ diff -aurN a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake b/plugin/auth_gssapi/cmak
+ find_package(PkgConfig)
+ IF(PKG_CONFIG_FOUND)
-+ pkg_search_module(GSSAPI mit-krb5-gssapi)
++ pkg_search_module(GSSAPI mit-krb5-gssapi mit-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "MIT")
+ ELSE()
-+ pkg_search_module(GSSAPI heimdal-gssapi)
++ pkg_search_module(GSSAPI heimdal-gssapi heimdal-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "HEIMDAL")
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-07-29 1:13 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-07-29 1:13 UTC (permalink / raw
To: gentoo-commits
commit: 1fc8fcc82ad4eb28e68a5fa70bf8ea683e9643f6
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sat Jul 29 01:13:16 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Jul 29 01:13:16 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1fc8fcc8
20025: Additionally add -krb5 to pkg-config part2
20025_all_mariadb-10.2.6-gssapi-detect.patch | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/20025_all_mariadb-10.2.6-gssapi-detect.patch b/20025_all_mariadb-10.2.6-gssapi-detect.patch
index 7687e3d..8eec8d2 100644
--- a/20025_all_mariadb-10.2.6-gssapi-detect.patch
+++ b/20025_all_mariadb-10.2.6-gssapi-detect.patch
@@ -7,11 +7,11 @@ diff -aurN a/libmariadb/cmake/FindGSSAPI.cmake b/libmariadb/cmake/FindGSSAPI.cma
+ find_package(PkgConfig)
+ IF(PKG_CONFIG_FOUND)
-+ pkg_search_module(GSSAPI mit-krb5-gssapi mit-krb5)
++ pkg_check_modules(GSSAPI mit-krb5-gssapi mit-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "MIT")
+ ELSE()
-+ pkg_search_module(GSSAPI heimdal-gssapi heimdal-krb5)
++ pkg_check_modules(GSSAPI heimdal-gssapi heimdal-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "HEIMDAL")
+ ENDIF()
@@ -40,11 +40,11 @@ diff -aurN a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake b/plugin/auth_gssapi/cmak
+ find_package(PkgConfig)
+ IF(PKG_CONFIG_FOUND)
-+ pkg_search_module(GSSAPI mit-krb5-gssapi mit-krb5)
++ pkg_check_modules(GSSAPI mit-krb5-gssapi mit-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "MIT")
+ ELSE()
-+ pkg_search_module(GSSAPI heimdal-gssapi heimdal-krb5)
++ pkg_check_modules(GSSAPI heimdal-gssapi heimdal-krb5)
+ IF(GSSAPI_FOUND)
+ set(GSSAPI_FLAVOR "HEIMDAL")
+ ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-08-03 18:14 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-08-03 18:14 UTC (permalink / raw
To: gentoo-commits
commit: 386bd2fe281cb605ddefb3819a31bfad9a66e3f9
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 3 18:13:01 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Aug 3 18:13:01 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=386bd2fe
Add Patch such that the INSTALL_MYSQLSHAREDIR is considered for mysql_install_db
20026_all_mariadb-add-pkgdatadir.patch | 37 ++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/20026_all_mariadb-add-pkgdatadir.patch b/20026_all_mariadb-add-pkgdatadir.patch
new file mode 100644
index 0000000..3e25acc
--- /dev/null
+++ b/20026_all_mariadb-add-pkgdatadir.patch
@@ -0,0 +1,37 @@
+diff -uarN a/scripts/mysql_install_db.pl.in b/scripts/mysql_install_db.pl.in
+--- a/scripts/mysql_install_db.pl.in 2017-07-10 06:53:28.000000000 -0400
++++ b/scripts/mysql_install_db.pl.in 2017-08-03 12:41:39.480556405 -0400
+@@ -320,7 +320,7 @@
+ find_in_basedir($opt,"file","mysqld-nt",
+ "bin"); # ,"sql"
+ $srcpkgdatadir = find_in_basedir($opt,"dir","fill_help_tables.sql",
+- "share","share/mysql"); # ,"scripts"
++ "@pkgdatadir@","share","share/mysql"); # ,"scripts"
+ $buildpkgdir = $srcpkgdatadir;
+ $scriptdir = "$opt->{basedir}/scripts";
+ }
+diff -uarN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2017-07-10 06:53:28.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2017-08-03 12:38:26.509073203 -0400
+@@ -312,17 +312,17 @@
+ cannot_find_file mysqld $basedir/libexec $basedir/sbin $basedir/bin
+ exit 1
+ fi
+- langdir=`find_in_basedir --dir errmsg.sys share/english share/mysql/english`
++ langdir=`find_in_basedir --dir errmsg.sys @pkgdatadir@/english share/english share/mysql/english`
+ if test -z "$langdir"
+ then
+- cannot_find_file errmsg.sys $basedir/share/english $basedir/share/mysql/english
++ cannot_find_file errmsg.sys $basedir/@pkgdatadir@/english $basedir/share/english $basedir/share/mysql/english
+ exit 1
+ fi
+- srcpkgdatadir=`find_in_basedir --dir fill_help_tables.sql share share/mysql`
++ srcpkgdatadir=`find_in_basedir --dir fill_help_tables.sql @pkgdatadir@ share share/mysql`
+ buildpkgdatadir=$srcpkgdatadir
+ if test -z "$srcpkgdatadir"
+ then
+- cannot_find_file fill_help_tables.sql $basedir/share $basedir/share/mysql
++ cannot_find_file fill_help_tables.sql $basedir/@pkgdatadir@ $basedir/share $basedir/share/mysql
+ exit 1
+ fi
+ scriptdir="$basedir/scripts"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-08-20 22:45 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-08-20 22:45 UTC (permalink / raw
To: gentoo-commits
commit: 2c3b90e4ca44236232045fcd5ac65926606c17fd
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Aug 20 22:29:23 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Aug 20 22:29:23 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=2c3b90e4
Respin clientlibs patch for MariaDB 10.2.8
...l_mariadb-10.2.8-without-clientlibs-tools.patch | 161 +++++++++++++++++++++
1 file changed, 161 insertions(+)
diff --git a/20018_all_mariadb-10.2.8-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.8-without-clientlibs-tools.patch
new file mode 100644
index 0000000..79dc7a4
--- /dev/null
+++ b/20018_all_mariadb-10.2.8-without-clientlibs-tools.patch
@@ -0,0 +1,161 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/CMakeLists.txt 2017-06-28 13:14:25.686006673 -0400
+@@ -325,8 +325,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -363,28 +361,40 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
++IF(NOT WITHOUT_CLIENTLIBS)
+-INCLUDE(submodules)
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
++ENDIF()
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/extra/CMakeLists.txt 2017-06-28 12:54:14.972089739 -0400
+@@ -46,12 +46,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-TARGET_LINK_LIBRARIES(my_print_defaults mysys)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+-ADD_DEPENDENCIES(perror GenError)
+-TARGET_LINK_LIBRARIES(perror mysys)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ ADD_DEPENDENCIES(perror GenError)
++ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-05-14 19:13:15.000000000 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-06-28 13:08:17.185731795 -0400
+@@ -380,8 +380,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -379,7 +381,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "-Wl,--version-script=${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -398,9 +402,11 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2017-05-14 19:13:18.000000000 -0400
++++ b/scripts/CMakeLists.txt 2017-06-28 12:56:23.774081970 -0400
+@@ -276,7 +276,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -288,6 +287,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+
+
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2017-07-26 20:26:17.094481997 -0400
++++ b/libmariadb/libmariadb/CMakeLists.txt 2017-07-26 20:31:47.042608316 -0400
+@@ -427,9 +427,11 @@
+
+ IF(WITH_MYSQLCOMPAT)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-08-30 12:08 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-08-30 12:08 UTC (permalink / raw
To: gentoo-commits
commit: 848893453814ffa2b548180a1b3cdd96ec187a6f
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Aug 30 12:08:18 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Aug 30 12:08:18 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=84889345
Respin GSSAPI detection patch for 10.1.26
20025_all_mariadb-10.1.26-gssapi-detect.patch | 33 +++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
diff --git a/20025_all_mariadb-10.1.26-gssapi-detect.patch b/20025_all_mariadb-10.1.26-gssapi-detect.patch
new file mode 100644
index 0000000..846737e
--- /dev/null
+++ b/20025_all_mariadb-10.1.26-gssapi-detect.patch
@@ -0,0 +1,33 @@
+diff -aurN a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake b/plugin/auth_gssapi/cmake/FindGSSAPI.cmake
+--- a/plugin/auth_gssapi/cmake/FindGSSAPI.cmake 2017-05-14 19:13:17.000000000 -0400
++++ b/plugin/auth_gssapi/cmake/FindGSSAPI.cmake 2017-06-28 14:42:30.307704810 -0400
+@@ -39,6 +39,29 @@
+
+ else(GSSAPI_LIBS AND GSSAPI_FLAVOR)
+
++ find_package(PkgConfig)
++ IF(PKG_CONFIG_FOUND)
++ pkg_check_modules(GSSAPI mit-krb5-gssapi mit-krb5)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "MIT")
++ ELSE()
++ pkg_check_modules(GSSAPI heimdal-gssapi heimdal-krb5)
++ IF(GSSAPI_FOUND)
++ set(GSSAPI_FLAVOR "HEIMDAL")
++ ENDIF()
++ ENDIF()
++ IF(GSSAPI_FOUND)
++ message(STATUS "Found GSSAPI: ${GSSAPI_LIBRARIES}")
++
++ set(GSSAPI_INCS ${GSSAPI_INCLUDE_DIRS} CACHE STRING "" FORCE)
++ set(GSSAPI_LIBS ${GSSAPI_LIBRARIES} CACHE STRING "" FORCE)
++ set(GSSAPI_FLAVOR ${GSSAPI_FLAVOR} CACHE STRING "" FORCE)
++
++ mark_as_advanced(GSSAPI_INCS GSSAPI_LIBS GSSAPI_FLAVOR)
++ RETURN()
++ ENDIF()
++ ENDIF(PKG_CONFIG_FOUND)
++
+ find_program(KRB5_CONFIG NAMES krb5-config heimdal-krb5-config PATHS
+ /opt/local/bin
+ ONLY_CMAKE_FIND_ROOT_PATH # this is required when cross compiling with cmake 2.6 and ignored with cmake 2.4, Alex
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-09-26 13:18 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-09-26 13:18 UTC (permalink / raw
To: gentoo-commits
commit: 544d1a2e4ec9800d6926200401017f89f98d911d
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Sep 26 13:18:08 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Sep 26 13:18:08 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=544d1a2e
Respin elib patch for new versions
20006_all_cmake_elib-mariadb-10.0.33.patch | 178 +++++++++++++++++++++++++++++
20006_all_cmake_elib-mariadb-10.1.27.patch | 178 +++++++++++++++++++++++++++++
2 files changed, 356 insertions(+)
diff --git a/20006_all_cmake_elib-mariadb-10.0.33.patch b/20006_all_cmake_elib-mariadb-10.0.33.patch
new file mode 100644
index 0000000..03e94a9
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.0.33.patch
@@ -0,0 +1,178 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+ CACHE STRING "${var} installation directory" ${FORCE})
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT Development)
+
+@@ -163,7 +168,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql-old/scripts/mysql_config.sh b/mysql/scripts/mysql_config.sh
+--- mysql-old/scripts/mysql_config.sh 2014-04-25 20:05:16.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-04-25 20:08:01.000000000 -0400
+@@ -91,6 +91,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel lib/mysql/plugin lib/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -109,7 +113,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
diff --git a/20006_all_cmake_elib-mariadb-10.1.27.patch b/20006_all_cmake_elib-mariadb-10.1.27.patch
new file mode 100644
index 0000000..f93db99
--- /dev/null
+++ b/20006_all_cmake_elib-mariadb-10.1.27.patch
@@ -0,0 +1,178 @@
+diff -ur mysql-old/cmake/install_layout.cmake mysql/cmake/install_layout.cmake
+--- mysql-old/cmake/install_layout.cmake 2014-01-18 22:28:40.431273470 -0100
++++ mysql/cmake/install_layout.cmake 2014-01-18 22:40:48.646301163 -0100
+@@ -44,7 +44,8 @@
+ # - INSTALL_SYSCONFDIR (my.cnf config file. Usually /etc or nothing)
+ # - INSTALL_SYSCONF2DIR (additional config files, e.g. /etc/mysql/conf.d)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -120,6 +121,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include/mysql")
+@@ -150,9 +152,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -183,6 +187,7 @@
+ SET(INSTALL_SYSCONF2DIR_DEB "/etc/mysql/conf.d")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/mysql/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include/mysql")
+@@ -210,6 +215,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include/mysql")
+@@ -241,7 +247,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN SYSCONF SYSCONF2
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA UNIX_ADDR
+ SYSTEMD_UNIT)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -ur mysql-old/cmake/libutils.cmake mysql/cmake/libutils.cmake
+--- mysql-old/cmake/libutils.cmake 2014-01-18 22:28:40.430273470 -0100
++++ mysql/cmake/libutils.cmake 2014-01-18 22:28:52.801273941 -0100
+@@ -211,10 +211,11 @@
+ # [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exportedFuncN]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;VERSION;SOVERSION;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -274,7 +275,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE()
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+ IF(ARG_SHARED AND LINK_FLAG_NO_UNDEFINED)
+diff -ur mysql-old/libmysql/CMakeLists.txt mysql/libmysql/CMakeLists.txt
+--- mysql-old/libmysql/CMakeLists.txt 2014-01-18 22:28:40.429273470 -0100
++++ mysql/libmysql/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -327,9 +327,14 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -350,7 +355,9 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -ur mysql-old/libmysqld/CMakeLists.txt mysql/libmysqld/CMakeLists.txt
+--- mysql-old/libmysqld/CMakeLists.txt 2014-01-18 22:28:40.090273457 -0100
++++ mysql/libmysqld/CMakeLists.txt 2014-01-18 22:28:53.025273949 -0100
+@@ -133,8 +133,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER})
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT ${COMPONENT_MYSQLSERVER} OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ INSTALL(FILES embedded_priv.h DESTINATION ${INSTALL_INCLUDEDIR}/private COMPONENT ${COMPONENT_MYSQLSERVER})
+
+@@ -163,7 +167,7 @@
+
+ IF(NOT DISABLE_SHARED)
+ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${EMBEDDED_API}
+- COMPONENT ${COMPONENT_LIBMYSQLD})
++ COMPONENT ${COMPONENT_LIBMYSQLD} OUTPUT_DIR ${INSTALL_ELIBDIR})
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client
+ # library hence the same version)
+diff -aurN a/mysql/scripts/CMakeLists.txt b/mysql/scripts/CMakeLists.txt
+--- mysql-old/scripts/CMakeLists.txt 2014-04-15 07:02:28.000000000 -0400
++++ mysql/scripts/CMakeLists.txt 2014-04-25 19:24:14.000000000 -0400
+@@ -236,6 +236,7 @@
+ SET(pkglibdir ${prefix}/${INSTALL_LIBDIR})
+ SET(pkgplugindir ${prefix}/${INSTALL_PLUGINDIR})
+ SET(localstatedir ${MYSQL_DATADIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+
+ SET(RPATH_OPTION "")
+ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
+diff -aurN mysql.orig/scripts/mysql_config.sh mysql/scripts/mysql_config.sh
+--- mysql.orig/scripts/mysql_config.sh 2014-10-15 18:53:51.000000000 -0400
++++ mysql/scripts/mysql_config.sh 2014-10-22 16:17:02.590868620 -0400
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel @libsubdir@/mysql @libsubdir@
++
+ pkgincludedir='@pkgincludedir@'
+ fix_path pkgincludedir include/mysql
+
+@@ -106,7 +110,7 @@
+
+ # Create options
+ libs="-L$pkglibdir @RPATH_OPTION@ @LIBS_FOR_CLIENTS@"
+-embedded_libs="-L$pkglibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
++embedded_libs="-L$elibdir @RPATH_OPTION@ @EMB_LIBS_FOR_CLIENTS@"
+
+ include="-I$pkgincludedir"
+ if [ "$basedir" != "/usr" ]; then
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-10-18 13:24 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-10-18 13:24 UTC (permalink / raw
To: gentoo-commits
commit: c3f93e9d43c49c57f6bcbb92e55e7bb106ee4297
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 18 13:23:56 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 18 13:23:56 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c3f93e9d
Add patch for Perl 5.26+ compatibility for tests
20027_all_mysql-5.5-perl5.26-includes.patch | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/20027_all_mysql-5.5-perl5.26-includes.patch b/20027_all_mysql-5.5-perl5.26-includes.patch
new file mode 100644
index 0000000..f1e02cc
--- /dev/null
+++ b/20027_all_mysql-5.5-perl5.26-includes.patch
@@ -0,0 +1,29 @@
+diff -aurN a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
+--- a/mysql-test/mysql-test-run.pl 2017-09-13 11:20:41.000000000 -0400
++++ b/mysql-test/mysql-test-run.pl 2017-10-18 09:04:10.470550268 -0400
+@@ -75,7 +75,7 @@
+ }
+ }
+
+-use lib "lib";
++use lib "./lib";
+
+ use Cwd;
+ use Getopt::Long;
+@@ -100,11 +100,11 @@
+ use IO::Socket::INET;
+ use IO::Select;
+
+-require "lib/mtr_process.pl";
+-require "lib/mtr_io.pl";
+-require "lib/mtr_gcov.pl";
+-require "lib/mtr_gprof.pl";
+-require "lib/mtr_misc.pl";
++require "./lib/mtr_process.pl";
++require "./lib/mtr_io.pl";
++require "./lib/mtr_gcov.pl";
++require "./lib/mtr_gprof.pl";
++require "./lib/mtr_misc.pl";
+
+ $SIG{INT}= sub { mtr_error("Got ^C signal"); };
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-10-18 13:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-10-18 13:40 UTC (permalink / raw
To: gentoo-commits
commit: ff68f2bbf85966901b1ba59e60d98465aca6a2bf
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 18 13:27:12 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 18 13:27:12 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=ff68f2bb
Update index for last patch
00000_index.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 980ddd4..3239669 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -960,3 +960,9 @@
@pn mysql
@@ Fix use-after-free in mysql_prune_stmt_list
@@ Back ported from mysql 5.6; Oracle bug 17512527
+
+@patch 20027_all_mysql-5.5-perl5.26-includes.patch
+@ver 5.05.00.00 to 5.07.99.99
+@pn mysql
+@pn mariadb
+@@ Fix tests for Perl 5.26+ compatibility
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-10-18 19:48 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-10-18 19:48 UTC (permalink / raw
To: gentoo-commits
commit: 3b2b8ea223d5dea9954adc01f0a4129925e4cc27
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 18 19:47:58 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Oct 18 19:47:58 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3b2b8ea2
Rebase Perl test patch on what MariaDB did
20027_all_mysql-5.5-perl5.26-includes.patch | 79 +++++++++++++++++++++++------
1 file changed, 64 insertions(+), 15 deletions(-)
diff --git a/20027_all_mysql-5.5-perl5.26-includes.patch b/20027_all_mysql-5.5-perl5.26-includes.patch
index f1e02cc..9e3479e 100644
--- a/20027_all_mysql-5.5-perl5.26-includes.patch
+++ b/20027_all_mysql-5.5-perl5.26-includes.patch
@@ -1,15 +1,64 @@
-diff -aurN a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
---- a/mysql-test/mysql-test-run.pl 2017-09-13 11:20:41.000000000 -0400
-+++ b/mysql-test/mysql-test-run.pl 2017-10-18 09:04:10.470550268 -0400
-@@ -75,7 +75,7 @@
- }
- }
+Based on MariaDB commit:
+
+From d185f1d68bb1f37bea10d8ac6188e5a04faf4522 Mon Sep 17 00:00:00 2001
+From: Oleksandr Byelkin <sanja@mariadb.com>
+Date: Wed, 19 Apr 2017 14:30:52 +0200
+Subject: [PATCH] Fix use of `require` in mysql-test-run.
+
+The motivation for this is that Perl is moving towards not having
+current directory ./ in @INC by default. This is causing
+mysql-test-run.pl to fail in latest Debian Unstable:
+
+ https://lists.debian.org/debian-devel-announce/2016/08/msg00013.html
+
+However, we have `use "lib"`, there is no need for current directory
+in @INC, except for a gross hack. In mtr_cases.pm, there is a
+`require "mtr_misc.pl"`, which hides mtr_misc.pl away in mtr_cases
+namespace. And things only work because mysql-test-run.pl loads it
+with a different name, `require "lib/mtr_misc.pl"`! (Perl will
+`require` only once for each unique filename).
+
+Fix this by only using `require` in main program, and referencing
+functions with :: scope from other namespaces. For multi-use in
+different namespaces, proper `use` modules should be used.
+
+Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
+
+diff -aurN a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm
+--- a/mysql-test/lib/mtr_cases.pm 2017-09-13 11:20:41.000000000 -0400
++++ b/mysql-test/lib/mtr_cases.pm 2017-10-18 13:26:23.071250558 -0400
+@@ -68,8 +68,6 @@
+ use My::Test;
+ use My::Find;
--use lib "lib";
-+use lib "./lib";
+-require "mtr_misc.pl";
+-
+ # Precompiled regex's for tests to do or skip
+ my $do_test_reg;
+ my $skip_test_reg;
+diff -aurN a/mysql-test/lib/mtr_report.pm b/mysql-test/lib/mtr_report.pm
+--- a/mysql-test/lib/mtr_report.pm 2017-09-13 11:20:41.000000000 -0400
++++ b/mysql-test/lib/mtr_report.pm 2017-10-18 13:23:22.589301656 -0400
+@@ -33,7 +33,6 @@
+ use My::Platform;
+ use POSIX qw[ _exit ];
+ use IO::Handle qw[ flush ];
+-require "mtr_io.pl";
+ use mtr_results;
- use Cwd;
- use Getopt::Long;
+ my $tot_real_time= 0;
+@@ -95,7 +94,7 @@
+ my $timer_str= "";
+ if ( $timer and -f "$::opt_vardir/log/timer" )
+ {
+- $timer_str= mtr_fromfile("$::opt_vardir/log/timer");
++ $timer_str= ::mtr_fromfile("$::opt_vardir/log/timer");
+ $tinfo->{timer}= $timer_str;
+ resfile_test_info('duration', $timer_str) if $::opt_resfile;
+ }
+diff -aurN a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
+--- a/mysql-test/mysql-test-run.pl 2017-09-13 11:20:41.000000000 -0400
++++ b/mysql-test/mysql-test-run.pl 2017-10-18 13:22:05.012314793 -0400
@@ -100,11 +100,11 @@
use IO::Socket::INET;
use IO::Select;
@@ -19,11 +68,11 @@ diff -aurN a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
-require "lib/mtr_gcov.pl";
-require "lib/mtr_gprof.pl";
-require "lib/mtr_misc.pl";
-+require "./lib/mtr_process.pl";
-+require "./lib/mtr_io.pl";
-+require "./lib/mtr_gcov.pl";
-+require "./lib/mtr_gprof.pl";
-+require "./lib/mtr_misc.pl";
++require "mtr_process.pl";
++require "mtr_io.pl";
++require "mtr_gcov.pl";
++require "mtr_gprof.pl";
++require "mtr_misc.pl";
$SIG{INT}= sub { mtr_error("Got ^C signal"); };
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-11-08 20:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-11-08 20:50 UTC (permalink / raw
To: gentoo-commits
commit: 9f62f53fdece8ae9441a9909b95e6f024849ddd1
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Nov 8 20:50:04 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Nov 8 20:50:04 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=9f62f53f
Respin index for cluster updates
00000_index.txt | 96 +++++++++++++++++----------------------------------------
1 file changed, 28 insertions(+), 68 deletions(-)
diff --git a/00000_index.txt b/00000_index.txt
index 3239669..19fb8a1 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -96,23 +96,17 @@
@patch 01050_all_mysql_config_cleanup-5.5.patch
@ver 5.05.00.00 to 5.05.99.99
-@pn mysql
-@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-
-@patch 01050_all_mysql_config_cleanup-5.5.patch
@ver 7.02.00.00 to 7.02.99.99
@pn mysql-cluster
-@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
-
-@patch 01050_all_mysql_config_cleanup-5.6.patch
-@ver 5.06.00.00 to 5.06.99.99
@pn mysql
-@pn percona-server
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 01050_all_mysql_config_cleanup-5.6.patch
+@ver 5.06.00.00 to 5.06.99.99
@ver 7.03.00.00 to 7.03.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ fix bug #156301 mysql_config wrongly retains too much info from CFLAGS
@patch 02000_all_query-logging-bypass-4.1.19.patch
@@ -133,13 +127,10 @@
@patch 02040_all_embedded-library-shared-5.5.10.patch
@ver 5.05.10.00 to 5.07.99.99
-@pn mysql
-@pn percona-server
-@@ Take libmysqld to be a proper shared library.
-
-@patch 02040_all_embedded-library-shared-5.5.10.patch
@ver 7.02.01.00 to 7.99.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Take libmysqld to be a proper shared library.
@patch 04000_all_mysqld-safe-sh-4.0.27.patch
@@ -455,13 +446,10 @@
@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
@ver 5.05.41.00 to 5.05.99.99
-@pn mysql
-@pn percona-server
-@@ Fix the minimal build by reordering CMakeLists.txt
-
-@patch 20001_all_fix-minimal-build-cmake-mysql-5.5.41.patch
@ver 7.02.19.00 to 7.02.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.patch
@@ -472,13 +460,10 @@
@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
@ver 5.06.20.00 to 5.06.99.99
-@pn mysql
-@pn percona-server
-@@ Fix the minimal build by reordering CMakeLists.txt
-
-@patch 20001_all_fix-minimal-build-cmake-mysql-5.6.20.patch
@ver 7.03.07.00 to 7.03.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Fix the minimal build by reordering CMakeLists.txt
@patch 20001_all_fix-minimal-build-cmake-mariadb.patch
@@ -495,13 +480,10 @@
@patch 20002_all_mysql-va-list.patch
@ver 5.05.00.00 to 5.05.99.99
-@pn mysql
-@pn percona-server
-@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
-
-@patch 20002_all_mysql-va-list.patch
@ver 7.02.01.00 to 7.02.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Bug 442000, upstream 62769 compilation failure on arm and possibly other arches where va_list is a struct or array.
@patch 20002_all_mysql-va-list-5.6.patch
@@ -602,7 +584,7 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-cluster-5.5.37.patch
-@ver 7.02.16.00 to 7.02.99.99
+@ver 7.02.16.00 to 7.02.25.99
@pn mysql-cluster
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
@@ -626,7 +608,7 @@
@@ Also install static libs by ENABLE_STATIC_LIBS
@patch 20006_all_cmake_elib-mysql-cluster-5.6.22.patch
-@ver 7.03.08.00 to 7.03.99.99
+@ver 7.03.08.00 to 7.03.18.99
@pn mysql-cluster
@@ Add ELIBPATH to split client and embedded libs
@@ Also install static libs by ENABLE_STATIC_LIBS
@@ -732,13 +714,10 @@
@patch 20007_all_cmake-debug-werror-5.6.22.patch
@ver 5.05.41.00 to 5.05.99.99
@ver 5.06.22.00 to 5.06.99.99
-@pn mysql
-@pn percona-server
-@@ Remove -Werror from USE="debug" builds
-
-@patch 20007_all_cmake-debug-werror-5.6.22.patch
@ver 7.02.19.00 to 7.99.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Remove -Werror from USE="debug" builds
@patch 20008_all_mysql-tzinfo-symlink.patch
@@ -762,7 +741,8 @@
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@patch 20008_all_mysql-tzinfo-symlink.patch
-@ver 7.02.16.00 to 7.99.99.99
+@ver 7.02.16.00 to 7.02.25.99
+@ver 7.03.00.00 to 7.03.14.99
@pn mysql-cluster
@@ Backport tzinfo symlink fix from MariaDB bug 491176
@@ -775,17 +755,16 @@
@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
@ver 5.05.38.00 to 5.05.99.99
-@pn mysql
-@pn percona-server
-@@ Export missing symbols
-
-@patch 20009_all_mysql_myodbc_symbol_fix-5.5.38.patch
@ver 7.02.18.00 to 7.02.99.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Export missing symbols
@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
@ver 5.06.00.00 to 5.06.99.99
+@ver 7.03.00.00 to 7.99.99.99
+@pn mysql-cluster
@pn mysql
@pn percona-server
@@ Export missing symbols
@@ -808,11 +787,6 @@
@pn percona-server
@@ Export missing symbols
-@patch 20009_all_mysql_myodbc_symbol_fix-5.6.patch
-@ver 7.03.00.00 to 7.99.99.99
-@pn mysql-cluster
-@@ Export missing symbols
-
@patch 20009_all_mariadb_myodbc_symbol_fix-5.5.38.patch
@ver 5.05.38.00 to 10.99.99.99
@pn mariadb
@@ -872,15 +846,10 @@
@patch 20017_all_mysql-openssl-cmake-detection.patch
@ver 5.06.00.00 to 5.06.23.99
@ver 5.07.00.00 to 5.07.06.99
-@pn mysql
-@pn percona-server
-@@ Fix detection of OpenSSL 1.0.2
-@@ Bug 537872
-@@ Upstream bug 75622
-
-@patch 20017_all_mysql-openssl-cmake-detection.patch
@ver 7.03.00.00 to 7.03.08.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Fix detection of OpenSSL 1.0.2
@@ Bug 537872
@@ Upstream bug 75622
@@ -924,28 +893,19 @@
@patch 20019_all_mysql-5.5-mtr-perl-deprecation.patch
@ver 5.05.45.00 to 5.05.52.99
-@pn mysql
-@@ Fix deprecated perl array defined syntax on mtr test script
-@@ Ported forward from mysql 5.6; Oracle bug 18145121
-
-@patch 20019_all_mysql-5.5-mtr-perl-deprecation.patch
-@ver 7.02.00.00 to 7.02.99.99
+@ver 7.02.00.00 to 7.02.25.99
@pn mysql-cluster
+@pn mysql
@@ Fix deprecated perl array defined syntax on mtr test script
@@ Ported forward from mysql 5.6; Oracle bug 18145121
@patch 20020_all_mysql-5.6-events_1-bug-78899.patch
@ver 5.06.00.00 to 5.06.27.99
-@pn mysql
-@pn percona-server
-@@ Fix events_1 test for October 2015
-@@ Patch backported from mariadb
-@@ Bug 564968 Upstream bug 78899
-
-@patch 20020_all_mysql-5.6-events_1-bug-78899.patch
-@ver 7.02.00.00 to 7.02.99.99
+@ver 7.02.00.00 to 7.02.22.99
@ver 7.03.00.00 to 7.03.12.99
@pn mysql-cluster
+@pn mysql
+@pn percona-server
@@ Fix events_1 test for October 2015
@@ Patch backported from mariadb
@@ Bug 564968 Upstream bug 78899
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2017-11-21 15:00 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2017-11-21 15:00 UTC (permalink / raw
To: gentoo-commits
commit: 3a4ccb251df768eb8d9ab440ebf220c22a8556af
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Nov 21 15:00:08 2017 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Nov 21 15:00:08 2017 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3a4ccb25
Add gcc 7 compilation patch for MySQL 5.6
20028_all_mysql-5.6-gcc7.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20028_all_mysql-5.6-gcc7.patch b/20028_all_mysql-5.6-gcc7.patch
new file mode 100644
index 0000000..cf8caed
--- /dev/null
+++ b/20028_all_mysql-5.6-gcc7.patch
@@ -0,0 +1,13 @@
+diff --git a/sql-common/client_authentication.cc b/sql-common/client_authentication.cc
+index eaeb2d4..035ecd2 100644
+--- a/sql-common/client_authentication.cc
++++ b/sql-common/client_authentication.cc
+@@ -84,7 +84,7 @@ RSA *rsa_init(MYSQL *mysql)
+
+ if (mysql->options.extension != NULL &&
+ mysql->options.extension->server_public_key_path != NULL &&
+- mysql->options.extension->server_public_key_path != '\0')
++ mysql->options.extension->server_public_key_path[0] != '\0')
+ {
+ pub_key_file= fopen(mysql->options.extension->server_public_key_path,
+ "r");
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-02-09 21:42 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-02-09 21:42 UTC (permalink / raw
To: gentoo-commits
commit: 04ef58d781e50b4f676789e70899e761dbdcdd0f
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Feb 9 21:41:49 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Feb 9 21:41:49 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=04ef58d7
Add patch to enable NUMA in MariaDB 10.1
20029_all_mariadb-10.1.31-enable-numa.patch | 209 ++++++++++++++++++++++++++++
1 file changed, 209 insertions(+)
diff --git a/20029_all_mariadb-10.1.31-enable-numa.patch b/20029_all_mariadb-10.1.31-enable-numa.patch
new file mode 100644
index 0000000..41c8fa0
--- /dev/null
+++ b/20029_all_mariadb-10.1.31-enable-numa.patch
@@ -0,0 +1,209 @@
+Backport MariaDB 10.2 support into 10.1
+
+diff --git a/cmake/numa.cmake b/cmake/numa.cmake
+new file mode 100644
+index 000000000000..d5234a5ef4f6
+--- /dev/null
++++ b/cmake/numa.cmake
+@@ -0,0 +1,43 @@
++MACRO (MYSQL_CHECK_NUMA)
++
++ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
++ CHECK_INCLUDE_FILES(numa.h HAVE_NUMA_H)
++ CHECK_INCLUDE_FILES(numaif.h HAVE_NUMAIF_H)
++
++ IF(HAVE_NUMA_H AND HAVE_NUMAIF_H)
++ OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" ON)
++ ELSE()
++ OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" OFF)
++ ENDIF()
++
++ IF(WITH_NUMA AND HAVE_NUMA_H AND HAVE_NUMAIF_H)
++ SET(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
++ SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} numa)
++ CHECK_C_SOURCE_COMPILES(
++ "
++ #include <numa.h>
++ #include <numaif.h>
++ int main()
++ {
++ struct bitmask *all_nodes= numa_all_nodes_ptr;
++ set_mempolicy(MPOL_DEFAULT, 0, 0);
++ return all_nodes != NULL;
++ }"
++ HAVE_LIBNUMA)
++ SET(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
++ IF(HAVE_LIBNUMA)
++ ADD_DEFINITIONS(-DHAVE_LIBNUMA=1)
++ SET(NUMA_LIBRARY "numa")
++ ENDIF()
++ ENDIF()
++
++ IF(WITH_NUMA AND NOT HAVE_LIBNUMA)
++ # Forget it in cache, abort the build.
++ UNSET(WITH_NUMA CACHE)
++ UNSET(NUMA_LIBRARY CACHE)
++ MESSAGE(FATAL_ERROR "Could not find numa headers/libraries")
++ ENDIF()
++ ENDIF()
++
++ENDMACRO()
++
+diff --git a/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt
+new file mode 100644
+index 000000000000..c1c2bb26b8ac
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt
+@@ -0,0 +1,1 @@
++--loose-innodb_numa_interleave=1
+diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
+index 7e667d5ebb29..c80ef6f09937 100644
+--- a/storage/innobase/CMakeLists.txt
++++ b/storage/innobase/CMakeLists.txt
+@@ -23,12 +23,14 @@ INCLUDE(lzo)
+ INCLUDE(lzma)
+ INCLUDE(bzip2)
+ INCLUDE(snappy)
++INCLUDE(numa)
+
+ MYSQL_CHECK_LZ4()
+ MYSQL_CHECK_LZO()
+ MYSQL_CHECK_LZMA()
+ MYSQL_CHECK_BZIP2()
+ MYSQL_CHECK_SNAPPY()
++MYSQL_CHECK_NUMA()
+
+ IF(CMAKE_CROSSCOMPILING)
+ # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when
+@@ -63,5 +63,2 @@
+ ENDIF()
+ ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1")
+- IF(HAVE_LIBNUMA)
+- LINK_LIBRARIES(numa)
+- ENDIF()
+@@ -517,6 +517,10 @@
+ MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
+ MODULE_ONLY
+ MODULE_OUTPUT_NAME ha_innodb
+- LINK_LIBRARIES ${ZLIB_LIBRARY} ${LIBSYSTEMD} ${LINKER_SCRIPT})
++ LINK_LIBRARIES
++ ${ZLIB_LIBRARY}
++ ${NUMA_LIBRARY}
++ ${LIBSYSTEMD}
++ ${LINKER_SCRIPT})
+
+ ADD_DEPENDENCIES(innobase GenError)
+diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
+index 7d2a3fad56dc..51e24b3cd8a2 100644
+--- a/storage/xtradb/CMakeLists.txt
++++ b/storage/xtradb/CMakeLists.txt
+@@ -23,12 +23,14 @@ INCLUDE(lzo)
+ INCLUDE(lzma)
+ INCLUDE(bzip2)
+ INCLUDE(snappy)
++INCLUDE(numa)
+
+ MYSQL_CHECK_LZ4()
+ MYSQL_CHECK_LZO()
+ MYSQL_CHECK_LZMA()
+ MYSQL_CHECK_BZIP2()
+ MYSQL_CHECK_SNAPPY()
++MYSQL_CHECK_NUMA()
+
+ IF(CMAKE_CROSSCOMPILING)
+ # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when
+@@ -63,5 +63,2 @@
+ ENDIF()
+ ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1")
+- IF(HAVE_LIBNUMA)
+- LINK_LIBRARIES(numa)
+- ENDIF()
+@@ -507,6 +507,9 @@
+ MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE
+ DEFAULT RECOMPILE_FOR_EMBEDDED
+- LINK_LIBRARIES ${ZLIB_LIBRARY} ${LINKER_SCRIPT})
++ LINK_LIBRARIES
++ ${ZLIB_LIBRARY}
++ ${NUMA_LIBRARY}
++ ${LINKER_SCRIPT})
+
+ IF(TARGET xtradb AND NOT XTRADB_OK)
+ MESSAGE(FATAL_ERROR "Percona XtraDB is not supported on this platform")
+diff --git a/mysql-test/include/have_numa.inc b/mysql-test/include/have_numa.inc
+new file mode 100644
+index 000000000000..18bca99e04d7
+--- /dev/null
++++ b/mysql-test/include/have_numa.inc
+@@ -0,0 +1,9 @@
++let $numa_support = `SELECT COUNT(VARIABLE_VALUE) = 1 FROM
++ INFORMATION_SCHEMA.GLOBAL_VARIABLES
++ WHERE VARIABLE_NAME='innodb_numa_interleave'`;
++
++if ( $numa_support == 0 )
++{
++ --skip Test requires: Binary must be built with NUMA support.
++}
++
+diff --git a/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result b/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result
+new file mode 100644
+index 000000000000..21ed16c1dab8
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result
+@@ -0,0 +1,11 @@
++call mtr.add_suppression("InnoDB: Failed to set NUMA memory policy");
++SELECT @@GLOBAL.innodb_numa_interleave;
++@@GLOBAL.innodb_numa_interleave
++1
++SET @@GLOBAL.innodb_numa_interleave=off;
++ERROR HY000: Variable 'innodb_numa_interleave' is a read only variable
++SELECT @@GLOBAL.innodb_numa_interleave;
++@@GLOBAL.innodb_numa_interleave
++1
++SELECT @@SESSION.innodb_numa_interleave;
++ERROR HY000: Variable 'innodb_numa_interleave' is a GLOBAL variable
+diff --git a/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test
+new file mode 100644
+index 000000000000..518b5ebba177
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test
+@@ -0,0 +1,15 @@
++--source include/have_innodb.inc
++--source include/have_numa.inc
++
++call mtr.add_suppression("InnoDB: Failed to set NUMA memory policy");
++
++SELECT @@GLOBAL.innodb_numa_interleave;
++
++--error ER_INCORRECT_GLOBAL_LOCAL_VAR
++SET @@GLOBAL.innodb_numa_interleave=off;
++
++SELECT @@GLOBAL.innodb_numa_interleave;
++
++--error ER_INCORRECT_GLOBAL_LOCAL_VAR
++SELECT @@SESSION.innodb_numa_interleave;
++
+diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+index 87e000faf025..ad6dcc1bb643 100644
+--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
++++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+@@ -2,6 +2,7 @@ select * from information_schema.system_variables
+ where variable_name like 'innodb%' and
+ variable_name not in (
+ 'innodb_disallow_writes', # only available WITH_WSREP
++'innodb_numa_interleave', # only available WITH_NUMA
+ 'innodb_sched_priority_cleaner', # linux only
+ 'innodb_use_native_aio') # default value depends on OS
+ order by variable_name;
+diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+index bd8442b6a443..38f248cb6113 100644
+--- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test
++++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+@@ -9,6 +9,7 @@ select * from information_schema.system_variables
+ where variable_name like 'innodb%' and
+ variable_name not in (
+ 'innodb_disallow_writes', # only available WITH_WSREP
++ 'innodb_numa_interleave', # only available WITH_NUMA
+ 'innodb_sched_priority_cleaner', # linux only
+ 'innodb_use_native_aio') # default value depends on OS
+ order by variable_name;
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-02-14 0:43 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-02-14 0:43 UTC (permalink / raw
To: gentoo-commits
commit: bb6f2115f03bcc765a2b1958016cbc1c6c9918c9
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 14 00:05:17 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Feb 14 00:24:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=bb6f2115
Add patch to fix invalid type in MySQL 5.5
Bug: https://bugs.gentoo.org/645894
00000_index.txt | 6 +++++
20030_all_mysql-5.5-fix-client-mysql-type.patch | 29 +++++++++++++++++++++++++
2 files changed, 35 insertions(+)
diff --git a/00000_index.txt b/00000_index.txt
index 19fb8a1..b5d3ee4 100644
--- a/00000_index.txt
+++ b/00000_index.txt
@@ -926,3 +926,9 @@
@pn mysql
@pn mariadb
@@ Fix tests for Perl 5.26+ compatibility
+
+@patch 20030_all_mysql-5.5-fix-client-mysql-type.patch
+@ver 5.05.58.00 to 5.05.99.99
+@pn mysql
+@@ Fix type in mysql client
+@@ Bug 645894
diff --git a/20030_all_mysql-5.5-fix-client-mysql-type.patch b/20030_all_mysql-5.5-fix-client-mysql-type.patch
new file mode 100644
index 0000000..b62e192
--- /dev/null
+++ b/20030_all_mysql-5.5-fix-client-mysql-type.patch
@@ -0,0 +1,29 @@
+From https://github.com/MariaDB/server/commit/7338d3f221e33042dfcf5c1a245317aa7cb015a7
+From: Daniel Black <daniel.black@au.ibm.com>
+Date: Fri, 14 Jul 2017 13:37:37 +1000
+Subject: [PATCH] client: mysql - fix type
+
+field_names[x][y] is a pointer
+
+client/mysql.cc: In function 'void build_completion_hash(bool, bool)':
+client/mysql.cc:2855:37: error: invalid conversion from 'char' to 'char*' [-fpermissive]
+ field_names[i][num_fields*2]= '\0';
+
+Bug: https://bugs.gentoo.org/645894
+---
+ client/mysql.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/client/mysql.cc b/client/mysql.cc
+index a965ced89c65..ca586a5590fb 100644
+--- a/client/mysql.cc
++++ b/client/mysql.cc
+@@ -2852,7 +2852,7 @@ You can turn off this feature to get a quicker startup with -A\n\n");
+ mysql_free_result(fields);
+ break;
+ }
+- field_names[i][num_fields*2]= '\0';
++ field_names[i][num_fields*2]= NULL;
+ j=0;
+ while ((sql_field=mysql_fetch_field(fields)))
+ {
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-02-14 0:43 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-02-14 0:43 UTC (permalink / raw
To: gentoo-commits
commit: 7b6db3c69be46456e84788a875bc7fb8eb09e16f
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 14 00:06:46 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Feb 14 00:24:35 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=7b6db3c6
Add patch to fix monitor.test in MySQL 5.6
Bug: https://bugs.gentoo.org/645838
20031_all_mysql-5.6-fix-monitor.test.patch | 129 +++++++++++++++++++++++++++++
1 file changed, 129 insertions(+)
diff --git a/20031_all_mysql-5.6-fix-monitor.test.patch b/20031_all_mysql-5.6-fix-monitor.test.patch
new file mode 100644
index 0000000..14825ff
--- /dev/null
+++ b/20031_all_mysql-5.6-fix-monitor.test.patch
@@ -0,0 +1,129 @@
+From https://github.com/MariaDB/server/commit/07977c13e71a9fc4a7695facff5fac9d7ff1e870
+From: Monty <monty@mariadb.org>
+Date: Tue, 5 Sep 2017 16:24:29 +0300
+Subject: [PATCH] Fixed monitor.test to handle statistics >= 10
+
+Bug: https://bugs.gentoo.org/645838
+---
+ mysql-test/suite/innodb/r/monitor.result | 30 +++++++++++++++---------------
+ mysql-test/suite/innodb/t/monitor.test | 18 ++++++------------
+ 2 files changed, 21 insertions(+), 27 deletions(-)
+
+diff --git a/mysql-test/suite/innodb/r/monitor.result b/mysql-test/suite/innodb/r/monitor.result
+index 33a09a553b98..2700479e7f73 100644
+--- a/mysql-test/suite/innodb/r/monitor.result
++++ b/mysql-test/suite/innodb/r/monitor.result
+@@ -622,46 +622,46 @@ set global innodb_monitor_reset_all = default;
+ # MONITORS
+ #
+ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
++NAME COUNT > 0
+ buffer_page_written_index_leaf 0
+ SET GLOBAL innodb_monitor_enable='module_buffer_page';
+ INSERT INTO t1 VALUES (1), (2), (3), (4);
+ FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
+-buffer_page_written_index_leaf NNNN
++NAME COUNT > 0
++buffer_page_written_index_leaf 1
+ SET GLOBAL innodb_monitor_disable='module_buffer_page';
+ SET GLOBAL innodb_monitor_reset_all='module_buffer_page';
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
++NAME COUNT > 0
+ buffer_page_written_index_leaf 0
+ SET GLOBAL innodb_monitor_enable='%';
+ INSERT INTO t1 VALUES (5), (6), (7), (8);
+ FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
+-buffer_page_written_index_leaf NNNN
++NAME COUNT > 0
++buffer_page_written_index_leaf 1
+ SET GLOBAL innodb_monitor_disable='%';
+ SET GLOBAL innodb_monitor_reset_all='%';
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
++NAME COUNT > 0
+ buffer_page_written_index_leaf 0
+ SET GLOBAL innodb_monitor_enable='ALL';
+ INSERT INTO t1 VALUES (9), (10), (11), (12);
+ FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+-NAME COUNT
+-buffer_page_written_index_leaf NNNN
++NAME COUNT > 0
++buffer_page_written_index_leaf 1
+ SET GLOBAL innodb_monitor_enable=default;
+ SET GLOBAL innodb_monitor_disable=default;
+ SET GLOBAL innodb_monitor_reset_all=default;
+diff --git a/mysql-test/suite/innodb/t/monitor.test b/mysql-test/suite/innodb/t/monitor.test
+index 98aa4505e341..dfae93694bff 100644
+--- a/mysql-test/suite/innodb/t/monitor.test
++++ b/mysql-test/suite/innodb/t/monitor.test
+@@ -391,41 +391,35 @@ CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
+
+ let $innodb_monitor_enable = `SELECT @@innodb_monitor_enable`;
+
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ SET GLOBAL innodb_monitor_enable='module_buffer_page';
+ INSERT INTO t1 VALUES (1), (2), (3), (4); FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ SET GLOBAL innodb_monitor_disable='module_buffer_page';
+ SET GLOBAL innodb_monitor_reset_all='module_buffer_page';
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ SET GLOBAL innodb_monitor_enable='%';
+ INSERT INTO t1 VALUES (5), (6), (7), (8); FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ SET GLOBAL innodb_monitor_disable='%';
+ SET GLOBAL innodb_monitor_reset_all='%';
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ SET GLOBAL innodb_monitor_enable='ALL';
+ INSERT INTO t1 VALUES (9), (10), (11), (12); FLUSH TABLES t1 FOR EXPORT;
+ UNLOCK TABLES;
+---replace_regex /[1-9]/NNNN/
+-SELECT NAME, COUNT FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
++SELECT NAME, COUNT > 0 FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE NAME
+ LIKE 'buffer_page_written_index_leaf';
+
+ --disable_warnings
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-02-28 16:11 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-02-28 16:11 UTC (permalink / raw
To: gentoo-commits
commit: a98663207844c9e435f2c63d8a8ff81f9e042a08
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Feb 28 16:10:53 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Feb 28 16:10:53 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a9866320
Fix patch for client-libs on 10.2/10.3
...l_mariadb-10.2.9-without-clientlibs-tools.patch | 200 +++++++++++++++++++++
1 file changed, 200 insertions(+)
diff --git a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
new file mode 100644
index 0000000..5919c67
--- /dev/null
+++ b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
@@ -0,0 +1,200 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2018-02-27 16:45:56.740178421 -0500
++++ b/CMakeLists.txt 2018-02-28 09:06:59.163673185 -0500
+@@ -339,8 +339,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -377,28 +375,38 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
+-INCLUDE(submodules)
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2018-02-27 16:45:56.470183732 -0500
++++ b/extra/CMakeLists.txt 2018-02-27 16:53:11.095621060 -0500
+@@ -46,12 +46,14 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+ MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(UNIX)
+ MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+diff -aurN a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt
+--- a/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.434184441 -0500
++++ b/libmariadb/CMakeLists.txt 2018-02-28 09:15:16.258725638 -0500
+@@ -378,7 +378,7 @@
+ ADD_SUBDIRECTORY(include)
+ ADD_SUBDIRECTORY(libmariadb)
+ ADD_SUBDIRECTORY(plugins)
+-IF(NOT WIN32)
++IF(NOT WIN32 AND NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(mariadb_config)
+ ENDIF()
+
+diff -aurN a/libmariadb/include/CMakeLists.txt b/libmariadb/include/CMakeLists.txt
+--- a/libmariadb/include/CMakeLists.txt 2018-02-27 16:45:56.408184952 -0500
++++ b/libmariadb/include/CMakeLists.txt 2018-02-27 16:59:34.668054644 -0500
+@@ -26,6 +26,7 @@
+ SET(WIX_INCLUDES ${MARIADB_CLIENT_INCLUDES} ${MARIADB_ADDITIONAL_INCLUDES} ${MYSQL_ADDITIONAL_INCLUDES} PARENT_SCOPE)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES
+ ${MARIADB_CLIENT_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}
+@@ -38,3 +39,4 @@
+ ${MARIADB_ADDITIONAL_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}/mariadb
+ COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.421184696 -0500
++++ b/libmariadb/libmariadb/CMakeLists.txt 2018-02-28 09:10:54.981951174 -0500
+@@ -371,8 +371,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -398,7 +400,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
+-SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -412,11 +416,13 @@
+ # of the config program. To make sure these programs can
+ # use mariadb client library we provide libmysql symlinks
+
+-IF(WITH_MYSQLCOMPAT)
++IF(WITH_MYSQLCOMPAT AND NOT WITHOUT_CLIENTLIBS)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
+@@ -424,12 +430,16 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(NOT WITHOUT_CLIENTLIBS)
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(WIN32)
+ # On Windows, install PDB
+diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.txt
+--- a/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:45:56.445184224 -0500
++++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
+@@ -1,3 +1,4 @@
++IF(NOT WITHOUT_CLIENTLIBS)
+ SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
+ FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
+ FOREACH(dir ${plugin_dirs})
+@@ -5,3 +6,4 @@
+ ADD_SUBDIRECTORY(${dir})
+ ENDIF()
+ ENDFOREACH()
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
++++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
+@@ -293,7 +293,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -305,6 +304,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-08 19:38 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-08 19:38 UTC (permalink / raw
To: gentoo-commits
commit: 3584815a283b153d5df68daf6d0e58d9c82f1f0c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 8 19:34:15 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Mar 8 19:34:15 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3584815a
client-libs: Fix creation of my_print_defaults but keep it from install
20018_all_mariadb-10.2.9-without-clientlibs-tools.patch | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
index 5919c67..db72584 100644
--- a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
@@ -56,18 +56,18 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2018-02-27 16:45:56.470183732 -0500
+++ b/extra/CMakeLists.txt 2018-02-27 16:53:11.095621060 -0500
-@@ -46,12 +46,14 @@
+@@ -46,12 +46,12 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
-+IF(NOT WITHOUT_CLIENTLIBS)
- MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
TARGET_LINK_LIBRARIES(my_print_defaults mysys)
- MYSQL_ADD_EXECUTABLE(perror perror.c)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
++ADD_EXECUTABLE(perror perror.c)
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys)
-+ENDIF(NOT WITHOUT_CLIENTLIBS)
IF(UNIX)
MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-08 19:38 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-08 19:38 UTC (permalink / raw
To: gentoo-commits
commit: 0a55720a55f21363de137e2389ba8196e40471bb
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Mar 8 19:35:12 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Mar 8 19:35:12 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=0a55720a
Add new upstream patches
Fix MDEV-15254 10.1.31 does not join an existing cluster with SST
Fix MDEV-15345 Compilation fails to build my_addr_resolve.c
...2_all_mariadb-10.2.12-fix-address-resolve.patch | 29 +++++++++++++++++
20033_all_mariadb-10.1.31-xtradb-sst.patch | 36 ++++++++++++++++++++++
2 files changed, 65 insertions(+)
diff --git a/20032_all_mariadb-10.2.12-fix-address-resolve.patch b/20032_all_mariadb-10.2.12-fix-address-resolve.patch
new file mode 100644
index 0000000..13dbfd5
--- /dev/null
+++ b/20032_all_mariadb-10.2.12-fix-address-resolve.patch
@@ -0,0 +1,29 @@
+From 8ea4f7e4eebefa5daa98f0098b031095b98a1918 Mon Sep 17 00:00:00 2001
+From: Sergei Golubchik <serg@mariadb.org>
+Date: Thu, 22 Feb 2018 15:58:07 +0100
+Subject: [PATCH] MDEV-15345 Compilation fails to build my_addr_resolve.c
+
+fix the compilation error.
+no support for plugins yet.
+---
+ mysys/my_addr_resolve.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/mysys/my_addr_resolve.c b/mysys/my_addr_resolve.c
+index 10f8552f226b..84bff47d1a93 100644
+--- a/mysys/my_addr_resolve.c
++++ b/mysys/my_addr_resolve.c
+@@ -49,6 +49,13 @@ static const char *strip_path(const char *s)
+ static bfd *bfdh= 0;
+ static asymbol **symtable= 0;
+
++#if defined(HAVE_LINK_H) && defined(HAVE_DLOPEN)
++#include <link.h>
++static ElfW(Addr) offset= 0;
++#else
++#define offset 0
++#endif
++
+ /**
+ finds a file name, a line number, and a function name corresponding to addr.
+
diff --git a/20033_all_mariadb-10.1.31-xtradb-sst.patch b/20033_all_mariadb-10.1.31-xtradb-sst.patch
new file mode 100644
index 0000000..50d1fa7
--- /dev/null
+++ b/20033_all_mariadb-10.1.31-xtradb-sst.patch
@@ -0,0 +1,36 @@
+From 4e6dab94d0931eafba502f5a91da29a54e75bb33 Mon Sep 17 00:00:00 2001
+From: Daniel Black <daniel.black@au1.ibm.com>
+Date: Wed, 21 Feb 2018 19:38:57 +0530
+Subject: [PATCH] MDEV-10.1.31 does not join an existing cluster with SST
+ xtrabackup-v2
+
+Analysis:- The problem is the change in the implementation of wait_for_listen
+in wsrep_sst_xtrabackup-v2.sh. The new script uses lsof which will always
+exit with an error code if it can't find all the items, and because the
+script has the -e option set in the hashbang line (#!/bin/bash -ue), the
+script will abort right after running lsof if lsof can't find even a single
+item among all the items listed in its arguments. This will happen even if
+socat is running and listening, because it can't find nc. The loop in
+wait_for_listen will therefore always quit after one iteration without
+writing the "ready" line to signal the parent.
+
+Solution:- We will or the lsof with true.
+
+Patch Credit :Daniel Black and David Wang
+---
+ scripts/wsrep_sst_xtrabackup-v2.sh | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
+index 64dd182e2f2f..9104daf19bc3 100644
+--- a/scripts/wsrep_sst_xtrabackup-v2.sh
++++ b/scripts/wsrep_sst_xtrabackup-v2.sh
+@@ -644,7 +644,7 @@ wait_for_listen()
+
+ for i in {1..300}
+ do
+- LSOF_OUT=$(lsof -sTCP:LISTEN -i TCP:${PORT} -a -c nc -c socat -F c)
++ LSOF_OUT=$(lsof -sTCP:LISTEN -i TCP:${PORT} -a -c nc -c socat -F c 2> /dev/null || :)
+ [ -n "${LSOF_OUT}" ] && break
+ sleep 0.2
+ done
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-09 14:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-09 14:02 UTC (permalink / raw
To: gentoo-commits
commit: ffe03fdc0db87c6022545d785e1cce0548cee361
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 9 14:01:50 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Mar 9 14:01:50 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=ffe03fdc
client-libs: Adjust patch correctly for perror and my_print_defaults
20018_all_mariadb-10.2.9-without-clientlibs-tools.patch | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
index db72584..36dff10 100644
--- a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
@@ -56,16 +56,19 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2018-02-27 16:45:56.470183732 -0500
+++ b/extra/CMakeLists.txt 2018-02-27 16:53:11.095621060 -0500
-@@ -46,12 +46,12 @@
+@@ -46,12 +46,17 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
-
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
+ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
TARGET_LINK_LIBRARIES(my_print_defaults mysys)
-MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ADD_EXECUTABLE(perror perror.c)
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-09 15:12 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-09 15:12 UTC (permalink / raw
To: gentoo-commits
commit: d7129d5122f41176422c625002097dac3fafcb3d
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 9 15:12:32 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Mar 9 15:12:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d7129d51
client-libs: fix malformed patch
20018_all_mariadb-10.2.9-without-clientlibs-tools.patch | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
index 36dff10..40f6a30 100644
--- a/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.9-without-clientlibs-tools.patch
@@ -54,11 +54,12 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
ADD_SUBDIRECTORY(libmysqld/examples)
ENDIF(WITH_EMBEDDED_SERVER)
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
---- a/extra/CMakeLists.txt 2018-02-27 16:45:56.470183732 -0500
-+++ b/extra/CMakeLists.txt 2018-02-27 16:53:11.095621060 -0500
-@@ -46,12 +46,17 @@
+--- a/extra/CMakeLists.txt 2018-02-25 22:27:15.000000000 -0500
++++ b/extra/CMakeLists.txt 2018-03-09 10:08:24.532158129 -0500
+@@ -46,10 +46,15 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
+IF(NOT WITHOUT_CLIENTLIBS)
MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
+MYSQL_ADD_EXECUTABLE(perror perror.c)
@@ -71,9 +72,7 @@ diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
-MYSQL_ADD_EXECUTABLE(perror perror.c)
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys)
-
- IF(UNIX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+
diff -aurN a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt
--- a/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.434184441 -0500
+++ b/libmariadb/CMakeLists.txt 2018-02-28 09:15:16.258725638 -0500
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-09 15:32 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-09 15:32 UTC (permalink / raw
To: gentoo-commits
commit: 370e827dc0e64d9f97b63711ce28f87bd16fd93b
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Fri Mar 9 15:31:58 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Fri Mar 9 15:31:58 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=370e827d
client-libs: Apply previous change to 10.0 and 10.1 version patches
..._mariadb-10.0.20-without-clientlibs-tools.patch | 25 ++++++++++------------
...l_mariadb-10.1.7-without-clientlibs-tools.patch | 25 ++++++++++------------
2 files changed, 22 insertions(+), 28 deletions(-)
diff --git a/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
index 7b759f3..8d3b41e 100644
--- a/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
@@ -53,26 +53,23 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
+++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
-@@ -54,12 +54,14 @@
+@@ -54,10 +54,15 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
--TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
-+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
-
--MYSQL_ADD_EXECUTABLE(perror perror.c)
--ADD_DEPENDENCIES(perror GenError)
--TARGET_LINK_LIBRARIES(perror mysys)
-+ MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ ADD_DEPENDENCIES(perror GenError)
-+ TARGET_LINK_LIBRARIES(perror mysys)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
- IF(UNIX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
+++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
diff --git a/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
index 702b0cb..06e49e3 100644
--- a/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.7-without-clientlibs-tools.patch
@@ -51,26 +51,23 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
+++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
-@@ -54,12 +54,14 @@
+@@ -54,10 +54,15 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
--TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
-+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
-
--MYSQL_ADD_EXECUTABLE(perror perror.c)
--ADD_DEPENDENCIES(perror GenError)
--TARGET_LINK_LIBRARIES(perror mysys)
-+ MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ ADD_DEPENDENCIES(perror GenError)
-+ TARGET_LINK_LIBRARIES(perror mysys)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
- IF(UNIX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
+++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-12 16:26 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-12 16:26 UTC (permalink / raw
To: gentoo-commits
commit: 05773b8c4f253449faf5e776257653fcc8d5d6d0
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 12 16:23:16 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 12 16:23:16 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=05773b8c
respin client-libs patch for 5.7.21
...all_mysql-5.7.21-without-clientlibs-tools.patch | 116 +++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
new file mode 100644
index 0000000..e0f5369
--- /dev/null
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -0,0 +1,116 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
++++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
+@@ -405,8 +405,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+
+@@ -436,7 +434,10 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -462,7 +463,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -470,11 +470,20 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -72,12 +72,16 @@
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
+-
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
++++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
+@@ -217,6 +217,6 @@
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
++++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
+@@ -433,18 +433,21 @@
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+-
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-12 16:39 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-12 16:39 UTC (permalink / raw
To: gentoo-commits
commit: da9ce51a55c888d57aab055b16bcdd77937ef833
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 12 16:39:15 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 12 16:39:15 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=da9ce51a
client-libs: 5.7.21 patch goes too far for libmysql
20018_all_mysql-5.7.21-without-clientlibs-tools.patch | 11 -----------
1 file changed, 11 deletions(-)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
index e0f5369..b9e8f09 100644
--- a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -74,17 +74,6 @@ diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
-diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
---- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
-+++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
-@@ -217,6 +217,6 @@
- ENDIF()
-
--IF(NOT DISABLE_SHARED)
-+IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
- # Merge several convenience libraries into one big mysqlclient
- # and link them together into shared library.
- MERGE_LIBRARIES(libmysql SHARED ${LIBS}
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
+++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-12 18:10 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-12 18:10 UTC (permalink / raw
To: gentoo-commits
commit: fae6321070c88cdb61d2094ffb71f050b76c50c5
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 12 18:10:08 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 12 18:10:08 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=fae63210
client-libs: don't install for 5.7.21
...all_mysql-5.7.21-without-clientlibs-tools.patch | 42 ++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
index b9e8f09..267af79 100644
--- a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -103,3 +103,45 @@ diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2018-03-12 12:40:52.937143630 -0400
++++ b/libmysql/CMakeLists.txt 2018-03-12 14:07:13.513114687 -0400
+@@ -232,12 +232,16 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -271,9 +276,15 @@
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ IF(UNIX)
+ # libtool compatability
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-12 19:54 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-12 19:54 UTC (permalink / raw
To: gentoo-commits
commit: 3e8cb1fb6e9b2aa83bee3c0eacfd957d144c8982
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 12 19:54:00 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 12 19:54:00 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3e8cb1fb
client-libs: Dont install m4 when not needed
20018_all_mysql-5.7.21-without-clientlibs-tools.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
index 05f5328..0ca8f48 100644
--- a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -154,3 +154,16 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
IF(UNIX)
# libtool compatability
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
+--- a/support-files/CMakeLists.txt 2018-03-12 14:11:44.931656906 -0400
++++ b/support-files/CMakeLists.txt 2018-03-12 15:44:53.381846650 -0400
+@@ -59,8 +59,9 @@
+ IF(INSTALL_SUPPORTFILESDIR)
+ INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
+ ENDIF()
+-
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-12 19:54 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-12 19:54 UTC (permalink / raw
To: gentoo-commits
commit: a3ff8cc5f82d562d12e70e33a9a4e0875dc4bcb7
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Mar 12 19:42:10 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Mar 12 19:42:10 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a3ff8cc5
client-libs: Dont install pkgconfig file
20018_all_mysql-5.7.21-without-clientlibs-tools.patch | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
index 267af79..05f5328 100644
--- a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -103,6 +103,15 @@ diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -448,7 +448,7 @@
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
--- a/libmysql/CMakeLists.txt 2018-03-12 12:40:52.937143630 -0400
+++ b/libmysql/CMakeLists.txt 2018-03-12 14:07:13.513114687 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-03-28 20:33 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-03-28 20:33 UTC (permalink / raw
To: gentoo-commits
commit: 82e97f419283b275ce708b44b355b39d400876b3
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Mar 28 20:33:41 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Mar 28 20:33:41 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=82e97f41
Respin client-libs patch for percona 5.6.39
...na-server-5.6.39-without-clientlibs-tools.patch | 125 +++++++++++++++++++++
1 file changed, 125 insertions(+)
diff --git a/20018_all_percona-server-5.6.39-without-clientlibs-tools.patch b/20018_all_percona-server-5.6.39-without-clientlibs-tools.patch
new file mode 100644
index 0000000..0630dfe
--- /dev/null
+++ b/20018_all_percona-server-5.6.39-without-clientlibs-tools.patch
@@ -0,0 +1,125 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2018-03-28 16:15:18.101318534 -0400
++++ b/CMakeLists.txt 2018-03-28 16:18:43.863239965 -0400
+@@ -452,8 +452,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+
+@@ -490,7 +488,9 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -515,7 +515,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -523,6 +522,13 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2018-03-28 16:15:17.764325211 -0400
++++ b/extra/CMakeLists.txt 2018-03-28 16:20:44.569845200 -0400
+@@ -60,11 +60,16 @@
+ ENDIF()
+
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2018-03-28 16:15:18.014320257 -0400
++++ b/libmysql/CMakeLists.txt 2018-03-28 16:31:25.938114668 -0400
+@@ -181,8 +181,13 @@
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ # Merge several convenience libraries into one big perconaserverclient
+-MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(perconaserverclient STATIC ${LIBS} COMPONENT Development ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -210,14 +215,14 @@
+ ENDMACRO()
+ ENDIF()
+
+-IF(UNIX)
++IF(UNIX AND ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ GET_TARGET_NAME(perconaserverclient lib_name)
+ INSTALL_SYMLINK(perconaserverclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}perconaserverclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2018-03-28 16:15:17.706326360 -0400
++++ b/scripts/CMakeLists.txt 2018-03-28 16:29:23.168556104 -0400
+@@ -358,7 +358,6 @@
+ SET(mysql_config_COMPONENT COMPONENT Development)
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_zap
+@@ -372,6 +371,12 @@
+ mysqld_safe
+ ps_tokudb_admin
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-15 0:59 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-15 0:59 UTC (permalink / raw
To: gentoo-commits
commit: 678eed98813b2485d9c4ab96421befb59b570a31
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue May 15 00:58:32 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue May 15 00:58:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=678eed98
Add atomic detection patch from Debian
20035_all_mariadb-10.1-atomic-detection.patch | 140 ++++++++++++++++++++++++++
1 file changed, 140 insertions(+)
diff --git a/20035_all_mariadb-10.1-atomic-detection.patch b/20035_all_mariadb-10.1-atomic-detection.patch
new file mode 100644
index 0000000..b2545c0
--- /dev/null
+++ b/20035_all_mariadb-10.1-atomic-detection.patch
@@ -0,0 +1,140 @@
+Borrowed from Debian to make atomic detection easier
+
+From: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org>
+Date: Thu, 10 Aug 2017 20:40:29 +0200
+Subject: c11_atomics
+
+---
+ configure.cmake | 23 +++++++++++++++++++++--
+ include/atomic/gcc_builtins.h | 15 +++++++++++++++
+ include/atomic/nolock.h | 4 ++--
+ mysys/CMakeLists.txt | 4 ++++
+ sql/CMakeLists.txt | 4 ++++
+ 5 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/configure.cmake b/configure.cmake
+index 0057c7f..43ad114 100644
+--- a/configure.cmake
++++ b/configure.cmake
+@@ -128,7 +128,7 @@ IF(UNIX)
+ ENDIF()
+ FIND_PACKAGE(Threads)
+
+- SET(CMAKE_REQUIRED_LIBRARIES
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO})
+ # Need explicit pthread for gcc -fsanitize=address
+ IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=")
+@@ -1028,7 +1028,26 @@ ELSEIF(NOT WITH_ATOMIC_OPS)
+ long long int *ptr= &var;
+ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+ }"
+- HAVE_GCC_C11_ATOMICS)
++ HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++ IF(HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ ELSE()
++ SET(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
++ CHECK_CXX_SOURCE_COMPILES("
++ int main()
++ {
++ long long int var= 1;
++ long long int *ptr= &var;
++ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
++ }"
++ HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ ELSE()
++ SET(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
++ ENDIF()
++ ENDIF()
+ ELSE()
+ MESSAGE(FATAL_ERROR "${WITH_ATOMIC_OPS} is not a valid value for WITH_ATOMIC_OPS!")
+ ENDIF()
+diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h
+index 56a0323..044be2e 100644
+--- a/include/atomic/gcc_builtins.h
++++ b/include/atomic/gcc_builtins.h
+@@ -16,6 +16,7 @@
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
++#if defined (HAVE_GCC_ATOMIC_BUILTINS)
+ #define make_atomic_add_body(S) \
+ v= __sync_fetch_and_add(a, v);
+ #define make_atomic_fas_body(S) \
+@@ -26,6 +27,20 @@
+ sav= __sync_val_compare_and_swap(a, cmp_val, set);\
+ if (!(ret= (sav == cmp_val))) *cmp= sav
+
++#elif defined(HAVE_GCC_C11_ATOMICS)
++
++#define make_atomic_add_body(S) \
++ v= __atomic_fetch_add(a, v, __ATOMIC_SEQ_CST)
++#define make_atomic_fas_body(S) \
++ v= __atomic_exchange_n(a, v, __ATOMIC_SEQ_CST)
++#define make_atomic_cas_body(S) \
++ int ## S sav; \
++ ret= __atomic_compare_exchange_n(a, cmp, set, \
++ 0, \
++ __ATOMIC_SEQ_CST,\
++ __ATOMIC_SEQ_CST);
++#endif
++
+ #ifdef MY_ATOMIC_MODE_DUMMY
+ #define make_atomic_load_body(S) ret= *a
+ #define make_atomic_store_body(S) *a= v
+diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h
+index 2137445..2ad7d98 100644
+--- a/include/atomic/nolock.h
++++ b/include/atomic/nolock.h
+@@ -17,7 +17,7 @@
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+ #if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__) \
+- || defined(HAVE_GCC_ATOMIC_BUILTINS) \
++ || defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_C11_ATOMICS) \
+ || defined(HAVE_SOLARIS_ATOMIC)
+
+ # ifdef MY_ATOMIC_MODE_DUMMY
+@@ -41,7 +41,7 @@
+ # elif __GNUC__
+ # if defined(HAVE_SOLARIS_ATOMIC)
+ # include "solaris.h"
+-# elif defined(HAVE_GCC_ATOMIC_BUILTINS)
++# elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_C11_ATOMICS)
+ # include "gcc_builtins.h"
+ # elif defined(__i386__) || defined(__x86_64__)
+ # include "x86-gcc.h"
+diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
+index eb7f75e..a9221d7 100644
+--- a/mysys/CMakeLists.txt
++++ b/mysys/CMakeLists.txt
+@@ -78,6 +78,10 @@ IF(HAVE_BFD_H)
+ TARGET_LINK_LIBRARIES(mysys bfd)
+ ENDIF(HAVE_BFD_H)
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(mysys atomic)
++ENDIF()
++
+ IF (WIN32)
+ TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
+ ENDIF(WIN32)
+diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
+index b4acac5..8247714 100644
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
+@@ -165,6 +165,10 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
+ ${SSL_LIBRARIES}
+ ${LIBSYSTEMD})
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(sql atomic)
++ENDIF()
++
+ IF(WIN32)
+ SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc)
+ TARGET_LINK_LIBRARIES(sql psapi)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-15 13:34 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-15 13:34 UTC (permalink / raw
To: gentoo-commits
commit: cc2e5a0cca290d160cb91cb9fd23c2bb2444654f
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue May 15 13:34:18 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue May 15 13:34:18 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=cc2e5a0c
Respin atomic patch for mariadb 10.2 and 10.3
20035_all_mariadb-10.2-atomic-detection.patch | 133 ++++++++++++++++++++++++++
20035_all_mariadb-10.3-atomic-detection.patch | 84 ++++++++++++++++
2 files changed, 217 insertions(+)
diff --git a/20035_all_mariadb-10.2-atomic-detection.patch b/20035_all_mariadb-10.2-atomic-detection.patch
new file mode 100644
index 0000000..659e630
--- /dev/null
+++ b/20035_all_mariadb-10.2-atomic-detection.patch
@@ -0,0 +1,133 @@
+10.1 patch borrowed from Debian to make atomic detection easier
+
+10.2 adjustments by Brian Evans <grknight@gentoo.org>
+
+From: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org>
+Date: Thu, 10 Aug 2017 20:40:29 +0200
+Subject: c11_atomics
+
+---
+ configure.cmake | 23 +++++++++++++++++++++--
+ include/atomic/gcc_builtins.h | 15 +++++++++++++++
+ include/my_atomic.h | 4 ++--
+ mysys/CMakeLists.txt | 4 ++++
+ sql/CMakeLists.txt | 4 ++++
+ 5 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/configure.cmake b/configure.cmake
+index 0057c7f..43ad114 100644
+--- a/configure.cmake
++++ b/configure.cmake
+@@ -128,7 +128,7 @@ IF(UNIX)
+ ENDIF()
+ FIND_PACKAGE(Threads)
+
+- SET(CMAKE_REQUIRED_LIBRARIES
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO})
+ # Need explicit pthread for gcc -fsanitize=address
+ IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=")
+@@ -1028,7 +1028,26 @@ ELSEIF(NOT WITH_ATOMIC_OPS)
+ long long int *ptr= &var;
+ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+ }"
+- HAVE_GCC_C11_ATOMICS)
++ HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++ IF(HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ ELSE()
++ SET(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
++ CHECK_CXX_SOURCE_COMPILES("
++ int main()
++ {
++ long long int var= 1;
++ long long int *ptr= &var;
++ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
++ }"
++ HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ ELSE()
++ SET(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
++ ENDIF()
++ ENDIF()
+ ELSE()
+ MESSAGE(FATAL_ERROR "${WITH_ATOMIC_OPS} is not a valid value for WITH_ATOMIC_OPS!")
+ ENDIF()
+diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h
+index 56a0323..044be2e 100644
+--- a/include/atomic/gcc_builtins.h
++++ b/include/atomic/gcc_builtins.h
+@@ -16,6 +16,7 @@
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
++#if defined (HAVE_GCC_ATOMIC_BUILTINS)
+ #define make_atomic_add_body(S) \
+ v= __sync_fetch_and_add(a, v);
+ #define make_atomic_fas_body(S) \
+@@ -26,6 +27,20 @@
+ sav= __sync_val_compare_and_swap(a, cmp_val, set);\
+ if (!(ret= (sav == cmp_val))) *cmp= sav
+
++#elif defined(HAVE_GCC_C11_ATOMICS)
++
++#define make_atomic_add_body(S) \
++ v= __atomic_fetch_add(a, v, __ATOMIC_SEQ_CST)
++#define make_atomic_fas_body(S) \
++ v= __atomic_exchange_n(a, v, __ATOMIC_SEQ_CST)
++#define make_atomic_cas_body(S) \
++ int ## S sav; \
++ ret= __atomic_compare_exchange_n(a, cmp, set, \
++ 0, \
++ __ATOMIC_SEQ_CST,\
++ __ATOMIC_SEQ_CST);
++#endif
++
+ #ifdef MY_ATOMIC_MODE_DUMMY
+ #define make_atomic_load_body(S) ret= *a
+ #define make_atomic_store_body(S) *a= v
+diff --git a/include/my_atomic.h b/include/my_atomic.h
+index 2137445..2ad7d98 100644
+--- a/include/my_atomic.h
++++ b/include/my_atomic.h
+@@ -126,7 +126,7 @@
+ #include "atomic/generic-msvc.h"
+ #elif defined(HAVE_SOLARIS_ATOMIC)
+ #include "atomic/solaris.h"
+-#elif defined(HAVE_GCC_ATOMIC_BUILTINS)
++#elif defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(HAVE_GCC_C11_ATOMICS)
+ #include "atomic/gcc_builtins.h"
+ #elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
+ #include "atomic/x86-gcc.h"
+diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
+index eb7f75e..a9221d7 100644
+--- a/mysys/CMakeLists.txt
++++ b/mysys/CMakeLists.txt
+@@ -78,6 +78,10 @@ IF(HAVE_BFD_H)
+ TARGET_LINK_LIBRARIES(mysys bfd)
+ ENDIF(HAVE_BFD_H)
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(mysys atomic)
++ENDIF()
++
+ IF (WIN32)
+ TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
+ ENDIF(WIN32)
+diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
+index b4acac5..8247714 100644
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
+@@ -165,6 +165,10 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
+ ${SSL_LIBRARIES}
+ ${LIBSYSTEMD})
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(sql atomic)
++ENDIF()
++
+ IF(WIN32)
+ SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc)
+ TARGET_LINK_LIBRARIES(sql psapi)
diff --git a/20035_all_mariadb-10.3-atomic-detection.patch b/20035_all_mariadb-10.3-atomic-detection.patch
new file mode 100644
index 0000000..0f7d522
--- /dev/null
+++ b/20035_all_mariadb-10.3-atomic-detection.patch
@@ -0,0 +1,84 @@
+Original 10.1 patch Borrowed from Debian to make atomic detection easier
+Modified for 10.3 by Brian Evans <grknight@gentoo.org>
+
+From: Debian MySQL Maintainers <pkg-mysql-maint@lists.alioth.debian.org>
+Date: Thu, 10 Aug 2017 20:40:29 +0200
+Subject: c11_atomics
+
+---
+ configure.cmake | 23 +++++++++++++++++++++--
+ mysys/CMakeLists.txt | 4 ++++
+ sql/CMakeLists.txt | 4 ++++
+ 5 files changed, 46 insertions(+), 4 deletions(-)
+
+diff --git a/configure.cmake b/configure.cmake
+index 0057c7f..43ad114 100644
+--- a/configure.cmake
++++ b/configure.cmake
+@@ -128,7 +128,7 @@ IF(UNIX)
+ ENDIF()
+ FIND_PACKAGE(Threads)
+
+- SET(CMAKE_REQUIRED_LIBRARIES
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES
+ ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT} ${LIBEXECINFO})
+ # Need explicit pthread for gcc -fsanitize=address
+ IF(CMAKE_USE_PTHREADS_INIT AND CMAKE_C_FLAGS MATCHES "-fsanitize=")
+@@ -1028,7 +1028,26 @@ ELSEIF(NOT WITH_ATOMIC_OPS)
+ long long int *ptr= &var;
+ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
+ }"
+-HAVE_GCC_C11_ATOMICS)
++HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++IF(HAVE_GCC_C11_ATOMICS_WITHOUT_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ELSE()
++ SET(OLD_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
++ LIST(APPEND CMAKE_REQUIRED_LIBRARIES "atomic")
++ CHECK_CXX_SOURCE_COMPILES("
++ int main()
++ {
++ long long int var= 1;
++ long long int *ptr= &var;
++ return (int)__atomic_load_n(ptr, __ATOMIC_SEQ_CST);
++ }"
++ HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ SET(HAVE_GCC_C11_ATOMICS True)
++ ELSE()
++ SET(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQUIRED_LIBRARIES})
++ ENDIF()
++ENDIF()
+
+ IF(WITH_VALGRIND)
+ SET(HAVE_valgrind 1)
+diff --git a/mysys/CMakeLists.txt b/mysys/CMakeLists.txt
+index eb7f75e..a9221d7 100644
+--- a/mysys/CMakeLists.txt
++++ b/mysys/CMakeLists.txt
+@@ -78,6 +78,10 @@ IF(HAVE_BFD_H)
+ TARGET_LINK_LIBRARIES(mysys bfd)
+ ENDIF(HAVE_BFD_H)
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(mysys atomic)
++ENDIF()
++
+ IF (WIN32)
+ TARGET_LINK_LIBRARIES(mysys IPHLPAPI)
+ ENDIF(WIN32)
+diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
+index b4acac5..8247714 100644
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
+@@ -165,6 +165,10 @@ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
+ ${SSL_LIBRARIES}
+ ${LIBSYSTEMD})
+
++IF(HAVE_GCC_C11_ATOMICS_WITH_LIBATOMIC)
++ TARGET_LINK_LIBRARIES(sql atomic)
++ENDIF()
++
+ IF(WIN32)
+ SET(MYSQLD_SOURCE main.cc nt_servc.cc message.rc)
+ TARGET_LINK_LIBRARIES(sql psapi)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-28 0:28 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-28 0:28 UTC (permalink / raw
To: gentoo-commits
commit: 74f656fffe9ea6b56bcafd3f8457cb306f1ed979
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 28 00:27:57 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon May 28 00:27:57 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=74f656ff
Respin client-libs patch for changes
..._mariadb-10.2.16-without-clientlibs-tools.patch | 201 +++++++++++++++++++++
1 file changed, 201 insertions(+)
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
new file mode 100644
index 0000000..fa449e1
--- /dev/null
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -0,0 +1,201 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2018-02-27 16:45:56.740178421 -0500
++++ b/CMakeLists.txt 2018-02-28 09:06:59.163673185 -0500
+@@ -339,8 +339,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -377,28 +375,38 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
+-INCLUDE(submodules)
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2018-02-25 22:27:15.000000000 -0500
++++ b/extra/CMakeLists.txt 2018-03-09 10:08:24.532158129 -0500
+@@ -46,10 +46,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt
+--- a/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.434184441 -0500
++++ b/libmariadb/CMakeLists.txt 2018-02-28 09:15:16.258725638 -0500
+@@ -378,6 +378,6 @@
+ ADD_SUBDIRECTORY(include)
+ ADD_SUBDIRECTORY(libmariadb)
+-IF(NOT WIN32)
++IF(NOT WIN32 AND NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(mariadb_config)
+ ENDIF()
+
+diff -aurN a/libmariadb/include/CMakeLists.txt b/libmariadb/include/CMakeLists.txt
+--- a/libmariadb/include/CMakeLists.txt 2018-02-27 16:45:56.408184952 -0500
++++ b/libmariadb/include/CMakeLists.txt 2018-02-27 16:59:34.668054644 -0500
+@@ -26,6 +26,7 @@
+ SET(WIX_INCLUDES ${MARIADB_CLIENT_INCLUDES} ${MARIADB_ADDITIONAL_INCLUDES} ${MYSQL_ADDITIONAL_INCLUDES} PARENT_SCOPE)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES
+ ${MARIADB_CLIENT_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}
+@@ -38,3 +39,4 @@
+ ${MARIADB_ADDITIONAL_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}/mariadb
+ COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.421184696 -0500
++++ b/libmariadb/libmariadb/CMakeLists.txt 2018-02-28 09:10:54.981951174 -0500
+@@ -371,8 +371,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -398,7 +400,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
+-SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -412,11 +416,13 @@
+ # of the config program. To make sure these programs can
+ # use mariadb client library we provide libmysql symlinks
+
+-IF(WITH_MYSQLCOMPAT)
++IF(WITH_MYSQLCOMPAT AND NOT WITHOUT_CLIENTLIBS)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
+@@ -424,12 +430,16 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(NOT WITHOUT_CLIENTLIBS)
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(WIN32)
+ # On Windows, install PDB
+diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.txt
+--- a/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:45:56.445184224 -0500
++++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
+@@ -1,3 +1,4 @@
++IF(NOT WITHOUT_CLIENTLIBS)
+ SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
+ FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
+ FOREACH(dir ${plugin_dirs})
+@@ -5,3 +6,4 @@
+ ADD_SUBDIRECTORY(${dir})
+ ENDIF()
+ ENDFOREACH()
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
++++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
+@@ -293,7 +293,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -305,6 +304,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-28 1:03 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-28 1:03 UTC (permalink / raw
To: gentoo-commits
commit: 228f1b5dd2811089a5c395c196e7521486289c9e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 28 01:02:40 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon May 28 01:02:40 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=228f1b5d
client-libs: ensure pvio is always built
20018_all_mariadb-10.2.16-without-clientlibs-tools.patch | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index fa449e1..ba97631 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -165,8 +165,10 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.txt
--- a/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:45:56.445184224 -0500
+++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
-@@ -1,3 +1,4 @@
-+IF(NOT WITHOUT_CLIENTLIBS)
+@@ -1,3 +1,6 @@
++IF(WITHOUT_CLIENTLIBS)
++INCLUDE(pvio}/CMakeLists.txt)
++ELSE(WITHOUT_CLIENTLIBS)
SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
FOREACH(dir ${plugin_dirs})
@@ -174,7 +176,7 @@ diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.t
ADD_SUBDIRECTORY(${dir})
ENDIF()
ENDFOREACH()
-+ENDIF(NOT WITHOUT_CLIENTLIBS)
++ENDIF(WITHOUT_CLIENTLIBS)
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
+++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-28 1:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-28 1:05 UTC (permalink / raw
To: gentoo-commits
commit: 50ebb32f871e276ffef3660acab4ad8c6a4c5f46
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 28 01:04:59 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon May 28 01:04:59 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=50ebb32f
client-libs: fix typo
20018_all_mariadb-10.2.16-without-clientlibs-tools.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index ba97631..8a7aae8 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -167,7 +167,7 @@ diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.t
+++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
@@ -1,3 +1,6 @@
+IF(WITHOUT_CLIENTLIBS)
-+INCLUDE(pvio}/CMakeLists.txt)
++INCLUDE(pvio/CMakeLists.txt)
+ELSE(WITHOUT_CLIENTLIBS)
SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-29 0:35 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-29 0:35 UTC (permalink / raw
To: gentoo-commits
commit: 18cce4abed47991b0685e50bab80bb0fa70a3f6d
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon May 28 01:09:31 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon May 28 01:09:31 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=18cce4ab
client-libs: fix further errors
20018_all_mariadb-10.2.16-without-clientlibs-tools.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index 8a7aae8..510e647 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -167,7 +167,7 @@ diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.t
+++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
@@ -1,3 +1,6 @@
+IF(WITHOUT_CLIENTLIBS)
-+INCLUDE(pvio/CMakeLists.txt)
++INCLUDE(${CC_SOURCE_DIR}/plugins/pvio/CMakeLists.txt)
+ELSE(WITHOUT_CLIENTLIBS)
SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-05-29 0:35 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-05-29 0:35 UTC (permalink / raw
To: gentoo-commits
commit: 86ca91356862d9c4966ba880da4c33c992e16fa0
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue May 29 00:34:33 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue May 29 00:34:33 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=86ca9135
client-libs: Remove a section on plugins
Can be controlled by CMake options instead
20018_all_mariadb-10.2.16-without-clientlibs-tools.patch | 15 ---------------
1 file changed, 15 deletions(-)
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index 510e647..a0159fe 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -162,21 +162,6 @@ diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeL
IF(WIN32)
# On Windows, install PDB
-diff -aurN a/libmariadb/plugins/CMakeLists.txt b/libmariadb/plugins/CMakeLists.txt
---- a/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:45:56.445184224 -0500
-+++ b/libmariadb/plugins/CMakeLists.txt 2018-02-27 16:59:59.028574104 -0500
-@@ -1,3 +1,6 @@
-+IF(WITHOUT_CLIENTLIBS)
-+INCLUDE(${CC_SOURCE_DIR}/plugins/pvio/CMakeLists.txt)
-+ELSE(WITHOUT_CLIENTLIBS)
- SET(PLUGIN_EXTRA_FILES ${CC_SOURCE_DIR}/libmariadb/ma_errmsg.c)
- FILE(GLOB plugin_dirs ${CC_SOURCE_DIR}/plugins/*)
- FOREACH(dir ${plugin_dirs})
-@@ -5,3 +6,4 @@
- ADD_SUBDIRECTORY(${dir})
- ENDIF()
- ENDFOREACH()
-+ENDIF(WITHOUT_CLIENTLIBS)
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
+++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-06-21 2:02 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-06-21 2:02 UTC (permalink / raw
To: gentoo-commits
commit: 1582310ee6efcb58945a7be8005eac78bfccd0e7
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 21 02:01:42 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jun 21 02:01:42 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1582310e
client-libs: Fix tests of 10.1
..._mariadb-10.1.16-without-clientlibs-tools.patch | 24 +++++++++-------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
index db1988d..e6cb129 100644
--- a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -51,26 +51,22 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
+++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
-@@ -54,12 +54,14 @@
+@@ -54,10 +54,15 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
--TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
-+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
-
--MYSQL_ADD_EXECUTABLE(perror perror.c)
--ADD_DEPENDENCIES(perror GenError)
--TARGET_LINK_LIBRARIES(perror mysys)
-+ MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ ADD_DEPENDENCIES(perror GenError)
-+ TARGET_LINK_LIBRARIES(perror mysys)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
- IF(UNIX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
+++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-06-21 2:05 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-06-21 2:05 UTC (permalink / raw
To: gentoo-commits
commit: 6a621f0c274a6a40b4eb610d31bf70076b71e44f
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 21 02:05:32 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jun 21 02:05:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=6a621f0c
client-libs: Too much edit in last commit
20018_all_mariadb-10.1.16-without-clientlibs-tools.patch | 1 +
1 file changed, 1 insertion(+)
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
index e6cb129..3487b70 100644
--- a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -67,6 +67,7 @@ diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
-MYSQL_ADD_EXECUTABLE(perror perror.c)
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys)
+
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
+++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-06-27 14:29 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-06-27 14:29 UTC (permalink / raw
To: gentoo-commits
commit: 3b4c64717d773c3a591a534da81dc51944aa0b68
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Wed Jun 27 14:28:53 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Wed Jun 27 14:28:53 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3b4c6471
Respin client-libs patch for MariaDB 5.5.60
...l_mariadb-5.5.60-without-clientlibs-tools.patch | 114 +++++++++++++++++++++
1 file changed, 114 insertions(+)
diff --git a/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch b/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch
new file mode 100644
index 0000000..3115fa6
--- /dev/null
+++ b/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch
@@ -0,0 +1,114 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -394,24 +392,35 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(support-files)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,10 +54,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -440,12 +440,12 @@
+ SET(${OUTNAME} ${LIBNAME}${EXTENSION}${DOT_VERSION})
+ ENDIF()
+ ENDMACRO()
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a mysqlclient ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-06-28 1:08 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-06-28 1:08 UTC (permalink / raw
To: gentoo-commits
commit: e2d9073f6238abafd50c83daea0cd49ba43d7f4e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Jun 28 01:08:05 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Jun 28 01:08:05 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e2d9073f
Respin clientlibs for mysql 5.5.60
...all_mysql-5.5.60-without-clientlibs-tools.patch | 108 +++++++++++++++++++++
1 file changed, 108 insertions(+)
diff --git a/20018_all_mysql-5.5.60-without-clientlibs-tools.patch b/20018_all_mysql-5.5.60-without-clientlibs-tools.patch
new file mode 100644
index 0000000..6a00364
--- /dev/null
+++ b/20018_all_mysql-5.5.60-without-clientlibs-tools.patch
@@ -0,0 +1,108 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -354,8 +354,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+ CHECK_JEMALLOC()
+@@ -404,14 +404,19 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(regex)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(libmysql)
+-ADD_SUBDIRECTORY(client)
++IF(NOT WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(sql/share)
+@@ -432,6 +437,9 @@
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(NOT WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(NOT WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,10 +54,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -202,14 +202,14 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(mysqlclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-08-04 23:23 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-08-04 23:23 UTC (permalink / raw
To: gentoo-commits
commit: b0ef30fe27f707ab0b55e35cb8934fa1bb88b945
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 4 23:23:17 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Aug 4 23:23:17 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=b0ef30fe
Fix tests on 5.6 for clientlibs
...all_mysql-5.6.25-without-clientlibs-tools.patch | 37 +++++++++-------------
1 file changed, 15 insertions(+), 22 deletions(-)
diff --git a/20018_all_mysql-5.6.25-without-clientlibs-tools.patch b/20018_all_mysql-5.6.25-without-clientlibs-tools.patch
index 35e60de..3ae9551 100644
--- a/20018_all_mysql-5.6.25-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.6.25-without-clientlibs-tools.patch
@@ -52,33 +52,26 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
ADD_SUBDIRECTORY(libmysqld/examples)
ENDIF(WITH_EMBEDDED_SERVER)
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
---- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
-+++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
-@@ -59,15 +59,16 @@
- ADD_DEPENDENCIES(GenError copy_openssl_extra)
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -60,11 +60,16 @@
ENDIF()
-+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
-+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
-+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
--TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
--SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
--
--MYSQL_ADD_EXECUTABLE(perror perror.c)
--ADD_DEPENDENCIES(perror GenError)
--TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
--SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
-+ MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ ADD_DEPENDENCIES(perror GenError)
-+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
-+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
- TARGET_LINK_LIBRARIES(resolveip mysys mysys_ssl)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
+++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-08-09 17:01 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-08-09 17:01 UTC (permalink / raw
To: gentoo-commits
commit: 59a8e4748b669c389241d118a54f23cc1c7a9e9c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 9 16:58:52 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Aug 9 16:58:52 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=59a8e474
client-libs: Add options to execute my_print_defaults from libexec
This is needed for the mariadb's addition of the --mysqld option
used in galera sst and initial database setup
..._mariadb-10.0.20-without-clientlibs-tools.patch | 16 ++++++++++
..._mariadb-10.1.16-without-clientlibs-tools.patch | 36 ++++++++++++++++++++++
..._mariadb-10.2.16-without-clientlibs-tools.patch | 36 ++++++++++++++++++++++
...l_mariadb-5.5.60-without-clientlibs-tools.patch | 16 ++++++++++
4 files changed, 104 insertions(+)
diff --git a/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
index 8d3b41e..5d17863 100644
--- a/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.0.20-without-clientlibs-tools.patch
@@ -112,3 +112,19 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
MERGE_LIBRARIES(libmysql SHARED ${LIBS}
EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
COMPONENT SharedLibraries)
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
index 3487b70..8e1a30d 100644
--- a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -109,3 +109,39 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
MERGE_LIBRARIES(libmysql SHARED ${LIBS}
EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
COMPONENT SharedLibraries)
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
+diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
+--- a/scripts/wsrep_sst_common.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/wsrep_sst_common.sh 2018-08-09 12:30:24.976706933 -0400
+@@ -148,6 +148,7 @@
+ SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
+ EXTRA_DIR="$SCRIPTS_DIR/../extra"
+ CLIENT_DIR="$SCRIPTS_DIR/../client"
++LIBEXEC_DIR="$SCRIPTS_DIR/../libexec/mariadb"
+
+ if [ -x "$CLIENT_DIR/mysql" ]; then
+ MYSQL_CLIENT="$CLIENT_DIR/mysql"
+@@ -165,6 +166,8 @@
+ MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
+ elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
++elif [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="LIBEXEC_DIR/my_print_defaults"
+ else
+ MY_PRINT_DEFAULTS=$(which my_print_defaults)
+ fi
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index a0159fe..e844046 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -186,3 +186,39 @@ diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
FOREACH(file ${BIN_SCRIPTS})
IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
+diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
+--- a/scripts/wsrep_sst_common.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/wsrep_sst_common.sh 2018-08-09 12:30:24.976706933 -0400
+@@ -148,6 +148,7 @@
+ SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
+ EXTRA_DIR="$SCRIPTS_DIR/../extra"
+ CLIENT_DIR="$SCRIPTS_DIR/../client"
++LIBEXEC_DIR="$SCRIPTS_DIR/../libexec/mariadb"
+
+ if [ -x "$CLIENT_DIR/mysql" ]; then
+ MYSQL_CLIENT="$CLIENT_DIR/mysql"
+@@ -165,6 +166,8 @@
+ MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
+ elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
++elif [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="LIBEXEC_DIR/my_print_defaults"
+ else
+ MY_PRINT_DEFAULTS=$(which my_print_defaults)
+ fi
diff --git a/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch b/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch
index 3115fa6..12d5da2 100644
--- a/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-5.5.60-without-clientlibs-tools.patch
@@ -112,3 +112,19 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
MERGE_LIBRARIES(libmysql SHARED ${LIBS}
EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
COMPONENT SharedLibraries)
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-13 23:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-13 23:31 UTC (permalink / raw
To: gentoo-commits
commit: 439462f3d9f725e2aa96d60e55c6286797c61607
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 13 21:15:04 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Oct 13 21:15:04 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=439462f3
Add 20018_all_mysql-5.7.23-round-off-test-values-for-same-output-on-all-architectures.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...lues-for-same-output-on-all-architectures.patch | 332 +++++++++++++++++++++
1 file changed, 332 insertions(+)
diff --git a/20018_all_mysql-5.7.23-round-off-test-values-for-same-output-on-all-architectures.patch b/20018_all_mysql-5.7.23-round-off-test-values-for-same-output-on-all-architectures.patch
new file mode 100644
index 0000000..337e5a1
--- /dev/null
+++ b/20018_all_mysql-5.7.23-round-off-test-values-for-same-output-on-all-architectures.patch
@@ -0,0 +1,332 @@
+Description: Fix failing arithmetic tests on ppc64el
+ The architecture provides a math library with 128bit precision, giving
+ slightly different results on certain calculations used in tests.
+ Round off the values so the output is the same on all architectures.
+Author: Lars Tangvald <lars.tangvald@oracle.com>
+Bug: https://bugs.mysql.com/bug.php?id=92375
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/mysql-5.7/+bug/1791010
+Forwarded: not-needed
+Last-Update: 2018-09-11
+
+--- a/mysql-test/include/select.inc
++++ b/mysql-test/include/select.inc
+@@ -2344,12 +2344,16 @@ where key1 <= 0.6158 and key2 >= 1.3762;
+ explain select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ explain select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+
++--replace_numeric_round 4
+ select max(key1) from t1 where key1 <= 0.6158;
++--replace_numeric_round 4
+ select max(key2) from t2 where key2 <= 1.6158;
+ select min(key1) from t1 where key1 >= 0.3762;
+ select min(key2) from t2 where key2 >= 1.3762;
++--replace_numeric_round 4
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
++--replace_numeric_round 4
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+
+--- a/mysql-test/r/ps.result
++++ b/mysql-test/r/ps.result
+@@ -3418,9 +3418,9 @@ Table Create Table
+ tmp1 CREATE TEMPORARY TABLE `tmp1` (
+ `c1` double DEFAULT NULL
+ ) ENGINE=InnoDB DEFAULT CHARSET=latin1
+-SELECT @a, @a - 123.4567 < 0.00001;
+-@a @a - 123.4567 < 0.00001
+-123.45670318603516 1
++SELECT @a, @a - 123.4567 < 0.0001;
++@a @a - 123.4567 < 0.0001
++123.4567 1
+ DROP TEMPORARY TABLE tmp1;
+ DROP PROCEDURE p1;
+
+--- a/mysql-test/r/select_all.result
++++ b/mysql-test/r/select_all.result
+@@ -2899,10 +2899,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2912,10 +2912,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_all_bka.result
++++ b/mysql-test/r/select_all_bka.result
+@@ -2900,10 +2900,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2913,10 +2913,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_all_bka_nixbnl.result
++++ b/mysql-test/r/select_all_bka_nixbnl.result
+@@ -2900,10 +2900,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2913,10 +2913,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_icp_mrr.result
++++ b/mysql-test/r/select_icp_mrr.result
+@@ -2899,10 +2899,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2912,10 +2912,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_icp_mrr_bka.result
++++ b/mysql-test/r/select_icp_mrr_bka.result
+@@ -2900,10 +2900,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2913,10 +2913,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_icp_mrr_bka_nixbnl.result
++++ b/mysql-test/r/select_icp_mrr_bka_nixbnl.result
+@@ -2900,10 +2900,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2913,10 +2913,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_none.result
++++ b/mysql-test/r/select_none.result
+@@ -2898,10 +2898,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2911,10 +2911,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_none_bka.result
++++ b/mysql-test/r/select_none_bka.result
+@@ -2899,10 +2899,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2912,10 +2912,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/select_none_bka_nixbnl.result
++++ b/mysql-test/r/select_none_bka_nixbnl.result
+@@ -2899,10 +2899,10 @@ Warnings:
+ Note 1003 /* select#1 */ select min(`test`.`t1`.`key1`) AS `min(key1)` from `test`.`t1` where ((`test`.`t1`.`key1` >= 0.3762) and ((rand() + 0.5) >= 0.5))
+ select max(key1) from t1 where key1 <= 0.6158;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select max(key2) from t2 where key2 <= 1.6158;
+ max(key2)
+-1.6158000230789185
++1.6158
+ select min(key1) from t1 where key1 >= 0.3762;
+ min(key1)
+ 0.37619999051094055
+@@ -2912,10 +2912,10 @@ min(key2)
+ select max(key1), min(key2) from t1, t2
+ where key1 <= 0.6158 and key2 >= 1.3762;
+ max(key1) min(key2)
+-0.6158000230789185 1.3761999607086182
++0.6158 1.3762
+ select max(key1) from t1 where key1 <= 0.6158 and rand() + 0.5 >= 0.5;
+ max(key1)
+-0.6158000230789185
++0.6158
+ select min(key1) from t1 where key1 >= 0.3762 and rand() + 0.5 >= 0.5;
+ min(key1)
+ 0.37619999051094055
+--- a/mysql-test/r/sp.result
++++ b/mysql-test/r/sp.result
+@@ -5982,9 +5982,9 @@ CREATE TABLE t3 (f1 INT, f2 FLOAT)|
+ INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)|
+ SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP|
+ SUM(f2) bug25373(f1)
+-6.300000071525574 1
++6.3 1
+ 15 2
+-21.300000071525574 NULL
++21.3 NULL
+ DROP FUNCTION bug25373|
+ DROP TABLE t3|
+ DROP DATABASE IF EXISTS mysqltest1|
+--- a/mysql-test/t/sp.test
++++ b/mysql-test/t/sp.test
+@@ -6817,6 +6817,7 @@ LANGUAGE SQL DETERMINISTIC
+ RETURN p1;|
+ CREATE TABLE t3 (f1 INT, f2 FLOAT)|
+ INSERT INTO t3 VALUES (1, 3.4), (1, 2), (1, 0.9), (2, 8), (2, 7)|
++--replace_numeric_round 4
+ SELECT SUM(f2), bug25373(f1) FROM t3 GROUP BY bug25373(f1) WITH ROLLUP|
+ DROP FUNCTION bug25373|
+ DROP TABLE t3|
+--- a/mysql-test/t/wl4435_generated.inc
++++ b/mysql-test/t/wl4435_generated.inc
+@@ -246,7 +246,8 @@ CREATE TEMPORARY TABLE tmp1 AS SELECT @a
+
+ SHOW CREATE TABLE tmp1;
+
+-SELECT @a, @a - 123.4567 < 0.00001;
++--replace_numeric_round 4
++SELECT @a, @a - 123.4567 < 0.0001;
+
+ DROP TEMPORARY TABLE tmp1;
+ DROP PROCEDURE p1;
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-13 23:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-13 23:31 UTC (permalink / raw
To: gentoo-commits
commit: 90f28c8ff5cf894d67240c6acaae538d9f564c19
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 13 14:32:32 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Oct 13 14:32:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=90f28c8f
Add 20018_all_mysql-5.7.23-fix-libressl-support.patch
Bug: https://bugs.gentoo.org/662826
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.23-fix-libressl-support.patch | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/20018_all_mysql-5.7.23-fix-libressl-support.patch b/20018_all_mysql-5.7.23-fix-libressl-support.patch
new file mode 100644
index 0000000..f6beecd
--- /dev/null
+++ b/20018_all_mysql-5.7.23-fix-libressl-support.patch
@@ -0,0 +1,14 @@
+https://bugs.gentoo.org/662826
+
+--- a/sql/auth/sha2_password_common.cc
++++ b/sql/auth/sha2_password_common.cc
+@@ -146,7 +146,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
+ DBUG_RETURN(true);
+ }
+ m_ok= EVP_DigestFinal_ex(md_context, m_digest, NULL);
+-#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
++#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
+ EVP_MD_CTX_cleanup(md_context);
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ EVP_MD_CTX_reset(md_context);
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-13 23:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-13 23:31 UTC (permalink / raw
To: gentoo-commits
commit: 845f78800450b3590a12c085444183918ff48efd
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 13 21:12:11 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Oct 13 21:12:11 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=845f7880
Add 20018_all_mysql-5.7.23-fix-grant_user_lock-a-root.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...l_mysql-5.7.23-fix-grant_user_lock-a-root.patch | 85 ++++++++++++++++++++++
1 file changed, 85 insertions(+)
diff --git a/20018_all_mysql-5.7.23-fix-grant_user_lock-a-root.patch b/20018_all_mysql-5.7.23-fix-grant_user_lock-a-root.patch
new file mode 100644
index 0000000..aecc6a5
--- /dev/null
+++ b/20018_all_mysql-5.7.23-fix-grant_user_lock-a-root.patch
@@ -0,0 +1,85 @@
+Description: Fixes test failing when run as root
+ Certain tests will fail when run as root. This patch fixes one,
+ main.grant_user_lock, which tries to test an anonymous user in
+ a way that fails when running as root. The patch fixes only
+ this test because there have been issues in Debian with only
+ this test failing in this way.
+Author: Lars Tangvald <lars.tangvald@oracle.com>
+Bug-Debian: https://bugs.debian.org/841592
+Bug: http://bugs.mysql.com/bug.php?id=83751
+Last-Update: 2016-11-09
+
+--- mysql-5.7-5.7.16.orig/mysql-test/r/grant_user_lock.result
++++ mysql-5.7-5.7.16/mysql-test/r/grant_user_lock.result
+@@ -98,13 +98,13 @@ CURRENT_USER()
+ DROP USER ''@localhost;
+ # Create anonymous user - LOCK
+ CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK;
+-connect(localhost,,pass,test,MASTER_PORT,MASTER_SOCKET);
++connect(localhost, ,pass,test,MASTER_PORT,MASTER_SOCKET);
+ ERROR HY000: Access denied for user '(null)'@'localhost'. Account is locked.
+ DROP USER ''@localhost;
+ # Disabling anonymous user
+ CREATE USER ''@localhost IDENTIFIED BY 'pass';
+ ALTER USER ''@localhost ACCOUNT LOCK;
+-connect(localhost,,pass,test,MASTER_PORT,MASTER_SOCKET);
++connect(localhost, ,pass,test,MASTER_PORT,MASTER_SOCKET);
+ ERROR HY000: Access denied for user '(null)'@'localhost'. Account is locked.
+ DROP USER ''@localhost;
+ # Enabling anonymous user
+--- mysql-5.7-5.7.16.orig/mysql-test/t/grant_user_lock.test
++++ mysql-5.7-5.7.16/mysql-test/t/grant_user_lock.test
+@@ -113,7 +113,7 @@ DROP USER unlocked_user2@localhost;
+ --echo # Create anonymous user
+ connection default;
+ CREATE USER ''@localhost IDENTIFIED BY 'pass';
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ SELECT CURRENT_USER();
+ disconnect anonymous_user_con;
+ connection default;
+@@ -122,7 +122,7 @@ DROP USER ''@localhost;
+ --echo # Create anonymous user - explicit UNLOCK
+ connection default;
+ CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT UNLOCK;
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ SELECT CURRENT_USER();
+ disconnect anonymous_user_con;
+ connection default;
+@@ -133,7 +133,7 @@ connection default;
+ CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK;
+ --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+ --error ER_ACCOUNT_HAS_BEEN_LOCKED
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ connection default;
+ DROP USER ''@localhost;
+
+@@ -143,7 +143,7 @@ CREATE USER ''@localhost IDENTIFIED BY '
+ ALTER USER ''@localhost ACCOUNT LOCK;
+ --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
+ --error ER_ACCOUNT_HAS_BEEN_LOCKED
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ connection default;
+ DROP USER ''@localhost;
+
+@@ -151,7 +151,7 @@ DROP USER ''@localhost;
+ connection default;
+ CREATE USER ''@localhost IDENTIFIED BY 'pass' ACCOUNT LOCK;
+ ALTER USER ''@localhost ACCOUNT UNLOCK;
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ SELECT CURRENT_USER();
+ disconnect anonymous_user_con;
+ connection default;
+@@ -171,7 +171,7 @@ connection default;
+ CREATE user ''@localhost IDENTIFIED BY 'pass';
+ CREATE USER 'unlocked_user'@localhost IDENTIFIED BY 'pass';
+
+-connect(anonymous_user_con, localhost, '', pass);
++connect(anonymous_user_con, localhost, ' ', pass);
+ --error ER_TABLEACCESS_DENIED_ERROR
+ UPDATE mysql.user SET account_locked='Y'
+ WHERE user='unlocked_user' and host = 'localhost';
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-13 23:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-13 23:31 UTC (permalink / raw
To: gentoo-commits
commit: 87d6895e070ae14ebaf813c7884c8dd3210887d3
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 13 14:58:13 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Oct 13 14:58:13 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=87d6895e
Add 20018_all_mysql-5.7.23-add-missing-gcc-8-fix.patch
Bug: https://bugs.gentoo.org/662816
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.23-add-missing-gcc-8-fix.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_mysql-5.7.23-add-missing-gcc-8-fix.patch b/20018_all_mysql-5.7.23-add-missing-gcc-8-fix.patch
new file mode 100644
index 0000000..0463813
--- /dev/null
+++ b/20018_all_mysql-5.7.23-add-missing-gcc-8-fix.patch
@@ -0,0 +1,13 @@
+https://bugs.gentoo.org/662816
+
+--- a/regex/CMakeLists.txt
++++ b/regex/CMakeLists.txt
+@@ -15,6 +15,8 @@
+
+ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include)
+
++INCLUDE(${MYSQL_CMAKE_SCRIPT_DIR}/compile_flags.cmake)
++
+ MY_CHECK_C_COMPILER_FLAG("-Wstringop-truncation" HAVE_STRINGOP_TRUNCATION)
+ IF(HAVE_STRINGOP_TRUNCATION)
+ ADD_COMPILE_FLAGS(
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-13 23:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-13 23:31 UTC (permalink / raw
To: gentoo-commits
commit: 0b4f9a102c7c577af28a9db47dc3120028d2427c
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Oct 13 21:16:54 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Oct 13 21:16:54 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=0b4f9a10
Add 20018_all_mysql-5.7.23-fix-mips-ASM.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.23-fix-mips-ASM.patch | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/20018_all_mysql-5.7.23-fix-mips-ASM.patch b/20018_all_mysql-5.7.23-fix-mips-ASM.patch
new file mode 100644
index 0000000..9cda592
--- /dev/null
+++ b/20018_all_mysql-5.7.23-fix-mips-ASM.patch
@@ -0,0 +1,21 @@
+Description: Fix MIPS64 asm constraints
+ Assembly problem, using =l instead of =lc.
+ http://stackoverflow.com/questions/3652153/impossible-constraint-in-asm
+Author: YunQiang Su <wzssyqa@gmail.com>
+Bug: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=798126
+Forwarded: yes, http://bugs.mysql.com/69978
+Last-Update: 2015-09-21
+
+Index: mysql-5.6/extra/yassl/taocrypt/src/integer.cpp
+===================================================================
+--- mysql-5.6.orig/extra/yassl/taocrypt/src/integer.cpp
++++ mysql-5.6/extra/yassl/taocrypt/src/integer.cpp
+@@ -192,7 +192,7 @@
+ "a" (a), "rm" (b) : "cc");
+
+ #elif defined(__mips64)
+- __asm__("dmultu %2,%3" : "=h" (r.halfs_.high), "=l" (r.halfs_.low)
++ __asm__("dmultu %2,%3" : "=d" (r.halfs_.high), "=lc" (r.halfs_.low)
+ : "r" (a), "r" (b));
+
+ #elif defined(_M_IX86)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-14 21:03 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-14 21:03 UTC (permalink / raw
To: gentoo-commits
commit: 88b72825824f4dffccaf9d8aced0f03283278611
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 14 15:37:17 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Oct 14 15:37:17 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=88b72825
Add 20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-5.7.23-without-clientlibs-tools.patch | 161 +++++++++++++++++++++
1 file changed, 161 insertions(+)
diff --git a/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch b/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
new file mode 100644
index 0000000..35221f7
--- /dev/null
+++ b/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
@@ -0,0 +1,161 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -534,8 +534,6 @@ INCLUDE_DIRECTORIES(
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+ # Add lz4 library
+@@ -624,7 +622,10 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -665,7 +666,6 @@ IF(WITH_UNIT_TESTS)
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -673,11 +673,20 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+--- a/extra/CMakeLists.txt
++++ b/extra/CMakeLists.txt
+@@ -72,12 +72,16 @@ IF (WIN32 AND WITH_SSL_PATH AND HAVE_CRYPTO_DLL)
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
+-
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -233,12 +233,17 @@ IF(WIN32)
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big perconaserverclient
+-MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -285,9 +290,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ IF(UNIX)
+ # libtool compatability
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -411,7 +411,6 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ ps_tokudb_admin
+ ps_mysqld_helper
+@@ -419,7 +418,6 @@ ELSE()
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+@@ -429,6 +427,13 @@ ELSE()
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -59,8 +59,9 @@ IF(UNIX)
+ IF(INSTALL_SUPPORTFILESDIR)
+ INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
+ ENDIF()
+-
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-14 23:20 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-14 23:20 UTC (permalink / raw
To: gentoo-commits
commit: e1379f95b711bf310eb3723674d8fc2af69548be
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Oct 14 23:19:41 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Oct 14 23:19:41 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e1379f95
Add 20018_all_percona-server-5.7.23-rocksdb-use-system-libs.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...ona-server-5.7.23-rocksdb-use-system-libs.patch | 50 ++++++++++++++++++++++
1 file changed, 50 insertions(+)
diff --git a/20018_all_percona-server-5.7.23-rocksdb-use-system-libs.patch b/20018_all_percona-server-5.7.23-rocksdb-use-system-libs.patch
new file mode 100644
index 0000000..98494ae
--- /dev/null
+++ b/20018_all_percona-server-5.7.23-rocksdb-use-system-libs.patch
@@ -0,0 +1,50 @@
+--- a/storage/rocksdb/CMakeLists.txt
++++ b/storage/rocksdb/CMakeLists.txt
+@@ -114,38 +114,11 @@ EXECUTE_PROCESS(
+ # split the list into lines
+ STRING(REGEX MATCHALL "[^\n]+" ROCKSDB_LIB_SOURCES ${SCRIPT_OUTPUT})
+
+-# add bundled compression code
+-SET(ROCKSDB_LIB_SOURCES
+- ${ROCKSDB_LIB_SOURCES}
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lz4/lib/lz4.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lz4/lib/lz4hc.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lz4/lib/lz4frame.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/entropy_common.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/error_private.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/fse_decompress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/pool.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/threading.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/xxhash.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common/zstd_common.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/compress/fse_compress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/compress/huf_compress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/compress/zstd_compress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/compress/zstdmt_compress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/decompress/huf_decompress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/decompress/zstd_decompress.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/dictBuilder/divsufsort.c
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/dictBuilder/zdict.c
+-)
+-
+ INCLUDE_DIRECTORIES(
+ ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb
+ ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include
+ ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/include/rocksdb
+ ${CMAKE_CURRENT_SOURCE_DIR}/rocksdb/third-party/gtest-1.7.0/fused-src
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/lz4/lib
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/common
+- ${CMAKE_CURRENT_SOURCE_DIR}/third_party/zstd/lib/dictBuilder
+ )
+
+ ADD_DEFINITIONS(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DZLIB -DLZ4
+@@ -177,7 +150,7 @@ SET(ROCKSDB_SOURCES
+ ${ROCKSDB_LIB_SOURCES}
+ )
+
+-SET(rocksdb_static_libs ${rocksdb_static_libs} ${ZLIB_LIBRARY} "-lrt")
++SET(rocksdb_static_libs ${rocksdb_static_libs} ${ZLIB_LIBRARY} "-lrt -llz4 -lzstd")
+
+ MYSQL_ADD_PLUGIN(rocksdb ${ROCKSDB_SOURCES} STORAGE_ENGINE DEFAULT MODULE_ONLY
+ LINK_LIBRARIES ${rocksdb_static_libs}
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-16 15:19 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-16 15:19 UTC (permalink / raw
To: gentoo-commits
commit: 0d47dcbb9cab7990a02f7b4977033b825a4dbdad
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 16 15:04:21 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Oct 16 15:04:21 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=0d47dcbb
Fix 20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
Don't install PKCONFIG file.
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...all_percona-server-5.7.23-without-clientlibs-tools.patch | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch b/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
index 35221f7..c2add24 100644
--- a/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
+++ b/20018_all_percona-server-5.7.23-without-clientlibs-tools.patch
@@ -74,7 +74,7 @@
SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
-@@ -233,12 +233,17 @@ IF(WIN32)
+@@ -231,12 +231,17 @@ IF(WIN32)
LIST(APPEND LIBS auth_win_client)
ENDIF()
@@ -98,7 +98,7 @@
# Visual Studio users need debug static library for debug projects
IF(MSVC)
-@@ -285,9 +290,15 @@ ENDIF()
+@@ -283,9 +288,15 @@ ENDIF()
IF(NOT DISABLE_SHARED)
# Merge several convenience libraries into one big perconaserverclient
# and link them together into shared library.
@@ -146,6 +146,15 @@
SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -443,7 +448,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -59,8 +59,9 @@ IF(UNIX)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-16 16:17 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-16 16:17 UTC (permalink / raw
To: gentoo-commits
commit: 8bc22a0db98cf0628fc01af900fb450219d57103
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 16 16:03:32 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Oct 16 16:03:32 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=8bc22a0d
Fix 20018_all_mysql-5.7.21-without-clientlibs-tools.patch
Don't install PKCONFIG file.
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...all_mysql-5.7.21-without-clientlibs-tools.patch | 113 ++++++++++-----------
1 file changed, 54 insertions(+), 59 deletions(-)
diff --git a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
index 0ca8f48..35cc8de 100644
--- a/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
+++ b/20018_all_mysql-5.7.21-without-clientlibs-tools.patch
@@ -1,7 +1,6 @@
-diff -aurN a/CMakeLists.txt b/CMakeLists.txt
---- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
-+++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
-@@ -405,8 +405,6 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -530,8 +530,6 @@ INCLUDE_DIRECTORIES(
MYSQL_CHECK_ZLIB_WITH_COMPRESS()
# Add bundled yassl/taocrypt or system openssl.
MYSQL_CHECK_SSL()
@@ -9,9 +8,9 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
-MYSQL_CHECK_EDITLINE()
# Add libevent
MYSQL_CHECK_LIBEVENT()
-
-@@ -436,7 +434,10 @@
- ADD_SUBDIRECTORY(storage/ndb)
+ # Add lz4 library
+@@ -620,7 +618,10 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
ENDIF()
-ADD_SUBDIRECTORY(include)
@@ -22,7 +21,7 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
ADD_SUBDIRECTORY(dbug)
ADD_SUBDIRECTORY(strings)
ADD_SUBDIRECTORY(vio)
-@@ -462,7 +463,6 @@
+@@ -661,7 +662,6 @@ IF(WITH_UNIT_TESTS)
ENDIF()
ADD_SUBDIRECTORY(extra)
@@ -30,7 +29,7 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
ADD_SUBDIRECTORY(sql/share)
ADD_SUBDIRECTORY(libservices)
-@@ -470,11 +470,20 @@
+@@ -669,11 +669,20 @@ IF(UNIX)
ADD_SUBDIRECTORY(man)
ENDIF()
@@ -51,10 +50,9 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
ADD_SUBDIRECTORY(libmysqld)
ADD_SUBDIRECTORY(libmysqld/examples)
ENDIF(WITH_EMBEDDED_SERVER)
-diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
---- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
-+++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
-@@ -72,12 +72,16 @@
+--- a/extra/CMakeLists.txt
++++ b/extra/CMakeLists.txt
+@@ -72,12 +72,16 @@ IF (WIN32 AND WITH_SSL_PATH AND HAVE_CRYPTO_DLL)
ADD_DEPENDENCIES(GenError copy_openssl_extra)
ENDIF()
@@ -74,48 +72,9 @@ diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
-diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
---- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
-+++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
-@@ -433,18 +433,21 @@
-
- IF(WITH_SYSTEMD)
- SET(BIN_SCRIPTS
-- mysql_config
- mysqldumpslow
- )
- ELSE()
- SET(BIN_SCRIPTS
-- mysql_config
- mysqldumpslow
- mysqld_multi
- mysqld_safe
- )
- ENDIF()
--
-+ IF(NOT WITHOUT_CLIENTLIBS)
-+ SET(BIN_SCRIPTS
-+ ${BIN_SCRIPTS}
-+ mysql_config
-+ )
-+ ENDIF(NOT WITHOUT_CLIENTLIBS)
- SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
- STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
- SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
-
-@@ -448,7 +448,7 @@
- ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
- ESCAPE_QUOTES @ONLY)
-
-- IF(INSTALL_PKGCONFIGDIR)
-+ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
- MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
- INSTALL(FILES
- ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
-diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
---- a/libmysql/CMakeLists.txt 2018-03-12 12:40:52.937143630 -0400
-+++ b/libmysql/CMakeLists.txt 2018-03-12 14:07:13.513114687 -0400
-@@ -232,12 +232,16 @@
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -231,12 +231,16 @@ IF(WIN32)
LIST(APPEND LIBS auth_win_client)
ENDIF()
@@ -138,7 +97,7 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
# Visual Studio users need debug static library for debug projects
IF(MSVC)
-@@ -271,9 +276,15 @@
+@@ -283,9 +287,15 @@ ENDIF()
IF(NOT DISABLE_SHARED)
# Merge several convenience libraries into one big mysqlclient
# and link them together into shared library.
@@ -154,9 +113,45 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
IF(UNIX)
# libtool compatability
IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
---- a/support-files/CMakeLists.txt 2018-03-12 14:11:44.931656906 -0400
-+++ b/support-files/CMakeLists.txt 2018-03-12 15:44:53.381846650 -0400
-@@ -59,8 +59,9 @@
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -411,18 +411,21 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+-
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -437,7 +440,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -59,8 +59,9 @@ IF(UNIX)
IF(INSTALL_SUPPORTFILESDIR)
INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-17 0:45 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-17 0:45 UTC (permalink / raw
To: gentoo-commits
commit: c5bf7666c3bb6f495079ebf43eb9cfaa2198f1bc
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 17 00:33:06 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 17 00:33:06 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c5bf7666
Update 20018_all_mysql-5.7.23-fix-libressl-support.patch
Closes: https://bugs.gentoo.org/668832
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.23-fix-libressl-support.patch | 36 +++++++++++++++++++++++
1 file changed, 36 insertions(+)
diff --git a/20018_all_mysql-5.7.23-fix-libressl-support.patch b/20018_all_mysql-5.7.23-fix-libressl-support.patch
index f6beecd..c5ca308 100644
--- a/20018_all_mysql-5.7.23-fix-libressl-support.patch
+++ b/20018_all_mysql-5.7.23-fix-libressl-support.patch
@@ -1,4 +1,5 @@
https://bugs.gentoo.org/662826
+https://bugs.gentoo.org/668832
--- a/sql/auth/sha2_password_common.cc
+++ b/sql/auth/sha2_password_common.cc
@@ -12,3 +13,38 @@ https://bugs.gentoo.org/662826
EVP_MD_CTX_cleanup(md_context);
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
EVP_MD_CTX_reset(md_context);
+--- a/vio/viosslfactories.c
++++ b/vio/viosslfactories.c
+@@ -121,21 +121,19 @@ static DH *get_dh2048(void)
+ DH *dh;
+ if ((dh=DH_new()))
+ {
+- BIGNUM *p= BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+- BIGNUM *g= BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+- if (!p || !g
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+- || !DH_set0_pqg(dh, p, NULL, g)
+-#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+- ) {
+- /* DH_free() will free 'p' and 'g' at once. */
++ BIGNUM *p = BN_bin2bn(dh2048_p,sizeof(dh2048_p), NULL);
++ BIGNUM *g = BN_bin2bn(dh2048_g,sizeof(dh2048_g), NULL);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ dh->p=p;
++ dh->g=g;
++ if (! dh->p || ! dh->g)
++#else
++ if (!DH_set0_pqg(dh, p, NULL, g))
++#endif
++ {
+ DH_free(dh);
+- return NULL;
++ dh = NULL;
+ }
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+- dh->p= p;
+- dh->g= g;
+-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ }
+ return(dh);
+ }
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-17 10:37 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-17 10:37 UTC (permalink / raw
To: gentoo-commits
commit: a08fd23b4270c4105d441ff573fde2af037146e4
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 17 10:34:08 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 17 10:34:08 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a08fd23b
Add 20018_all_percona-server-5.7.23-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...ercona-server-5.7.23-fix-libressl-support.patch | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/20018_all_percona-server-5.7.23-fix-libressl-support.patch b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
new file mode 100644
index 0000000..a30dbc1
--- /dev/null
+++ b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
@@ -0,0 +1,26 @@
+https://bugs.gentoo.org/662826
+https://bugs.gentoo.org/668832
+
+--- a/sql/auth/sha2_password_common.cc
++++ b/sql/auth/sha2_password_common.cc
+@@ -146,7 +146,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
+ DBUG_RETURN(true);
+ }
+ m_ok= EVP_DigestFinal_ex(md_context, m_digest, NULL);
+-#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
++#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
+ EVP_MD_CTX_cleanup(md_context);
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ EVP_MD_CTX_reset(md_context);
+--- a/vio/viosslfactories.c
++++ b/vio/viosslfactories.c
+@@ -123,7 +123,7 @@ static DH *get_dh2048(void)
+ {
+ BIGNUM* p= BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+ BIGNUM* g= BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ dh->p= p;
+ dh->g= g;
+ if (! dh->p || ! dh->g)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-17 12:24 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-17 12:24 UTC (permalink / raw
To: gentoo-commits
commit: cfe842ed9596ea5bdd8e76636033116cc77cd213
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 17 12:23:42 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 17 12:23:42 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=cfe842ed
Update 20018_all_percona-server-5.7.23-fix-libressl-support.patch
Bug: https://bugs.gentoo.org/668818
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_percona-server-5.7.23-fix-libressl-support.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_percona-server-5.7.23-fix-libressl-support.patch b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
index a30dbc1..72d7a06 100644
--- a/20018_all_percona-server-5.7.23-fix-libressl-support.patch
+++ b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
@@ -1,6 +1,19 @@
https://bugs.gentoo.org/662826
https://bugs.gentoo.org/668832
+https://bugs.gentoo.org/668818
+--- a/mysys_ssl/my_crypt.cc
++++ b/mysys_ssl/my_crypt.cc
+@@ -95,7 +95,8 @@ MyEncryptionCTX::MyEncryptionCTX()
+ MyEncryptionCTX::~MyEncryptionCTX()
+ {
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
+ EVP_CIPHER_CTX_cleanup(ctx);
+ delete ctx;
+ ERR_remove_thread_state(0);
--- a/sql/auth/sha2_password_common.cc
+++ b/sql/auth/sha2_password_common.cc
@@ -146,7 +146,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-17 22:22 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-17 22:22 UTC (permalink / raw
To: gentoo-commits
commit: a9c411d5ee037b430376d6f302cbea405653b7f7
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 17 21:59:41 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 17 21:59:41 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a9c411d5
Update 20018_all_mysql-5.7.23-fix-libressl-support.patch
Bug: https://bugs.gentoo.org/668894
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.23-fix-libressl-support.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_mysql-5.7.23-fix-libressl-support.patch b/20018_all_mysql-5.7.23-fix-libressl-support.patch
index c5ca308..6e4bd50 100644
--- a/20018_all_mysql-5.7.23-fix-libressl-support.patch
+++ b/20018_all_mysql-5.7.23-fix-libressl-support.patch
@@ -1,5 +1,6 @@
https://bugs.gentoo.org/662826
https://bugs.gentoo.org/668832
+https://bugs.gentoo.org/668894
--- a/sql/auth/sha2_password_common.cc
+++ b/sql/auth/sha2_password_common.cc
@@ -13,6 +14,18 @@ https://bugs.gentoo.org/668832
EVP_MD_CTX_cleanup(md_context);
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
EVP_MD_CTX_reset(md_context);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -3408,7 +3408,8 @@ static int init_ssl()
+ {
+ #ifdef HAVE_OPENSSL
+ #ifndef HAVE_YASSL
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
+ CRYPTO_malloc_init();
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ OPENSSL_malloc_init();
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -121,21 +121,19 @@ static DH *get_dh2048(void)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-17 22:22 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-10-17 22:22 UTC (permalink / raw
To: gentoo-commits
commit: 3098bcea9e263bcc864956ccaf551ad9f540e150
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 17 21:58:22 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 17 21:58:22 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3098bcea
Update 20018_all_percona-server-5.7.23-fix-libressl-support.patch
Bug: https://bugs.gentoo.org/668894
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_percona-server-5.7.23-fix-libressl-support.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_percona-server-5.7.23-fix-libressl-support.patch b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
index 72d7a06..f368f57 100644
--- a/20018_all_percona-server-5.7.23-fix-libressl-support.patch
+++ b/20018_all_percona-server-5.7.23-fix-libressl-support.patch
@@ -1,6 +1,7 @@
https://bugs.gentoo.org/662826
https://bugs.gentoo.org/668832
https://bugs.gentoo.org/668818
+https://bugs.gentoo.org/668894
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
@@ -26,6 +27,18 @@ https://bugs.gentoo.org/668818
EVP_MD_CTX_cleanup(md_context);
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
EVP_MD_CTX_reset(md_context);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -3679,7 +3679,8 @@ static int init_ssl()
+ " Disabling FIPS.");
+ FIPS_mode_set(0);
+ }
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
+ CRYPTO_malloc_init();
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ OPENSSL_malloc_init();
--- a/vio/viosslfactories.c
+++ b/vio/viosslfactories.c
@@ -123,7 +123,7 @@ static DH *get_dh2048(void)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-10-23 0:12 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-10-23 0:12 UTC (permalink / raw
To: gentoo-commits
commit: 27250c4031ebd8502062cea753ade01d155a486c
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 23 00:11:47 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Oct 23 00:11:47 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=27250c40
Respin minimal build patch for bug 669236
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
..._all_fix-minimal-build-cmake-mysql-5.7.23.patch | 26 ++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/20001_all_fix-minimal-build-cmake-mysql-5.7.23.patch b/20001_all_fix-minimal-build-cmake-mysql-5.7.23.patch
new file mode 100644
index 0000000..915ad1d
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-5.7.23.patch
@@ -0,0 +1,26 @@
+diff -aurwN mysql.orig/CMakeLists.txt mysql/CMakeLists.txt
+--- a/CMakeLists.txt 2014-07-18 11:48:39.000000000 -0400
++++ b/CMakeLists.txt 2014-08-01 12:54:52.612732241 -0400
+@@ -531,7 +531,9 @@
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+ # Add libevent
+-MYSQL_CHECK_LIBEVENT()
++IF(NOT WITHOUT_SERVER)
++ MYSQL_CHECK_LIBEVENT()
++ENDIF()
+ # Add lz4 library
+ MYSQL_CHECK_LZ4()
+ # Add protoc and libprotobuf
+@@ -626,10 +626,10 @@
+ # scripts/mysql_config depends on client and server targets loaded above.
+ # It is referenced by some of the directories below, so we insert it here.
+ ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-11-04 22:52 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-11-04 22:52 UTC (permalink / raw
To: gentoo-commits
commit: 239f0e8dd9c003252a3c627d86c06744918bd965
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Nov 4 22:51:35 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Nov 4 22:51:35 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=239f0e8d
Respin numa patch for mariadb 10.1.37
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20029_all_mariadb-10.1.37-enable-numa.patch | 204 ++++++++++++++++++++++++++++
1 file changed, 204 insertions(+)
diff --git a/20029_all_mariadb-10.1.37-enable-numa.patch b/20029_all_mariadb-10.1.37-enable-numa.patch
new file mode 100644
index 0000000..a924534
--- /dev/null
+++ b/20029_all_mariadb-10.1.37-enable-numa.patch
@@ -0,0 +1,204 @@
+Backport MariaDB 10.2 support into 10.1
+
+diff --git a/cmake/numa.cmake b/cmake/numa.cmake
+new file mode 100644
+index 000000000000..d5234a5ef4f6
+--- /dev/null
++++ b/cmake/numa.cmake
+@@ -0,0 +1,43 @@
++MACRO (MYSQL_CHECK_NUMA)
++
++ IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
++ CHECK_INCLUDE_FILES(numa.h HAVE_NUMA_H)
++ CHECK_INCLUDE_FILES(numaif.h HAVE_NUMAIF_H)
++
++ IF(HAVE_NUMA_H AND HAVE_NUMAIF_H)
++ OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" ON)
++ ELSE()
++ OPTION(WITH_NUMA "Explicitly set NUMA memory allocation policy" OFF)
++ ENDIF()
++
++ IF(WITH_NUMA AND HAVE_NUMA_H AND HAVE_NUMAIF_H)
++ SET(SAVE_CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
++ SET(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} numa)
++ CHECK_C_SOURCE_COMPILES(
++ "
++ #include <numa.h>
++ #include <numaif.h>
++ int main()
++ {
++ struct bitmask *all_nodes= numa_all_nodes_ptr;
++ set_mempolicy(MPOL_DEFAULT, 0, 0);
++ return all_nodes != NULL;
++ }"
++ HAVE_LIBNUMA)
++ SET(CMAKE_REQUIRED_LIBRARIES ${SAVE_CMAKE_REQUIRED_LIBRARIES})
++ IF(HAVE_LIBNUMA)
++ ADD_DEFINITIONS(-DHAVE_LIBNUMA=1)
++ SET(NUMA_LIBRARY "numa")
++ ENDIF()
++ ENDIF()
++
++ IF(WITH_NUMA AND NOT HAVE_LIBNUMA)
++ # Forget it in cache, abort the build.
++ UNSET(WITH_NUMA CACHE)
++ UNSET(NUMA_LIBRARY CACHE)
++ MESSAGE(FATAL_ERROR "Could not find numa headers/libraries")
++ ENDIF()
++ ENDIF()
++
++ENDMACRO()
++
+diff --git a/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt
+new file mode 100644
+index 000000000000..c1c2bb26b8ac
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic-master.opt
+@@ -0,0 +1,1 @@
++--loose-innodb_numa_interleave=1
+diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
+index 7e667d5ebb29..c80ef6f09937 100644
+--- a/storage/innobase/CMakeLists.txt
++++ b/storage/innobase/CMakeLists.txt
+@@ -23,12 +23,14 @@ INCLUDE(lzo)
+ INCLUDE(lzma)
+ INCLUDE(bzip2)
+ INCLUDE(snappy)
++INCLUDE(numa)
+
+ MYSQL_CHECK_LZ4()
+ MYSQL_CHECK_LZO()
+ MYSQL_CHECK_LZMA()
+ MYSQL_CHECK_BZIP2()
+ MYSQL_CHECK_SNAPPY()
++MYSQL_CHECK_NUMA()
+
+ IF(CMAKE_CROSSCOMPILING)
+ # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when
+@@ -63,5 +63,2 @@
+ ENDIF()
+ ADD_DEFINITIONS("-DUNIV_LINUX -D_GNU_SOURCE=1")
+- IF(HAVE_LIBNUMA)
+- LINK_LIBRARIES(numa)
+- ENDIF()
+@@ -517,6 +517,10 @@
+ MYSQL_ADD_PLUGIN(innobase ${INNOBASE_SOURCES} STORAGE_ENGINE
+ MODULE_ONLY
+ MODULE_OUTPUT_NAME ha_innodb
+- LINK_LIBRARIES ${ZLIB_LIBRARY} ${LIBSYSTEMD} ${LINKER_SCRIPT})
++ LINK_LIBRARIES
++ ${ZLIB_LIBRARY}
++ ${NUMA_LIBRARY}
++ ${LIBSYSTEMD}
++ ${LINKER_SCRIPT})
+
+ ADD_DEPENDENCIES(innobase GenError)
+diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
+index 7d2a3fad56dc..51e24b3cd8a2 100644
+--- a/storage/xtradb/CMakeLists.txt
++++ b/storage/xtradb/CMakeLists.txt
+@@ -23,12 +23,14 @@ INCLUDE(lzo)
+ INCLUDE(lzma)
+ INCLUDE(bzip2)
+ INCLUDE(snappy)
++INCLUDE(numa)
+
+ MYSQL_CHECK_LZ4()
+ MYSQL_CHECK_LZO()
+ MYSQL_CHECK_LZMA()
+ MYSQL_CHECK_BZIP2()
+ MYSQL_CHECK_SNAPPY()
++MYSQL_CHECK_NUMA()
+
+ IF(CMAKE_CROSSCOMPILING)
+ # Use CHECK_C_SOURCE_COMPILES instead of CHECK_C_SOURCE_RUNS when
+@@ -504,11 +504,6 @@
+ )
+ ENDIF()
+
+-UNSET(NUMA_LIBRARY)
+-IF(HAVE_LIBNUMA)
+- SET(NUMA_LIBRARY "numa")
+-ENDIF()
+-
+ MYSQL_ADD_PLUGIN(xtradb ${INNOBASE_SOURCES} STORAGE_ENGINE
+ DEFAULT
+ RECOMPILE_FOR_EMBEDDED
+diff --git a/mysql-test/include/have_numa.inc b/mysql-test/include/have_numa.inc
+new file mode 100644
+index 000000000000..18bca99e04d7
+--- /dev/null
++++ b/mysql-test/include/have_numa.inc
+@@ -0,0 +1,9 @@
++let $numa_support = `SELECT COUNT(VARIABLE_VALUE) = 1 FROM
++ INFORMATION_SCHEMA.GLOBAL_VARIABLES
++ WHERE VARIABLE_NAME='innodb_numa_interleave'`;
++
++if ( $numa_support == 0 )
++{
++ --skip Test requires: Binary must be built with NUMA support.
++}
++
+diff --git a/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result b/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result
+new file mode 100644
+index 000000000000..21ed16c1dab8
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/r/innodb_numa_interleave_basic.result
+@@ -0,0 +1,11 @@
++call mtr.add_suppression("InnoDB: Failed to set NUMA memory policy");
++SELECT @@GLOBAL.innodb_numa_interleave;
++@@GLOBAL.innodb_numa_interleave
++1
++SET @@GLOBAL.innodb_numa_interleave=off;
++ERROR HY000: Variable 'innodb_numa_interleave' is a read only variable
++SELECT @@GLOBAL.innodb_numa_interleave;
++@@GLOBAL.innodb_numa_interleave
++1
++SELECT @@SESSION.innodb_numa_interleave;
++ERROR HY000: Variable 'innodb_numa_interleave' is a GLOBAL variable
+diff --git a/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test
+new file mode 100644
+index 000000000000..518b5ebba177
+--- /dev/null
++++ b/mysql-test/suite/sys_vars/t/innodb_numa_interleave_basic.test
+@@ -0,0 +1,15 @@
++--source include/have_innodb.inc
++--source include/have_numa.inc
++
++call mtr.add_suppression("InnoDB: Failed to set NUMA memory policy");
++
++SELECT @@GLOBAL.innodb_numa_interleave;
++
++--error ER_INCORRECT_GLOBAL_LOCAL_VAR
++SET @@GLOBAL.innodb_numa_interleave=off;
++
++SELECT @@GLOBAL.innodb_numa_interleave;
++
++--error ER_INCORRECT_GLOBAL_LOCAL_VAR
++SELECT @@SESSION.innodb_numa_interleave;
++
+diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+index 87e000faf025..ad6dcc1bb643 100644
+--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
++++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+@@ -2,6 +2,7 @@ select * from information_schema.system_variables
+ where variable_name like 'innodb%' and
+ variable_name not in (
+ 'innodb_disallow_writes', # only available WITH_WSREP
++'innodb_numa_interleave', # only available WITH_NUMA
+ 'innodb_sched_priority_cleaner', # linux only
+ 'innodb_use_native_aio') # default value depends on OS
+ order by variable_name;
+diff --git a/mysql-test/suite/sys_vars/t/sysvars_innodb.test b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+index bd8442b6a443..38f248cb6113 100644
+--- a/mysql-test/suite/sys_vars/t/sysvars_innodb.test
++++ b/mysql-test/suite/sys_vars/t/sysvars_innodb.test
+@@ -9,6 +9,7 @@ select * from information_schema.system_variables
+ where variable_name like 'innodb%' and
+ variable_name not in (
+ 'innodb_disallow_writes', # only available WITH_WSREP
++ 'innodb_numa_interleave', # only available WITH_NUMA
+ 'innodb_sched_priority_cleaner', # linux only
+ 'innodb_use_native_aio') # default value depends on OS
+ order by variable_name;
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-11-11 23:17 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2018-11-11 23:17 UTC (permalink / raw
To: gentoo-commits
commit: 0f5f17c5a15d7a2bba4fd46615a655b0f0bf5ca7
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Nov 11 23:14:29 2018 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Nov 11 23:14:29 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=0f5f17c5
Add 20036_all_mysql-5.6-fix-rpl_semi_sync_shutdown_hang.test.patch
Bug: https://bugs.gentoo.org/670882
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...-5.6-fix-rpl_semi_sync_shutdown_hang.test.patch | 52 ++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/20036_all_mysql-5.6-fix-rpl_semi_sync_shutdown_hang.test.patch b/20036_all_mysql-5.6-fix-rpl_semi_sync_shutdown_hang.test.patch
new file mode 100644
index 0000000..97bd08e
--- /dev/null
+++ b/20036_all_mysql-5.6-fix-rpl_semi_sync_shutdown_hang.test.patch
@@ -0,0 +1,52 @@
+From a9840ba26e9f2af18c5f16ee79d0b008f98f22d0 Mon Sep 17 00:00:00 2001
+From: Sujatha Sivakumar <sujatha.sivakumar@oracle.com>
+Date: Mon, 27 Oct 2014 11:49:59 +0530
+Subject: [PATCH] Bug#19583563: RPL.RPL_SEMI_SYNC_SHUTDOWN_HANG FAILS
+ SPORADICALLY ON PB2
+
+Problem:
+========
+CURRENT_TEST: rpl.rpl_semi_sync_shutdown_hang
+mysqltest: At line 52: query 'reap' failed: 2013: Lost
+connection to MySQL server during query
+
+Analysis:
+========
+As part of test script with semisync enabled we stop the
+slave's IO thread and execute a CREATE TABLE on master. This
+statement will hang waiting for acknowledgement from slave
+and IO thread has gone away. This CREATE TABLE statement is
+kept in hang mode using --send command. Then master server
+goes down because of shutdown causing the CREATE TABLE
+statement to end successfully. When ever --send is used in
+MTR it expects a --reap command to be used to capture the
+return status of the statement that used --send. Because of
+timing issue some times --reap command is able to get the
+successful return status of --send command and some times
+the --reap command is executed post the server has actually
+shutdown. Because of this the reap command complains that it
+has lost connection to mysql server during query. --reap
+commands return code is not important for the actual bugfix
+verification. The main aim of test script is shutdown should
+not hang.
+
+Fix:
+===
+As part of fix --error 0,2013 is added above the --reap
+command.
+---
+ mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_hang.test | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_hang.test b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_hang.test
+index c632ee1b971..397450e19d5 100644
+--- a/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_hang.test
++++ b/mysql-test/suite/rpl/t/rpl_semi_sync_shutdown_hang.test
+@@ -49,6 +49,7 @@ SET GLOBAL rpl_semi_sync_master_timeout = 10000000;
+ --enable_result_log
+
+ --source include/rpl_connection_master.inc
++--error 0,2013
+ --reap
+ --let $rpl_server_number=1
+ --source include/rpl_start_server.inc
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2018-12-11 17:34 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2018-12-11 17:34 UTC (permalink / raw
To: gentoo-commits
commit: a033f9e0dc35edad0a3d5f02b1caa0855aefadaf
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Dec 11 17:33:44 2018 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Dec 11 17:33:44 2018 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a033f9e0
Restore jemalloc support on the server for 10.2 and 10.3 MariaDB
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20037_all_mariadb-10.2-restore-jemalloc.patch | 155 ++++++++++++++++++++++++++
20037_all_mariadb-10.3-restore-jemalloc.patch | 130 +++++++++++++++++++++
2 files changed, 285 insertions(+)
diff --git a/20037_all_mariadb-10.2-restore-jemalloc.patch b/20037_all_mariadb-10.2-restore-jemalloc.patch
new file mode 100644
index 0000000..0cf1fbb
--- /dev/null
+++ b/20037_all_mariadb-10.2-restore-jemalloc.patch
@@ -0,0 +1,155 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index be86adbf67b8..59dc149410f1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -154,6 +154,7 @@ INCLUDE(ssl)
+ INCLUDE(readline)
+ INCLUDE(libutils)
+ INCLUDE(dtrace)
++INCLUDE(jemalloc)
+ INCLUDE(pcre)
+ INCLUDE(ctest)
+ INCLUDE(plugin)
+@@ -329,6 +328,7 @@ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
++CHECK_JEMALLOC()
+
+ CHECK_PCRE()
+
+diff --git a/include/my_global.h b/include/my_global.h
+index e4ca562772e0..30db38ce35b5 100644
+--- a/include/my_global.h
++++ b/include/my_global.h
+@@ -1071,7 +1071,6 @@ typedef ulong myf; /* Type of MyFlags in my_funcs */
+ #ifdef _WIN32
+ #define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
+ #define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
+-#define RTLD_DEFAULT GetModuleHandle(NULL)
+ #define dlclose(lib) FreeLibrary((HMODULE)lib)
+ static inline char *dlerror(void)
+ {
+diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
+index 814993355b0f..243468e095a3 100644
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
+@@ -170,7 +170,7 @@ ADD_DEPENDENCIES(sql GenServerSource)
+ ADD_DEPENDENCIES(sql GenDigestServerSource)
+ DTRACE_INSTRUMENT(sql)
+ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
+- mysys mysys_ssl dbug strings vio pcre
++ mysys mysys_ssl dbug strings vio pcre ${LIBJEMALLOC}
+ ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT}
+ ${WSREP_LIB}
+ ${SSL_LIBRARIES}
+diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
+index d6b1c76ea004..fd724bc7dd16 100644
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -3489,32 +3489,11 @@ static Sys_var_charptr Sys_version_compile_os(
+ CMD_LINE_HELP_ONLY,
+ IN_SYSTEM_CHARSET, DEFAULT(SYSTEM_TYPE));
+
+-static char *guess_malloc_library()
+-{
+- if (strcmp(MALLOC_LIBRARY, "system") == 0)
+- {
+-#ifdef HAVE_DLOPEN
+- typedef int (*mallctl_type)(const char*, void*, size_t*, void*, size_t);
+- mallctl_type mallctl_func;
+- mallctl_func= (mallctl_type)dlsym(RTLD_DEFAULT, "mallctl");
+- if (mallctl_func)
+- {
+- static char buf[128];
+- char *ver;
+- size_t len = sizeof(ver);
+- mallctl_func("version", &ver, &len, NULL, 0);
+- strxnmov(buf, sizeof(buf)-1, "jemalloc ", ver, NULL);
+- return buf;
+- }
+-#endif
+- }
+- return const_cast<char*>(MALLOC_LIBRARY);
+-}
+ static char *malloc_library;
+ static Sys_var_charptr Sys_malloc_library(
+ "version_malloc_library", "Version of the used malloc library",
+ READ_ONLY GLOBAL_VAR(malloc_library), CMD_LINE_HELP_ONLY,
+- IN_SYSTEM_CHARSET, DEFAULT(guess_malloc_library()));
++ IN_SYSTEM_CHARSET, DEFAULT(MALLOC_LIBRARY));
+
+ #ifdef HAVE_YASSL
+ #include <openssl/ssl.h>
+diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
+index 4cfb177e495f..fd9a4790a7ea 100644
+--- a/storage/tokudb/CMakeLists.txt
++++ b/storage/tokudb/CMakeLists.txt
+@@ -5,8 +5,6 @@
+ RETURN()
+ ELSEIF(CMAKE_VERSION VERSION_LESS "2.8.9")
+ MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
+-ELSEIF(NOT HAVE_DLOPEN)
+- MESSAGE(STATUS "dlopen is required by TokuDB")
+ ELSEIF(PLUGIN_PERFSCHEMA MATCHES "^NO$")
+ MESSAGE(STATUS "Performance Schema is required by TokuDB")
+ RETURN()
+@@ -37,8 +35,7 @@
+ tokudb_sysvars.cc
+ tokudb_thread.cc
+ tokudb_dir_cmd.cc)
+-MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
+- COMPONENT tokudb-engine CONFIG ${CMAKE_CURRENT_BINARY_DIR}/tokudb.cnf)
++MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY COMPONENT Server)
+
+ IF(NOT TARGET tokudb)
+ RETURN()
+@@ -57,27 +54,6 @@
+ GET_FILENAME_COMPONENT(LIBJEMALLOC_PATH ${LIBJEMALLOC_SO} REALPATH CACHE)
+ ENDIF()
+
+-IF(LIBJEMALLOC_PATH AND (RPM OR DEB))
+- UNSET(LIBJEMALLOC)
+- GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES)
+- SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE)
+- SET(systemd_env "Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+- SET(cnf_malloc_lib "malloc-lib=${LIBJEMALLOC_PATH}")
+-ELSEIF(LIBJEMALLOC_PATH)
+- SET(systemd_env "#Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+- SET(cnf_malloc_lib "#malloc-lib=${LIBJEMALLOC_PATH}")
+-ELSE()
+- SET(systemd_env "#Environment=\"LD_PRELOAD=/path/to/libjemalloc.so\"") #"
+- SET(cnf_malloc_lib "#malloc-lib=/path/to/libjemalloc.so")
+-ENDIF()
+-CONFIGURE_FILE(tokudb.cnf.in tokudb.cnf @ONLY)
+-CONFIGURE_FILE(tokudb.conf.in tokudb.conf @ONLY)
+-IF(INSTALL_SYSCONFDIR)
+- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tokudb.conf
+- DESTINATION ${INSTALL_SYSCONFDIR}/systemd/system/mariadb.service.d/
+- COMPONENT tokudb-engine)
+-ENDIF()
+-
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-shadow")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
+@@ -154,7 +130,7 @@
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/${TOKU_FT_DIR_NAME}/portability)
+
+ TARGET_LINK_LIBRARIES(tokudb tokufractaltree_static tokuportability_static
+- ${ZLIB_LIBRARY} ${LIBJEMALLOC} stdc++)
++ ${ZLIB_LIBRARY} stdc++)
+
+ SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
+ SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
+diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+index f11b9f350d72..e62931524c9d 100644
+--- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt
++++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+@@ -12,5 +12,5 @@ endforeach(tool)
+ # link in math.h library just for this tool.
+ target_link_libraries(ftverify m)
+
+-install(TARGETS tokuftdump DESTINATION ${INSTALL_BINDIR} COMPONENT tokudb-engine)
+-install(TARGETS tokuft_logprint DESTINATION ${INSTALL_BINDIR} COMPONENT tokudb-engine)
++install(TARGETS tokuftdump DESTINATION ${INSTALL_BINDIR} COMPONENT Server)
++install(TARGETS tokuft_logprint DESTINATION ${INSTALL_BINDIR} COMPONENT Server)
diff --git a/20037_all_mariadb-10.3-restore-jemalloc.patch b/20037_all_mariadb-10.3-restore-jemalloc.patch
new file mode 100644
index 0000000..e8d239b
--- /dev/null
+++ b/20037_all_mariadb-10.3-restore-jemalloc.patch
@@ -0,0 +1,130 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index be86adbf67b8..59dc149410f1 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -154,6 +154,7 @@ INCLUDE(ssl)
+ INCLUDE(readline)
+ INCLUDE(libutils)
+ INCLUDE(dtrace)
++INCLUDE(jemalloc)
+ INCLUDE(pcre)
+ INCLUDE(ctest)
+ INCLUDE(plugin)
+@@ -329,6 +328,7 @@ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
++CHECK_JEMALLOC()
+
+ CHECK_PCRE()
+
+diff --git a/include/my_global.h b/include/my_global.h
+index e4ca562772e0..30db38ce35b5 100644
+--- a/include/my_global.h
++++ b/include/my_global.h
+@@ -1071,7 +1071,6 @@ typedef ulong myf; /* Type of MyFlags in my_funcs */
+ #ifdef _WIN32
+ #define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
+ #define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
+-#define RTLD_DEFAULT GetModuleHandle(NULL)
+ #define dlclose(lib) FreeLibrary((HMODULE)lib)
+ static inline char *dlerror(void)
+ {
+diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
+index 814993355b0f..243468e095a3 100644
+--- a/sql/CMakeLists.txt
++++ b/sql/CMakeLists.txt
+@@ -170,7 +170,7 @@ ADD_DEPENDENCIES(sql GenServerSource)
+ ADD_DEPENDENCIES(sql GenDigestServerSource)
+ DTRACE_INSTRUMENT(sql)
+ TARGET_LINK_LIBRARIES(sql ${MYSQLD_STATIC_PLUGIN_LIBS}
+- mysys mysys_ssl dbug strings vio pcre
++ mysys mysys_ssl dbug strings vio pcre ${LIBJEMALLOC}
+ ${LIBWRAP} ${LIBCRYPT} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT}
+ ${WSREP_LIB}
+ ${SSL_LIBRARIES}
+diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
+index d6b1c76ea004..fd724bc7dd16 100644
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -3793,7 +3793,7 @@
+ static Sys_var_charptr Sys_malloc_library(
+ "version_malloc_library", "Version of the used malloc library",
+ READ_ONLY GLOBAL_VAR(malloc_library), CMD_LINE_HELP_ONLY,
+- IN_SYSTEM_CHARSET, DEFAULT(guess_malloc_library()));
++ IN_SYSTEM_CHARSET, DEFAULT(MALLOC_LIBRARY));
+
+ static char *ssl_library;
+ static Sys_var_charptr Sys_ssl_library(
+diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
+index 4cfb177e495f..fd9a4790a7ea 100644
+--- a/storage/tokudb/CMakeLists.txt
++++ b/storage/tokudb/CMakeLists.txt
+@@ -5,8 +5,6 @@
+ RETURN()
+ ELSEIF(CMAKE_VERSION VERSION_LESS "2.8.9")
+ MESSAGE(STATUS "CMake 2.8.9 or higher is required by TokuDB")
+-ELSEIF(NOT HAVE_DLOPEN)
+- MESSAGE(STATUS "dlopen is required by TokuDB")
+ ELSEIF(PLUGIN_PERFSCHEMA MATCHES "^NO$")
+ MESSAGE(STATUS "Performance Schema is required by TokuDB")
+ RETURN()
+@@ -37,8 +35,7 @@
+ tokudb_sysvars.cc
+ tokudb_thread.cc
+ tokudb_dir_cmd.cc)
+-MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY
+- COMPONENT tokudb-engine CONFIG ${CMAKE_CURRENT_BINARY_DIR}/tokudb.cnf)
++MYSQL_ADD_PLUGIN(tokudb ${TOKUDB_SOURCES} STORAGE_ENGINE MODULE_ONLY COMPONENT Server)
+
+ IF(NOT TARGET tokudb)
+ RETURN()
+@@ -57,27 +54,6 @@
+ GET_FILENAME_COMPONENT(LIBJEMALLOC_PATH ${LIBJEMALLOC_SO} REALPATH CACHE)
+ ENDIF()
+
+-IF(LIBJEMALLOC_PATH AND (RPM OR DEB))
+- UNSET(LIBJEMALLOC)
+- GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES)
+- SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE)
+- SET(systemd_env "Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+- SET(cnf_malloc_lib "malloc-lib=${LIBJEMALLOC_PATH}")
+-ELSEIF(LIBJEMALLOC_PATH)
+- SET(systemd_env "#Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
+- SET(cnf_malloc_lib "#malloc-lib=${LIBJEMALLOC_PATH}")
+-ELSE()
+- SET(systemd_env "#Environment=\"LD_PRELOAD=/path/to/libjemalloc.so\"") #"
+- SET(cnf_malloc_lib "#malloc-lib=/path/to/libjemalloc.so")
+-ENDIF()
+-CONFIGURE_FILE(tokudb.cnf.in tokudb.cnf @ONLY)
+-CONFIGURE_FILE(tokudb.conf.in tokudb.conf @ONLY)
+-IF(INSTALL_SYSCONFDIR)
+- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tokudb.conf
+- DESTINATION ${INSTALL_SYSCONFDIR}/systemd/system/mariadb.service.d/
+- COMPONENT tokudb-engine)
+-ENDIF()
+-
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-shadow")
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
+ MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-implicit-fallthrough")
+@@ -154,7 +130,7 @@
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR}/${TOKU_FT_DIR_NAME}/portability)
+
+ TARGET_LINK_LIBRARIES(tokudb tokufractaltree_static tokuportability_static
+- ${ZLIB_LIBRARY} ${LIBJEMALLOC} stdc++)
++ ${ZLIB_LIBRARY} stdc++)
+
+ SET(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} -flto -fuse-linker-plugin")
+ SET(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "${CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO} -flto -fuse-linker-plugin")
+diff --git a/storage/tokudb/PerconaFT/tools/CMakeLists.txt b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+index f11b9f350d72..e62931524c9d 100644
+--- a/storage/tokudb/PerconaFT/tools/CMakeLists.txt
++++ b/storage/tokudb/PerconaFT/tools/CMakeLists.txt
+@@ -12,5 +12,5 @@ endforeach(tool)
+ # link in math.h library just for this tool.
+ target_link_libraries(ftverify m)
+
+-install(TARGETS tokuftdump DESTINATION ${INSTALL_BINDIR} COMPONENT tokudb-engine)
+-install(TARGETS tokuft_logprint DESTINATION ${INSTALL_BINDIR} COMPONENT tokudb-engine)
++install(TARGETS tokuftdump DESTINATION ${INSTALL_BINDIR} COMPONENT Server)
++install(TARGETS tokuft_logprint DESTINATION ${INSTALL_BINDIR} COMPONENT Server)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-01-19 20:38 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-01-19 20:38 UTC (permalink / raw
To: gentoo-commits
commit: d3f03ae3af3e7413ab6c5382bebb65bd8e28bfa5
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 19 20:37:29 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Jan 19 20:37:29 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d3f03ae3
Respin patch for mysql-cluster-7.2.34
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20006_all_cmake_elib-mysql-cluster-7.2.34.patch | 225 ++++++++++++++++++++++++
1 file changed, 225 insertions(+)
diff --git a/20006_all_cmake_elib-mysql-cluster-7.2.34.patch b/20006_all_cmake_elib-mysql-cluster-7.2.34.patch
new file mode 100644
index 0000000..91bcea5
--- /dev/null
+++ b/20006_all_cmake_elib-mysql-cluster-7.2.34.patch
@@ -0,0 +1,225 @@
+diff -aurN a/cmake/install_layout.cmake b/cmake/install_layout.cmake
+--- a/cmake/install_layout.cmake 2018-06-21 07:34:38.000000000 -0400
++++ b/cmake/install_layout.cmake 2019-01-19 15:20:18.791407251 -0500
+@@ -55,7 +55,8 @@
+ # - INSTALL_SBINDIR (directory with mysqld)
+ # - INSTALL_SCRIPTDIR (several scripts, rarely used)
+ #
+-# - INSTALL_LIBDIR (directory with client end embedded libraries)
++# - INSTALL_LIBDIR (directory with client libraries)
++# - INSTALL_ELIBDIR (directory with embedded libraries)
+ # - INSTALL_PLUGINDIR (directory for plugins)
+ #
+ # - INSTALL_INCLUDEDIR (directory for MySQL headers)
+@@ -156,6 +157,7 @@
+ SET(INSTALL_SCRIPTDIR_STANDALONE "scripts")
+ #
+ SET(INSTALL_LIBDIR_STANDALONE "lib")
++SET(INSTALL_ELIBDIR_STANDALONE "lib")
+ SET(INSTALL_PLUGINDIR_STANDALONE "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_STANDALONE "include")
+@@ -329,9 +331,11 @@
+ #
+ IF(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64")
+ SET(INSTALL_LIBDIR_RPM "lib64")
++ SET(INSTALL_ELIBDIR_RPM "lib64")
+ SET(INSTALL_PLUGINDIR_RPM "lib64/mysql/plugin")
+ ELSE()
+ SET(INSTALL_LIBDIR_RPM "lib")
++ SET(INSTALL_ELIBDIR_RPM "lib")
+ SET(INSTALL_PLUGINDIR_RPM "lib/mysql/plugin")
+ ENDIF()
+ #
+@@ -394,6 +398,7 @@
+ SET(INSTALL_SCRIPTDIR_DEB "scripts")
+ #
+ SET(INSTALL_LIBDIR_DEB "lib")
++SET(INSTALL_ELIBDIR_DEB "lib")
+ SET(INSTALL_PLUGINDIR_DEB "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_DEB "include")
+@@ -422,6 +427,7 @@
+ SET(INSTALL_SCRIPTDIR_SVR4 "scripts")
+ #
+ SET(INSTALL_LIBDIR_SVR4 "lib")
++SET(INSTALL_ELIBDIR_SVR4 "lib")
+ SET(INSTALL_PLUGINDIR_SVR4 "lib/plugin")
+ #
+ SET(INSTALL_INCLUDEDIR_SVR4 "include")
+@@ -453,7 +459,7 @@
+ # Set INSTALL_FOODIR variables for chosen layout (for example, INSTALL_BINDIR
+ # will be defined as ${INSTALL_BINDIR_STANDALONE} by default if STANDALONE
+ # layout is chosen)
+-FOREACH(var BIN SBIN LIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
++FOREACH(var BIN SBIN LIB ELIB MYSQLSHARE SHARE PLUGIN INCLUDE SCRIPT DOC MAN
+ INFO MYSQLTEST SQLBENCH DOCREADME SUPPORTFILES MYSQLDATA PLUGINTEST
+ SECURE_FILE_PRIV SECURE_FILE_PRIV_EMBEDDED)
+ SET(INSTALL_${var}DIR ${INSTALL_${var}DIR_${INSTALL_LAYOUT}}
+diff -aurN a/cmake/libutils.cmake b/cmake/libutils.cmake
+--- a/cmake/libutils.cmake 2019-01-19 15:15:56.294486959 -0500
++++ b/cmake/libutils.cmake 2019-01-19 15:23:39.369054028 -0500
+@@ -40,6 +40,7 @@
+ # - MERGE_LIBRARIES(target [STATIC|SHARED|MODULE] [linklib1 .... linklibN]
+ # [EXPORTS exported_func1 .... exported_func_N]
+ # [OUTPUT_NAME output_name]
++# [OUTPUT_DIR output_dir]
+ # This macro merges several static libraries into a single one or creates a shared
+ # library from several convenience libraries
+
+@@ -215,7 +216,7 @@
+ #)
+ MACRO(MERGE_LIBRARIES)
+ MYSQL_PARSE_ARGUMENTS(ARG
+- "EXPORTS;OUTPUT_NAME;COMPONENT"
++ "EXPORTS;OUTPUT_NAME;COMPONENT;OUTPUT_DIR"
+ "STATIC;SHARED;MODULE;NOINSTALL"
+ ${ARGN}
+ )
+@@ -266,7 +267,11 @@
+ IF(ARG_COMPONENT)
+ SET(COMP COMPONENT ${ARG_COMPONENT})
+ ENDIF()
+- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ IF(ARG_OUTPUT_DIR)
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
++ ELSE
++ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
++ ENDIF()
+ ENDIF()
+ SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_INTERFACE_LIBRARIES "")
+
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2019-01-19 15:15:56.504484491 -0500
++++ b/libmysql/CMakeLists.txt 2019-01-19 15:26:57.836803741 -0500
+@@ -153,6 +153,11 @@
+
+ SET(LIBS clientlib dbug strings vio mysys ${ZLIB_LIBRARY} ${SSL_LIBRARIES} ${LIBDL})
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ #
+ # On Windows platform client library includes the client-side
+ # Windows Native Authentication plugin.
+@@ -165,7 +170,7 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+-MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development)
++MERGE_LIBRARIES(mysqlclient STATIC ${LIBS} COMPONENT Development OUTPUT_DIR ${INSTALL_LIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -195,9 +200,11 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- INSTALL_SYMLINK(mysqlclient
+- ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+- ${INSTALL_LIBDIR} Development)
++ IF(ENABLE_STATIC_LIBS)
++ INSTALL_SYMLINK(mysqlclient
++ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
++ ${INSTALL_LIBDIR} Development)
++ ENDIF()
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+diff -aurN a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt
+--- a/libmysqld/CMakeLists.txt 2019-01-19 15:15:56.504484491 -0500
++++ b/libmysqld/CMakeLists.txt 2019-01-19 15:30:07.304860344 -0500
+@@ -135,8 +135,13 @@
+ ENDIF()
+ ENDFOREACH()
+
++SET(INSTALL_STATIC_LIBS "")
++IF(NOT ENABLE_STATIC_LIBS)
++ SET(INSTALL_STATIC_LIBS "NOINSTALL")
++ENDIF()
++
+ MERGE_LIBRARIES(mysqlserver STATIC ${EMBEDDED_LIBS}
+- OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded)
++ OUTPUT_NAME ${MYSQLSERVER_OUTPUT_NAME} COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR} ${INSTALL_STATIC_LIBS})
+
+ # Visual Studio users need debug static library
+ IF(MSVC)
+@@ -149,12 +154,14 @@
+ # to handle. So, for now, we just disable it for those builds.
+ #
+ IF(UNIX AND NOT INSTALL_LAYOUT MATCHES "SVR4")
+- INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_LIBDIR} RENAME
++ INSTALL_DEBUG_TARGET(mysqlserver DESTINATION ${INSTALL_ELIBDIR} RENAME
+ ${CMAKE_STATIC_LIBRARY_PREFIX}mysqld-debug)
+ ENDIF()
+
+ IF(NOT DISABLE_SHARED)
+- MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS})
++ MERGE_LIBRARIES(libmysqld SHARED mysqlserver EXPORTS ${CLIENT_API_FUNCTIONS}
++ COMPONENT Embedded OUTPUT_DIR ${INSTALL_ELIBDIR})
++
+ IF(UNIX)
+ # Name the shared library, handle versioning (provides same api as client library
+ # hence the same version)
+diff -aurN a/libservices/CMakeLists.txt b/libservices/CMakeLists.txt
+--- a/libservices/CMakeLists.txt 2019-01-19 15:15:56.504484491 -0500
++++ b/libservices/CMakeLists.txt 2019-01-19 15:31:15.404161862 -0500
+@@ -22,4 +22,6 @@
+ my_thread_scheduler_service.c)
+
+ ADD_LIBRARY(mysqlservices ${MYSQLSERVICES_SOURCES})
+-INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++IF(ENABLE_STATIC_LIBS)
++ INSTALL(TARGETS mysqlservices DESTINATION ${INSTALL_LIBDIR} COMPONENT Development)
++ENDIF()
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2019-01-19 15:15:56.504484491 -0500
++++ b/scripts/CMakeLists.txt 2019-01-19 15:31:59.513709368 -0500
+@@ -209,6 +209,7 @@
+ SET(scriptdir ${prefix}/${INSTALL_BINDIR})
+ SET(libexecdir ${prefix}/${INSTALL_SBINDIR})
+ SET(pkgdatadir ${prefix}/${INSTALL_MYSQLSHAREDIR})
++SET(elibdir ${prefix}/${INSTALL_ELIBDIR})
+ IF(INSTALL_LAYOUT MATCHES "STANDALONE")
+ SET(localstatedir ${prefix}/data)
+ ELSE()
+diff -aurN a/scripts/mysql_config.pl.in b/scripts/mysql_config.pl.in
+--- a/scripts/mysql_config.pl.in 2018-06-21 07:34:38.000000000 -0400
++++ b/scripts/mysql_config.pl.in 2019-01-19 15:33:17.682907458 -0500
+@@ -190,9 +190,10 @@
+ else
+ {
+ my $linkpath = "-L$pkglibdir @RPATH_OPTION@";
++ my $elinkpath = "-L@elibdir@ @RPATH_OPTION@";
+ @lib_opts = ($linkpath,"-lmysqlclient");
+ @lib_r_opts = ($linkpath,"-lmysqlclient_r");
+- @lib_e_opts = ($linkpath,"-lmysqld");
++ @lib_e_opts = ($elinkpath,"-lmysqld");
+ }
+
+ my $flags;
+diff -aurN a/scripts/mysql_config.sh b/scripts/mysql_config.sh
+--- a/scripts/mysql_config.sh 2019-01-19 15:15:56.294486959 -0500
++++ b/scripts/mysql_config.sh 2019-01-19 15:34:31.992145205 -0500
+@@ -92,6 +92,10 @@
+ plugindir_rel=`echo $plugindir | sed -e "s;^$basedir/;;"`
+ fix_path plugindir $plugindir_rel @libsubdir@/mysql/plugin @libsubdir@/plugin
+
++elibdir='@elibdir@'
++elibdir_rel=`echo $elibdir | sed -e "s;^$basedir/;;"`
++fix_path elibdir $elibdir_rel lib64/mysql lib64 lib/mysql lib
++
+ pkgincludedir='@pkgincludedir@'
+ if [ -f "$basedir/include/mysql/mysql.h" ]; then
+ pkgincludedir="$basedir/include/mysql"
+@@ -114,7 +118,7 @@
+ libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient @ZLIB_DEPS@ @NON_THREADED_LIBS@"
+ libs="$libs @openssl_libs@ @STATIC_NSS_FLAGS@ "
+ libs_r=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqlclient_r @ZLIB_DEPS@ @CLIENT_LIBS@ @openssl_libs@ "
+-embedded_libs=" $ldflags -L$pkglibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
++embedded_libs=" $ldflags -L$elibdir @RPATH_OPTION@ -lmysqld @LIBDL@ @ZLIB_DEPS@ @LIBS@ @WRAPLIBS@ @openssl_libs@ "
+
+ if [ -r "$pkglibdir/libmygcc.a" ]; then
+ # When linking against the static library with a different version of GCC
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-01-19 20:42 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-01-19 20:42 UTC (permalink / raw
To: gentoo-commits
commit: fcdce92cc5c7a5315b403ff331b77c0e5e1a5520
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 19 20:42:08 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sat Jan 19 20:42:08 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=fcdce92c
Fix syntax error
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20006_all_cmake_elib-mysql-cluster-7.2.34.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/20006_all_cmake_elib-mysql-cluster-7.2.34.patch b/20006_all_cmake_elib-mysql-cluster-7.2.34.patch
index 91bcea5..fb9cd86 100644
--- a/20006_all_cmake_elib-mysql-cluster-7.2.34.patch
+++ b/20006_all_cmake_elib-mysql-cluster-7.2.34.patch
@@ -83,7 +83,7 @@ diff -aurN a/cmake/libutils.cmake b/cmake/libutils.cmake
- MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
+ IF(ARG_OUTPUT_DIR)
+ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${ARG_OUTPUT_DIR}" ${COMP})
-+ ELSE
++ ELSE()
+ MYSQL_INSTALL_TARGETS(${TARGET} DESTINATION "${INSTALL_LIBDIR}" ${COMP})
+ ENDIF()
ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-01-20 18:22 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-01-20 18:22 UTC (permalink / raw
To: gentoo-commits
commit: 90f5dcf89b9f9781de9a3ee1dabaf741c580c619
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 20 18:22:22 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jan 20 18:22:22 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=90f5dcf8
Respin clientlibs patch for cluster 7.2
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
...l-cluster-7.2.34-without-clientlibs-tools.patch | 78 ++++++++++++++++++++++
1 file changed, 78 insertions(+)
diff --git a/20018_all_mysql-cluster-7.2.34-without-clientlibs-tools.patch b/20018_all_mysql-cluster-7.2.34-without-clientlibs-tools.patch
new file mode 100644
index 0000000..e5ddff3
--- /dev/null
+++ b/20018_all_mysql-cluster-7.2.34-without-clientlibs-tools.patch
@@ -0,0 +1,78 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/CMakeLists.txt 2015-06-24 10:34:17.314169100 -0400
+@@ -404,7 +404,9 @@
+ CONFIGURE_PLUGINS()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
+@@ -54,10 +54,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
++++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
+@@ -327,7 +327,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_secure_installation
+@@ -341,6 +340,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-06-24 12:32:11.606169100 -0400
++++ b/libmysql/CMakeLists.txt 2015-06-24 13:44:53.857169100 -0400
+@@ -202,14 +202,14 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(mysqlclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS}
+ COMPONENT SharedLibraries)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-01-20 23:10 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-01-20 23:10 UTC (permalink / raw
To: gentoo-commits
commit: 1d80ca492bb85a92377fb00588b4e9e8ac28bc57
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Jan 20 23:09:59 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Jan 20 23:09:59 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1d80ca49
Respin clientlibs for cluster 7.3.22
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
...l-cluster-7.3.22-without-clientlibs-tools.patch | 100 +++++++++++++++++++++
1 file changed, 100 insertions(+)
diff --git a/20018_all_mysql-cluster-7.3.22-without-clientlibs-tools.patch b/20018_all_mysql-cluster-7.3.22-without-clientlibs-tools.patch
new file mode 100644
index 0000000..5ca164e
--- /dev/null
+++ b/20018_all_mysql-cluster-7.3.22-without-clientlibs-tools.patch
@@ -0,0 +1,100 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2015-07-09 09:04:00.118091000 -0400
++++ b/CMakeLists.txt 2015-07-09 09:17:06.291091000 -0400
+@@ -436,7 +434,10 @@
+ ADD_SUBDIRECTORY(storage/ndb)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -462,7 +463,6 @@
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -470,7 +470,11 @@
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2015-05-05 07:05:53.000000000 -0400
++++ b/extra/CMakeLists.txt 2015-07-09 09:18:16.982091000 -0400
+@@ -60,11 +60,16 @@
+ ENDIF()
+
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+--- a/libmysql/CMakeLists.txt 2015-07-09 09:04:01.217091000 -0400
++++ b/libmysql/CMakeLists.txt 2015-07-09 09:22:47.903091000 -0400
+@@ -217,14 +217,14 @@
+
+ IF(UNIX)
+ GET_TARGET_NAME(mysqlclient lib_name)
+- IF(ENABLE_STATIC_LIBS)
++ IF(ENABLE_STATIC_LIBS AND NOT WITHOUT_CLIENTLIBS)
+ INSTALL_SYMLINK(mysqlclient
+ ${lib_name} ${CMAKE_STATIC_LIBRARY_PREFIX}mysqlclient_r.a
+ ${INSTALL_LIBDIR} Development)
+ ENDIF()
+ ENDIF()
+
+-IF(NOT DISABLE_SHARED)
++IF(NOT DISABLE_SHARED AND NOT WITHOUT_CLIENTLIBS)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
+ MERGE_LIBRARIES(libmysql SHARED ${LIBS}
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2015-07-09 09:04:00.401091000 -0400
++++ b/scripts/CMakeLists.txt 2015-07-09 09:20:25.723091000 -0400
+@@ -347,7 +347,6 @@
+ SET(mysql_config_COMPONENT COMPONENT Development)
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_fix_extensions
+ mysql_setpermission
+ mysql_zap
+@@ -360,6 +359,12 @@
+ mysqld_multi
+ mysqld_safe
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-01-26 19:21 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-01-26 19:21 UTC (permalink / raw
To: gentoo-commits
commit: 596d171d828ced4a268af307f42c64fa5bac993e
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 26 19:19:24 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Jan 26 19:19:24 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=596d171d
Add 20018_all_mysql-5.7.25-fix-build-without-server.patch
Bug: https://bugs.gentoo.org/671722
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.25-fix-build-without-server.patch | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/20018_all_mysql-5.7.25-fix-build-without-server.patch b/20018_all_mysql-5.7.25-fix-build-without-server.patch
new file mode 100644
index 0000000..37e8202
--- /dev/null
+++ b/20018_all_mysql-5.7.25-fix-build-without-server.patch
@@ -0,0 +1,12 @@
+https://bugs.gentoo.org/671722
+
+--- a/mysys/mf_iocache2.c
++++ b/mysys/mf_iocache2.c
+@@ -22,6 +22,7 @@
+ #include <m_string.h>
+ #include <stdarg.h>
+ #include <m_ctype.h>
++#include "mysql/psi/mysql_file.h"
+
+ /*
+ Copy contents of an IO_CACHE to a file.
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-03 18:44 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-03-03 18:44 UTC (permalink / raw
To: gentoo-commits
commit: 185eb05d83c466b5506a4dd0e9353bc52b7f7064
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 3 18:38:50 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Mar 3 18:43:17 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=185eb05d
Replace percona-server LibreSSL patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...atch => 20018_all_percona-server-5.7.25-fix-libressl-support.patch | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/20018_all_percona-server-5.7.23-fix-libressl-support.patch b/20018_all_percona-server-5.7.25-fix-libressl-support.patch
similarity index 98%
rename from 20018_all_percona-server-5.7.23-fix-libressl-support.patch
rename to 20018_all_percona-server-5.7.25-fix-libressl-support.patch
index f368f57..8ff17b9 100644
--- a/20018_all_percona-server-5.7.23-fix-libressl-support.patch
+++ b/20018_all_percona-server-5.7.25-fix-libressl-support.patch
@@ -11,7 +11,7 @@ https://bugs.gentoo.org/668894
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
EVP_CIPHER_CTX_cleanup(ctx);
delete ctx;
ERR_remove_thread_state(0);
@@ -35,7 +35,7 @@ https://bugs.gentoo.org/668894
}
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
CRYPTO_malloc_init();
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
OPENSSL_malloc_init();
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-03 18:44 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-03-03 18:44 UTC (permalink / raw
To: gentoo-commits
commit: c08bdd10a1c9d7e81532ecd9a1e5cb646c9cf0d1
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 3 18:37:18 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Mar 3 18:42:54 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c08bdd10
Replace mysql LibreSSL patch
Bug: https://bugs.gentoo.org/678682
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...pport.patch => 20018_all_mysql-5.7.25-fix-libressl-support.patch | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/20018_all_mysql-5.7.23-fix-libressl-support.patch b/20018_all_mysql-5.7.25-fix-libressl-support.patch
similarity index 98%
rename from 20018_all_mysql-5.7.23-fix-libressl-support.patch
rename to 20018_all_mysql-5.7.25-fix-libressl-support.patch
index 6e4bd50..63eda07 100644
--- a/20018_all_mysql-5.7.23-fix-libressl-support.patch
+++ b/20018_all_mysql-5.7.25-fix-libressl-support.patch
@@ -10,7 +10,7 @@ https://bugs.gentoo.org/668894
m_ok= EVP_DigestFinal_ex(md_context, m_digest, NULL);
-#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
+#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
EVP_MD_CTX_cleanup(md_context);
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
EVP_MD_CTX_reset(md_context);
@@ -22,7 +22,7 @@ https://bugs.gentoo.org/668894
#ifndef HAVE_YASSL
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2070000fL)
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL)
CRYPTO_malloc_init();
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
OPENSSL_malloc_init();
@@ -60,4 +60,4 @@ https://bugs.gentoo.org/668894
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
}
return(dh);
- }
+ }
\ No newline at end of file
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-03 18:52 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-03-03 18:52 UTC (permalink / raw
To: gentoo-commits
commit: d188adfb1f6fd8d9095a7bda2c347b7dd79af1a5
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 3 18:49:06 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sun Mar 3 18:51:20 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d188adfb
20018_all_mysql-5.7.25-fix-libressl-support.patch: add newline
...to avoid patch warning.
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.25-fix-libressl-support.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/20018_all_mysql-5.7.25-fix-libressl-support.patch b/20018_all_mysql-5.7.25-fix-libressl-support.patch
index 63eda07..ce61a42 100644
--- a/20018_all_mysql-5.7.25-fix-libressl-support.patch
+++ b/20018_all_mysql-5.7.25-fix-libressl-support.patch
@@ -60,4 +60,4 @@ https://bugs.gentoo.org/668894
-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
}
return(dh);
- }
\ No newline at end of file
+ }
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-05 20:22 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-03-05 20:22 UTC (permalink / raw
To: gentoo-commits
commit: 54bb710131c1656d295a016c04e5a85b031e5013
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Mar 5 20:21:51 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Mar 5 20:21:51 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=54bb7101
Fix ordering of galera SST my_print_defaults location
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mariadb-10.1.16-without-clientlibs-tools.patch | 11 ++++++++---
20018_all_mariadb-10.2.16-without-clientlibs-tools.patch | 11 ++++++++---
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
index 8e1a30d..2664529 100644
--- a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -136,12 +136,17 @@ diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
if [ -x "$CLIENT_DIR/mysql" ]; then
MYSQL_CLIENT="$CLIENT_DIR/mysql"
-@@ -165,6 +166,8 @@
+@@ -165,10 +166,12 @@
+ MYSQLDUMP=$(which mysqldump)
+ fi
+
++if [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="$LIBEXEC_DIR/my_print_defaults"
+-if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
++elif [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
-+elif [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
-+ MY_PRINT_DEFAULTS="LIBEXEC_DIR/my_print_defaults"
else
MY_PRINT_DEFAULTS=$(which my_print_defaults)
fi
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index e844046..1c61475 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -213,12 +213,17 @@ diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
if [ -x "$CLIENT_DIR/mysql" ]; then
MYSQL_CLIENT="$CLIENT_DIR/mysql"
-@@ -165,6 +166,8 @@
+@@ -165,10 +166,12 @@
+ MYSQLDUMP=$(which mysqldump)
+ fi
+
++if [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="$LIBEXEC_DIR/my_print_defaults"
+-if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
++elif [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
-+elif [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
-+ MY_PRINT_DEFAULTS="LIBEXEC_DIR/my_print_defaults"
else
MY_PRINT_DEFAULTS=$(which my_print_defaults)
fi
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-05 20:39 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-03-05 20:39 UTC (permalink / raw
To: gentoo-commits
commit: 59179b9fa6353c6d770839914cb2ded055d733e4
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Mar 5 20:38:15 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Mar 5 20:38:15 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=59179b9f
Adjust patch for my_print_defaults location in mysqld_safe
Bug: https://bugs.gentoo.org/show_bug.cgi?id=672698
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
..._all_mariadb-10.1.16-without-clientlibs-tools.patch | 18 ++++++++++++++++++
..._all_mariadb-10.2.16-without-clientlibs-tools.patch | 18 ++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
index 2664529..af8305d 100644
--- a/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.1.16-without-clientlibs-tools.patch
@@ -150,3 +150,21 @@ diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
else
MY_PRINT_DEFAULTS=$(which my_print_defaults)
fi
+diff -aurN a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
+--- a/scripts/mysqld_safe.sh 2019-02-09 18:24:09.000000000 -0500
++++ b/scripts/mysqld_safe.sh 2019-03-05 15:30:25.455288087 -0500
+@@ -133,7 +133,13 @@
+ }
+
+ find_in_bin() {
+- if test -x "$MY_BASEDIR_VERSION/bin/$1"
++ if test -x "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ then
++ echo "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ elif test -x "@bindir@/../libexec/mariadb/$1"
++ then
++ echo "@bindir@/../libexec/mariadb/$1"
++ elif test -x "$MY_BASEDIR_VERSION/$1"
+ then
+ echo "$MY_BASEDIR_VERSION/bin/$1"
+ elif test -x "@bindir@/$1"
diff --git a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
index 1c61475..d284a93 100644
--- a/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.2.16-without-clientlibs-tools.patch
@@ -227,3 +227,21 @@ diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
else
MY_PRINT_DEFAULTS=$(which my_print_defaults)
fi
+diff -aurN a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
+--- a/scripts/mysqld_safe.sh 2019-02-09 18:24:09.000000000 -0500
++++ b/scripts/mysqld_safe.sh 2019-03-05 15:30:25.455288087 -0500
+@@ -133,7 +133,13 @@
+ }
+
+ find_in_bin() {
+- if test -x "$MY_BASEDIR_VERSION/bin/$1"
++ if test -x "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ then
++ echo "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ elif test -x "@bindir@/../libexec/mariadb/$1"
++ then
++ echo "@bindir@/../libexec/mariadb/$1"
++ elif test -x "$MY_BASEDIR_VERSION/$1"
+ then
+ echo "$MY_BASEDIR_VERSION/bin/$1"
+ elif test -x "@bindir@/$1"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-05 20:47 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-03-05 20:47 UTC (permalink / raw
To: gentoo-commits
commit: 41f7ff6e82003f33150a67783e3e0a1ee260af45
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Mar 5 20:47:26 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Mar 5 20:47:26 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=41f7ff6e
Respin clientlibs patch for 10.3.12
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
..._mariadb-10.3.12-without-clientlibs-tools.patch | 247 +++++++++++++++++++++
1 file changed, 247 insertions(+)
diff --git a/20018_all_mariadb-10.3.12-without-clientlibs-tools.patch b/20018_all_mariadb-10.3.12-without-clientlibs-tools.patch
new file mode 100644
index 0000000..dca9f0f
--- /dev/null
+++ b/20018_all_mariadb-10.3.12-without-clientlibs-tools.patch
@@ -0,0 +1,247 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2018-02-27 16:45:56.740178421 -0500
++++ b/CMakeLists.txt 2018-02-28 09:06:59.163673185 -0500
+@@ -339,8 +339,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -377,28 +375,38 @@
+
+ SET (MYSQLD_STATIC_PLUGIN_LIBS "" CACHE INTERNAL "")
+
+-INCLUDE(submodules)
+ INCLUDE(mariadb_connector_c) # this does ADD_SUBDIRECTORY(libmariadb)
+
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+- IF(WITH_EMBEDDED_SERVER)
++ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2018-02-25 22:27:15.000000000 -0500
++++ b/extra/CMakeLists.txt 2018-03-09 10:08:24.532158129 -0500
+@@ -46,10 +46,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt
+--- a/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.434184441 -0500
++++ b/libmariadb/CMakeLists.txt 2018-02-28 09:15:16.258725638 -0500
+@@ -378,6 +378,6 @@
+ ADD_SUBDIRECTORY(include)
+ ADD_SUBDIRECTORY(libmariadb)
+-IF(NOT WIN32)
++IF(NOT WIN32 AND NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(mariadb_config)
+ ENDIF()
+
+diff -aurN a/libmariadb/include/CMakeLists.txt b/libmariadb/include/CMakeLists.txt
+--- a/libmariadb/include/CMakeLists.txt 2018-02-27 16:45:56.408184952 -0500
++++ b/libmariadb/include/CMakeLists.txt 2018-02-27 16:59:34.668054644 -0500
+@@ -26,6 +26,7 @@
+ SET(WIX_INCLUDES ${MARIADB_CLIENT_INCLUDES} ${MARIADB_ADDITIONAL_INCLUDES} ${MYSQL_ADDITIONAL_INCLUDES} PARENT_SCOPE)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES
+ ${MARIADB_CLIENT_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}
+@@ -38,3 +39,4 @@
+ ${MARIADB_ADDITIONAL_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}/mariadb
+ COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.421184696 -0500
++++ b/libmariadb/libmariadb/CMakeLists.txt 2018-02-28 09:10:54.981951174 -0500
+@@ -371,8 +371,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -398,7 +400,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
+-SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -412,11 +416,13 @@
+ # of the config program. To make sure these programs can
+ # use mariadb client library we provide libmysql symlinks
+
+-IF(WITH_MYSQLCOMPAT)
++IF(WITH_MYSQLCOMPAT AND NOT WITHOUT_CLIENTLIBS)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
+@@ -424,12 +430,16 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(NOT WITHOUT_CLIENTLIBS)
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(WIN32)
+ # On Windows, install PDB
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
++++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
+@@ -293,7 +293,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -305,6 +304,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
+diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
+--- a/scripts/wsrep_sst_common.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/wsrep_sst_common.sh 2018-08-09 12:30:24.976706933 -0400
+@@ -148,6 +148,7 @@
+ SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
+ EXTRA_DIR="$SCRIPTS_DIR/../extra"
+ CLIENT_DIR="$SCRIPTS_DIR/../client"
++LIBEXEC_DIR="$SCRIPTS_DIR/../libexec/mariadb"
+
+ if [ -x "$CLIENT_DIR/mysql" ]; then
+ MYSQL_CLIENT="$CLIENT_DIR/mysql"
+@@ -165,10 +166,12 @@
+ MYSQLDUMP=mysqldump
+ fi
+
++if [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="$LIBEXEC_DIR/my_print_defaults"
+-if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
++elif [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
+ elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
+ else
+ MY_PRINT_DEFAULTS=my_print_defaults
+ fi
+diff -aurN a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
+--- a/scripts/mysqld_safe.sh 2019-02-09 18:24:09.000000000 -0500
++++ b/scripts/mysqld_safe.sh 2019-03-05 15:30:25.455288087 -0500
+@@ -133,7 +133,13 @@
+ }
+
+ find_in_bin() {
+- if test -x "$MY_BASEDIR_VERSION/bin/$1"
++ if test -x "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ then
++ echo "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ elif test -x "@bindir@/../libexec/mariadb/$1"
++ then
++ echo "@bindir@/../libexec/mariadb/$1"
++ elif test -x "$MY_BASEDIR_VERSION/$1"
+ then
+ echo "$MY_BASEDIR_VERSION/bin/$1"
+ elif test -x "@bindir@/$1"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-03-10 2:57 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-03-10 2:57 UTC (permalink / raw
To: gentoo-commits
commit: b907f44502e212663453acdeeae38b6521be4323
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Sun Mar 10 02:56:46 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Sun Mar 10 02:56:46 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=b907f445
Respin mariadb-galera client-libs patch
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
...b-galera-10.0.20-without-clientlibs-tools.patch | 41 ++++++++++++++--------
1 file changed, 27 insertions(+), 14 deletions(-)
diff --git a/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch b/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
index 85e9786..8e37835 100644
--- a/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-galera-10.0.20-without-clientlibs-tools.patch
@@ -56,26 +56,23 @@ diff -aurN a/CMakeLists.txt b/CMakeLists.txt
diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
--- a/extra/CMakeLists.txt 2015-06-17 10:54:11.000000000 -0400
+++ b/extra/CMakeLists.txt 2015-06-24 10:37:31.879169100 -0400
-@@ -54,12 +54,14 @@
+@@ -54,10 +54,15 @@
DEPENDS
${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
--TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
-+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
-
--MYSQL_ADD_EXECUTABLE(perror perror.c)
--ADD_DEPENDENCIES(perror GenError)
--TARGET_LINK_LIBRARIES(perror mysys)
-+ MYSQL_ADD_EXECUTABLE(perror perror.c)
-+ ADD_DEPENDENCIES(perror GenError)
-+ TARGET_LINK_LIBRARIES(perror mysys)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
- IF(UNIX)
- MYSQL_ADD_EXECUTABLE(resolveip resolveip.c)
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
--- a/scripts/CMakeLists.txt 2015-06-24 10:28:12.800169100 -0400
+++ b/scripts/CMakeLists.txt 2015-06-24 10:42:49.682169100 -0400
@@ -118,3 +115,19 @@ diff -aurN a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
MERGE_LIBRARIES(libmysql SHARED ${LIBS}
EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_5_1_EXTRA} ${CLIENT_API_5_5_EXTRA}
COMPONENT SharedLibraries)
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-05-21 18:03 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-05-21 18:03 UTC (permalink / raw
To: gentoo-commits
commit: a23761893982c253c2eac4b4f151e8f37152e30e
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue May 21 18:02:54 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue May 21 18:02:54 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a2376189
Respin clientlibs patch for MariaDB 10.4.5
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
...l_mariadb-10.4.5-without-clientlibs-tools.patch | 239 +++++++++++++++++++++
1 file changed, 239 insertions(+)
diff --git a/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch b/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch
new file mode 100644
index 0000000..9cc11e7
--- /dev/null
+++ b/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch
@@ -0,0 +1,239 @@
+diff -aurN a/CMakeLists.txt b/CMakeLists.txt
+--- a/CMakeLists.txt 2018-02-27 16:45:56.740178421 -0500
++++ b/CMakeLists.txt 2018-02-28 09:06:59.163673185 -0500
+@@ -339,8 +339,6 @@
+ MYSQL_CHECK_ZLIB_WITH_COMPRESS()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add readline or libedit.
+-MYSQL_CHECK_READLINE()
+
+ SET(MALLOC_LIBRARY "system")
+
+@@ -404,22 +404,32 @@
+ # Add storage engines and plugins.
+ CONFIGURE_PLUGINS()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+ ADD_SUBDIRECTORY(mysys_ssl)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(extra)
+ ADD_SUBDIRECTORY(libservices)
+ ADD_SUBDIRECTORY(sql/share)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add readline or libedit.
++ MYSQL_CHECK_READLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(tests)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_READLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ADD_SUBDIRECTORY(unittest/embedded)
+diff -aurN a/extra/CMakeLists.txt b/extra/CMakeLists.txt
+--- a/extra/CMakeLists.txt 2018-02-25 22:27:15.000000000 -0500
++++ b/extra/CMakeLists.txt 2018-03-09 10:08:24.532158129 -0500
+@@ -46,10 +46,15 @@
+ DEPENDS
+ ${CMAKE_BINARY_DIR}/include/mysqld_error.h.tmp)
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+diff -aurN a/libmariadb/CMakeLists.txt b/libmariadb/CMakeLists.txt
+--- a/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.434184441 -0500
++++ b/libmariadb/CMakeLists.txt 2018-02-28 09:15:16.258725638 -0500
+@@ -378,6 +378,6 @@
+ ADD_SUBDIRECTORY(include)
+ ADD_SUBDIRECTORY(libmariadb)
+-IF(NOT WIN32)
++IF(NOT WIN32 AND NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(mariadb_config)
+ ENDIF()
+
+diff -aurN a/libmariadb/include/CMakeLists.txt b/libmariadb/include/CMakeLists.txt
+--- a/libmariadb/include/CMakeLists.txt 2018-02-27 16:45:56.408184952 -0500
++++ b/libmariadb/include/CMakeLists.txt 2018-02-27 16:59:34.668054644 -0500
+@@ -26,6 +26,7 @@
+ SET(WIX_INCLUDES ${MARIADB_CLIENT_INCLUDES} ${MARIADB_ADDITIONAL_INCLUDES} ${MYSQL_ADDITIONAL_INCLUDES} PARENT_SCOPE)
+ ENDIF()
+
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES
+ ${MARIADB_CLIENT_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}
+@@ -38,3 +39,4 @@
+ ${MARIADB_ADDITIONAL_INCLUDES}
+ DESTINATION ${INSTALL_INCLUDEDIR}/mariadb
+ COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+diff -aurN a/libmariadb/libmariadb/CMakeLists.txt b/libmariadb/libmariadb/CMakeLists.txt
+--- a/libmariadb/libmariadb/CMakeLists.txt 2018-02-27 16:45:56.421184696 -0500
++++ b/libmariadb/libmariadb/CMakeLists.txt 2018-02-28 09:10:54.981951174 -0500
+@@ -371,8 +371,10 @@
+ "FILE_DESCRIPTION:Dynamic lib for client/server communication")
+ ENDIF()
+
+-ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
+-TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ ADD_LIBRARY(mariadbclient STATIC ${MARIADB_OBJECTS} ${EMPTY_FILE})
++ TARGET_LINK_LIBRARIES(mariadbclient ${SYSTEM_LIBS})
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+
+ IF(UNIX)
+ ADD_LIBRARY(libmariadb SHARED ${libmariadb_RC} ${MARIADB_OBJECTS} ${EMPTY_FILE} mariadbclient.def)
+@@ -398,7 +400,9 @@
+ TARGET_LINK_LIBRARIES (libmariadb "${CC_BINARY_DIR}/libmariadb/mariadbclient.def")
+ ENDIF()
+
+-SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++IF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
++ SET_TARGET_PROPERTIES(mariadbclient PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
++ENDIF(ENABLE_STATIC_LIBS OR NOT WITHOUT_TOOLS)
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES IMPORTED_INTERFACE_LINK_LIBRARIES "${SYSTEM_LIBS}")
+
+ SET_TARGET_PROPERTIES(libmariadb PROPERTIES PREFIX "")
+@@ -412,11 +416,13 @@
+ # of the config program. To make sure these programs can
+ # use mariadb client library we provide libmysql symlinks
+
+-IF(WITH_MYSQLCOMPAT)
++IF(WITH_MYSQLCOMPAT AND NOT WITHOUT_CLIENTLIBS)
+ create_symlink(libmysqlclient${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
+- create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_SHARED_LIBRARY_SUFFIX} libmariadb ${INSTALL_LIBDIR})
++ IF(ENABLE_STATIC_LIBS)
++ create_symlink(libmysqlclient${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++# create_symlink(libmysqlclient_r${CMAKE_STATIC_LIBRARY_SUFFIX} mariadbclient ${INSTALL_LIBDIR})
++ ENDIF(ENABLE_STATIC_LIBS)
+ ENDIF()
+
+
+@@ -424,12 +430,16 @@
+ ${CPACK_PACKAGE_VERSION_MAJOR}
+ SOVERSION ${CPACK_PACKAGE_VERSION_MAJOR})
+
++IF(NOT WITHOUT_CLIENTLIBS)
++IF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS mariadbclient
+ COMPONENT Development
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(ENABLE_STATIC_LIBS)
+ INSTALL(TARGETS libmariadb
+ COMPONENT SharedLibraries
+ DESTINATION ${INSTALL_LIBDIR})
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ IF(WIN32)
+ # On Windows, install PDB
+diff -aurN a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+--- a/scripts/CMakeLists.txt 2018-02-27 16:45:56.384185424 -0500
++++ b/scripts/CMakeLists.txt 2018-02-27 16:54:34.623973364 -0500
+@@ -293,7 +293,6 @@
+ # On Unix, most of the files end up in the bin directory
+ SET(BIN_SCRIPTS
+ msql2mysql
+- mysql_config
+ mysql_setpermission
+ mysql_secure_installation
+ mysqlaccess
+@@ -305,6 +304,12 @@
+ ${WSREP_SCRIPTS}
+ ${SYSTEMD_SCRIPTS}
+ )
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
+--- a/scripts/mysql_install_db.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/mysql_install_db.sh 2018-08-09 12:23:28.707894151 -0400
+@@ -280,10 +280,10 @@
+ print_defaults="$builddir/extra/my_print_defaults"
+ elif test -n "$basedir"
+ then
+- print_defaults=`find_in_dirs my_print_defaults $basedir/bin $basedir/extra`
++ print_defaults=`find_in_dirs my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra`
+ if test -z "$print_defaults"
+ then
+- cannot_find_file my_print_defaults $basedir/bin $basedir/extra
++ cannot_find_file my_print_defaults $basedir/libexec/mariadb $basedir/bin $basedir/extra
+ exit 1
+ fi
+ else
+diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
+--- a/scripts/wsrep_sst_common.sh 2018-08-04 18:20:58.000000000 -0400
++++ b/scripts/wsrep_sst_common.sh 2018-08-09 12:30:24.976706933 -0400
+@@ -148,6 +148,7 @@
+ SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
+ EXTRA_DIR="$SCRIPTS_DIR/../extra"
+ CLIENT_DIR="$SCRIPTS_DIR/../client"
++LIBEXEC_DIR="$SCRIPTS_DIR/../libexec/mariadb"
+
+ if [ -x "$CLIENT_DIR/mysql" ]; then
+ MYSQL_CLIENT="$CLIENT_DIR/mysql"
+@@ -165,10 +166,12 @@
+ MYSQLDUMP=mysqldump
+ fi
+
++if [ -x "$LIBEXEC_DIR/my_print_defaults" ]; then
++ MY_PRINT_DEFAULTS="$LIBEXEC_DIR/my_print_defaults"
+-if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
++elif [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
+ elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
+ MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
+ else
+ MY_PRINT_DEFAULTS=my_print_defaults
+ fi
+diff -aurN a/scripts/mysqld_safe.sh b/scripts/mysqld_safe.sh
+--- a/scripts/mysqld_safe.sh 2019-02-09 18:24:09.000000000 -0500
++++ b/scripts/mysqld_safe.sh 2019-03-05 15:30:25.455288087 -0500
+@@ -133,7 +133,13 @@
+ }
+
+ find_in_bin() {
+- if test -x "$MY_BASEDIR_VERSION/bin/$1"
++ if test -x "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ then
++ echo "$MY_BASEDIR_VERSION/libexec/mariadb/$1"
++ elif test -x "@bindir@/../libexec/mariadb/$1"
++ then
++ echo "@bindir@/../libexec/mariadb/$1"
++ elif test -x "$MY_BASEDIR_VERSION/$1"
+ then
+ echo "$MY_BASEDIR_VERSION/bin/$1"
+ elif test -x "@bindir@/$1"
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-05-24 10:51 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-05-24 10:51 UTC (permalink / raw
To: gentoo-commits
commit: 1b4d361a49193fcf6cad352352eecf4db65c202e
Author: Stefan Strogin <steils <AT> gentoo <DOT> org>
AuthorDate: Fri May 24 10:44:44 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Fri May 24 10:45:41 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1b4d361a
Respin LibreSSL patches
Bug: https://bugs.gentoo.org/669216
Bug: https://bugs.gentoo.org/685948
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.25-fix-libressl-support.patch | 3 ++-
...ercona-server-5.7.25-fix-libressl-support.patch | 23 ++++++++++++++++++++--
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/20018_all_mysql-5.7.25-fix-libressl-support.patch b/20018_all_mysql-5.7.25-fix-libressl-support.patch
index ce61a42..fd47809 100644
--- a/20018_all_mysql-5.7.25-fix-libressl-support.patch
+++ b/20018_all_mysql-5.7.25-fix-libressl-support.patch
@@ -1,6 +1,7 @@
https://bugs.gentoo.org/662826
https://bugs.gentoo.org/668832
https://bugs.gentoo.org/668894
+https://bugs.gentoo.org/685948
--- a/sql/auth/sha2_password_common.cc
+++ b/sql/auth/sha2_password_common.cc
@@ -22,7 +23,7 @@ https://bugs.gentoo.org/668894
#ifndef HAVE_YASSL
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x2090000fL)
++ defined(LIBRESSL_VERSION_NUMBER)
CRYPTO_malloc_init();
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
OPENSSL_malloc_init();
diff --git a/20018_all_percona-server-5.7.25-fix-libressl-support.patch b/20018_all_percona-server-5.7.25-fix-libressl-support.patch
index 8ff17b9..c147bf0 100644
--- a/20018_all_percona-server-5.7.25-fix-libressl-support.patch
+++ b/20018_all_percona-server-5.7.25-fix-libressl-support.patch
@@ -2,9 +2,19 @@ https://bugs.gentoo.org/662826
https://bugs.gentoo.org/668832
https://bugs.gentoo.org/668818
https://bugs.gentoo.org/668894
+https://bugs.gentoo.org/669216
--- a/mysys_ssl/my_crypt.cc
+++ b/mysys_ssl/my_crypt.cc
+@@ -30,7 +30,7 @@
+ #include <boost/move/unique_ptr.hpp>
+ #include <boost/core/noncopyable.hpp>
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define EVP_CIPHER_CTX_buf_noconst(ctx) ((ctx)->buf)
+ #define RAND_OpenSSL() RAND_SSLeay()
+ #endif
@@ -95,7 +95,8 @@ MyEncryptionCTX::MyEncryptionCTX()
MyEncryptionCTX::~MyEncryptionCTX()
{
@@ -29,13 +39,22 @@ https://bugs.gentoo.org/668894
EVP_MD_CTX_reset(md_context);
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
-@@ -3679,7 +3679,8 @@ static int init_ssl()
+@@ -3678,6 +3678,7 @@ static int init_ssl()
+ {
+ #ifdef HAVE_OPENSSL
+ #ifndef HAVE_YASSL
++#ifndef LIBRESSL_VERSION_NUMBER
+ int fips_mode= FIPS_mode();
+ if (fips_mode != 0)
+ {
+@@ -3687,7 +3688,9 @@ static int init_ssl()
" Disabling FIPS.");
FIPS_mode_set(0);
}
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#endif
+#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
++ defined(LIBRESSL_VERSION_NUMBER)
CRYPTO_malloc_init();
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
OPENSSL_malloc_init();
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-06-04 11:30 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-06-04 11:30 UTC (permalink / raw
To: gentoo-commits
commit: d39d694e00c32933328ae2cf091c7ddb98a669f2
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Jun 4 11:09:09 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Jun 4 11:09:09 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d39d694e
Add LibreSSL patches for MySQL 5.6
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.6.44-fix-libressl-support.patch | 47 +++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/20018_all_mysql-5.6.44-fix-libressl-support.patch b/20018_all_mysql-5.6.44-fix-libressl-support.patch
new file mode 100644
index 0000000..b180677
--- /dev/null
+++ b/20018_all_mysql-5.6.44-fix-libressl-support.patch
@@ -0,0 +1,47 @@
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4358,7 +4358,10 @@ static int init_ssl()
+ {
+ #ifdef HAVE_OPENSSL
+ #ifndef HAVE_YASSL
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ CRYPTO_malloc_init();
++#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
++ OPENSSL_malloc_init();
+ #endif
+ ssl_start();
+ #ifndef EMBEDDED_LIBRARY
+@@ -4372,7 +4375,9 @@ static int init_ssl()
+ opt_ssl_cipher, &error,
+ opt_ssl_crl, opt_ssl_crlpath);
+ DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ERR_remove_state(0);
++#endif
+ if (!ssl_acceptor_fd)
+ {
+ sql_print_warning("Failed to setup SSL");
+--- a/vio/viosslfactories.c
++++ b/vio/viosslfactories.c
+@@ -68,12 +68,18 @@ static DH *get_dh2048(void)
+ DH *dh;
+ if ((dh=DH_new()))
+ {
+- dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+- dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
++ BIGNUM* p= BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
++ BIGNUM* g= BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ dh->p= p;
++ dh->g= g;
+ if (! dh->p || ! dh->g)
++#else
++ if (!DH_set0_pqg(dh, p, NULL, g))
++#endif
+ {
+ DH_free(dh);
+- dh=0;
++ dh= NULL;
+ }
+ }
+ return(dh);
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-07-22 19:21 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-07-22 19:21 UTC (permalink / raw
To: gentoo-commits
commit: 6a716a7a98ae6fe077bca7b5e7f6716086301eec
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Jul 22 19:20:20 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Jul 22 19:20:20 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=6a716a7a
Fix custom plugin location for MariaDB >=10.4
Bug: https://bugs.gentoo.org/show_bug.cgi?id=689412
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mariadb-10.4.5-without-clientlibs-tools.patch | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch b/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch
index 9cc11e7..e9ba8cf 100644
--- a/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch
+++ b/20018_all_mariadb-10.4.5-without-clientlibs-tools.patch
@@ -194,6 +194,15 @@ diff -aurN a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh
exit 1
fi
else
+@@ -345,7 +345,7 @@
+ cannot_find_file fill_help_tables.sql @pkgdata_locations@
+ exit 1
+ fi
+- plugindir=`find_in_dirs --dir auth_pam.so $basedir/lib*/plugin $basedir/lib*/mysql/plugin`
++ plugindir="$basedir/@INSTALL_PLUGINDIR@"
+ pamtooldir=$plugindir
+ # relative from where the script was run for a relocatable install
+ elif test -n "$dirname0" -a -x "$rel_mysqld" -a ! "$rel_mysqld" -ef "@sbindir@/mysqld"
diff -aurN a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
--- a/scripts/wsrep_sst_common.sh 2018-08-04 18:20:58.000000000 -0400
+++ b/scripts/wsrep_sst_common.sh 2018-08-09 12:30:24.976706933 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-02 0:13 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-02 0:13 UTC (permalink / raw
To: gentoo-commits
commit: 4945033d7f4438ec0baf76975ffd07208630d685
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 2 00:13:03 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Fri Aug 2 00:13:03 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=4945033d
Add initial MySQL v8.0 patch set
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
..._all_fix-minimal-build-cmake-mysql-8.0.17.patch | 26 ++++
20007_all_cmake-debug-werror-8.0.17.patch | 15 ++
...ll_mysql-8.0.17-add-protobuf-3.8+-support.patch | 20 +++
20018_all_mysql-8.0.17-fix-libressl-support.patch | 12 ++
...all_mysql-8.0.17-without-clientlibs-tools.patch | 156 +++++++++++++++++++++
5 files changed, 229 insertions(+)
diff --git a/20001_all_fix-minimal-build-cmake-mysql-8.0.17.patch b/20001_all_fix-minimal-build-cmake-mysql-8.0.17.patch
new file mode 100644
index 0000000..d79ffe2
--- /dev/null
+++ b/20001_all_fix-minimal-build-cmake-mysql-8.0.17.patch
@@ -0,0 +1,26 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1117,7 +1117,9 @@ MYSQL_CHECK_SSL_DLLS()
+ # Add system/bundled editline.
+ MYSQL_CHECK_EDITLINE()
+ # Add libevent
+-MYSQL_CHECK_LIBEVENT()
++IF(NOT WITHOUT_SERVER)
++ MYSQL_CHECK_LIBEVENT()
++ENDIF()
+ # Add lz4 library
+ MYSQL_CHECK_LZ4()
+ # Add re2 library
+@@ -1261,11 +1263,11 @@ ENDIF()
+ # scripts/mysql_config depends on client and server targets loaded above.
+ # It is referenced by some of the directories below, so we insert it here.
+ ADD_SUBDIRECTORY(scripts)
++ADD_SUBDIRECTORY(support-files)
+
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+- ADD_SUBDIRECTORY(support-files)
+ IF(EXISTS ${CMAKE_SOURCE_DIR}/internal/CMakeLists.txt)
+ ADD_SUBDIRECTORY(internal)
+ ENDIF()
diff --git a/20007_all_cmake-debug-werror-8.0.17.patch b/20007_all_cmake-debug-werror-8.0.17.patch
new file mode 100644
index 0000000..0579754
--- /dev/null
+++ b/20007_all_cmake-debug-werror-8.0.17.patch
@@ -0,0 +1,15 @@
+--- a/cmake/maintainer.cmake
++++ b/cmake/maintainer.cmake
+@@ -207,12 +207,6 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ # -Wzero-as-null-pointer-constant
+ ENDIF()
+
+-# Turn on Werror (warning => error) when using maintainer mode.
+-IF(MYSQL_MAINTAINER_MODE)
+- STRING_APPEND(MY_C_WARNING_FLAGS " -Werror")
+- STRING_APPEND(MY_CXX_WARNING_FLAGS " -Werror")
+-ENDIF()
+-
+ # Set warning flags for GCC/Clang
+ IF(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID MATCHES "Clang")
+ STRING_APPEND(CMAKE_C_FLAGS " ${MY_C_WARNING_FLAGS}")
diff --git a/20018_all_mysql-8.0.17-add-protobuf-3.8+-support.patch b/20018_all_mysql-8.0.17-add-protobuf-3.8+-support.patch
new file mode 100644
index 0000000..d472e25
--- /dev/null
+++ b/20018_all_mysql-8.0.17-add-protobuf-3.8+-support.patch
@@ -0,0 +1,20 @@
+--- a/plugin/x/client/mysqlxclient/xmessage.h
++++ b/plugin/x/client/mysqlxclient/xmessage.h
+@@ -36,7 +36,6 @@
+ #include <google/protobuf/repeated_field.h>
+ #include <google/protobuf/text_format.h>
+ #include <google/protobuf/wire_format_lite.h>
+-#include <google/protobuf/wire_format_lite_inl.h>
+
+ #ifdef USE_MYSQLX_FULL_PROTO
+
+--- a/plugin/x/ngs/include/ngs/protocol/protocol_protobuf.h
++++ b/plugin/x/ngs/include/ngs/protocol/protocol_protobuf.h
+@@ -38,7 +38,6 @@
+ #include <google/protobuf/repeated_field.h>
+ #include <google/protobuf/text_format.h>
+ #include <google/protobuf/wire_format_lite.h>
+-#include <google/protobuf/wire_format_lite_inl.h>
+
+ #ifdef USE_MYSQLX_FULL_PROTO
+ #include "plugin/x/generated/protobuf/mysqlx.pb.h"
diff --git a/20018_all_mysql-8.0.17-fix-libressl-support.patch b/20018_all_mysql-8.0.17-fix-libressl-support.patch
new file mode 100644
index 0000000..44596cf
--- /dev/null
+++ b/20018_all_mysql-8.0.17-fix-libressl-support.patch
@@ -0,0 +1,12 @@
+--- a/sql/auth/sha2_password_common.cc
++++ b/sql/auth/sha2_password_common.cc
+@@ -101,7 +101,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
+ DBUG_RETURN(true);
+ }
+ m_ok = EVP_DigestFinal_ex(md_context, m_digest, NULL);
+-#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
++#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
+ EVP_MD_CTX_cleanup(md_context);
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ EVP_MD_CTX_reset(md_context);
diff --git a/20018_all_mysql-8.0.17-without-clientlibs-tools.patch b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
new file mode 100644
index 0000000..b37272c
--- /dev/null
+++ b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
@@ -0,0 +1,156 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1114,8 +1114,6 @@ ENDIF()
+ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_SSL_DLLS()
+
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -1207,7 +1205,9 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -1250,7 +1250,6 @@ IF(WITH_UNIT_TESTS)
+ ADD_SUBDIRECTORY(unittest/mytap/t)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(utilities)
+ ADD_SUBDIRECTORY(share)
+ ADD_SUBDIRECTORY(libservices)
+@@ -1295,6 +1294,12 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(packaging/rpm-common)
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -240,12 +240,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(mysqlclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -283,9 +288,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED} ${CLIENT_API_NONBLOCKING_FUNCTIONS}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED} ${CLIENT_API_NONBLOCKING_FUNCTIONS}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -459,18 +459,23 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -485,7 +490,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -24,8 +24,9 @@ IF(NOT UNIX)
+ RETURN()
+ ENDIF()
+
+-INSTALL(FILES mysql.m4
+- DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(localstatedir "${MYSQL_DATADIR}")
+
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -94,10 +94,15 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.cc)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-02 0:31 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-02 0:31 UTC (permalink / raw
To: gentoo-commits
commit: 8850f522b55bc90e42ce215fe10a35042ca36959
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 2 00:30:52 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Fri Aug 2 00:30:52 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=8850f522
Fix 20018_all_mysql-8.0.17-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-8.0.17-without-clientlibs-tools.patch | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/20018_all_mysql-8.0.17-without-clientlibs-tools.patch b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
index b37272c..16de874 100644
--- a/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
+++ b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
@@ -142,11 +142,11 @@
-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
-+ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
-+ELSE(NOT WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
+ MYSQL_ADD_EXECUTABLE(perror perror.cc)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
+ENDIF(NOT WITHOUT_CLIENTLIBS)
TARGET_LINK_LIBRARIES(my_print_defaults mysys)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-02 15:49 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-02 15:49 UTC (permalink / raw
To: gentoo-commits
commit: 511aab731f9fcb6e61f1eb1977f14b30682bb1ad
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Fri Aug 2 15:48:22 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Fri Aug 2 15:49:21 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=511aab73
Fix MySQL 8.0 patch set
- Fix 20018_all_mysql-8.0.17-fix-libressl-support.patch
- Fix 20018_all_mysql-8.0.17-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-8.0.17-fix-libressl-support.patch | 266 ++++++++++++++++++++-
...all_mysql-8.0.17-without-clientlibs-tools.patch | 13 +
2 files changed, 269 insertions(+), 10 deletions(-)
diff --git a/20018_all_mysql-8.0.17-fix-libressl-support.patch b/20018_all_mysql-8.0.17-fix-libressl-support.patch
index 44596cf..340f894 100644
--- a/20018_all_mysql-8.0.17-fix-libressl-support.patch
+++ b/20018_all_mysql-8.0.17-fix-libressl-support.patch
@@ -1,12 +1,258 @@
---- a/sql/auth/sha2_password_common.cc
-+++ b/sql/auth/sha2_password_common.cc
-@@ -101,7 +101,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
- DBUG_RETURN(true);
+From: Stefan Strogin <steils@gentoo.org>
+Date: Sat, 8 Jun 2019 15:52:26 +0300
+Subject: [PATCH] Fix build with LibreSSL
+
+- Fix version checks as OPENSSL_VERSION_NUMBER in OpenSSL is always
+ 0x20000000L.
+- FIPS support is removed from LibreSSL, do not use it.
+- Check for TLS1_3_VERSION define, not OpenSSL/LibreSSL version.
+ Theoretically even OpenSSL >=1.1.1 can be built with TLS 1.3 disabled.
+
+
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -304,13 +304,14 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+ CRYPTO_LIBRARY AND
+- OPENSSL_MAJOR_VERSION STREQUAL "1"
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
+--- a/extra/libevent/openssl-compat.h
++++ b/extra/libevent/openssl-compat.h
+@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+ #define BIO_set_init(b, val) (b)->init = (val)
+ #define BIO_set_data(b, val) (b)->ptr = (val)
+ #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
+-#define BIO_get_init(b) (b)->init
+ #define BIO_get_data(b) (b)->ptr
+ #define BIO_get_shutdown(b) (b)->shutdown
+
+@@ -32,4 +31,8 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#define BIO_get_init(b) (b)->init
++#endif
++
+ #endif /* OPENSSL_COMPAT_H */
+--- a/mysys/my_md5.cc
++++ b/mysys/my_md5.cc
+@@ -56,7 +56,7 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
+-#if !defined(HAVE_WOLFSSL)
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ fips_mode = FIPS_mode();
+ #endif /* HAVE_WOLFSSL */
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -297,7 +297,7 @@ error:
+ return 1;
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -521,7 +521,7 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -523,7 +523,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -573,7 +573,7 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED};
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
+ 1) {
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
}
- m_ok = EVP_DigestFinal_ex(md_context, m_digest, NULL);
--#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
-+#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
-+ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02070000fL)
- EVP_MD_CTX_cleanup(md_context);
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -93,7 +93,7 @@ static constexpr int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -123,9 +123,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ default:
+ // unknown, leave all disabled
+ // fallthrough
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
+ // fallthrough
++#endif
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+ // fallthrough
+@@ -172,8 +174,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -170,7 +170,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7602,7 +7602,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL) && !defined(HAVE_WOLFSSL)
++#if defined(HAVE_OPENSSL) && \
++ !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4795,7 +4795,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -4831,7 +4831,7 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4377,7 +4377,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4390,7 +4390,7 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ }
+ #endif
+
+-#ifdef HAVE_WOLFSSL
++#if defined(HAVE_WOLFSSL) || defined(LIBRESSL_VERSION_NUMBER)
+ static const char *ssl_fips_mode_names[] = {"OFF", 0};
+ #else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+@@ -4398,7 +4398,7 @@ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ "permitted values are: OFF, ON, STRICT",
+ #else
+ "permitted values are: OFF",
+@@ -4406,7 +4406,7 @@ static Sys_var_enum Sys_ssl_fips_mode(
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(NULL),
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ ON_UPDATE(update_fips_mode),
+ #else
+ ON_UPDATE(NULL),
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(HAVE_WOLFSSL) && !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -515,7 +515,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
- EVP_MD_CTX_reset(md_context);
+ DBUG_PRINT("info",
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -429,7 +429,7 @@ void ssl_start() {
+ }
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
diff --git a/20018_all_mysql-8.0.17-without-clientlibs-tools.patch b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
index 16de874..042dd3e 100644
--- a/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
+++ b/20018_all_mysql-8.0.17-without-clientlibs-tools.patch
@@ -154,3 +154,16 @@
ADD_DEPENDENCIES(perror GenError)
TARGET_LINK_LIBRARIES(perror mysys)
+@@ -107,7 +112,11 @@ IF (BUILD_BUNDLED_LZ4)
+ ENDIF()
+
+ IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+- MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ ELSE(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc SKIP_INSTALL)
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+ ENDIF()
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-17 0:24 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-17 0:24 UTC (permalink / raw
To: gentoo-commits
commit: e8f3654620e584011f2d2f7f793b2ecdc01b2522
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 17 00:22:44 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 00:23:42 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e8f36546
Add OpenSSL 1.1 support (compile only) for MySQL 5.6.x
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
..._all_mysql-5.6.44-add-openssl-1.1-support.patch | 221 +++++++++++++++++++++
1 file changed, 221 insertions(+)
diff --git a/20018_all_mysql-5.6.44-add-openssl-1.1-support.patch b/20018_all_mysql-5.6.44-add-openssl-1.1-support.patch
new file mode 100644
index 0000000..bffcb31
--- /dev/null
+++ b/20018_all_mysql-5.6.44-add-openssl-1.1-support.patch
@@ -0,0 +1,221 @@
+--- a/mysys_ssl/my_aes_openssl.cc
++++ b/mysys_ssl/my_aes_openssl.cc
+@@ -108,33 +108,54 @@ int my_aes_encrypt(const unsigned char *source, uint32 source_length,
+ const unsigned char *key, uint32 key_length,
+ enum my_aes_opmode mode, const unsigned char *iv)
+ {
+- EVP_CIPHER_CTX ctx;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ EVP_CIPHER_CTX ctx_value;
++ EVP_CIPHER_CTX *ctx= &ctx_value;
++#else
++ EVP_CIPHER_CTX *ctx= EVP_CIPHER_CTX_new();
++ if (unlikely(!ctx))
++ return MY_AES_BAD_DATA;
++#endif
+ const EVP_CIPHER *cipher= aes_evp_type(mode);
+ int u_len, f_len;
+ /* The real key to be used for encryption */
+ unsigned char rkey[MAX_AES_KEY_LENGTH / 8];
+ my_aes_create_key(key, key_length, rkey, mode);
+
+- if (!cipher || (EVP_CIPHER_iv_length(cipher) > 0 && !iv))
++ if (!cipher || (EVP_CIPHER_iv_length(cipher) > 0
++ && EVP_CIPHER_mode(cipher) != EVP_CIPH_ECB_MODE && !iv))
++ {
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return MY_AES_BAD_DATA;
++ }
+
+- if (!EVP_EncryptInit(&ctx, cipher, rkey, iv))
++ if (!EVP_EncryptInit(ctx, cipher, rkey, iv))
+ goto aes_error; /* Error */
+- if (!EVP_CIPHER_CTX_set_padding(&ctx, 1))
++ if (!EVP_CIPHER_CTX_set_padding(ctx, 1))
+ goto aes_error; /* Error */
+- if (!EVP_EncryptUpdate(&ctx, dest, &u_len, source, source_length))
++ if (!EVP_EncryptUpdate(ctx, dest, &u_len, source, source_length))
+ goto aes_error; /* Error */
+
+- if (!EVP_EncryptFinal(&ctx, dest + u_len, &f_len))
++ if (!EVP_EncryptFinal(ctx, dest + u_len, &f_len))
+ goto aes_error; /* Error */
+
+- EVP_CIPHER_CTX_cleanup(&ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ EVP_CIPHER_CTX_cleanup(ctx);
++#else
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return u_len + f_len;
+
+ aes_error:
+ /* need to explicitly clean up the error if we want to ignore it */
+ ERR_clear_error();
+- EVP_CIPHER_CTX_cleanup(&ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ EVP_CIPHER_CTX_cleanup(ctx);
++#else
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return MY_AES_BAD_DATA;
+ }
+
+@@ -145,7 +166,14 @@ int my_aes_decrypt(const unsigned char *source, uint32 source_length,
+ enum my_aes_opmode mode, const unsigned char *iv)
+ {
+
+- EVP_CIPHER_CTX ctx;
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++ EVP_CIPHER_CTX ctx_value;
++ EVP_CIPHER_CTX *ctx= &ctx_value;
++#else
++ EVP_CIPHER_CTX *ctx= EVP_CIPHER_CTX_new();
++ if (unlikely(!ctx))
++ return MY_AES_BAD_DATA;
++#endif
+ const EVP_CIPHER *cipher= aes_evp_type(mode);
+ int u_len, f_len;
+
+@@ -153,27 +181,41 @@ int my_aes_decrypt(const unsigned char *source, uint32 source_length,
+ unsigned char rkey[MAX_AES_KEY_LENGTH / 8];
+
+ my_aes_create_key(key, key_length, rkey, mode);
+- if (!cipher || (EVP_CIPHER_iv_length(cipher) > 0 && !iv))
++ if (!cipher || (EVP_CIPHER_iv_length(cipher) > 0
++ && EVP_CIPHER_mode(cipher) != EVP_CIPH_ECB_MODE && !iv))
++ {
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return MY_AES_BAD_DATA;
++ }
+
+- EVP_CIPHER_CTX_init(&ctx);
++ EVP_CIPHER_CTX_init(ctx);
+
+- if (!EVP_DecryptInit(&ctx, aes_evp_type(mode), rkey, iv))
++ if (!EVP_DecryptInit(ctx, aes_evp_type(mode), rkey, iv))
+ goto aes_error; /* Error */
+- if (!EVP_CIPHER_CTX_set_padding(&ctx, 1))
++ if (!EVP_CIPHER_CTX_set_padding(ctx, 1))
+ goto aes_error; /* Error */
+- if (!EVP_DecryptUpdate(&ctx, dest, &u_len, source, source_length))
++ if (!EVP_DecryptUpdate(ctx, dest, &u_len, source, source_length))
+ goto aes_error; /* Error */
+- if (!EVP_DecryptFinal_ex(&ctx, dest + u_len, &f_len))
++ if (!EVP_DecryptFinal_ex(ctx, dest + u_len, &f_len))
+ goto aes_error; /* Error */
+
+- EVP_CIPHER_CTX_cleanup(&ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ EVP_CIPHER_CTX_cleanup(ctx);
++#else
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return u_len + f_len;
+
+ aes_error:
+ /* need to explicitly clean up the error if we want to ignore it */
+ ERR_clear_error();
+- EVP_CIPHER_CTX_cleanup(&ctx);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ EVP_CIPHER_CTX_cleanup(ctx);
++#else
++ EVP_CIPHER_CTX_free(ctx);
++#endif
+ return MY_AES_BAD_DATA;
+ }
+
+--- a/sql-common/client.c
++++ b/sql-common/client.c
+@@ -1968,7 +1968,11 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const c
+ goto error;
+ }
+
+- cn= (char *) ASN1_STRING_data(cn_asn1);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ cn= (const char *) ASN1_STRING_data(cn_asn1);
++#else
++ cn= (const char *) ASN1_STRING_get0_data(cn_asn1);
++#endif
+
+ // There should not be any NULL embedded in the CN
+ if ((size_t)ASN1_STRING_length(cn_asn1) != strlen(cn))
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -1252,7 +1252,7 @@ char *opt_ssl_ca= NULL, *opt_ssl_capath= NULL, *opt_ssl_cert= NULL,
+
+ #ifdef HAVE_OPENSSL
+ #include <openssl/crypto.h>
+-#ifndef HAVE_YASSL
++#if !defined(HAVE_YASSL) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ typedef struct CRYPTO_dynlock_value
+ {
+ mysql_rwlock_t lock;
+@@ -2021,7 +2021,7 @@ static void clean_up_mutexes()
+ mysql_mutex_destroy(&LOCK_connection_count);
+ #ifdef HAVE_OPENSSL
+ mysql_mutex_destroy(&LOCK_des_key_file);
+-#ifndef HAVE_YASSL
++#if !defined(HAVE_YASSL) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
+ mysql_rwlock_destroy(&openssl_stdlocks[i].lock);
+ OPENSSL_free(openssl_stdlocks);
+@@ -4242,7 +4242,7 @@ static int init_thread_environment()
+ #ifdef HAVE_OPENSSL
+ mysql_mutex_init(key_LOCK_des_key_file,
+ &LOCK_des_key_file, MY_MUTEX_INIT_FAST);
+-#ifndef HAVE_YASSL
++#if !defined(HAVE_YASSL) && (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ openssl_stdlocks= (openssl_lock_t*) OPENSSL_malloc(CRYPTO_num_locks() *
+ sizeof(openssl_lock_t));
+ for (int i= 0; i < CRYPTO_num_locks(); ++i)
+@@ -4285,7 +4285,8 @@ static int init_thread_environment()
+ }
+
+
+-#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL)
++#if defined(HAVE_OPENSSL) && !defined(HAVE_YASSL) && \
++ (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ static unsigned long openssl_id_function()
+ {
+ return (unsigned long) pthread_self();
+--- a/vio/vio.c
++++ b/vio/vio.c
+@@ -383,8 +383,10 @@ void vio_end(void)
+ #if defined(HAVE_YASSL)
+ yaSSL_CleanUp();
+ #elif defined(HAVE_OPENSSL)
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ // This one is needed on the client side
+ ERR_remove_state(0);
++#endif
+ ERR_free_strings();
+ EVP_cleanup();
+ CRYPTO_cleanup_all_ex_data();
+--- a/vio/viossl.c
++++ b/vio/viossl.c
+@@ -380,7 +380,8 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio,
+ my_socket sd= mysql_socket_getfd(vio->mysql_socket);
+
+ /* Declared here to make compiler happy */
+-#if !defined(HAVE_YASSL) && !defined(DBUG_OFF)
++#if !defined(HAVE_YASSL) && !defined(DBUG_OFF) && \
++ (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ int j, n;
+ #endif
+
+@@ -403,7 +404,9 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio,
+ sk_SSL_COMP_zero(SSL_COMP_get_compression_methods());
+ #endif
+
+-#if !defined(HAVE_YASSL) && !defined(DBUG_OFF)
++#if !defined(HAVE_YASSL) && !defined(DBUG_OFF) && \
++ (OPENSSL_VERSION_NUMBER < 0x10100000L)
++
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+ ssl_comp_methods = SSL_COMP_get_compression_methods();
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-17 0:24 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-17 0:24 UTC (permalink / raw
To: gentoo-commits
commit: 90814b24c49ca1d46a500200b33b6243835047ab
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 17 00:18:50 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 00:18:50 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=90814b24
Add initial Percona-Server v8.0 patch set
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-8.0.16-without-clientlibs-tools.patch | 197 ++++++++++++++
...ercona-server-8.0.16-fix-libressl-support.patch | 297 +++++++++++++++++++++
2 files changed, 494 insertions(+)
diff --git a/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
new file mode 100644
index 0000000..dd06976
--- /dev/null
+++ b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
@@ -0,0 +1,197 @@
+From b38aad3589e5d7138d366bbde6336421f11829e9 Mon Sep 17 00:00:00 2001
+From: root <root@dev1.fritz.box>
+Date: Sat, 17 Aug 2019 00:08:53 +0200
+Subject: [PATCH 4/5] 20018_all_percona-server-8.0.18-without-clientlibs-tools
+
+---
+ CMakeLists.txt | 13 +++++++++----
+ libmysql/CMakeLists.txt | 23 +++++++++++++++++------
+ scripts/CMakeLists.txt | 11 ++++++++---
+ support-files/CMakeLists.txt | 4 +++-
+ utilities/CMakeLists.txt | 15 ++++++++++++---
+ 5 files changed, 49 insertions(+), 17 deletions(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 586797bf..eac43129 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1047,8 +1047,6 @@ ENDIF()
+ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_SSL_DLLS()
+
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -1140,7 +1138,9 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -1173,7 +1173,6 @@ IF(WITH_UNIT_TESTS)
+ ADD_SUBDIRECTORY(unittest/mytap/t)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(utilities)
+ ADD_SUBDIRECTORY(share)
+ ADD_SUBDIRECTORY(libservices)
+@@ -1192,6 +1191,12 @@ ENDIF()
+ ADD_SUBDIRECTORY(scripts)
+ ADD_SUBDIRECTORY(support-files)
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(mysql-test)
+ ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
+diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
+index 3258ad9b..ca05da85 100644
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -240,12 +240,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big perconaserverclient
+-MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(perconaserverclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -284,9 +289,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
+index 22683309..541eeefc 100644
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -470,14 +470,12 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ ps_mysqld_helper
+ ps-admin
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+@@ -486,6 +484,13 @@ ELSE()
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -500,7 +505,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
+index a5a31590..3b155127 100644
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -64,7 +64,9 @@ IF(UNIX)
+ PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
+ ENDFOREACH()
+
+- INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
+diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt
+index 9ffb59e6..d7263a75 100644
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -90,10 +90,15 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.cc)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+
+@@ -103,7 +108,11 @@ IF (BUILD_BUNDLED_LZ4)
+ ENDIF()
+
+ IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+- MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ ELSE(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc SKIP_INSTALL)
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+ ENDIF()
+
+--
+2.22.1
+
diff --git a/20018_percona-server-8.0.16-fix-libressl-support.patch b/20018_percona-server-8.0.16-fix-libressl-support.patch
new file mode 100644
index 0000000..5e7b24e
--- /dev/null
+++ b/20018_percona-server-8.0.16-fix-libressl-support.patch
@@ -0,0 +1,297 @@
+From da955a3a74c57688d33d845d5cb12cccf8004ff2 Mon Sep 17 00:00:00 2001
+From: root <root@dev1.fritz.box>
+Date: Sat, 17 Aug 2019 00:15:49 +0200
+Subject: [PATCH 5/5] percona-server-8.0.16-fix-libressl-support
+
+---
+ cmake/ssl.cmake | 6 ++++--
+ extra/libevent/openssl-compat.h | 5 ++++-
+ mysys_ssl/my_md5.cc | 2 +-
+ .../src/bindings/xcom/xcom/xcom_ssl_transport.c | 4 ++--
+ plugin/x/client/xconnection_impl.cc | 4 ++--
+ router/src/http/src/tls_client_context.cc | 2 +-
+ router/src/http/src/tls_context.cc | 6 +++++-
+ router/src/http/src/tls_server_context.cc | 3 ++-
+ sql-common/client.cc | 3 ++-
+ sql/mysqld.cc | 4 ++--
+ sql/sys_vars.cc | 8 ++++----
+ vio/viossl.cc | 4 ++--
+ vio/viosslfactories.cc | 2 +-
+ 13 files changed, 32 insertions(+), 21 deletions(-)
+
+diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
+index e93a12e0..06cd36ec 100644
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -313,12 +313,14 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+- CRYPTO_LIBRARY
++ CRYPTO_LIBRARY AND
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
+diff --git a/extra/libevent/openssl-compat.h b/extra/libevent/openssl-compat.h
+index 69afc716..deb21d6a 100644
+--- a/extra/libevent/openssl-compat.h
++++ b/extra/libevent/openssl-compat.h
+@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+ #define BIO_set_init(b, val) (b)->init = (val)
+ #define BIO_set_data(b, val) (b)->ptr = (val)
+ #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
+-#define BIO_get_init(b) (b)->init
+ #define BIO_get_data(b) (b)->ptr
+ #define BIO_get_shutdown(b) (b)->shutdown
+
+@@ -32,4 +31,8 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#define BIO_get_init(b) (b)->init
++#endif
++
+ #endif /* OPENSSL_COMPAT_H */
+diff --git a/mysys_ssl/my_md5.cc b/mysys_ssl/my_md5.cc
+index 095fcb4e..0bdc885a 100644
+--- a/mysys_ssl/my_md5.cc
++++ b/mysys_ssl/my_md5.cc
+@@ -56,7 +56,7 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
+-#if !defined(HAVE_WOLFSSL)
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ fips_mode = FIPS_mode();
+ #endif /* HAVE_WOLFSSL */
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+diff --git a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+index 67c151b2..6a18a717 100644
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -297,7 +297,7 @@ error:
+ return 1;
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -521,7 +521,7 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+diff --git a/plugin/x/client/xconnection_impl.cc b/plugin/x/client/xconnection_impl.cc
+index cab1836c..4ba28d8f 100644
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -489,7 +489,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -539,7 +539,7 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED};
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
+ 1) {
+diff --git a/router/src/http/src/tls_client_context.cc b/router/src/http/src/tls_client_context.cc
+index f9dff94d..ae7413b4 100644
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+diff --git a/router/src/http/src/tls_context.cc b/router/src/http/src/tls_context.cc
+index bae36860..2cdc3127 100644
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -92,7 +92,7 @@ static constexpr int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -122,9 +122,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ default:
+ // unknown, leave all disabled
+ // fallthrough
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
+ // fallthrough
++#endif
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+ // fallthrough
+@@ -171,8 +173,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+diff --git a/router/src/http/src/tls_server_context.cc b/router/src/http/src/tls_server_context.cc
+index 4f3fa39c..ecc97559 100644
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -162,7 +162,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+diff --git a/sql-common/client.cc b/sql-common/client.cc
+index b6a253cc..2375bd19 100644
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7681,7 +7681,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL) && !defined(HAVE_WOLFSSL)
++#if defined(HAVE_OPENSSL) && \
++ !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *(uint *)arg;
+diff --git a/sql/mysqld.cc b/sql/mysqld.cc
+index 22364edc..7b066343 100644
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4881,7 +4881,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -4917,7 +4917,7 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
+index 5d7f3555..334684d2 100644
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4405,7 +4405,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4418,7 +4418,7 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ }
+ #endif
+
+-#ifdef HAVE_WOLFSSL
++#if defined(HAVE_WOLFSSL) || defined(LIBRESSL_VERSION_NUMBER)
+ static const char *ssl_fips_mode_names[] = {"OFF", 0};
+ #else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+@@ -4426,7 +4426,7 @@ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ "permitted values are: OFF, ON, STRICT",
+ #else
+ "permitted values are: OFF",
+@@ -4434,7 +4434,7 @@ static Sys_var_enum Sys_ssl_fips_mode(
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(NULL),
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ ON_UPDATE(update_fips_mode),
+ #else
+ ON_UPDATE(NULL),
+diff --git a/vio/viossl.cc b/vio/viossl.cc
+index d69119b3..5fb7c883 100644
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(HAVE_WOLFSSL) && !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -515,7 +515,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+diff --git a/vio/viosslfactories.cc b/vio/viosslfactories.cc
+index ea79ad1b..8ed961d1 100644
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -429,7 +429,7 @@ void ssl_start() {
+ }
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+--
+2.22.1
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-17 0:24 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-17 0:24 UTC (permalink / raw
To: gentoo-commits
commit: 9cca68e0575d46455bde1c362c2892b4a4bc97e9
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Aug 17 00:20:18 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Aug 17 00:20:18 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=9cca68e0
Fix 20018_all_mysql-5.6.44-fix-libressl-support.patch
Bug: https://bugs.gentoo.org/692124
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.6.44-fix-libressl-support.patch | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/20018_all_mysql-5.6.44-fix-libressl-support.patch b/20018_all_mysql-5.6.44-fix-libressl-support.patch
index b180677..939459d 100644
--- a/20018_all_mysql-5.6.44-fix-libressl-support.patch
+++ b/20018_all_mysql-5.6.44-fix-libressl-support.patch
@@ -1,6 +1,6 @@
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
-@@ -4358,7 +4358,10 @@ static int init_ssl()
+@@ -4358,7 +4358,11 @@ static int init_ssl()
{
#ifdef HAVE_OPENSSL
#ifndef HAVE_YASSL
@@ -8,10 +8,11 @@
CRYPTO_malloc_init();
+#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ OPENSSL_malloc_init();
++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
#endif
ssl_start();
#ifndef EMBEDDED_LIBRARY
-@@ -4372,7 +4375,9 @@ static int init_ssl()
+@@ -4372,7 +4376,9 @@ static int init_ssl()
opt_ssl_cipher, &error,
opt_ssl_crl, opt_ssl_crlpath);
DBUG_PRINT("info",("ssl_acceptor_fd: 0x%lx", (long) ssl_acceptor_fd));
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-08-22 19:08 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-08-22 19:08 UTC (permalink / raw
To: gentoo-commits
commit: 45d70904911e890421d4dd2c73ebb93ee9c99a73
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Thu Aug 22 17:53:06 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Thu Aug 22 18:53:22 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=45d70904
Add 20018_all_{mysql,percona-server}-5.7.26-without-clientlibs-tools.patch
Don't install {lz4,zlib}_decompress.
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...all_mysql-5.7.26-without-clientlibs-tools.patch | 183 ++++++++++++++++++++
...na-server-5.7.26-without-clientlibs-tools.patch | 189 +++++++++++++++++++++
2 files changed, 372 insertions(+)
diff --git a/20018_all_mysql-5.7.26-without-clientlibs-tools.patch b/20018_all_mysql-5.7.26-without-clientlibs-tools.patch
new file mode 100644
index 0000000..b4a8d2b
--- /dev/null
+++ b/20018_all_mysql-5.7.26-without-clientlibs-tools.patch
@@ -0,0 +1,183 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -551,8 +551,6 @@ IF(BUILD_BUNDLED_ZLIB)
+ ENDIF()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -645,7 +643,10 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -692,7 +693,6 @@ IF(WITH_UNIT_TESTS)
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -700,11 +700,20 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+--- a/extra/CMakeLists.txt
++++ b/extra/CMakeLists.txt
+@@ -71,12 +71,16 @@ IF (WIN32 AND WITH_SSL_PATH AND HAVE_CRYPTO_DLL)
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
+-
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+@@ -95,10 +99,15 @@ ENDIF()
+ MYSQL_ADD_EXECUTABLE(replace replace.c)
+ TARGET_LINK_LIBRARIES(replace mysys)
+
+-MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+-TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+-MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
+ TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY})
+
+ IF(WITH_INNOBASE_STORAGE_ENGINE)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -232,12 +232,16 @@ IF(WIN32)
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -284,9 +288,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ IF(UNIX)
+ # libtool compatability
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -413,18 +413,21 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+-
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -439,7 +442,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -59,8 +59,9 @@ IF(UNIX)
+ IF(INSTALL_SUPPORTFILESDIR)
+ INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
+ ENDIF()
+-
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
diff --git a/20018_all_percona-server-5.7.26-without-clientlibs-tools.patch b/20018_all_percona-server-5.7.26-without-clientlibs-tools.patch
new file mode 100644
index 0000000..331ad54
--- /dev/null
+++ b/20018_all_percona-server-5.7.26-without-clientlibs-tools.patch
@@ -0,0 +1,189 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -545,8 +545,6 @@ IF(BUILD_BUNDLED_ZLIB)
+ ENDIF()
+ # Add bundled yassl/taocrypt or system openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ MYSQL_CHECK_LIBEVENT()
+ # Add lz4 library
+@@ -637,7 +635,10 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -678,7 +679,6 @@ IF(WITH_UNIT_TESTS)
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -686,11 +686,20 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+--- a/extra/CMakeLists.txt
++++ b/extra/CMakeLists.txt
+@@ -71,12 +71,16 @@ IF (WIN32 AND WITH_SSL_PATH AND HAVE_CRYPTO_DLL)
+ ADD_DEPENDENCIES(GenError copy_openssl_extra)
+ ENDIF()
+
+-
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+@@ -95,10 +99,15 @@ ENDIF()
+ MYSQL_ADD_EXECUTABLE(replace replace.c)
+ TARGET_LINK_LIBRARIES(replace mysys)
+
+-MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+-TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+-MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
+ TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY})
+
+ IF(WITH_INNOBASE_STORAGE_ENGINE)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -232,12 +232,17 @@ IF(WIN32)
+ LIST(APPEND LIBS auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big perconaserverclient
+-MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # Visual Studio users need debug static library for debug projects
+ IF(MSVC)
+@@ -284,9 +289,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ IF(UNIX)
+ # libtool compatability
+ IF(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" OR APPLE)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -411,7 +411,6 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ ps_tokudb_admin
+ ps_mysqld_helper
+@@ -419,7 +418,6 @@ ELSE()
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+@@ -429,6 +427,13 @@ ELSE()
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -443,7 +448,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -59,8 +59,9 @@ IF(UNIX)
+ IF(INSTALL_SUPPORTFILESDIR)
+ INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
+ ENDIF()
+-
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-14 18:28 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-14 18:28 UTC (permalink / raw
To: gentoo-commits
commit: c183824a35fe6a198a712af7ca2d0f0bc7de8eba
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 14 18:27:24 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Oct 14 18:27:24 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c183824a
Respin 2 patches for 8.0.18 - libressl still needs rewrite
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20007_all_cmake-debug-werror-8.0.18.patch | 15 ++
...all_mysql-8.0.18-without-clientlibs-tools.patch | 180 +++++++++++++++++++++
2 files changed, 195 insertions(+)
diff --git a/20007_all_cmake-debug-werror-8.0.18.patch b/20007_all_cmake-debug-werror-8.0.18.patch
new file mode 100644
index 0000000..c2c1573
--- /dev/null
+++ b/20007_all_cmake-debug-werror-8.0.18.patch
@@ -0,0 +1,15 @@
+--- a/cmake/maintainer.cmake
++++ b/cmake/maintainer.cmake
+@@ -207,12 +207,6 @@ IF(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ # -Wzero-as-null-pointer-constant
+ ENDIF()
+
+-# Turn on Werror (warning => error) when using maintainer mode.
+-IF(MYSQL_MAINTAINER_MODE)
+- STRING_APPEND(MY_C_WARNING_FLAGS " -Werror")
+- STRING_APPEND(MY_CXX_WARNING_FLAGS " -Werror")
+-ENDIF()
+-
+ # Set warning flags for gcc/g++/clang/clang++
+ IF(MY_COMPILER_IS_GNU_OR_CLANG)
+ STRING_APPEND(CMAKE_C_FLAGS " ${MY_C_WARNING_FLAGS}")
diff --git a/20018_all_mysql-8.0.18-without-clientlibs-tools.patch b/20018_all_mysql-8.0.18-without-clientlibs-tools.patch
new file mode 100644
index 0000000..b3d7d23
--- /dev/null
+++ b/20018_all_mysql-8.0.18-without-clientlibs-tools.patch
@@ -0,0 +1,180 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1114,8 +1114,6 @@ ENDIF()
+ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_SSL_DLLS()
+
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -1207,7 +1205,9 @@ IF(WITH_UNIT_TESTS)
+ INCLUDE(googletest)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+@@ -1250,7 +1250,6 @@ IF(WITH_UNIT_TESTS)
+ ADD_SUBDIRECTORY(unittest/mytap/t)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(utilities)
+ ADD_SUBDIRECTORY(share)
+ ADD_SUBDIRECTORY(libservices)
+@@ -1295,6 +1294,12 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(packaging/rpm-common)
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -240,12 +240,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(mysqlclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -286,12 +286,22 @@
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS
++ ${CLIENT_API_FUNCTIONS}
++ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
++ COMPONENT SharedLibraries
++ SKIP_INSTALL )
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS
+ ${CLIENT_API_FUNCTIONS}
+ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -459,18 +459,23 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -485,7 +490,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -24,8 +24,9 @@ IF(NOT UNIX)
+ RETURN()
+ ENDIF()
+
+-INSTALL(FILES mysql.m4
+- DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(localstatedir "${MYSQL_DATADIR}")
+
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -99,6 +99,26 @@
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
++IF(WITHOUT_CLIENTLIBS)
++MYSQL_ADD_EXECUTABLE(my_print_defaults
++ my_print_defaults.cc
++ COMPONENT Server
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++MYSQL_ADD_EXECUTABLE(perror
++ perror.cc
++ COMPONENT Server
++ DEPENDENCIES GenError
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress
++ lz4_decompress.cc
++ COMPONENT Server
++ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
++ SKIP_INSTALL )
++ENDIF()
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults
+ my_print_defaults.cc
+ COMPONENT Server
+@@ -117,6 +137,7 @@
+ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
+ )
+ ENDIF()
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+ MYSQL_ADD_EXECUTABLE(zlib_decompress
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-14 19:15 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-14 19:15 UTC (permalink / raw
To: gentoo-commits
commit: d7f9cfd3c4f6aabcbe92c0e4a76712d9a42e08a2
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Oct 14 19:14:58 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Oct 14 19:14:58 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=d7f9cfd3
Add another section to 8.0.18 without-clientlibs patch
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mysql-8.0.18-without-clientlibs-tools.patch | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/20018_all_mysql-8.0.18-without-clientlibs-tools.patch b/20018_all_mysql-8.0.18-without-clientlibs-tools.patch
index b3d7d23..bd6c1ad 100644
--- a/20018_all_mysql-8.0.18-without-clientlibs-tools.patch
+++ b/20018_all_mysql-8.0.18-without-clientlibs-tools.patch
@@ -178,3 +178,22 @@
IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
MYSQL_ADD_EXECUTABLE(zlib_decompress
+diff -aurN a/man/CMakeLists.txt b/man/CMakeLists.txt
+--- a/man/CMakeLists.txt 2019-10-14 14:23:01.188087069 -0400
++++ b/man/CMakeLists.txt 2019-10-14 14:43:18.723648241 -0400
+@@ -26,7 +26,6 @@
+ ibd2sdi.1
+ innochecksum.1
+ lz4_decompress.1
+- my_print_defaults.1
+ myisam_ftdump.1
+ myisamchk.1
+ myisamlog.1
+@@ -51,7 +50,5 @@
+ mysqlpump.1
+ mysqlshow.1
+ mysqlslap.1
+- perror.1
+- zlib_decompress.1
+ )
+ SET(MAN1_NDB
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-15 16:40 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-15 16:40 UTC (permalink / raw
To: gentoo-commits
commit: 355217b0b03e04b1f9257f7d685c66e91d0b91f6
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 15 16:39:49 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Oct 15 16:39:49 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=355217b0
Respin libressl patch for 8.0.18 which removed WOLFSSL
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mysql-8.0.18-fix-libressl-support.patch | 529 ++++++++++++++++++++++
1 file changed, 529 insertions(+)
diff --git a/20018_all_mysql-8.0.18-fix-libressl-support.patch b/20018_all_mysql-8.0.18-fix-libressl-support.patch
new file mode 100644
index 0000000..72a2472
--- /dev/null
+++ b/20018_all_mysql-8.0.18-fix-libressl-support.patch
@@ -0,0 +1,529 @@
+From: Stefan Strogin <steils@gentoo.org>
+Date: Sat, 8 Jun 2019 15:52:26 +0300
+Subject: [PATCH] Fix build with LibreSSL
+
+- Fix version checks as OPENSSL_VERSION_NUMBER in OpenSSL is always
+ 0x20000000L.
+- FIPS support is removed from LibreSSL, do not use it.
+- Check for TLS1_3_VERSION define, not OpenSSL/LibreSSL version.
+ Theoretically even OpenSSL >=1.1.1 can be built with TLS 1.3 disabled.
+
+
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -304,13 +304,14 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+ CRYPTO_LIBRARY AND
+- OPENSSL_MAJOR_VERSION STREQUAL "1"
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
+--- a/extra/libevent/openssl-compat.h
++++ b/extra/libevent/openssl-compat.h
+@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+ #define BIO_set_init(b, val) (b)->init = (val)
+ #define BIO_set_data(b, val) (b)->ptr = (val)
+ #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
+-#define BIO_get_init(b) (b)->init
+ #define BIO_get_data(b) (b)->ptr
+ #define BIO_get_shutdown(b) (b)->shutdown
+
+@@ -32,4 +31,8 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#define BIO_get_init(b) (b)->init
++#endif
++
+ #endif /* OPENSSL_COMPAT_H */
+--- a/mysys/my_md5.cc
++++ b/mysys/my_md5.cc
+@@ -56,7 +56,7 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
+-#if !defined(HAVE_WOLFSSL)
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ fips_mode = FIPS_mode();
+ #endif /* HAVE_WOLFSSL */
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -297,7 +297,7 @@ error:
+ return 1;
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -521,7 +521,7 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -523,7 +523,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -573,7 +573,7 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED};
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
+ 1) {
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -93,7 +93,7 @@ static constexpr int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -123,9 +123,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ default:
+ // unknown, leave all disabled
+ // fallthrough
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
+ // fallthrough
++#endif
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+ // fallthrough
+@@ -172,8 +174,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -170,7 +170,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7602,7 +7602,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL) && !defined(HAVE_WOLFSSL)
++#if defined(HAVE_OPENSSL) && \
++ !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4795,7 +4795,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -4831,7 +4831,7 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4377,7 +4377,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4390,7 +4390,7 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ }
+ #endif
+
+-#ifdef HAVE_WOLFSSL
++#if defined(HAVE_WOLFSSL) || defined(LIBRESSL_VERSION_NUMBER)
+ static const char *ssl_fips_mode_names[] = {"OFF", 0};
+ #else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+@@ -4398,7 +4398,7 @@ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ "permitted values are: OFF, ON, STRICT",
+ #else
+ "permitted values are: OFF",
+@@ -4406,7 +4406,7 @@ static Sys_var_enum Sys_ssl_fips_mode(
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(NULL),
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ ON_UPDATE(update_fips_mode),
+ #else
+ ON_UPDATE(NULL),
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(HAVE_WOLFSSL) && !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -515,7 +515,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -429,7 +429,7 @@ void ssl_start() {
+ }
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+diff -aurN a/cmake/ssl.cmake b/cmake/ssl.cmake
+--- a/cmake/ssl.cmake 2019-09-20 04:30:51.000000000 -0400
++++ b/cmake/ssl.cmake 2019-10-15 12:07:03.527238024 -0400
+@@ -214,13 +214,14 @@
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+ CRYPTO_LIBRARY AND
+- OPENSSL_MAJOR_VERSION STREQUAL "1"
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
+diff -aurN a/extra/libevent/openssl-compat.h b/extra/libevent/openssl-compat.h
+--- a/extra/libevent/openssl-compat.h 2019-09-20 04:30:51.000000000 -0400
++++ b/extra/libevent/openssl-compat.h 2019-10-15 12:08:10.936049576 -0400
+@@ -24,7 +24,6 @@
+ #define BIO_set_init(b, val) (b)->init = (val)
+ #define BIO_set_data(b, val) (b)->ptr = (val)
+ #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
+-#define BIO_get_init(b) (b)->init
+ #define BIO_get_data(b) (b)->ptr
+ #define BIO_get_shutdown(b) (b)->shutdown
+
+@@ -32,4 +31,8 @@
+
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#define BIO_get_init(b) (b)->init
++#endif
++
+ #endif /* OPENSSL_COMPAT_H */
+diff -aurN a/mysys/my_md5.cc b/mysys/my_md5.cc
+--- a/mysys/my_md5.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/mysys/my_md5.cc 2019-10-15 12:09:45.872784172 -0400
+@@ -56,7 +56,9 @@
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
++#ifndef LIBRESSL_VERSION_NUMBER
+ fips_mode = FIPS_mode();
++#endif /* LIBRESSL_VERSION_NUMBER 8?
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+ * skipping call. */
+ if (fips_mode == 0) {
+diff -aurN a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c 2019-09-20 04:30:51.000000000 -0400
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c 2019-10-15 12:15:01.414902035 -0400
+@@ -329,6 +329,7 @@
+ return 1;
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -352,6 +353,7 @@
+ EXIT:
+ return rc;
+ }
++#endif
+
+ static int configure_ssl_ca(SSL_CTX *ssl_ctx, const char *ca_file,
+ const char *ca_path) {
+@@ -555,10 +557,12 @@
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+ }
++#endif
+
+ SSL_library_init();
+ SSL_load_error_strings();
+diff -aurN a/plugin/x/client/xconnection_impl.cc b/plugin/x/client/xconnection_impl.cc
+--- a/plugin/x/client/xconnection_impl.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/plugin/x/client/xconnection_impl.cc 2019-10-15 12:18:03.522392929 -0400
+@@ -521,6 +521,7 @@
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -559,6 +560,7 @@
+ EXIT:
+ return rc;
+ }
++#endif
+
+ XError Connection_impl::activate_tls() {
+ if (nullptr == m_vio) return get_socket_error(SOCKET_ECONNRESET);
+@@ -569,11 +571,13 @@
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED, true};
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(static_cast<int>(m_context->m_ssl_config.m_ssl_fips_mode),
+ err_string) != 1) {
+ return XError{CR_SSL_CONNECTION_ERROR, err_string, true};
+ }
++#endif
+ auto ssl_ctx_flags = process_tls_version(
+ details::null_when_empty(m_context->m_ssl_config.m_tls_version));
+
+diff -aurN a/router/src/http/src/tls_client_context.cc b/router/src/http/src/tls_client_context.cc
+--- a/router/src/http/src/tls_client_context.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/router/src/http/src/tls_client_context.cc 2019-10-15 12:20:26.018994567 -0400
+@@ -54,7 +54,7 @@
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+diff -aurN a/router/src/http/src/tls_context.cc b/router/src/http/src/tls_context.cc
+--- a/router/src/http/src/tls_context.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/router/src/http/src/tls_context.cc 2019-10-15 12:22:15.244689211 -0400
+@@ -91,7 +91,7 @@
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -121,9 +121,11 @@
+ default:
+ // unknown, leave all disabled
+ // fallthrough
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
+ // fallthrough
++#endif
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+ // fallthrough
+@@ -170,8 +172,10 @@
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+diff -aurN a/router/src/http/src/tls_server_context.cc b/router/src/http/src/tls_server_context.cc
+--- a/router/src/http/src/tls_server_context.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/router/src/http/src/tls_server_context.cc 2019-10-15 12:23:44.637439306 -0400
+@@ -166,7 +166,8 @@
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+diff -aurN a/sql/mysqld.cc b/sql/mysqld.cc
+--- a/sql/mysqld.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/sql/mysqld.cc 2019-10-15 12:25:25.125158377 -0400
+@@ -4797,7 +4797,7 @@
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+diff -aurN a/sql/sys_vars.cc b/sql/sys_vars.cc
+--- a/sql/sys_vars.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/sql/sys_vars.cc 2019-10-15 12:31:09.656195203 -0400
+@@ -4416,7 +4416,7 @@
+ "milliseconds",
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+-
++#ifndef LIBRESSL_VERSION_NUMBER
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4436,6 +4436,16 @@
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(NULL), ON_UPDATE(update_fips_mode), NULL);
++#else
++static const char *ssl_fips_mode_names[] = {"OFF", 0};
++static Sys_var_enum Sys_ssl_fips_mode(
++ "ssl_fips_mode",
++ "SSL FIPS mode (applies only for OpenSSL); "
++ "permitted values are: OFF",
++ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
++ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
++ ON_CHECK(NULL), ON_UPDATE(NULL), NULL);
++#endif
+
+ #if defined(HAVE_OPENSSL)
+ static Sys_var_bool Sys_auto_generate_certs(
+diff -aurN a/sql-common/client.cc b/sql-common/client.cc
+--- a/sql-common/client.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/sql-common/client.cc 2019-10-15 12:24:52.867248560 -0400
+@@ -7715,7 +7715,7 @@
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL)
++#if defined(HAVE_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+diff -aurN a/vio/viossl.cc b/vio/viossl.cc
+--- a/vio/viossl.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/vio/viossl.cc 2019-10-15 12:33:17.966836499 -0400
+@@ -490,7 +490,7 @@
+ #if !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -498,7 +498,7 @@
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+diff -aurN a/vio/viosslfactories.cc b/vio/viosslfactories.cc
+--- a/vio/viosslfactories.cc 2019-09-20 04:30:51.000000000 -0400
++++ b/vio/viosslfactories.cc 2019-10-15 12:34:15.145676646 -0400
+@@ -420,6 +420,7 @@
+ }
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -466,6 +467,7 @@
+ EXIT:
+ return rc;
+ }
++#endif
+
+ /**
+ Get fips mode from openssl library,
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-15 16:48 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-15 16:48 UTC (permalink / raw
To: gentoo-commits
commit: 4c93355a539343e6ca6c88945c21a8ff94ef1d65
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 15 16:47:52 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Oct 15 16:47:52 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=4c93355a
Fix duplicated patch from previous commit
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mysql-8.0.18-fix-libressl-support.patch | 258 ----------------------
1 file changed, 258 deletions(-)
diff --git a/20018_all_mysql-8.0.18-fix-libressl-support.patch b/20018_all_mysql-8.0.18-fix-libressl-support.patch
index 72a2472..9bcbd3e 100644
--- a/20018_all_mysql-8.0.18-fix-libressl-support.patch
+++ b/20018_all_mysql-8.0.18-fix-libressl-support.patch
@@ -1,261 +1,3 @@
-From: Stefan Strogin <steils@gentoo.org>
-Date: Sat, 8 Jun 2019 15:52:26 +0300
-Subject: [PATCH] Fix build with LibreSSL
-
-- Fix version checks as OPENSSL_VERSION_NUMBER in OpenSSL is always
- 0x20000000L.
-- FIPS support is removed from LibreSSL, do not use it.
-- Check for TLS1_3_VERSION define, not OpenSSL/LibreSSL version.
- Theoretically even OpenSSL >=1.1.1 can be built with TLS 1.3 disabled.
-
-
---- a/cmake/ssl.cmake
-+++ b/cmake/ssl.cmake
-@@ -304,13 +304,14 @@ MACRO (MYSQL_CHECK_SSL)
- OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
- )
- ENDIF()
-- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
-+ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
-+ IF(HAVE_TLS1_3_VERSION)
- ADD_DEFINITIONS(-DHAVE_TLSv13)
- ENDIF()
- IF(OPENSSL_INCLUDE_DIR AND
- OPENSSL_LIBRARY AND
- CRYPTO_LIBRARY AND
-- OPENSSL_MAJOR_VERSION STREQUAL "1"
-+ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
- )
- SET(OPENSSL_FOUND TRUE)
- FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
---- a/extra/libevent/openssl-compat.h
-+++ b/extra/libevent/openssl-compat.h
-@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
- #define BIO_set_init(b, val) (b)->init = (val)
- #define BIO_set_data(b, val) (b)->ptr = (val)
- #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
--#define BIO_get_init(b) (b)->init
- #define BIO_get_data(b) (b)->ptr
- #define BIO_get_shutdown(b) (b)->shutdown
-
-@@ -32,4 +31,8 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
-
- #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
-
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
-+#define BIO_get_init(b) (b)->init
-+#endif
-+
- #endif /* OPENSSL_COMPAT_H */
---- a/mysys/my_md5.cc
-+++ b/mysys/my_md5.cc
-@@ -56,7 +56,7 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
- int compute_md5_hash(char *digest, const char *buf, int len) {
- int retval = 0;
- int fips_mode = 0;
--#if !defined(HAVE_WOLFSSL)
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- fips_mode = FIPS_mode();
- #endif /* HAVE_WOLFSSL */
- /* If fips mode is ON/STRICT restricted method calls will result into abort,
---- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
-+++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
-@@ -297,7 +297,7 @@ error:
- return 1;
- }
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- #define OPENSSL_ERROR_LENGTH 512
- static int configure_ssl_fips_mode(const uint fips_mode) {
- int rc = -1;
-@@ -521,7 +521,7 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
- int verify_server = SSL_VERIFY_NONE;
- int verify_client = SSL_VERIFY_NONE;
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
- G_ERROR("Error setting the ssl fips mode");
- goto error;
---- a/plugin/x/client/xconnection_impl.cc
-+++ b/plugin/x/client/xconnection_impl.cc
-@@ -523,7 +523,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
- return XError(CR_SSL_CONNECTION_ERROR, buffer);
- }
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- /**
- Set fips mode in openssl library,
- When we set fips mode ON/STRICT, it will perform following operations:
-@@ -573,7 +573,7 @@ XError Connection_impl::activate_tls() {
- if (!m_context->m_ssl_config.is_configured())
- return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED};
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
- if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
- 1) {
---- a/router/src/http/src/tls_client_context.cc
-+++ b/router/src/http/src/tls_client_context.cc
-@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
-
- void TlsClientContext::cipher_suites(const std::string &ciphers) {
- // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
--#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
-+#ifdef TLS1_3_VERSION
- if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
- throw TlsError("set-cipher-suites");
- }
---- a/router/src/http/src/tls_context.cc
-+++ b/router/src/http/src/tls_context.cc
-@@ -93,7 +93,7 @@ static constexpr int o11x_version(TlsVersion version) {
- return TLS1_1_VERSION;
- case TlsVersion::TLS_1_2:
- return TLS1_2_VERSION;
--#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
-+#ifdef TLS1_3_VERSION
- case TlsVersion::TLS_1_3:
- return TLS1_3_VERSION;
- #endif
-@@ -123,9 +123,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
- default:
- // unknown, leave all disabled
- // fallthrough
-+#ifdef TLS1_3_VERSION
- case TlsVersion::TLS_1_3:
- opts |= SSL_OP_NO_TLSv1_2;
- // fallthrough
-+#endif
- case TlsVersion::TLS_1_2:
- opts |= SSL_OP_NO_TLSv1_1;
- // fallthrough
-@@ -172,8 +174,10 @@ TlsVersion TlsContext::min_version() const {
- return TlsVersion::TLS_1_1;
- case TLS1_2_VERSION:
- return TlsVersion::TLS_1_2;
-+#ifdef TLS1_3_VERSION
- case TLS1_3_VERSION:
- return TlsVersion::TLS_1_3;
-+#endif
- case 0:
- return TlsVersion::AUTO;
- default:
---- a/router/src/http/src/tls_server_context.cc
-+++ b/router/src/http/src/tls_server_context.cc
-@@ -170,7 +170,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
- }
-
- } else {
--#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
-+#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
-+ !defined(LIBRESSL_VERSION_NUMBER)
- dh2048.reset(DH_get_2048_256());
- #else
- /*
---- a/sql-common/client.cc
-+++ b/sql-common/client.cc
-@@ -7602,7 +7602,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
- #endif
- break;
- case MYSQL_OPT_SSL_FIPS_MODE: {
--#if defined(HAVE_OPENSSL) && !defined(HAVE_WOLFSSL)
-+#if defined(HAVE_OPENSSL) && \
-+ !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
- ENSURE_EXTENSIONS_PRESENT(&mysql->options);
- mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
---- a/sql/mysqld.cc
-+++ b/sql/mysqld.cc
-@@ -4795,7 +4795,7 @@ static int init_thread_environment() {
-
- static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
-
--#if OPENSSL_VERSION_NUMBER < 0x10100000L
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
- #define FILE_LINE_ARGS
- #else
- #define FILE_LINE_ARGS , const char *, int
-@@ -4831,7 +4831,7 @@ static void init_ssl() {
- }
-
- static int init_ssl_communication() {
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
- int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
- if (ret_fips_mode != 1) {
---- a/sql/sys_vars.cc
-+++ b/sql/sys_vars.cc
-@@ -4377,7 +4377,7 @@ static Sys_var_ulong Sys_max_execution_time(
- HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
- VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
- char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
- if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
-@@ -4390,7 +4390,7 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
- }
- #endif
-
--#ifdef HAVE_WOLFSSL
-+#if defined(HAVE_WOLFSSL) || defined(LIBRESSL_VERSION_NUMBER)
- static const char *ssl_fips_mode_names[] = {"OFF", 0};
- #else
- static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
-@@ -4398,7 +4398,7 @@ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
- static Sys_var_enum Sys_ssl_fips_mode(
- "ssl_fips_mode",
- "SSL FIPS mode (applies only for OpenSSL); "
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- "permitted values are: OFF, ON, STRICT",
- #else
- "permitted values are: OFF",
-@@ -4406,7 +4406,7 @@ static Sys_var_enum Sys_ssl_fips_mode(
- GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
- ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
- ON_CHECK(NULL),
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- ON_UPDATE(update_fips_mode),
- #else
- ON_UPDATE(NULL),
---- a/vio/viossl.cc
-+++ b/vio/viossl.cc
-@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
- #if !defined(HAVE_WOLFSSL) && !defined(DBUG_OFF)
- {
- STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
-- ssl_comp_methods = SSL_COMP_get_compression_methods();
-+ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
- n = sk_SSL_COMP_num(ssl_comp_methods);
- DBUG_PRINT("info", ("Available compression methods:\n"));
- if (n == 0)
-@@ -515,7 +515,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
- else
- for (j = 0; j < n; j++) {
- SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
--#if OPENSSL_VERSION_NUMBER < 0x10100000L
-+#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
- DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
- #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
- DBUG_PRINT("info",
---- a/vio/viosslfactories.cc
-+++ b/vio/viosslfactories.cc
-@@ -429,7 +429,7 @@ void ssl_start() {
- }
- }
-
--#ifndef HAVE_WOLFSSL
-+#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
- /**
- Set fips mode in openssl library,
- When we set fips mode ON/STRICT, it will perform following operations:
diff -aurN a/cmake/ssl.cmake b/cmake/ssl.cmake
--- a/cmake/ssl.cmake 2019-09-20 04:30:51.000000000 -0400
+++ b/cmake/ssl.cmake 2019-10-15 12:07:03.527238024 -0400
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-15 17:00 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-15 17:00 UTC (permalink / raw
To: gentoo-commits
commit: 721fdd555e9999e2d436c1a2bf7a00af7742e6d8
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 15 16:59:47 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Tue Oct 15 16:59:47 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=721fdd55
Fix typo from last patch
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mysql-8.0.18-fix-libressl-support.patch | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/20018_all_mysql-8.0.18-fix-libressl-support.patch b/20018_all_mysql-8.0.18-fix-libressl-support.patch
index 9bcbd3e..f6dc74f 100644
--- a/20018_all_mysql-8.0.18-fix-libressl-support.patch
+++ b/20018_all_mysql-8.0.18-fix-libressl-support.patch
@@ -47,7 +47,7 @@ diff -aurN a/mysys/my_md5.cc b/mysys/my_md5.cc
int fips_mode = 0;
+#ifndef LIBRESSL_VERSION_NUMBER
fips_mode = FIPS_mode();
-+#endif /* LIBRESSL_VERSION_NUMBER 8?
++#endif /* LIBRESSL_VERSION_NUMBER */
/* If fips mode is ON/STRICT restricted method calls will result into abort,
* skipping call. */
if (fips_mode == 0) {
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-17 18:34 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2019-10-17 18:34 UTC (permalink / raw
To: gentoo-commits
commit: 5bda8618c55ed07f5652107d7b76ddc88454ee06
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Thu Oct 17 18:34:23 2019 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Thu Oct 17 18:34:23 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=5bda8618
Fix 8.0.18 libressl patch
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20018_all_mysql-8.0.18-fix-libressl-support.patch | 31 +++++++++++++++++------
1 file changed, 23 insertions(+), 8 deletions(-)
diff --git a/20018_all_mysql-8.0.18-fix-libressl-support.patch b/20018_all_mysql-8.0.18-fix-libressl-support.patch
index f6dc74f..e7e1a79 100644
--- a/20018_all_mysql-8.0.18-fix-libressl-support.patch
+++ b/20018_all_mysql-8.0.18-fix-libressl-support.patch
@@ -250,9 +250,24 @@ diff -aurN a/vio/viossl.cc b/vio/viossl.cc
DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
DBUG_PRINT("info",
+diff -aurN a/include/violite.h b/include/violite.h
+--- a/include/violite.h 2019-09-20 04:30:51.000000000 -0400
++++ b/include/violite.h 2019-10-17 14:31:39.045842844 -0400
+@@ -269,9 +269,11 @@
+
+ long process_tls_version(const char *tls_version);
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ int set_fips_mode(const uint fips_mode, char *err_string);
+
+ uint get_fips_mode();
++#endif
+
+ struct st_VioSSLFd *new_VioSSLAcceptorFd(
+ const char *key_file, const char *cert_file, const char *ca_file,
diff -aurN a/vio/viosslfactories.cc b/vio/viosslfactories.cc
---- a/vio/viosslfactories.cc 2019-09-20 04:30:51.000000000 -0400
-+++ b/vio/viosslfactories.cc 2019-10-15 12:34:15.145676646 -0400
+--- a/vio/viosslfactories.cc 2019-10-17 14:27:32.672896538 -0400
++++ b/vio/viosslfactories.cc 2019-10-17 14:27:47.776954552 -0400
@@ -420,6 +420,7 @@
}
}
@@ -261,11 +276,11 @@ diff -aurN a/vio/viosslfactories.cc b/vio/viosslfactories.cc
/**
Set fips mode in openssl library,
When we set fips mode ON/STRICT, it will perform following operations:
-@@ -466,6 +467,7 @@
- EXIT:
- return rc;
- }
+@@ -473,6 +474,7 @@
+ @returns openssl current fips mode
+ */
+ uint get_fips_mode() { return FIPS_mode(); }
+#endif
- /**
- Get fips mode from openssl library,
+ long process_tls_version(const char *tls_version) {
+ const char *separator = ",";
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-29 23:58 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-29 23:58 UTC (permalink / raw
To: gentoo-commits
commit: 9c58421e9770bc1719dff1a6f170432bc39aa79f
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 29 23:57:09 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Oct 29 23:57:09 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=9c58421e
Fix 20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-8.0.16-without-clientlibs-tools.patch | 80 ++++++++--------------
1 file changed, 28 insertions(+), 52 deletions(-)
diff --git a/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
index dd06976..7e025c2 100644
--- a/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
+++ b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
@@ -1,18 +1,3 @@
-From b38aad3589e5d7138d366bbde6336421f11829e9 Mon Sep 17 00:00:00 2001
-From: root <root@dev1.fritz.box>
-Date: Sat, 17 Aug 2019 00:08:53 +0200
-Subject: [PATCH 4/5] 20018_all_percona-server-8.0.18-without-clientlibs-tools
-
----
- CMakeLists.txt | 13 +++++++++----
- libmysql/CMakeLists.txt | 23 +++++++++++++++++------
- scripts/CMakeLists.txt | 11 ++++++++---
- support-files/CMakeLists.txt | 4 +++-
- utilities/CMakeLists.txt | 15 ++++++++++++---
- 5 files changed, 49 insertions(+), 17 deletions(-)
-
-diff --git a/CMakeLists.txt b/CMakeLists.txt
-index 586797bf..eac43129 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1047,8 +1047,6 @@ ENDIF()
@@ -43,9 +28,9 @@ index 586797bf..eac43129 100644
ADD_SUBDIRECTORY(utilities)
ADD_SUBDIRECTORY(share)
ADD_SUBDIRECTORY(libservices)
-@@ -1192,6 +1191,12 @@ ENDIF()
- ADD_SUBDIRECTORY(scripts)
- ADD_SUBDIRECTORY(support-files)
+@@ -1182,6 +1181,12 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+IF(NOT WITHOUT_TOOLS)
+ # Add system/bundled editline
@@ -54,10 +39,8 @@ index 586797bf..eac43129 100644
+ENDIF(NOT WITHOUT_TOOLS)
+
IF(NOT WITHOUT_SERVER)
- ADD_SUBDIRECTORY(mysql-test)
- ADD_SUBDIRECTORY(mysql-test/lib/My/SafeProcess)
-diff --git a/libmysql/CMakeLists.txt b/libmysql/CMakeLists.txt
-index 3258ad9b..ca05da85 100644
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -240,12 +240,17 @@ IF(WIN32)
@@ -100,8 +83,6 @@ index 3258ad9b..ca05da85 100644
TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
IF(WIN32)
-diff --git a/scripts/CMakeLists.txt b/scripts/CMakeLists.txt
-index 22683309..541eeefc 100644
--- a/scripts/CMakeLists.txt
+++ b/scripts/CMakeLists.txt
@@ -470,14 +470,12 @@ ELSE()
@@ -127,7 +108,7 @@ index 22683309..541eeefc 100644
+ SET(BIN_SCRIPTS
+ ${BIN_SCRIPTS}
+ mysql_config
-+ )
++ )
+ ENDIF(NOT WITHOUT_CLIENTLIBS)
+
SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
@@ -142,8 +123,6 @@ index 22683309..541eeefc 100644
MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
INSTALL(FILES
${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
-diff --git a/support-files/CMakeLists.txt b/support-files/CMakeLists.txt
-index a5a31590..3b155127 100644
--- a/support-files/CMakeLists.txt
+++ b/support-files/CMakeLists.txt
@@ -64,7 +64,9 @@ IF(UNIX)
@@ -157,41 +136,38 @@ index a5a31590..3b155127 100644
SET(bindir ${prefix}/${INSTALL_BINDIR})
SET(sbindir ${prefix}/${INSTALL_SBINDIR})
-diff --git a/utilities/CMakeLists.txt b/utilities/CMakeLists.txt
-index 9ffb59e6..d7263a75 100644
--- a/utilities/CMakeLists.txt
+++ b/utilities/CMakeLists.txt
-@@ -90,10 +90,15 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+@@ -90,6 +90,13 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
ENDIF()
--MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
-+IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
-+ MYSQL_ADD_EXECUTABLE(perror perror.cc)
-+ELSE(NOT WITHOUT_CLIENTLIBS)
++IF(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
+ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
-+ENDIF(NOT WITHOUT_CLIENTLIBS)
++IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc SKIP_INSTALL)
++ENDIF()
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
--MYSQL_ADD_EXECUTABLE(perror perror.cc)
- ADD_DEPENDENCIES(perror GenError)
- TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
-
-@@ -103,7 +108,11 @@ IF (BUILD_BUNDLED_LZ4)
+@@ -101,11 +108,14 @@ IF (BUILD_BUNDLED_LZ4)
+ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+ TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY} mysys)
ENDIF()
++ENDIF(WITHOUT_CLIENTLIBS)
- IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
-- MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
-+ IF(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
-+ ELSE(NOT WITHOUT_CLIENTLIBS)
-+ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc SKIP_INSTALL)
-+ ENDIF(NOT WITHOUT_CLIENTLIBS)
- TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
- ENDIF()
+-IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
++IF(WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
+- TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+-ENDIF()
++ENDIF(WITHOUT_CLIENTLIBS)
++TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+
+ IF(WITH_INNOBASE_STORAGE_ENGINE)
---
-2.22.1
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-29 23:58 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-29 23:58 UTC (permalink / raw
To: gentoo-commits
commit: 3977e69c277db98074d31d713df2a3d37edc78ab
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Oct 29 23:58:22 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Oct 29 23:58:22 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3977e69c
Fix 20018_all_percona-server-8.0.16-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...ercona-server-8.0.16-fix-libressl-support.patch | 58 +---------------------
1 file changed, 1 insertion(+), 57 deletions(-)
diff --git a/20018_percona-server-8.0.16-fix-libressl-support.patch b/20018_all_percona-server-8.0.16-fix-libressl-support.patch
similarity index 76%
rename from 20018_percona-server-8.0.16-fix-libressl-support.patch
rename to 20018_all_percona-server-8.0.16-fix-libressl-support.patch
index 5e7b24e..c54d7ae 100644
--- a/20018_percona-server-8.0.16-fix-libressl-support.patch
+++ b/20018_all_percona-server-8.0.16-fix-libressl-support.patch
@@ -1,29 +1,6 @@
-From da955a3a74c57688d33d845d5cb12cccf8004ff2 Mon Sep 17 00:00:00 2001
-From: root <root@dev1.fritz.box>
-Date: Sat, 17 Aug 2019 00:15:49 +0200
-Subject: [PATCH 5/5] percona-server-8.0.16-fix-libressl-support
-
----
- cmake/ssl.cmake | 6 ++++--
- extra/libevent/openssl-compat.h | 5 ++++-
- mysys_ssl/my_md5.cc | 2 +-
- .../src/bindings/xcom/xcom/xcom_ssl_transport.c | 4 ++--
- plugin/x/client/xconnection_impl.cc | 4 ++--
- router/src/http/src/tls_client_context.cc | 2 +-
- router/src/http/src/tls_context.cc | 6 +++++-
- router/src/http/src/tls_server_context.cc | 3 ++-
- sql-common/client.cc | 3 ++-
- sql/mysqld.cc | 4 ++--
- sql/sys_vars.cc | 8 ++++----
- vio/viossl.cc | 4 ++--
- vio/viosslfactories.cc | 2 +-
- 13 files changed, 32 insertions(+), 21 deletions(-)
-
-diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake
-index e93a12e0..06cd36ec 100644
--- a/cmake/ssl.cmake
+++ b/cmake/ssl.cmake
-@@ -313,12 +313,14 @@ MACRO (MYSQL_CHECK_SSL)
+@@ -313,7 +313,8 @@ MACRO (MYSQL_CHECK_SSL)
OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
)
ENDIF()
@@ -33,15 +10,6 @@ index e93a12e0..06cd36ec 100644
ADD_DEFINITIONS(-DHAVE_TLSv13)
ENDIF()
IF(OPENSSL_INCLUDE_DIR AND
- OPENSSL_LIBRARY AND
-- CRYPTO_LIBRARY
-+ CRYPTO_LIBRARY AND
-+ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
- )
- SET(OPENSSL_FOUND TRUE)
- FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
-diff --git a/extra/libevent/openssl-compat.h b/extra/libevent/openssl-compat.h
-index 69afc716..deb21d6a 100644
--- a/extra/libevent/openssl-compat.h
+++ b/extra/libevent/openssl-compat.h
@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
@@ -61,8 +29,6 @@ index 69afc716..deb21d6a 100644
+#endif
+
#endif /* OPENSSL_COMPAT_H */
-diff --git a/mysys_ssl/my_md5.cc b/mysys_ssl/my_md5.cc
-index 095fcb4e..0bdc885a 100644
--- a/mysys_ssl/my_md5.cc
+++ b/mysys_ssl/my_md5.cc
@@ -56,7 +56,7 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
@@ -74,8 +40,6 @@ index 095fcb4e..0bdc885a 100644
fips_mode = FIPS_mode();
#endif /* HAVE_WOLFSSL */
/* If fips mode is ON/STRICT restricted method calls will result into abort,
-diff --git a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
-index 67c151b2..6a18a717 100644
--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
@@ -297,7 +297,7 @@ error:
@@ -96,8 +60,6 @@ index 67c151b2..6a18a717 100644
if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
G_ERROR("Error setting the ssl fips mode");
goto error;
-diff --git a/plugin/x/client/xconnection_impl.cc b/plugin/x/client/xconnection_impl.cc
-index cab1836c..4ba28d8f 100644
--- a/plugin/x/client/xconnection_impl.cc
+++ b/plugin/x/client/xconnection_impl.cc
@@ -489,7 +489,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
@@ -118,8 +80,6 @@ index cab1836c..4ba28d8f 100644
char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
1) {
-diff --git a/router/src/http/src/tls_client_context.cc b/router/src/http/src/tls_client_context.cc
-index f9dff94d..ae7413b4 100644
--- a/router/src/http/src/tls_client_context.cc
+++ b/router/src/http/src/tls_client_context.cc
@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
@@ -131,8 +91,6 @@ index f9dff94d..ae7413b4 100644
if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
throw TlsError("set-cipher-suites");
}
-diff --git a/router/src/http/src/tls_context.cc b/router/src/http/src/tls_context.cc
-index bae36860..2cdc3127 100644
--- a/router/src/http/src/tls_context.cc
+++ b/router/src/http/src/tls_context.cc
@@ -92,7 +92,7 @@ static constexpr int o11x_version(TlsVersion version) {
@@ -167,8 +125,6 @@ index bae36860..2cdc3127 100644
case 0:
return TlsVersion::AUTO;
default:
-diff --git a/router/src/http/src/tls_server_context.cc b/router/src/http/src/tls_server_context.cc
-index 4f3fa39c..ecc97559 100644
--- a/router/src/http/src/tls_server_context.cc
+++ b/router/src/http/src/tls_server_context.cc
@@ -162,7 +162,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
@@ -181,8 +137,6 @@ index 4f3fa39c..ecc97559 100644
dh2048.reset(DH_get_2048_256());
#else
/*
-diff --git a/sql-common/client.cc b/sql-common/client.cc
-index b6a253cc..2375bd19 100644
--- a/sql-common/client.cc
+++ b/sql-common/client.cc
@@ -7681,7 +7681,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
@@ -195,8 +149,6 @@ index b6a253cc..2375bd19 100644
char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
ENSURE_EXTENSIONS_PRESENT(&mysql->options);
mysql->options.extension->ssl_fips_mode = *(uint *)arg;
-diff --git a/sql/mysqld.cc b/sql/mysqld.cc
-index 22364edc..7b066343 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4881,7 +4881,7 @@ static int init_thread_environment() {
@@ -217,8 +169,6 @@ index 22364edc..7b066343 100644
char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
if (ret_fips_mode != 1) {
-diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
-index 5d7f3555..334684d2 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -4405,7 +4405,7 @@ static Sys_var_ulong Sys_max_execution_time(
@@ -257,8 +207,6 @@ index 5d7f3555..334684d2 100644
ON_UPDATE(update_fips_mode),
#else
ON_UPDATE(NULL),
-diff --git a/vio/viossl.cc b/vio/viossl.cc
-index d69119b3..5fb7c883 100644
--- a/vio/viossl.cc
+++ b/vio/viossl.cc
@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
@@ -279,8 +227,6 @@ index d69119b3..5fb7c883 100644
DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
#else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
DBUG_PRINT("info",
-diff --git a/vio/viosslfactories.cc b/vio/viosslfactories.cc
-index ea79ad1b..8ed961d1 100644
--- a/vio/viosslfactories.cc
+++ b/vio/viosslfactories.cc
@@ -429,7 +429,7 @@ void ssl_start() {
@@ -292,6 +238,4 @@ index ea79ad1b..8ed961d1 100644
/**
Set fips mode in openssl library,
When we set fips mode ON/STRICT, it will perform following operations:
---
-2.22.1
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-30 1:01 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-30 1:01 UTC (permalink / raw
To: gentoo-commits
commit: e347577568d429b6896a39ba59e7eff200241fb0
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 30 01:00:34 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 30 01:00:34 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e3475775
Add 20038_all_percona-server-8.0.16-PS-5873.patch
Bug: https://bugs.gentoo.org/697980
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20038_all_percona-server-8.0.16-PS-5873.patch | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/20038_all_percona-server-8.0.16-PS-5873.patch b/20038_all_percona-server-8.0.16-PS-5873.patch
new file mode 100644
index 0000000..ab73594
--- /dev/null
+++ b/20038_all_percona-server-8.0.16-PS-5873.patch
@@ -0,0 +1,24 @@
+Fix
+
+ storage/innobase/handler/i_s.cc:7546:1: error: cannot convert 'std::nullptr_t' to 'unsigned int' in initialization
+
+https://jira.percona.com/browse/PS-5873
+---
+ storage/innobase/handler/i_s.cc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/storage/innobase/handler/i_s.cc
++++ b/storage/innobase/handler/i_s.cc
+@@ -7536,8 +7536,8 @@ struct st_mysql_plugin i_s_innodb_changed_pages = {
+ STRUCT_FLD(descr, "InnoDB CHANGED_PAGES table"),
+ STRUCT_FLD(license, PLUGIN_LICENSE_GPL),
+ STRUCT_FLD(init, i_s_innodb_changed_pages_init),
+- STRUCT_FLD(deinit, i_s_common_deinit),
+ nullptr,
++ STRUCT_FLD(deinit, i_s_common_deinit),
+ STRUCT_FLD(version, 0x0100 /* 1.0 */),
+ STRUCT_FLD(status_vars, nullptr),
+ STRUCT_FLD(system_vars, nullptr),
+--
+2.23.0
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-30 1:01 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-30 1:01 UTC (permalink / raw
To: gentoo-commits
commit: e1e48da44c654967c3edf685f903fa4266d64cf8
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 30 00:55:56 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 30 00:55:56 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e1e48da4
Fix 20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-8.0.16-without-clientlibs-tools.patch | 26 +++++++++++++++-------
1 file changed, 18 insertions(+), 8 deletions(-)
diff --git a/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
index 7e025c2..a1211fa 100644
--- a/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
+++ b/20018_all_percona-server-8.0.16-without-clientlibs-tools.patch
@@ -138,25 +138,35 @@
SET(sbindir ${prefix}/${INSTALL_SBINDIR})
--- a/utilities/CMakeLists.txt
+++ b/utilities/CMakeLists.txt
-@@ -90,6 +90,13 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+@@ -90,22 +90,35 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
ENDIF()
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
+IF(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
+ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
-+IF(BUILD_BUNDLED_LZ4)
-+ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc SKIP_INSTALL)
-+ENDIF()
++ IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc SKIP_INSTALL)
++ ENDIF()
+ELSE(WITHOUT_CLIENTLIBS)
- MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc)
++ IF (BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ ENDIF()
++ENDIF()
++
TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
-@@ -101,11 +108,14 @@ IF (BUILD_BUNDLED_LZ4)
- MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+-MYSQL_ADD_EXECUTABLE(perror perror.cc)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+
+ IF (BUILD_BUNDLED_LZ4)
+- MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY} mysys)
ENDIF()
-+ENDIF(WITHOUT_CLIENTLIBS)
-IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+IF(WITHOUT_CLIENTLIBS)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-30 1:24 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-30 1:24 UTC (permalink / raw
To: gentoo-commits
commit: 1f78e2170cf4d6c36c6cfa3937f65d4ab853c7b3
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 30 01:24:40 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 30 01:24:40 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1f78e217
Add 20018_all_percona-server-8.0.16-dont-install-tokudb-misc-files.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...cona-server-8.0.16-dont-install-tokudb-misc-files.patch | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/20018_all_percona-server-8.0.16-dont-install-tokudb-misc-files.patch b/20018_all_percona-server-8.0.16-dont-install-tokudb-misc-files.patch
new file mode 100644
index 0000000..036aa42
--- /dev/null
+++ b/20018_all_percona-server-8.0.16-dont-install-tokudb-misc-files.patch
@@ -0,0 +1,14 @@
+--- a/storage/tokudb/PerconaFT/CMakeLists.txt
++++ b/storage/tokudb/PerconaFT/CMakeLists.txt
+@@ -102,11 +102,5 @@ add_subdirectory(src)
+ add_subdirectory(ftcxx)
+ add_subdirectory(tools)
+
+-install(
+- FILES README.md COPYING.AGPLv3 COPYING.GPLv2 PATENTS
+- DESTINATION .
+- COMPONENT tokukv_misc
+- )
+-
+ ## build tags
+ include(TokuBuildTagDatabases)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-30 23:47 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-30 23:47 UTC (permalink / raw
To: gentoo-commits
commit: 2f686e103725496893e808b7761abc1d7673301f
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 30 23:47:28 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 30 23:47:28 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=2f686e10
Add 20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-8.0.17-without-clientlibs-tools.patch | 183 +++++++++++++++++++++
1 file changed, 183 insertions(+)
diff --git a/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
new file mode 100644
index 0000000..cf7f747
--- /dev/null
+++ b/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
@@ -0,0 +1,183 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1159,8 +1159,6 @@ ENDIF()
+ MYSQL_CHECK_SSL()
+ MYSQL_CHECK_SSL_DLLS()
+
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -1252,7 +1250,9 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -1295,7 +1295,6 @@ IF(WITH_UNIT_TESTS)
+ ADD_SUBDIRECTORY(unittest/mytap/t)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(utilities)
+ ADD_SUBDIRECTORY(share)
+ ADD_SUBDIRECTORY(libservices)
+@@ -1340,6 +1339,12 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(packaging/rpm-common)
+ ADD_SUBDIRECTORY(packaging/rpm-oel)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -240,12 +240,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big perconaserverclient
+-MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(perconaserverclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -283,9 +288,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED} ${CLIENT_API_NONBLOCKING_FUNCTIONS}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED} ${CLIENT_API_NONBLOCKING_FUNCTIONS}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -459,14 +459,12 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ ps_mysqld_helper
+ ps-admin
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+@@ -475,6 +473,13 @@ ELSE()
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -489,7 +494,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -24,8 +24,9 @@ IF(NOT UNIX)
+ RETURN()
+ ENDIF()
+
+-INSTALL(FILES mysql.m4
+- DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(localstatedir "${MYSQL_DATADIR}")
+
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -94,22 +94,35 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++IF(WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc SKIP_INSTALL)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc SKIP_INSTALL)
++ IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc SKIP_INSTALL)
++ ENDIF()
++ELSE(WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.cc)
++ MYSQL_ADD_EXECUTABLE(perror perror.cc)
++ IF (BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ ENDIF()
++ENDIF()
++
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.cc)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys)
+
+ IF (BUILD_BUNDLED_LZ4)
+- MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+ TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY} mysys)
+ ENDIF()
+
+-IF (BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
++IF(WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
+- TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+ ENDIF()
++TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY} mysys)
+
+ IF(WITH_INNOBASE_STORAGE_ENGINE)
+
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-30 23:49 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-30 23:49 UTC (permalink / raw
To: gentoo-commits
commit: c82b072c1bedd43a42f3eb9b0e214dff66d8faab
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Oct 30 23:49:16 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Oct 30 23:49:16 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=c82b072c
Add 20018_all_percona-server-8.0.17-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...ercona-server-8.0.17-fix-libressl-support.patch | 230 +++++++++++++++++++++
1 file changed, 230 insertions(+)
diff --git a/20018_all_percona-server-8.0.17-fix-libressl-support.patch b/20018_all_percona-server-8.0.17-fix-libressl-support.patch
new file mode 100644
index 0000000..29f2a0e
--- /dev/null
+++ b/20018_all_percona-server-8.0.17-fix-libressl-support.patch
@@ -0,0 +1,230 @@
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -304,7 +304,8 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+--- a/extra/libevent/openssl-compat.h
++++ b/extra/libevent/openssl-compat.h
+@@ -24,7 +24,6 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+ #define BIO_set_init(b, val) (b)->init = (val)
+ #define BIO_set_data(b, val) (b)->ptr = (val)
+ #define BIO_set_shutdown(b, val) (b)->shutdown = (val)
+-#define BIO_get_init(b) (b)->init
+ #define BIO_get_data(b) (b)->ptr
+ #define BIO_get_shutdown(b) (b)->shutdown
+
+@@ -32,4 +31,8 @@ static inline BIO_METHOD *BIO_meth_new(int type, const char *name)
+
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++#define BIO_get_init(b) (b)->init
++#endif
++
+ #endif /* OPENSSL_COMPAT_H */
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -297,7 +297,7 @@ error:
+ return 1;
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -521,7 +521,7 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -523,7 +523,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -573,7 +573,7 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED};
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode((int)m_context->m_ssl_config.m_ssl_fips_mode, err_string) !=
+ 1) {
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -93,7 +93,7 @@ static constexpr int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -123,9 +123,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ default:
+ // unknown, leave all disabled
+ // fallthrough
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
+ // fallthrough
++#endif
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+ // fallthrough
+@@ -172,8 +174,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -170,7 +170,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7768,7 +7768,8 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL) && !defined(HAVE_WOLFSSL)
++#if defined(HAVE_OPENSSL) && \
++ !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -5044,7 +5044,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -5080,7 +5080,7 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4500,7 +4500,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4513,7 +4513,7 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ }
+ #endif
+
+-#ifdef HAVE_WOLFSSL
++#if defined(HAVE_WOLFSSL) || defined(LIBRESSL_VERSION_NUMBER)
+ static const char *ssl_fips_mode_names[] = {"OFF", 0};
+ #else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+@@ -4521,7 +4521,7 @@ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ "permitted values are: OFF, ON, STRICT",
+ #else
+ "permitted values are: OFF",
+@@ -4529,7 +4529,7 @@ static Sys_var_enum Sys_ssl_fips_mode(
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+ ON_CHECK(NULL),
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ ON_UPDATE(update_fips_mode),
+ #else
+ ON_UPDATE(NULL),
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -507,7 +507,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(HAVE_WOLFSSL) && !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -515,7 +515,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -429,7 +429,7 @@ void ssl_start() {
+ }
+ }
+
+-#ifndef HAVE_WOLFSSL
++#if !defined(HAVE_WOLFSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2019-10-31 0:50 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2019-10-31 0:50 UTC (permalink / raw
To: gentoo-commits
commit: a2ad81add180c3980619ffb2cf31fc8cf8232580
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Thu Oct 31 00:49:57 2019 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Thu Oct 31 00:49:57 2019 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a2ad81ad
Fix 20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_percona-server-8.0.17-without-clientlibs-tools.patch | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
index cf7f747..a1a6eb0 100644
--- a/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
+++ b/20018_all_percona-server-8.0.17-without-clientlibs-tools.patch
@@ -20,7 +20,7 @@
ADD_SUBDIRECTORY(dbug)
ADD_SUBDIRECTORY(strings)
ADD_SUBDIRECTORY(vio)
-@@ -1295,7 +1295,6 @@ IF(WITH_UNIT_TESTS)
+@@ -1295,11 +1295,16 @@ IF(WITH_UNIT_TESTS)
ADD_SUBDIRECTORY(unittest/mytap/t)
ENDIF()
@@ -28,9 +28,6 @@
ADD_SUBDIRECTORY(utilities)
ADD_SUBDIRECTORY(share)
ADD_SUBDIRECTORY(libservices)
-@@ -1340,6 +1339,12 @@ IF(UNIX)
- ADD_SUBDIRECTORY(man)
- ENDIF()
+IF(NOT WITHOUT_TOOLS)
+ # Add system/bundled editline
@@ -39,8 +36,8 @@
+ENDIF(NOT WITHOUT_TOOLS)
+
IF(NOT WITHOUT_SERVER)
- ADD_SUBDIRECTORY(packaging/rpm-common)
- ADD_SUBDIRECTORY(packaging/rpm-oel)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
--- a/libmysql/CMakeLists.txt
+++ b/libmysql/CMakeLists.txt
@@ -240,12 +240,17 @@ IF(WIN32)
@@ -180,4 +177,3 @@
IF(WITH_INNOBASE_STORAGE_ENGINE)
-
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-20 2:21 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-20 2:21 UTC (permalink / raw
To: gentoo-commits
commit: 1f69699a3803985900c7a6ffc1eab5d6bc3d609a
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 02:20:54 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 02:20:54 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=1f69699a
Add 20018_all_mysql-8.0.19-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...all_mysql-8.0.19-without-clientlibs-tools.patch | 178 +++++++++++++++++++++
1 file changed, 178 insertions(+)
diff --git a/20018_all_mysql-8.0.19-without-clientlibs-tools.patch b/20018_all_mysql-8.0.19-without-clientlibs-tools.patch
new file mode 100644
index 0000000..ea6744e
--- /dev/null
+++ b/20018_all_mysql-8.0.19-without-clientlibs-tools.patch
@@ -0,0 +1,178 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1285,7 +1285,9 @@ IF(WITH_UNIT_TESTS)
+ INCLUDE(googletest)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -242,12 +242,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(mysqlclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -283,12 +288,22 @@ ENDIF()
+
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS
++ ${CLIENT_API_FUNCTIONS}
++ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
++ COMPONENT SharedLibraries
++ SKIP_INSTALL )
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS
+ ${CLIENT_API_FUNCTIONS}
+ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+--- a/man/CMakeLists.txt
++++ b/man/CMakeLists.txt
+@@ -26,7 +26,6 @@ SET(MAN1
+ ibd2sdi.1
+ innochecksum.1
+ lz4_decompress.1
+- my_print_defaults.1
+ myisam_ftdump.1
+ myisamchk.1
+ myisamlog.1
+@@ -51,8 +50,6 @@ SET(MAN1
+ mysqlpump.1
+ mysqlshow.1
+ mysqlslap.1
+- perror.1
+- zlib_decompress.1
+ )
+ SET(MAN1_NDB
+ ndb-common-options.1
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -414,7 +414,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+@@ -427,19 +427,24 @@ ELSE()
+ # mysqld_safe used in mtr even for systemd platforms
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_safe
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -24,8 +24,9 @@ IF(NOT UNIX)
+ RETURN()
+ ENDIF()
+
+-INSTALL(FILES mysql.m4
+- DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(localstatedir "${MYSQL_DATADIR}")
+
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -120,6 +120,26 @@ IF(LINUX_INSTALL_RPATH_ORIGIN)
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
++IF(WITHOUT_CLIENTLIBS)
++MYSQL_ADD_EXECUTABLE(my_print_defaults
++ my_print_defaults.cc
++ COMPONENT Server
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++MYSQL_ADD_EXECUTABLE(perror
++ perror.cc
++ COMPONENT Server
++ DEPENDENCIES GenError
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress
++ lz4_decompress.cc
++ COMPONENT Server
++ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
++ SKIP_INSTALL )
++ENDIF()
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults
+ my_print_defaults.cc
+ COMPONENT Server
+@@ -138,7 +158,6 @@ IF(BUILD_BUNDLED_LZ4)
+ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
+ )
+ ENDIF()
+-
+ IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+ MYSQL_ADD_EXECUTABLE(zlib_decompress
+ zlib_decompress.cc
+@@ -146,6 +165,7 @@ IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+ LINK_LIBRARIES ${ZLIB_LIBRARY} mysys
+ )
+ ENDIF()
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # All targets below belong to COMPONENT Server and depend on InnoDB.
+ IF(WITHOUT_SERVER)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-20 18:19 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-20 18:19 UTC (permalink / raw
To: gentoo-commits
commit: a1ff5a288f718b3b1035c5139f677a3a7371bcc5
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 18:19:09 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 18:19:09 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=a1ff5a28
Add 20018_all_mysql-8.0.19-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-8.0.19-fix-libressl-support.patch | 297 ++++++++++++++++++++++
1 file changed, 297 insertions(+)
diff --git a/20018_all_mysql-8.0.19-fix-libressl-support.patch b/20018_all_mysql-8.0.19-fix-libressl-support.patch
new file mode 100644
index 0000000..1fc949a
--- /dev/null
+++ b/20018_all_mysql-8.0.19-fix-libressl-support.patch
@@ -0,0 +1,297 @@
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -229,13 +229,14 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+ CRYPTO_LIBRARY AND
+- OPENSSL_MAJOR_VERSION STREQUAL "1"
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ FIND_PROGRAM(OPENSSL_EXECUTABLE openssl
+--- a/mysys/my_md5.cc
++++ b/mysys/my_md5.cc
+@@ -56,7 +56,9 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
++#ifndef LIBRESSL_VERSION_NUMBER
+ fips_mode = FIPS_mode();
++#endif
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+ * skipping call. */
+ if (fips_mode == 0) {
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -329,6 +329,7 @@ error:
+ return 1;
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -352,6 +353,7 @@ static int configure_ssl_fips_mode(const uint fips_mode) {
+ EXIT:
+ return rc;
+ }
++#endif
+
+ static int configure_ssl_ca(SSL_CTX *ssl_ctx, const char *ca_file,
+ const char *ca_path) {
+@@ -555,10 +557,12 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+ }
++#endif
+
+ SSL_library_init();
+ SSL_load_error_strings();
+@@ -622,7 +626,7 @@ error:
+ void xcom_cleanup_ssl() {
+ if (!xcom_use_ssl()) return;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ERR_remove_thread_state(0);
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ }
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -520,6 +520,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -559,6 +560,7 @@ int set_fips_mode(const uint32_t fips_mode,
+ EXIT:
+ return rc;
+ }
++#endif
+
+ XError Connection_impl::activate_tls() {
+ if (nullptr == m_vio) return get_socket_error(SOCKET_ECONNRESET);
+@@ -569,12 +571,14 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED, true};
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(
+ static_cast<uint32_t>(m_context->m_ssl_config.m_ssl_fips_mode),
+ err_string) != 1) {
+ return XError{CR_SSL_CONNECTION_ERROR, err_string, true};
+ }
++#endif
+ auto ssl_ctx_flags = process_tls_version(
+ details::null_when_empty(m_context->m_ssl_config.m_tls_version));
+
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -91,7 +91,7 @@ static int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -120,9 +120,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ switch (min_version) {
+ default:
+ // unknown, leave all disabled
++#ifdef TLS1_3_VERSION
+ // fallthrough
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
++#endif
+ // fallthrough
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+@@ -170,8 +172,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+@@ -230,7 +234,8 @@ TlsContext::InfoCallback TlsContext::info_callback() const {
+ }
+
+ int TlsContext::security_level() const {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ return SSL_CTX_get_security_level(ssl_ctx_.get());
+ #else
+ return 0;
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -166,7 +166,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7730,7 +7730,7 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL)
++#if defined(HAVE_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -4818,7 +4818,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -4854,12 +4854,14 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
++#ifndef LIBRESSL_VERSION_NUMBER
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+ LogErr(ERROR_LEVEL, ER_SSL_FIPS_MODE_ERROR, ssl_err_string);
+ return 1;
+ }
++#endif
+ if (SslAcceptorContext::singleton_init(opt_use_ssl)) return 1;
+
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4417,6 +4417,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4427,15 +4428,30 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ return false;
+ }
+ }
++#endif
+
++#if defined(LIBRESSL_VERSION_NUMBER)
++static const char *ssl_fips_mode_names[] = {"OFF", 0};
++#else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
++#endif
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
++#ifndef LIBRESSL_VERSION_NUMBER
+ "permitted values are: OFF, ON, STRICT",
++#else
++ "permitted values are: OFF",
++#endif
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+- ON_CHECK(NULL), ON_UPDATE(update_fips_mode), NULL);
++ ON_CHECK(NULL),
++#ifndef LIBRESSL_VERSION_NUMBER
++ ON_UPDATE(update_fips_mode),
++#else
++ ON_UPDATE(NULL),
++#endif
++ NULL);
+
+ #if defined(HAVE_OPENSSL)
+ static Sys_var_bool Sys_auto_generate_certs(
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -45,7 +45,7 @@
+ BIO_set_callback_ex was added in openSSL 1.1.1
+ For older openSSL, use the deprecated BIO_set_callback.
+ */
+-#if OPENSSL_VERSION_NUMBER >= 0x10101000L
++#if OPENSSL_VERSION_NUMBER >= 0x10101000L && !defined(LIBRESSL_VERSION_NUMBER)
+ #define HAVE_BIO_SET_CALLBACK_EX
+ #endif
+
+@@ -637,7 +637,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -645,7 +645,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -420,6 +420,7 @@ void ssl_start() {
+ }
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -473,6 +474,7 @@ EXIT:
+ @returns openssl current fips mode
+ */
+ uint get_fips_mode() { return FIPS_mode(); }
++#endif
+
+ long process_tls_version(const char *tls_version) {
+ const char *separator = ",";
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-20 18:28 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-20 18:28 UTC (permalink / raw
To: gentoo-commits
commit: fb00ac7f844cce16f64e3b9d602c0907840bd32e
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Mon Jan 20 18:28:17 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Mon Jan 20 18:28:17 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=fb00ac7f
Add 20018_all_mysql-8.0.19-fix-events_bugs-test.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-8.0.19-fix-events_bugs-test.patch | 42 +++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/20018_all_mysql-8.0.19-fix-events_bugs-test.patch b/20018_all_mysql-8.0.19-fix-events_bugs-test.patch
new file mode 100644
index 0000000..6a737f2
--- /dev/null
+++ b/20018_all_mysql-8.0.19-fix-events_bugs-test.patch
@@ -0,0 +1,42 @@
+https://bugs.mysql.com/bug.php?id=98107
+
+--- a/mysql-test/r/events_bugs.result
++++ b/mysql-test/r/events_bugs.result
+@@ -647,7 +647,7 @@ SET GLOBAL READ_ONLY = 1;
+ # Connection: u1_con (mysqltest_u1@localhost/events_test).
+ #
+
+-CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
++CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1;
+ ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
+
+ ALTER EVENT e1 COMMENT 'comment';
+@@ -660,7 +660,7 @@ ERROR HY000: The MySQL server is running with the --read-only option so it canno
+ # Connection: root_con (root@localhost/events_test).
+ #
+
+-CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
++CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1;
+
+ ALTER EVENT e1 COMMENT 'comment';
+
+--- a/mysql-test/t/events_bugs.test
++++ b/mysql-test/t/events_bugs.test
+@@ -1033,7 +1033,7 @@ SET GLOBAL READ_ONLY = 1;
+ --echo
+
+ --error ER_OPTION_PREVENTS_STATEMENT
+-CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
++CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1;
+
+ --echo
+
+@@ -1057,7 +1057,7 @@ DROP EVENT e1;
+
+ --echo
+
+-CREATE EVENT e1 ON SCHEDULE AT '2020-01-01 00:00:00' DO SET @a = 1;
++CREATE EVENT e1 ON SCHEDULE AT '2038-01-01 00:00:00' DO SET @a = 1;
+
+ --echo
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-22 18:27 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-22 18:27 UTC (permalink / raw
To: gentoo-commits
commit: 20c9f6511b8550ea954bdd8377580581e2b52071
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 22 18:25:21 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Jan 22 18:25:21 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=20c9f651
Add 20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...na-server-8.0.18-without-clientlibs-tools.patch | 181 +++++++++++++++++++++
1 file changed, 181 insertions(+)
diff --git a/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
new file mode 100644
index 0000000..bf07285
--- /dev/null
+++ b/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
@@ -0,0 +1,181 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -1284,7 +1284,9 @@ IF(WITH_UNIT_TESTS)
+ INCLUDE(googletest)
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+ ADD_SUBDIRECTORY(mysys)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -240,12 +240,18 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big perconaserverclient
+-MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big perconaserverclient
++ MERGE_CONVENIENCE_LIBRARIES(perconaserverclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
++
+ TARGET_LINK_LIBRARIES(perconaserverclient PRIVATE ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -281,12 +287,22 @@ ENDIF()
+
+ # Merge several convenience libraries into one big perconaserverclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS
++ ${CLIENT_API_FUNCTIONS}
++ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
++ COMPONENT SharedLibraries
++ SKIP_INSTALL )
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS
+ ${CLIENT_API_FUNCTIONS}
+ ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ ${CLIENT_API_NONBLOCKING_FUNCTIONS}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql PRIVATE ${LIBS_TO_LINK})
+
+ IF(WIN32)
+--- a/man/CMakeLists.txt
++++ b/man/CMakeLists.txt
+@@ -26,7 +26,6 @@ SET(MAN1
+ ibd2sdi.1
+ innochecksum.1
+ lz4_decompress.1
+- my_print_defaults.1
+ myisam_ftdump.1
+ myisamchk.1
+ myisamlog.1
+@@ -51,8 +50,6 @@ SET(MAN1
+ mysqlpump.1
+ mysqlshow.1
+ mysqlslap.1
+- perror.1
+- zlib_decompress.1
+ )
+ SET(MAN1_NDB
+ ndb-common-options.1
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -423,14 +423,12 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ ps_mysqld_helper
+ ps-admin
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+@@ -453,7 +451,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+@@ -463,6 +461,13 @@ ELSE()
+ )
+ ENDIF()
+
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ FOREACH(file ${BIN_SCRIPTS})
+ IF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh)
+ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/${file}.sh
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -24,8 +24,9 @@ IF(NOT UNIX)
+ RETURN()
+ ENDIF()
+
+-INSTALL(FILES mysql.m4
+- DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++IF(NOT WITHOUT_CLIENTLIBS)
++ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(localstatedir "${MYSQL_DATADIR}")
+
+--- a/utilities/CMakeLists.txt
++++ b/utilities/CMakeLists.txt
+@@ -99,6 +99,26 @@ IF(APPLE AND HAVE_CRYPTO_DYLIB AND HAVE_OPENSSL_DYLIB)
+ ADD_DEPENDENCIES(comp_err copy_openssl_dlls)
+ ENDIF()
+
++IF(WITHOUT_CLIENTLIBS)
++MYSQL_ADD_EXECUTABLE(my_print_defaults
++ my_print_defaults.cc
++ COMPONENT Server
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++MYSQL_ADD_EXECUTABLE(perror
++ perror.cc
++ COMPONENT Server
++ DEPENDENCIES GenError
++ LINK_LIBRARIES mysys
++ SKIP_INSTALL )
++IF(BUILD_BUNDLED_LZ4)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress
++ lz4_decompress.cc
++ COMPONENT Server
++ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
++ SKIP_INSTALL )
++ENDIF()
++ELSE(WITHOUT_CLIENTLIBS)
+ MYSQL_ADD_EXECUTABLE(my_print_defaults
+ my_print_defaults.cc
+ COMPONENT Server
+@@ -117,7 +137,6 @@ IF(BUILD_BUNDLED_LZ4)
+ LINK_LIBRARIES ${LZ4_LIBRARY} mysys
+ )
+ ENDIF()
+-
+ IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+ MYSQL_ADD_EXECUTABLE(zlib_decompress
+ zlib_decompress.cc
+@@ -125,6 +144,7 @@ IF(BUILD_BUNDLED_ZLIB OR NOT OPENSSL_EXECUTABLE_HAS_ZLIB)
+ LINK_LIBRARIES ${ZLIB_LIBRARY} mysys
+ )
+ ENDIF()
++ENDIF(WITHOUT_CLIENTLIBS)
+
+ # All targets below belong to COMPONENT Server and depend on InnoDB.
+ IF(WITHOUT_SERVER)
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-22 18:27 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-22 18:27 UTC (permalink / raw
To: gentoo-commits
commit: 3a9749587f76ed52ddae5d4c484302854b79f8c5
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 22 18:23:25 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Jan 22 18:23:25 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=3a974958
Add 20018_all_percona-server-8.0.18-fix-building-with-make-4.3.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...l_percona-server-8.0.18-fix-building-with-make-4.3.patch | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/20018_all_percona-server-8.0.18-fix-building-with-make-4.3.patch b/20018_all_percona-server-8.0.18-fix-building-with-make-4.3.patch
new file mode 100644
index 0000000..1846058
--- /dev/null
+++ b/20018_all_percona-server-8.0.18-fix-building-with-make-4.3.patch
@@ -0,0 +1,13 @@
+https://jira.percona.com/browse/PS-6802
+
+--- a/storage/rocksdb/get_rocksdb_files.sh
++++ b/storage/rocksdb/get_rocksdb_files.sh
+@@ -4,7 +4,7 @@ MKFILE=`mktemp`
+ # include rocksdb make file relative to the path of this script
+ echo "include rocksdb/src.mk
+ all:
+- @echo \$(LIB_SOURCES)" > $MKFILE
++ @echo \"\$(LIB_SOURCES)\"" > $MKFILE
+ for f in `make --makefile $MKFILE`
+ do
+ echo ./rocksdb/$f
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-22 18:27 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-22 18:27 UTC (permalink / raw
To: gentoo-commits
commit: ac8332f5611918465f0d7325d6a33388c9947629
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Wed Jan 22 18:27:09 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Wed Jan 22 18:27:09 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=ac8332f5
Add 20018_all_percona-server-8.0.18-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...ercona-server-8.0.18-fix-libressl-support.patch | 310 +++++++++++++++++++++
1 file changed, 310 insertions(+)
diff --git a/20018_all_percona-server-8.0.18-fix-libressl-support.patch b/20018_all_percona-server-8.0.18-fix-libressl-support.patch
new file mode 100644
index 0000000..3006c23
--- /dev/null
+++ b/20018_all_percona-server-8.0.18-fix-libressl-support.patch
@@ -0,0 +1,310 @@
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -214,7 +214,8 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ ENDIF()
+ IF(OPENSSL_INCLUDE_DIR AND
+--- a/mysys/my_crypt.cc
++++ b/mysys/my_crypt.cc
+@@ -27,7 +27,7 @@
+
+ #include "my_dbug.h"
+
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
++#if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
+ #define ERR_remove_state(X) ERR_clear_error()
+ #else
+ #define EVP_CIPHER_CTX_buf_noconst(ctx) ((ctx)->buf)
+@@ -86,7 +86,7 @@ class MyEncryptionCTX : private boost::noncopyable {
+ };
+
+ MyEncryptionCTX::MyEncryptionCTX() {
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ctx = new EVP_CIPHER_CTX();
+ EVP_CIPHER_CTX_init(ctx);
+ #else
+@@ -95,7 +95,8 @@ MyEncryptionCTX::MyEncryptionCTX() {
+ }
+
+ MyEncryptionCTX::~MyEncryptionCTX() {
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
+ EVP_CIPHER_CTX_cleanup(ctx);
+ delete ctx;
+ #else
+--- a/mysys/my_md5.cc
++++ b/mysys/my_md5.cc
+@@ -56,7 +56,9 @@ static void my_md5_hash(unsigned char *digest, unsigned const char *buf,
+ int compute_md5_hash(char *digest, const char *buf, int len) {
+ int retval = 0;
+ int fips_mode = 0;
++#ifndef LIBRESSL_VERSION_NUMBER
+ fips_mode = FIPS_mode();
++#endif
+ /* If fips mode is ON/STRICT restricted method calls will result into abort,
+ * skipping call. */
+ if (fips_mode == 0) {
+--- a/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
++++ b/plugin/group_replication/libmysqlgcs/src/bindings/xcom/xcom/xcom_ssl_transport.c
+@@ -329,6 +329,7 @@ error:
+ return 1;
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ #define OPENSSL_ERROR_LENGTH 512
+ static int configure_ssl_fips_mode(const uint fips_mode) {
+ int rc = -1;
+@@ -352,6 +353,7 @@ static int configure_ssl_fips_mode(const uint fips_mode) {
+ EXIT:
+ return rc;
+ }
++#endif
+
+ static int configure_ssl_ca(SSL_CTX *ssl_ctx, const char *ca_file,
+ const char *ca_path) {
+@@ -555,10 +557,12 @@ int xcom_init_ssl(const char *server_key_file, const char *server_cert_file,
+ int verify_server = SSL_VERIFY_NONE;
+ int verify_client = SSL_VERIFY_NONE;
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ if (configure_ssl_fips_mode(ssl_fips_mode) != 1) {
+ G_ERROR("Error setting the ssl fips mode");
+ goto error;
+ }
++#endif
+
+ SSL_library_init();
+ SSL_load_error_strings();
+@@ -622,7 +626,7 @@ error:
+ void xcom_cleanup_ssl() {
+ if (!xcom_use_ssl()) return;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ ERR_remove_thread_state(0);
+ #endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ }
+--- a/plugin/x/client/xconnection_impl.cc
++++ b/plugin/x/client/xconnection_impl.cc
+@@ -521,6 +521,7 @@ XError Connection_impl::get_ssl_error(const int error_id) {
+ return XError(CR_SSL_CONNECTION_ERROR, buffer);
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -559,6 +560,7 @@ int set_fips_mode(const uint fips_mode, char err_string[OPENSSL_ERROR_LENGTH]) {
+ EXIT:
+ return rc;
+ }
++#endif
+
+ XError Connection_impl::activate_tls() {
+ if (nullptr == m_vio) return get_socket_error(SOCKET_ECONNRESET);
+@@ -569,11 +571,13 @@ XError Connection_impl::activate_tls() {
+ if (!m_context->m_ssl_config.is_configured())
+ return XError{CR_SSL_CONNECTION_ERROR, ER_TEXT_TLS_NOT_CONFIGURATED, true};
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ char err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(static_cast<int>(m_context->m_ssl_config.m_ssl_fips_mode),
+ err_string) != 1) {
+ return XError{CR_SSL_CONNECTION_ERROR, err_string, true};
+ }
++#endif
+ auto ssl_ctx_flags = process_tls_version(
+ details::null_when_empty(m_context->m_ssl_config.m_tls_version));
+
+--- a/router/src/http/src/tls_client_context.cc
++++ b/router/src/http/src/tls_client_context.cc
+@@ -54,7 +54,7 @@ void TlsClientContext::verify(TlsVerify verify) {
+
+ void TlsClientContext::cipher_suites(const std::string &ciphers) {
+ // TLSv1.3 ciphers are controlled via SSL_CTX_set_ciphersuites()
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ if (1 != SSL_CTX_set_ciphersuites(ssl_ctx_.get(), ciphers.c_str())) {
+ throw TlsError("set-cipher-suites");
+ }
+--- a/router/src/http/src/tls_context.cc
++++ b/router/src/http/src/tls_context.cc
+@@ -91,7 +91,7 @@ static int o11x_version(TlsVersion version) {
+ return TLS1_1_VERSION;
+ case TlsVersion::TLS_1_2:
+ return TLS1_2_VERSION;
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 1)
++#ifdef TLS1_3_VERSION
+ case TlsVersion::TLS_1_3:
+ return TLS1_3_VERSION;
+ #endif
+@@ -120,9 +120,11 @@ void TlsContext::version_range(TlsVersion min_version, TlsVersion max_version) {
+ switch (min_version) {
+ default:
+ // unknown, leave all disabled
++#ifdef TLS1_3_VERSION
+ // fallthrough
+ case TlsVersion::TLS_1_3:
+ opts |= SSL_OP_NO_TLSv1_2;
++#endif
+ // fallthrough
+ case TlsVersion::TLS_1_2:
+ opts |= SSL_OP_NO_TLSv1_1;
+@@ -170,8 +172,10 @@ TlsVersion TlsContext::min_version() const {
+ return TlsVersion::TLS_1_1;
+ case TLS1_2_VERSION:
+ return TlsVersion::TLS_1_2;
++#ifdef TLS1_3_VERSION
+ case TLS1_3_VERSION:
+ return TlsVersion::TLS_1_3;
++#endif
+ case 0:
+ return TlsVersion::AUTO;
+ default:
+@@ -230,7 +234,8 @@ TlsContext::InfoCallback TlsContext::info_callback() const {
+ }
+
+ int TlsContext::security_level() const {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ return SSL_CTX_get_security_level(ssl_ctx_.get());
+ #else
+ return 0;
+--- a/router/src/http/src/tls_server_context.cc
++++ b/router/src/http/src/tls_server_context.cc
+@@ -166,7 +166,8 @@ void TlsServerContext::init_tmp_dh(const std::string &dh_params) {
+ }
+
+ } else {
+-#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0)
++#if OPENSSL_VERSION_NUMBER >= ROUTER_OPENSSL_VERSION(1, 1, 0) && \
++ !defined(LIBRESSL_VERSION_NUMBER)
+ dh2048.reset(DH_get_2048_256());
+ #else
+ /*
+--- a/sql-common/client.cc
++++ b/sql-common/client.cc
+@@ -7881,7 +7881,7 @@ int STDCALL mysql_options(MYSQL *mysql, enum mysql_option option,
+ #endif
+ break;
+ case MYSQL_OPT_SSL_FIPS_MODE: {
+-#if defined(HAVE_OPENSSL)
++#if defined(HAVE_OPENSSL) && !defined(LIBRESSL_VERSION_NUMBER)
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ ENSURE_EXTENSIONS_PRESENT(&mysql->options);
+ mysql->options.extension->ssl_fips_mode = *static_cast<const uint *>(arg);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -5047,7 +5047,7 @@ static int init_thread_environment() {
+
+ static PSI_memory_key key_memory_openssl = PSI_NOT_INSTRUMENTED;
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ #define FILE_LINE_ARGS
+ #else
+ #define FILE_LINE_ARGS , const char *, int
+@@ -5083,12 +5083,14 @@ static void init_ssl() {
+ }
+
+ static int init_ssl_communication() {
++#ifndef LIBRESSL_VERSION_NUMBER
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ int ret_fips_mode = set_fips_mode(opt_ssl_fips_mode, ssl_err_string);
+ if (ret_fips_mode != 1) {
+ LogErr(ERROR_LEVEL, ER_SSL_FIPS_MODE_ERROR, ssl_err_string);
+ return 1;
+ }
++#endif
+ if (SslAcceptorContext::singleton_init(opt_use_ssl)) return 1;
+
+ #if OPENSSL_VERSION_NUMBER < 0x10100000L
+--- a/sql/sys_vars.cc
++++ b/sql/sys_vars.cc
+@@ -4540,6 +4540,7 @@ static Sys_var_ulong Sys_max_execution_time(
+ HINT_UPDATEABLE SESSION_VAR(max_execution_time), CMD_LINE(REQUIRED_ARG),
+ VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ char ssl_err_string[OPENSSL_ERROR_LENGTH] = {'\0'};
+ if (set_fips_mode(opt_ssl_fips_mode, ssl_err_string) != 1) {
+@@ -4550,15 +4551,30 @@ static bool update_fips_mode(sys_var *, THD *, enum_var_type) {
+ return false;
+ }
+ }
++#endif
+
++#if defined(LIBRESSL_VERSION_NUMBER)
++static const char *ssl_fips_mode_names[] = {"OFF", 0};
++#else
+ static const char *ssl_fips_mode_names[] = {"OFF", "ON", "STRICT", 0};
++#endif
+ static Sys_var_enum Sys_ssl_fips_mode(
+ "ssl_fips_mode",
+ "SSL FIPS mode (applies only for OpenSSL); "
++#ifndef LIBRESSL_VERSION_NUMBER
+ "permitted values are: OFF, ON, STRICT",
++#else
++ "permitted values are: OFF",
++#endif
+ GLOBAL_VAR(opt_ssl_fips_mode), CMD_LINE(REQUIRED_ARG, OPT_SSL_FIPS_MODE),
+ ssl_fips_mode_names, DEFAULT(0), NO_MUTEX_GUARD, NOT_IN_BINLOG,
+- ON_CHECK(NULL), ON_UPDATE(update_fips_mode), NULL);
++ ON_CHECK(NULL),
++#ifndef LIBRESSL_VERSION_NUMBER
++ ON_UPDATE(update_fips_mode),
++#else
++ ON_UPDATE(NULL),
++#endif
++ NULL);
+
+ #if defined(HAVE_OPENSSL)
+ static Sys_var_bool Sys_auto_generate_certs(
+--- a/vio/viossl.cc
++++ b/vio/viossl.cc
+@@ -490,7 +490,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ #if !defined(DBUG_OFF)
+ {
+ STACK_OF(SSL_COMP) *ssl_comp_methods = NULL;
+- ssl_comp_methods = SSL_COMP_get_compression_methods();
++ ssl_comp_methods = (STACK_OF(SSL_COMP) *)SSL_COMP_get_compression_methods();
+ n = sk_SSL_COMP_num(ssl_comp_methods);
+ DBUG_PRINT("info", ("Available compression methods:\n"));
+ if (n == 0)
+@@ -498,7 +498,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout,
+ else
+ for (j = 0; j < n; j++) {
+ SSL_COMP *c = sk_SSL_COMP_value(ssl_comp_methods, j);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ DBUG_PRINT("info", (" %d: %s\n", c->id, c->name));
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ DBUG_PRINT("info",
+--- a/vio/viosslfactories.cc
++++ b/vio/viosslfactories.cc
+@@ -420,6 +420,7 @@ void ssl_start() {
+ }
+ }
+
++#ifndef LIBRESSL_VERSION_NUMBER
+ /**
+ Set fips mode in openssl library,
+ When we set fips mode ON/STRICT, it will perform following operations:
+@@ -473,6 +474,7 @@ EXIT:
+ @returns openssl current fips mode
+ */
+ uint get_fips_mode() { return FIPS_mode(); }
++#endif
+
+ long process_tls_version(const char *tls_version) {
+ const char *separator = ",";
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-25 19:42 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-25 19:42 UTC (permalink / raw
To: gentoo-commits
commit: af5234eeeb8e6208d80bd5d97fe43d37dcbc563a
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 25 19:42:46 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Jan 25 19:42:46 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=af5234ee
Add 20018_all_mysql-5.7.29-fix-libressl-support.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-5.7.29-fix-libressl-support.patch | 79 +++++++++++++++++++++++
1 file changed, 79 insertions(+)
diff --git a/20018_all_mysql-5.7.29-fix-libressl-support.patch b/20018_all_mysql-5.7.29-fix-libressl-support.patch
new file mode 100644
index 0000000..c3604cb
--- /dev/null
+++ b/20018_all_mysql-5.7.29-fix-libressl-support.patch
@@ -0,0 +1,79 @@
+--- a/cmake/ssl.cmake
++++ b/cmake/ssl.cmake
+@@ -186,7 +186,8 @@ MACRO (MYSQL_CHECK_SSL)
+ OPENSSL_FIX_VERSION "${OPENSSL_VERSION_NUMBER}"
+ )
+ ENDIF()
+- IF("${OPENSSL_MAJOR_VERSION}.${OPENSSL_MINOR_VERSION}.${OPENSSL_FIX_VERSION}" VERSION_GREATER "1.1.0")
++ CHECK_SYMBOL_EXISTS(TLS1_3_VERSION "openssl/tls1.h" HAVE_TLS1_3_VERSION)
++ IF(HAVE_TLS1_3_VERSION)
+ ADD_DEFINITIONS(-DHAVE_TLSv13)
+ SET(HAVE_TLSv13 1)
+ IF(SOLARIS)
+@@ -196,7 +197,7 @@ MACRO (MYSQL_CHECK_SSL)
+ IF(OPENSSL_INCLUDE_DIR AND
+ OPENSSL_LIBRARY AND
+ CRYPTO_LIBRARY AND
+- OPENSSL_MAJOR_VERSION STREQUAL "1"
++ OPENSSL_MAJOR_VERSION VERSION_GREATER_EQUAL "1"
+ )
+ SET(OPENSSL_FOUND TRUE)
+ ELSE()
+--- a/sql/auth/sha2_password_common.cc
++++ b/sql/auth/sha2_password_common.cc
+@@ -116,7 +116,8 @@ bool SHA256_digest::retrieve_digest(unsigned char *digest,
+ DBUG_RETURN(true);
+ }
+ m_ok= EVP_DigestFinal_ex(md_context, m_digest, NULL);
+-#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L
++#if defined(HAVE_WOLFSSL) || OPENSSL_VERSION_NUMBER < 0x10100000L || \
++ (defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x02090000fL)
+ EVP_MD_CTX_cleanup(md_context);
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ EVP_MD_CTX_reset(md_context);
+--- a/sql/mysqld.cc
++++ b/sql/mysqld.cc
+@@ -3419,7 +3419,7 @@ int warn_self_signed_ca()
+ static int init_ssl()
+ {
+ #ifdef HAVE_OPENSSL
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
+ CRYPTO_malloc_init();
+ #else /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ OPENSSL_malloc_init();
+--- a/vio/viosslfactories.c
++++ b/vio/viosslfactories.c
+@@ -123,21 +123,19 @@ static DH *get_dh2048(void)
+ DH *dh;
+ if ((dh=DH_new()))
+ {
+- BIGNUM *p= BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL);
+- BIGNUM *g= BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL);
+- if (!p || !g
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000L
+- || !DH_set0_pqg(dh, p, NULL, g)
+-#endif /* OPENSSL_VERSION_NUMBER >= 0x10100000L */
+- ) {
+- /* DH_free() will free 'p' and 'g' at once. */
++ BIGNUM *p = BN_bin2bn(dh2048_p,sizeof(dh2048_p), NULL);
++ BIGNUM *g = BN_bin2bn(dh2048_g,sizeof(dh2048_g), NULL);
++#if OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER)
++ dh->p=p;
++ dh->g=g;
++ if (! dh->p || ! dh->g)
++#else
++ if (!DH_set0_pqg(dh, p, NULL, g))
++#endif
++ {
+ DH_free(dh);
+- return NULL;
++ dh = NULL;
+ }
+-#if OPENSSL_VERSION_NUMBER < 0x10100000L
+- dh->p= p;
+- dh->g= g;
+-#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
+ }
+ return(dh);
+ }
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-01-25 19:42 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-01-25 19:42 UTC (permalink / raw
To: gentoo-commits
commit: 34a0bdaad4e20ddc3446e2bbfb24185d03b6b4b2
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat Jan 25 19:42:31 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat Jan 25 19:42:31 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=34a0bdaa
Add 20018_all_mysql-5.7.29-without-clientlibs-tools.patch
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
...all_mysql-5.7.29-without-clientlibs-tools.patch | 183 +++++++++++++++++++++
1 file changed, 183 insertions(+)
diff --git a/20018_all_mysql-5.7.29-without-clientlibs-tools.patch b/20018_all_mysql-5.7.29-without-clientlibs-tools.patch
new file mode 100644
index 0000000..3f00c0a
--- /dev/null
+++ b/20018_all_mysql-5.7.29-without-clientlibs-tools.patch
@@ -0,0 +1,183 @@
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -577,8 +577,6 @@ IF(BUILD_BUNDLED_ZLIB)
+ ENDIF()
+ # Add openssl.
+ MYSQL_CHECK_SSL()
+-# Add system/bundled editline.
+-MYSQL_CHECK_EDITLINE()
+ # Add libevent
+ IF(NOT WITHOUT_SERVER)
+ MYSQL_CHECK_LIBEVENT()
+@@ -673,7 +671,10 @@ IF(WITH_UNIT_TESTS)
+ ENABLE_TESTING()
+ ENDIF()
+
+-ADD_SUBDIRECTORY(include)
++IF(NOT WITHOUT_CLIENTLIBS)
++ ADD_SUBDIRECTORY(include)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
++
+ ADD_SUBDIRECTORY(dbug)
+ ADD_SUBDIRECTORY(strings)
+ ADD_SUBDIRECTORY(vio)
+@@ -720,7 +721,6 @@ IF(WITH_UNIT_TESTS)
+ ENDIF()
+
+ ADD_SUBDIRECTORY(extra)
+-ADD_SUBDIRECTORY(client)
+ ADD_SUBDIRECTORY(sql/share)
+ ADD_SUBDIRECTORY(libservices)
+
+@@ -728,11 +728,20 @@ IF(UNIX)
+ ADD_SUBDIRECTORY(man)
+ ENDIF()
+
++IF(NOT WITHOUT_TOOLS)
++ # Add system/bundled editline
++ MYSQL_CHECK_EDITLINE()
++ ADD_SUBDIRECTORY(client)
++ENDIF(NOT WITHOUT_TOOLS)
++
+ IF(NOT WITHOUT_SERVER)
+ ADD_SUBDIRECTORY(testclients)
+ ADD_SUBDIRECTORY(sql)
+ OPTION (WITH_EMBEDDED_SERVER "Compile MySQL with embedded server" OFF)
+ IF(WITH_EMBEDDED_SERVER)
++ IF(WITHOUT_TOOLS)
++ MYSQL_CHECK_EDITLINE()
++ ENDIF(WITHOUT_TOOLS)
+ ADD_SUBDIRECTORY(libmysqld)
+ ADD_SUBDIRECTORY(libmysqld/examples)
+ ENDIF(WITH_EMBEDDED_SERVER)
+--- a/extra/CMakeLists.txt
++++ b/extra/CMakeLists.txt
+@@ -71,11 +71,16 @@ ADD_CUSTOM_TARGET(GenError
+ # Set InnoDB mutex type
+ ADD_DEFINITIONS(-DMUTEX_EVENT)
+
+-MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ MYSQL_ADD_EXECUTABLE(perror perror.c)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(my_print_defaults my_print_defaults.c)
++ ADD_EXECUTABLE(perror perror.c)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(my_print_defaults mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(my_print_defaults PROPERTIES LINKER_LANGUAGE CXX)
+
+-MYSQL_ADD_EXECUTABLE(perror perror.c)
+ ADD_DEPENDENCIES(perror GenError)
+ TARGET_LINK_LIBRARIES(perror mysys mysys_ssl)
+ SET_TARGET_PROPERTIES(perror PROPERTIES LINKER_LANGUAGE CXX)
+@@ -94,10 +99,15 @@ ENDIF()
+ MYSQL_ADD_EXECUTABLE(replace replace.c)
+ TARGET_LINK_LIBRARIES(replace mysys)
+
+-MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
+-TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
++IF(NOT WITHOUT_CLIENTLIBS)
++ MYSQL_ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ELSE(NOT WITHOUT_CLIENTLIBS)
++ ADD_EXECUTABLE(lz4_decompress lz4_decompress.cc)
++ ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+-MYSQL_ADD_EXECUTABLE(zlib_decompress zlib_decompress.cc)
++TARGET_LINK_LIBRARIES(lz4_decompress ${LZ4_LIBRARY})
+ TARGET_LINK_LIBRARIES(zlib_decompress ${ZLIB_LIBRARY})
+
+ IF(WITH_INNOBASE_STORAGE_ENGINE)
+--- a/libmysql/CMakeLists.txt
++++ b/libmysql/CMakeLists.txt
+@@ -263,12 +263,17 @@ IF(WIN32)
+ LIST(APPEND LIBS_TO_MERGE auth_win_client)
+ ENDIF()
+
+-# LDAP authentication SASL client plugin
+-MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
+-ADD_SUBDIRECTORY(authentication_ldap)
+-
+-# Merge several convenience libraries into one big mysqlclient
+-MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++IF(WITHOUT_CLIENTLIBS)
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
++ # LDAP authentication SASL client plugin
++ MESSAGE(STATUS "Creating LDAP authentication SASL client library.")
++ ADD_SUBDIRECTORY(authentication_ldap)
++
++ # Merge several convenience libraries into one big mysqlclient
++ MERGE_CONVENIENCE_LIBRARIES(mysqlclient ${LIBS_TO_MERGE} COMPONENT Development)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(mysqlclient ${LIBS_TO_LINK})
+
+ # Visual Studio users need debug static library for debug projects
+@@ -312,9 +317,15 @@ ENDIF()
+ IF(NOT DISABLE_SHARED)
+ # Merge several convenience libraries into one big mysqlclient
+ # and link them together into shared library.
++IF(WITHOUT_CLIENTLIBS)
++ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
++ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
++ COMPONENT SharedLibraries SKIP_INSTALL)
++ELSE(WITHOUT_CLIENTLIBS)
+ MERGE_LIBRARIES_SHARED(libmysql ${LIBS_TO_MERGE}
+ EXPORTS ${CLIENT_API_FUNCTIONS} ${CLIENT_API_FUNCTIONS_UNDOCUMENTED}
+ COMPONENT SharedLibraries)
++ENDIF(WITHOUT_CLIENTLIBS)
+ TARGET_LINK_LIBRARIES(libmysql ${LIBS_TO_LINK})
+ IF(UNIX)
+ # libtool compatability
+--- a/scripts/CMakeLists.txt
++++ b/scripts/CMakeLists.txt
+@@ -423,18 +423,21 @@ ELSE()
+
+ IF(WITH_SYSTEMD)
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ )
+ ELSE()
+ SET(BIN_SCRIPTS
+- mysql_config
+ mysqldumpslow
+ mysqld_multi
+ mysqld_safe
+ )
+ ENDIF()
+-
++ IF(NOT WITHOUT_CLIENTLIBS)
++ SET(BIN_SCRIPTS
++ ${BIN_SCRIPTS}
++ mysql_config
++ )
++ ENDIF(NOT WITHOUT_CLIENTLIBS)
+ SET(PKGCONFIG_FILE ${LIBMYSQL_OS_OUTPUT_NAME}.pc)
+ STRING(REGEX REPLACE "/mysql$" "" PKGCONFIG_DIR "${INSTALL_LIBDIR}")
+ SET(PKGCONFIG_DIR "${PKGCONFIG_DIR}/pkgconfig")
+@@ -449,7 +452,7 @@ ELSE()
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+ ESCAPE_QUOTES @ONLY)
+
+- IF(INSTALL_PKGCONFIGDIR)
++ IF(INSTALL_PKGCONFIGDIR AND NOT WITHOUT_CLIENTLIBS)
+ MESSAGE(STATUS "INSTALL ${PKGCONFIG_FILE} ${INSTALL_PKGCONFIGDIR}")
+ INSTALL(FILES
+ ${CMAKE_CURRENT_BINARY_DIR}/${PKGCONFIG_FILE}
+--- a/support-files/CMakeLists.txt
++++ b/support-files/CMakeLists.txt
+@@ -66,8 +66,9 @@ IF(UNIX)
+ IF(INSTALL_SUPPORTFILESDIR)
+ INSTALL(FILES magic DESTINATION ${inst_location} COMPONENT SupportFiles)
+ ENDIF()
+-
++IF(NOT WITHOUT_CLIENTLIBS)
+ INSTALL(FILES mysql.m4 DESTINATION ${INSTALL_SHAREDIR}/aclocal COMPONENT Development)
++ENDIF(NOT WITHOUT_CLIENTLIBS)
+
+ SET(bindir ${prefix}/${INSTALL_BINDIR})
+ SET(sbindir ${prefix}/${INSTALL_SBINDIR})
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-02-03 17:50 Brian Evans
0 siblings, 0 replies; 300+ messages in thread
From: Brian Evans @ 2020-02-03 17:50 UTC (permalink / raw
To: gentoo-commits
commit: 020e559e8a8f1b39c1553322ee6247a537e1e5e5
Author: Brian Evans <grknight <AT> gentoo <DOT> org>
AuthorDate: Mon Feb 3 17:48:41 2020 +0000
Commit: Brian Evans <grknight <AT> gentoo <DOT> org>
CommitDate: Mon Feb 3 17:48:41 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=020e559e
mariadb: Add new patch for binutil-libs 2.34 API change
Signed-off-by: Brian Evans <grknight <AT> gentoo.org>
20039_all_mariadb-binutil-libs-2.34.patch | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/20039_all_mariadb-binutil-libs-2.34.patch b/20039_all_mariadb-binutil-libs-2.34.patch
new file mode 100644
index 0000000..0e57b3e
--- /dev/null
+++ b/20039_all_mariadb-binutil-libs-2.34.patch
@@ -0,0 +1,23 @@
+--- a/mysys/my_addr_resolve.c
++++ b/mysys/my_addr_resolve.c
+@@ -74,11 +74,20 @@ int my_addr_resolve(void *ptr, my_addr_loc *loc)
+ {
+ bfd_vma start;
+
++#ifdef bfd_get_section_flags
+ if ((bfd_get_section_flags(bfdh, sec) & SEC_ALLOC) == 0)
++#else
++ if ((bfd_section_flags(sec) & SEC_ALLOC) == 0)
++#endif
+ continue;
+
++#ifdef bfd_get_section_vma
+ start = bfd_get_section_vma(bfdh, sec);
+ if (addr < start || addr >= start + bfd_get_section_size(sec))
++#else
++ start = bfd_section_vma(sec);
++ if (addr < start || addr >= start + bfd_section_size(sec))
++#endif
+ continue;
+
+ if (bfd_find_nearest_line(bfdh, sec, symtable, addr - start,
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-03-17 0:57 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-03-17 0:57 UTC (permalink / raw
To: gentoo-commits
commit: b2acb6e8c9967432ac93905e707d5217f926f9cb
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Tue Mar 17 00:55:56 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Tue Mar 17 00:55:56 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=b2acb6e8
Fix 20018_all_*-8.0.*-without-clientlibs-tools.patch
ICU is not required when building client tools only.
Bug: https://bugs.gentoo.org/712072
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20018_all_mysql-8.0.19-without-clientlibs-tools.patch | 13 ++++++++++++-
...all_percona-server-8.0.18-without-clientlibs-tools.patch | 13 ++++++++++++-
2 files changed, 24 insertions(+), 2 deletions(-)
diff --git a/20018_all_mysql-8.0.19-without-clientlibs-tools.patch b/20018_all_mysql-8.0.19-without-clientlibs-tools.patch
index ea6744e..722ddac 100644
--- a/20018_all_mysql-8.0.19-without-clientlibs-tools.patch
+++ b/20018_all_mysql-8.0.19-without-clientlibs-tools.patch
@@ -1,6 +1,17 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -1285,7 +1285,9 @@ IF(WITH_UNIT_TESTS)
+@@ -1200,7 +1200,9 @@ ENDIF()
+ # Add lz4 library
+ MYSQL_CHECK_LZ4()
+ # Add icu library
+-MYSQL_CHECK_ICU()
++IF(NOT WITHOUT_SERVER)
++ MYSQL_CHECK_ICU()
++ENDIF()
+ # Add SASL library
+ MYSQL_CHECK_SASL()
+ # Add protoc and libprotobuf
+@@ -1285,7 +1287,9 @@ IF(WITH_UNIT_TESTS)
INCLUDE(googletest)
ENDIF()
diff --git a/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch b/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
index bf07285..0b466ea 100644
--- a/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
+++ b/20018_all_percona-server-8.0.18-without-clientlibs-tools.patch
@@ -1,6 +1,17 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
-@@ -1284,7 +1284,9 @@ IF(WITH_UNIT_TESTS)
+@@ -1199,7 +1199,9 @@ ENDIF()
+ # Add lz4 library
+ MYSQL_CHECK_LZ4()
+ # Add icu library
+-MYSQL_CHECK_ICU()
++IF(NOT WITHOUT_SERVER)
++ MYSQL_CHECK_ICU()
++ENDIF()
+ # Add SASL library
+ MYSQL_CHECK_SASL()
+ # Add protoc and libprotobuf
+@@ -1284,7 +1286,9 @@ IF(WITH_UNIT_TESTS)
INCLUDE(googletest)
ENDIF()
^ permalink raw reply related [flat|nested] 300+ messages in thread
* [gentoo-commits] proj/mysql-extras:master commit in: /
@ 2020-05-23 12:19 Thomas Deutschmann
0 siblings, 0 replies; 300+ messages in thread
From: Thomas Deutschmann @ 2020-05-23 12:19 UTC (permalink / raw
To: gentoo-commits
commit: e18b5c5dd7b65d46d60b934398ff6e0fa2e5047f
Author: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
AuthorDate: Sat May 23 12:19:14 2020 +0000
Commit: Thomas Deutschmann <whissi <AT> gentoo <DOT> org>
CommitDate: Sat May 23 12:19:14 2020 +0000
URL: https://gitweb.gentoo.org/proj/mysql-extras.git/commit/?id=e18b5c5d
Respin tokudb CFLAGS patch for new MariaDB versions
Link: https://github.com/MariaDB/server/commit/a13157a561d960604c0c8cfd23b79783cfe76861
Signed-off-by: Thomas Deutschmann <whissi <AT> gentoo.org>
20004_all_mariadb-filter-tokudb-flags-5.5.68.patch | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/20004_all_mariadb-filter-tokudb-flags-5.5.68.patch b/20004_all_mariadb-filter-tokudb-flags-5.5.68.patch
new file mode 100644
index 0000000..2a5c3fa
--- /dev/null
+++ b/20004_all_mariadb-filter-tokudb-flags-5.5.68.patch
@@ -0,0 +1,21 @@
+diff -aurN mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake
+--- mysql.orig/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-09-19 18:34:24.000000000 -0400
++++ mysql/storage/tokudb/ft-index/cmake_modules/TokuSetupCompiler.cmake 2013-10-09 14:16:46.197211235 -0400
+@@ -136,12 +136,10 @@
+ set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ else ()
+ # we overwrite this because the default passes -DNDEBUG and we don't want that
+- set(CMAKE_C_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -g -O3 -UNDEBUG")
+- set(CMAKE_C_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_CXX_FLAGS_RELEASE "-g -O3 -flto -fuse-linker-plugin ${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+- set(CMAKE_EXE_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_EXE_LINKER_FLAGS}")
+- set(CMAKE_SHARED_LINKER_FLAGS "-g -fuse-linker-plugin ${CMAKE_SHARED_LINKER_FLAGS}")
++ set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -UNDEBUG")
++ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -UNDEBUG")
++ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -UNDEBUG")
+ endif ()
+
+ ## set warnings
+
^ permalink raw reply related [flat|nested] 300+ messages in thread
end of thread, other threads:[~2020-05-23 12:19 UTC | newest]
Thread overview: 300+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-02-17 2:04 [gentoo-commits] proj/mysql-extras:master commit in: / Jorge Manuel B. S. Vicetto
-- strict thread matches above, loose matches on Subject: below --
2020-05-23 12:19 Thomas Deutschmann
2020-03-17 0:57 Thomas Deutschmann
2020-02-03 17:50 Brian Evans
2020-01-25 19:42 Thomas Deutschmann
2020-01-25 19:42 Thomas Deutschmann
2020-01-22 18:27 Thomas Deutschmann
2020-01-22 18:27 Thomas Deutschmann
2020-01-22 18:27 Thomas Deutschmann
2020-01-20 18:28 Thomas Deutschmann
2020-01-20 18:19 Thomas Deutschmann
2020-01-20 2:21 Thomas Deutschmann
2019-10-31 0:50 Thomas Deutschmann
2019-10-30 23:49 Thomas Deutschmann
2019-10-30 23:47 Thomas Deutschmann
2019-10-30 1:24 Thomas Deutschmann
2019-10-30 1:01 Thomas Deutschmann
2019-10-30 1:01 Thomas Deutschmann
2019-10-29 23:58 Thomas Deutschmann
2019-10-29 23:58 Thomas Deutschmann
2019-10-17 18:34 Brian Evans
2019-10-15 17:00 Brian Evans
2019-10-15 16:48 Brian Evans
2019-10-15 16:40 Brian Evans
2019-10-14 19:15 Brian Evans
2019-10-14 18:28 Brian Evans
2019-08-22 19:08 Thomas Deutschmann
2019-08-17 0:24 Thomas Deutschmann
2019-08-17 0:24 Thomas Deutschmann
2019-08-17 0:24 Thomas Deutschmann
2019-08-02 15:49 Thomas Deutschmann
2019-08-02 0:31 Thomas Deutschmann
2019-08-02 0:13 Thomas Deutschmann
2019-07-22 19:21 Brian Evans
2019-06-04 11:30 Thomas Deutschmann
2019-05-24 10:51 Thomas Deutschmann
2019-05-21 18:03 Brian Evans
2019-03-10 2:57 Brian Evans
2019-03-05 20:47 Brian Evans
2019-03-05 20:39 Brian Evans
2019-03-05 20:22 Brian Evans
2019-03-03 18:52 Thomas Deutschmann
2019-03-03 18:44 Thomas Deutschmann
2019-03-03 18:44 Thomas Deutschmann
2019-01-26 19:21 Thomas Deutschmann
2019-01-20 23:10 Brian Evans
2019-01-20 18:22 Brian Evans
2019-01-19 20:42 Brian Evans
2019-01-19 20:38 Brian Evans
2018-12-11 17:34 Brian Evans
2018-11-11 23:17 Thomas Deutschmann
2018-11-04 22:52 Brian Evans
2018-10-23 0:12 Brian Evans
2018-10-17 22:22 Thomas Deutschmann
2018-10-17 22:22 Thomas Deutschmann
2018-10-17 12:24 Thomas Deutschmann
2018-10-17 10:37 Thomas Deutschmann
2018-10-17 0:45 Thomas Deutschmann
2018-10-16 16:17 Thomas Deutschmann
2018-10-16 15:19 Thomas Deutschmann
2018-10-14 23:20 Thomas Deutschmann
2018-10-14 21:03 Thomas Deutschmann
2018-10-13 23:31 Thomas Deutschmann
2018-10-13 23:31 Thomas Deutschmann
2018-10-13 23:31 Thomas Deutschmann
2018-10-13 23:31 Thomas Deutschmann
2018-10-13 23:31 Thomas Deutschmann
2018-08-09 17:01 Brian Evans
2018-08-04 23:23 Brian Evans
2018-06-28 1:08 Brian Evans
2018-06-27 14:29 Brian Evans
2018-06-21 2:05 Brian Evans
2018-06-21 2:02 Brian Evans
2018-05-29 0:35 Brian Evans
2018-05-29 0:35 Brian Evans
2018-05-28 1:05 Brian Evans
2018-05-28 1:03 Brian Evans
2018-05-28 0:28 Brian Evans
2018-05-15 13:34 Brian Evans
2018-05-15 0:59 Brian Evans
2018-03-28 20:33 Brian Evans
2018-03-12 19:54 Brian Evans
2018-03-12 19:54 Brian Evans
2018-03-12 18:10 Brian Evans
2018-03-12 16:39 Brian Evans
2018-03-12 16:26 Brian Evans
2018-03-09 15:32 Brian Evans
2018-03-09 15:12 Brian Evans
2018-03-09 14:02 Brian Evans
2018-03-08 19:38 Brian Evans
2018-03-08 19:38 Brian Evans
2018-02-28 16:11 Brian Evans
2018-02-14 0:43 Thomas Deutschmann
2018-02-14 0:43 Thomas Deutschmann
2018-02-09 21:42 Brian Evans
2017-11-21 15:00 Brian Evans
2017-11-08 20:50 Brian Evans
2017-10-18 19:48 Brian Evans
2017-10-18 13:40 Brian Evans
2017-10-18 13:24 Brian Evans
2017-09-26 13:18 Brian Evans
2017-08-30 12:08 Brian Evans
2017-08-20 22:45 Brian Evans
2017-08-03 18:14 Brian Evans
2017-07-29 1:13 Brian Evans
2017-07-29 1:00 Brian Evans
2017-07-27 0:36 Brian Evans
2017-07-27 0:26 Brian Evans
2017-07-19 16:30 Brian Evans
2017-07-19 13:35 Brian Evans
2017-07-19 1:08 Brian Evans
2017-07-19 1:08 Brian Evans
2017-06-28 18:47 Brian Evans
2017-06-28 17:40 Brian Evans
2017-06-28 17:21 Brian Evans
2017-05-29 2:02 Brian Evans
2017-03-16 13:55 Brian Evans
2017-03-16 13:40 Brian Evans
2017-03-10 14:26 Brian Evans
2017-03-01 21:39 Brian Evans
2017-03-01 20:41 Thomas Deutschmann
2017-01-29 1:26 Brian Evans
2016-12-03 20:41 Thomas Deutschmann
2016-10-19 19:14 Brian Evans
2016-10-19 18:53 Brian Evans
2016-08-18 17:25 Brian Evans
2016-08-18 17:20 Brian Evans
2016-07-21 15:26 Brian Evans
2016-07-21 15:26 Brian Evans
2016-06-28 14:22 Brian Evans
2016-06-28 14:15 Brian Evans
2016-04-27 18:40 Brian Evans
2016-04-27 18:06 Brian Evans
2016-04-27 17:32 Brian Evans
2016-03-07 18:54 Brian Evans
2016-03-07 18:49 Brian Evans
2016-02-12 2:33 Brian Evans
2016-02-12 2:26 Brian Evans
2016-01-31 1:57 Brian Evans
2016-01-31 1:46 Brian Evans
2016-01-21 13:50 Brian Evans
2015-12-22 21:38 Brian Evans
2015-11-23 16:43 Brian Evans
2015-11-17 20:40 Brian Evans
2015-11-05 20:51 Brian Evans
2015-10-19 17:25 Brian Evans
2015-09-11 15:05 Brian Evans
2015-08-05 16:09 Brian Evans
2015-07-29 18:46 Brian Evans
2015-07-17 17:04 Brian Evans
2015-07-10 19:09 Brian Evans
2015-05-09 18:16 Brian Evans
2015-04-10 18:53 Brian Evans
2015-03-10 20:43 Brian Evans
2015-03-04 3:35 git@oystercatcher mirror+tproxy
2015-03-04 3:35 Brian Evans
2015-02-10 17:50 Brian Evans
2015-02-10 17:50 Brian Evans
2015-02-10 15:02 Brian Evans
2015-01-27 13:51 Brian Evans
2015-01-13 18:54 Brian Evans
2014-12-15 2:02 Brian Evans
2014-12-15 1:44 Brian Evans
2014-12-09 23:20 Brian Evans
2014-12-03 19:36 Brian Evans
2014-12-03 19:04 Brian Evans
2014-12-03 18:22 Brian Evans
2014-12-03 18:16 Brian Evans
2014-11-25 14:15 Brian Evans
2014-11-25 13:52 Brian Evans
2014-11-25 13:51 Brian Evans
2014-11-25 13:47 Brian Evans
2014-10-25 2:42 Brian Evans
2014-10-22 20:44 Brian Evans
2014-10-22 19:12 Brian Evans
2014-10-21 17:41 Brian Evans
2014-10-19 19:27 Brian Evans
2014-10-19 19:21 Brian Evans
2014-10-18 0:15 Brian Evans
2014-10-17 14:20 Brian Evans
2014-10-09 14:50 Brian Evans
2014-09-09 18:03 Brian Evans
2014-09-03 19:11 Brian Evans
2014-08-18 23:37 Brian Evans
2014-08-18 23:37 Brian Evans
2014-08-18 23:37 Brian Evans
2014-08-18 23:37 Brian Evans
2014-08-18 20:21 Robin H. Johnson
2014-08-18 20:21 Robin H. Johnson
2014-08-18 20:21 Robin H. Johnson
2014-08-17 23:32 Brian Evans
2014-08-17 23:19 Brian Evans
2014-08-11 23:05 Brian Evans
2014-08-05 18:17 Brian Evans
2014-07-29 18:41 Brian Evans
2014-07-28 23:43 Brian Evans
2014-07-28 22:54 Brian Evans
2014-05-14 0:58 Brian Evans
2014-05-14 0:52 Brian Evans
2014-05-12 18:19 Brian Evans
2014-05-12 18:16 Brian Evans
2014-05-06 19:37 Brian Evans
2014-05-06 19:29 Brian Evans
2014-04-26 3:53 Brian Evans
2014-04-26 1:26 Brian Evans
2014-04-26 0:57 Brian Evans
2014-04-23 16:22 Brian Evans
2014-04-18 15:28 Brian Evans
2014-04-17 19:45 Brian Evans
2014-04-10 15:29 Brian Evans
2014-03-31 18:05 Brian Evans
2014-03-31 17:48 Brian Evans
2014-03-27 17:45 Brian Evans
2014-03-11 15:02 Brian Evans
2014-03-11 14:59 Brian Evans
2014-03-11 14:55 Brian Evans
2014-03-10 20:02 Brian Evans
2014-03-04 15:33 Brian Evans
2014-02-26 18:37 Brian Evans
2014-02-24 14:57 Brian Evans
2014-01-23 3:40 Brian Evans
2014-01-23 0:14 Brian Evans
2014-01-20 14:03 Jorge Manuel B. S. Vicetto
2014-01-20 2:05 Brian Evans
2014-01-20 1:35 Jorge Manuel B. S. Vicetto
2014-01-20 1:08 Jorge Manuel B. S. Vicetto
2014-01-20 1:04 Jorge Manuel B. S. Vicetto
2014-01-19 2:11 Brian Evans
2014-01-18 23:47 Jorge Manuel B. S. Vicetto
2014-01-18 22:40 Jorge Manuel B. S. Vicetto
2013-12-12 15:25 Brian Evans
2013-12-10 18:24 Brian Evans
2013-10-09 19:30 Brian Evans
2013-10-09 19:30 Brian Evans
2013-08-23 18:56 Brian Evans
2013-06-27 12:31 Brian Evans
2013-06-27 12:31 Brian Evans
2013-06-25 15:48 Jorge Manuel B. S. Vicetto
2013-06-06 20:32 Robin H. Johnson
2013-05-28 19:46 Robin H. Johnson
2013-05-28 19:42 Robin H. Johnson
2013-05-28 19:39 Robin H. Johnson
2013-05-28 19:34 Robin H. Johnson
2013-05-28 19:34 Robin H. Johnson
2013-05-28 19:34 Robin H. Johnson
2013-05-28 19:16 Robin H. Johnson
2013-05-01 0:07 Jorge Manuel B. S. Vicetto
2013-04-24 19:49 Jorge Manuel B. S. Vicetto
2013-04-23 23:26 Jorge Manuel B. S. Vicetto
2013-03-01 2:47 Robin H. Johnson
2013-01-28 17:27 Robin H. Johnson
2013-01-20 23:03 Robin H. Johnson
2013-01-19 22:38 Robin H. Johnson
2013-01-19 22:38 Robin H. Johnson
2013-01-18 18:10 Robin H. Johnson
2012-09-06 13:45 Jorge Manuel B. S. Vicetto
2012-09-05 15:11 Jorge Manuel B. S. Vicetto
2012-08-14 1:23 Jorge Manuel B. S. Vicetto
2012-08-07 17:42 Robin H. Johnson
2012-08-06 18:58 Robin H. Johnson
2012-08-02 19:27 Robin H. Johnson
2012-04-21 20:34 Robin H. Johnson
2012-04-21 20:34 Robin H. Johnson
2012-04-16 20:20 Robin H. Johnson
2012-04-01 17:59 Robin H. Johnson
2012-04-01 17:54 Robin H. Johnson
2012-04-01 5:13 Robin H. Johnson
2012-04-01 5:13 Robin H. Johnson
2011-11-18 20:58 Robin H. Johnson
2011-08-19 4:15 Jorge Manuel B. S. Vicetto
2011-08-19 4:04 Jorge Manuel B. S. Vicetto
2011-07-21 2:27 Jorge Manuel B. S. Vicetto
2011-07-21 2:20 Jorge Manuel B. S. Vicetto
2011-07-15 11:17 Jorge Manuel B. S. Vicetto
2011-06-16 2:20 Jorge Manuel B. S. Vicetto
2011-05-10 18:05 Jorge Manuel B. S. Vicetto
2011-04-26 9:51 Robin H. Johnson
2011-04-26 9:48 Robin H. Johnson
2011-04-26 9:23 Robin H. Johnson
2011-04-26 9:15 Robin H. Johnson
2011-04-17 22:42 Robin H. Johnson
2011-04-17 20:10 Robin H. Johnson
2011-04-17 20:10 Robin H. Johnson
2011-04-17 20:10 Robin H. Johnson
2011-04-17 3:40 Jorge Manuel B. S. Vicetto
2011-03-27 21:02 Jorge Manuel B. S. Vicetto
2011-03-27 20:58 Jorge Manuel B. S. Vicetto
2011-03-21 2:23 Jorge Manuel B. S. Vicetto
2011-03-04 12:53 Jorge Manuel B. S. Vicetto
2011-03-02 19:55 Jorge Manuel B. S. Vicetto
2011-02-17 21:05 Jorge Manuel B. S. Vicetto
2011-02-17 21:05 Jorge Manuel B. S. Vicetto
2011-02-17 20:49 Jorge Manuel B. S. Vicetto
2011-02-17 20:36 Jorge Manuel B. S. Vicetto
2011-02-17 12:08 Jorge Manuel B. S. Vicetto
2011-02-17 1:47 Jorge Manuel B. S. Vicetto
2011-02-17 1:42 Jorge Manuel B. S. Vicetto
2011-02-17 1:34 Jorge Manuel B. S. Vicetto
2011-02-17 1:25 Jorge Manuel B. S. Vicetto
2011-02-17 1:20 Jorge Manuel B. S. Vicetto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox