Merge a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.0

into  a193-229-222-105.elisa-laajakaista.fi:/home/my/bk/mysql-5.1-new


Makefile.am:
  Auto merged
client/mysqltest.c:
  Auto merged
configure.in:
  Auto merged
extra/Makefile.am:
  Auto merged
include/Makefile.am:
  Auto merged
include/my_global.h:
  Auto merged
libmysqld/examples/Makefile.am:
  Auto merged
mysql-test/Makefile.am:
  Auto merged
mysql-test/r/ndb_alter_table.result:
  Auto merged
mysql-test/t/ndb_alter_table.test:
  Auto merged
scripts/Makefile.am:
  Auto merged
sql/Makefile.am:
  Auto merged
sql/field.cc:
  Auto merged
sql/ha_federated.cc:
  Auto merged
sql/ha_federated.h:
  Auto merged
sql/ha_innodb.cc:
  Auto merged
sql/ha_myisammrg.cc:
  Auto merged
sql/ha_ndbcluster.cc:
  Auto merged
sql/handler.cc:
  Auto merged
sql/item.cc:
  Auto merged
sql/item_subselect.cc:
  Auto merged
sql/key.cc:
  Auto merged
sql/log.cc:
  Auto merged
sql/log_event.cc:
  Auto merged
sql/mysqld.cc:
  Auto merged
sql/opt_range.cc:
  Auto merged
sql/repl_failsafe.cc:
  Auto merged
sql/slave.cc:
  Auto merged
sql/sp.cc:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_acl.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_cache.h:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_load.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_prepare.cc:
  Auto merged
sql/sql_repl.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_table.cc:
  Auto merged
sql/structs.h:
  Auto merged
sql/table.cc:
  Auto merged
sql/tztime.cc:
  Auto merged
storage/myisam/myisamchk.c:
  Auto merged
storage/myisam/myisampack.c:
  Auto merged
storage/ndb/docs/Makefile.am:
  Auto merged
support-files/mysql.spec.sh:
  Auto merged
libmysqld/Makefile.am:
  Merged from 5.0 to 5.1.
sql/ha_berkeley.cc:
  Merged from 5.0 to 5.1.
sql/lex.h:
  Merged from 5.0 to 5.1.
sql/set_var.cc:
  Merged from 5.0 to 5.1.
sql/share/errmsg.txt:
  Merged from 5.0 to 5.1.
sql/sql_lex.h:
  Merged from 5.0 to 5.1.
sql/sql_show.cc:
  Merged from 5.0 to 5.1.
sql/sql_yacc.yy:
  Merged from 5.0 to 5.1.
This commit is contained in:
unknown 2005-11-23 14:57:00 +02:00
commit 33a2716a85
121 changed files with 2854 additions and 984 deletions

View File

@ -18,11 +18,11 @@ noinst_SCRIPTS = Support/generate-text-files.pl
EXTRA_DIST = $(noinst_SCRIPTS) mysql.info INSTALL-BINARY
all: txt_files
txt_files: ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \
TXT_FILES= ../INSTALL-SOURCE ../INSTALL-WIN-SOURCE ../EXCEPTIONS-CLIENT \
INSTALL-BINARY ../support-files/MacOSX/ReadMe.txt
all-local: $(TXT_FILES)
# make sure that "make install" installs the info page, too
# automake only seems to take care of this automatically,
# if we're building the info page from texi directly.
@ -30,28 +30,37 @@ install-data-hook: mysql.info
$(mkinstalldirs) $(DESTDIR)$(infodir)
$(INSTALL_DATA) $(srcdir)/mysql.info $(DESTDIR)$(infodir)
CLEAN_FILES: $(txt_files)
touch $(txt_files)
uninstall-local:
@RM@ -f $(DESTDIR)$(infodir)/mysql.info
# Problems with "make distclean", works differently for make files
# generated by different versions of the automake. Some require the
# generated files explicitly in DISTCLEANFILES.
DISTCLEANFILES = $(TXT_FILES)
# This target is not used in builds, just for convinience
CLEAN_FILES: $(TXT_FILES)
touch $(TXT_FILES)
GT = $(srcdir)/Support/generate-text-files.pl
../INSTALL-SOURCE: mysql.info $(GT)
perl -w $(GT) mysql.info "installing-source" "windows-source-build" > $@
perl -w $(GT) $< "installing-source" "windows-source-build" > $@
../INSTALL-WIN-SOURCE: mysql.info $(GT)
perl -w $(GT) mysql.info "windows-source-build" "post-installation" > $@
perl -w $(GT) $< "windows-source-build" "post-installation" > $@
# We put the description for the binary installation here so that
# people who download source wont have to see it. It is moved up to
# the toplevel by the script that makes the binary tar files.
INSTALL-BINARY: mysql.info $(GT)
perl -w $(GT) mysql.info "installing-binary" "installing-source" > $@
perl -w $(GT) $< "installing-binary" "installing-source" > $@
../EXCEPTIONS-CLIENT: mysql.info $(GT)
perl -w $(GT) mysql.info "mysql-floss-license-exception" "function-index" > $@
perl -w $(GT) $< "mysql-floss-license-exception" "function-index" > $@
../support-files/MacOSX/ReadMe.txt: mysql.info $(GT)
perl -w $(GT) mysql.info "mac-os-x-installation" "netware-installation" > $@
perl -w $(GT) $< "mac-os-x-installation" "netware-installation" > $@
# Don't update the files from bitkeeper
%::SCCS/s.%

View File

@ -19,7 +19,8 @@
AUTOMAKE_OPTIONS = foreign
# These are built from source in the Docs directory
EXTRA_DIST = INSTALL-SOURCE README COPYING EXCEPTIONS-CLIENT
EXTRA_DIST = INSTALL-SOURCE INSTALL-WIN-SOURCE \
README COPYING EXCEPTIONS-CLIENT
SUBDIRS = . include @docs_dirs@ @zlib_dir@ @yassl_dir@ \
@readline_topdir@ sql-common \
@thread_dirs@ pstack \
@ -37,16 +38,19 @@ DIST_SUBDIRS = . include @docs_dirs@ zlib \
BUILD netware os2 @libmysqld_dirs@\
@bench_dirs@ support-files server-tools tools
# Relink after clean
linked_sources = linked_client_sources linked_server_sources \
linked_libmysql_sources linked_libmysql_r_sources \
linked_libmysqld_sources linked_libmysqldex_sources \
# Run these targets before any others, also make part of clean target,
# to make sure we create new links after a clean.
BUILT_SOURCES = linked_client_sources linked_server_sources \
@linked_client_targets@ \
@linked_libmysqld_targets@ \
linked_include_sources @linked_netware_sources@
CLEANFILES = $(linked_sources)
# This is just so that the linking is done early.
all-local: $(linked_sources)
# The db.h file is a bit special, see note in "configure.in".
# In the case we didn't compile with bdb, a dummy file is put
# there, but will not be removed by the bdb make file becuase
# it will never be called.
CLEANFILES = $(BUILT_SOURCES) bdb/build_unix/db.h
DISTCLEANFILES = ac_available_languages_fragment
linked_include_sources:
cd include; $(MAKE) link_sources
@ -76,13 +80,8 @@ linked_netware_sources:
cd @netware_dir@; $(MAKE) link_sources
echo timestamp > linked_netware_sources
#avoid recursive make calls in sql directory
linked_server_sources:
cd sql; rm -f mini_client_errors.c;\
@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c;\
rm -f pack.c;@LN_CP_F@ ../sql-common/pack.c pack.c;\
rm -f client.c;@LN_CP_F@ ../sql-common/client.c client.c;\
rm -f my_time.c;@LN_CP_F@ ../sql-common/my_time.c my_time.c
cd sql; $(MAKE) link_sources
echo timestamp > linked_server_sources
# Create permission databases
@ -94,7 +93,7 @@ bin-dist: all
# Remove BK's "SCCS" subdirectories from source distribution
dist-hook:
rm -rf `find $(distdir) -type d -name SCCS`
rm -rf `find $(distdir) -type d -name SCCS -print`
tags:
support-files/build-tags

View File

@ -56,12 +56,12 @@ DEFS = -DUNDEF_THREADS_HACK
link_sources:
for f in $(sql_src) ; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(top_srcdir)/sql/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
done; \
for f in $(strings_src) ; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(top_srcdir)/strings/$$f $(srcdir)/$$f; \
@LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \
done;
# Don't update the files from bitkeeper

View File

@ -527,7 +527,7 @@ static struct my_option my_long_options[] =
{"help", 'I', "Synonym for -?", 0, 0, 0, GET_NO_ARG, NO_ARG, 0,
0, 0, 0, 0, 0},
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"auto-rehash", OPT_AUTO_REHASH,

View File

@ -127,7 +127,7 @@ static TYPELIB command_typelib=
static struct my_option my_long_options[] =
{
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"count", 'c',

View File

@ -647,7 +647,7 @@ static struct my_option my_long_options[] =
{
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
/*

View File

@ -63,7 +63,7 @@ static struct my_option my_long_options[] =
(gptr*) &opt_all_in_1, (gptr*) &opt_all_in_1, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"auto-repair", OPT_AUTO_REPAIR,

View File

@ -173,7 +173,7 @@ static struct my_option my_long_options[] =
"Allow creation of column names that are keywords.", (gptr*) &opt_keywords,
(gptr*) &opt_keywords, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"character-sets-dir", OPT_CHARSETS_DIR,
@ -1841,12 +1841,13 @@ DELIMITER ;;\n");
while ((row= mysql_fetch_row(result)))
{
fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */;;\n\
/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */;;\n\n",
/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s%s */;;\n\n",
row[6], /* sql_mode */
quote_name(row[0], name_buff, 0), /* Trigger */
row[4], /* Timing */
row[1], /* Event */
result_table,
(strchr(" \t\n\r", *(row[3]))) ? "" : " ",
row[3] /* Statement */);
}
if (mysql_num_rows(result))

View File

@ -59,7 +59,7 @@ static char *shared_memory_base_name=0;
static struct my_option my_long_options[] =
{
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"character-sets-dir", OPT_CHARSETS_DIR,

View File

@ -157,7 +157,7 @@ int main(int argc, char **argv)
static struct my_option my_long_options[] =
{
#ifdef __NETWARE__
{"auto-close", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
{"autoclose", OPT_AUTO_CLOSE, "Auto close the screen on exit for Netware.",
0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
{"character-sets-dir", 'c', "Directory where character sets are.",

View File

@ -3314,20 +3314,23 @@ static int handle_error(const char *query, struct st_query *q,
((q->expected_errno[i].type == ERR_SQLSTATE) &&
(strcmp(q->expected_errno[i].code.sqlstate, err_sqlstate) == 0)))
{
if (q->expected_errors == 1)
if (!disable_result_log)
{
/* Only log error if there is one possible error */
dynstr_append_mem(ds, "ERROR ", 6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds,"\n",1);
if (q->expected_errors == 1)
{
/* Only log error if there is one possible error */
dynstr_append_mem(ds, "ERROR ", 6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds,"\n",1);
}
/* Don't log error if we may not get an error */
else if (q->expected_errno[0].type == ERR_SQLSTATE ||
(q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
}
/* Don't log error if we may not get an error */
else if (q->expected_errno[0].type == ERR_SQLSTATE ||
(q->expected_errno[0].type == ERR_ERRNO &&
q->expected_errno[0].code.errnum != 0))
dynstr_append(ds,"Got one of the listed errors\n");
/* OK */
DBUG_RETURN(0);
}
@ -3335,11 +3338,14 @@ static int handle_error(const char *query, struct st_query *q,
DBUG_PRINT("info",("i: %d expected_errors: %d", i, q->expected_errors));
dynstr_append_mem(ds, "ERROR ",6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds, "\n", 1);
if (!disable_result_log)
{
dynstr_append_mem(ds, "ERROR ",6);
replace_dynstr_append(ds, err_sqlstate);
dynstr_append_mem(ds, ": ", 2);
replace_dynstr_append(ds, err_error);
dynstr_append_mem(ds, "\n", 1);
}
if (i)
{

View File

@ -2,8 +2,8 @@
# Makefile for the GNU readline library.
# Copyright (C) 1994,1996,1997 Free Software Foundation, Inc.
ASRC=vi.c emacs.c common.c
AHDR=vi.h emacs.h common.h
ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
AHDR = vi.h emacs.h common.h
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \
-I$(srcdir)/../.. -I..
@ -42,16 +42,16 @@ SUFFIXES = .sh
$< > $@-t
@MV@ $@-t $@
vi.h: vi.c makelist
sh ./makelist -h ./vi.c > $@.tmp && \
vi.h: $(srcdir)/vi.c makelist
sh ./makelist -h $(srcdir)/vi.c > $@.tmp && \
mv $@.tmp $@
emacs.h: emacs.c makelist
sh ./makelist -h ./emacs.c > $@.tmp && \
emacs.h: $(srcdir)/emacs.c makelist
sh ./makelist -h $(srcdir)/emacs.c > $@.tmp && \
mv $@.tmp $@
common.h: common.c makelist
sh ./makelist -h ./common.c > $@.tmp && \
common.h: $(srcdir)/common.c makelist
sh ./makelist -h $(srcdir)/common.c > $@.tmp && \
mv $@.tmp $@
help.c: ${ASRC} makelist

View File

@ -19,7 +19,7 @@ INCLUDES="$INCLUDES $ZLIB_INCLUDES"
LIBS="$LIBS $ZLIB_LIBS"
AC_CACHE_VAL([mysql_cv_compress],
[AC_TRY_LINK([#include <zlib.h>],
[return compress(0, (unsigned long*) 0, "", 0);],
[return zlibCompileFlags();],
[mysql_cv_compress="yes"
AC_MSG_RESULT([ok])],
[mysql_cv_compress="no"])

View File

@ -60,7 +60,6 @@ AC_DEFINE_UNQUOTED([DOT_FRM_VERSION], [$DOT_FRM_VERSION],
[Version of .frm files])
AC_SUBST(SHARED_LIB_VERSION)
AC_SUBST(AVAILABLE_LANGUAGES)
AC_SUBST(AVAILABLE_LANGUAGES_ERRORS)
# Canonicalize the configuration name.
@ -2181,6 +2180,7 @@ then
AC_MSG_WARN([extra-tools disabled because --enable-thread-safe-client wasn't used])
else
tools_dirs="tools"
AC_CONFIG_FILES(tools/Makefile)
fi
fi
@ -2202,9 +2202,12 @@ MYSQL_CHECK_OPENSSL
MYSQL_CHECK_YASSL
libmysqld_dirs=
linked_libmysqld_targets=
if test "$with_embedded_server" = "yes"
then
libmysqld_dirs=libmysqld
linked_libmysqld_targets="linked_libmysqld_sources linked_libmysqldex_sources"
AC_CONFIG_FILES(libmysqld/Makefile libmysqld/examples/Makefile)
# We can't build embedded library without building the server, because
# we depend on libmysys, libmystrings, libmyisam, etc.
with_server=yes
@ -2213,6 +2216,7 @@ fi
# mysql_config --libmysqld-libs will print out something like
# -L/path/to/lib/mysql -lmysqld -lmyisam -lmysys -lmystrings -ldbug ...
AC_SUBST([libmysqld_dirs])
AC_SUBST([linked_libmysqld_targets])
# Shall we build the docs?
AC_ARG_WITH(docs,
@ -2317,7 +2321,7 @@ then
readline_basedir="libedit"
readline_dir="$readline_topdir/$readline_basedir"
readline_link="\$(top_builddir)/cmd-line-utils/libedit/libedit.a"
readline_h_ln_cmd="\$(LN) -s \$(top_builddir)/cmd-line-utils/libedit/readline readline"
readline_h_ln_cmd="\$(LN) -s \$(top_srcdir)/cmd-line-utils/libedit/readline readline"
compile_libedit=yes
AC_DEFINE_UNQUOTED(HAVE_HIST_ENTRY, 1)
AC_DEFINE_UNQUOTED(USE_LIBEDIT_INTERFACE, 1)
@ -2327,7 +2331,7 @@ then
readline_basedir="readline"
readline_dir="$readline_topdir/$readline_basedir"
readline_link="\$(top_builddir)/cmd-line-utils/readline/libreadline.a"
readline_h_ln_cmd="\$(LN) -s \$(top_builddir)/cmd-line-utils/readline readline"
readline_h_ln_cmd="\$(LN) -s \$(top_srcdir)/cmd-line-utils/readline readline"
compile_readline=yes
AC_DEFINE_UNQUOTED(USE_NEW_READLINE_INTERFACE, 1)
else
@ -2432,6 +2436,7 @@ if test "$THREAD_SAFE_CLIENT" != "no"
then
sql_client_dirs="libmysql_r $sql_client_dirs"
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])
fi
@ -2531,12 +2536,11 @@ AC_CONFIG_FILES(Makefile extra/Makefile mysys/Makefile dnl
storage/myisam/Makefile storage/myisammrg/Makefile dnl
os2/Makefile os2/include/Makefile os2/include/sys/Makefile dnl
man/Makefile BUILD/Makefile vio/Makefile dnl
libmysql_r/Makefile libmysqld/Makefile libmysqld/examples/Makefile dnl
libmysql/Makefile client/Makefile dnl
pstack/Makefile pstack/aout/Makefile sql/Makefile sql/share/Makefile dnl
sql/handlerton.cc sql-common/Makefile SSL/Makefile dnl
dbug/Makefile scripts/Makefile dnl
include/Makefile sql-bench/Makefile tools/Makefile dnl
include/Makefile sql-bench/Makefile dnl
server-tools/Makefile server-tools/instance-manager/Makefile dnl
tests/Makefile Docs/Makefile support-files/Makefile dnl
support-files/MacOSX/Makefile mysql-test/Makefile dnl

View File

@ -23,6 +23,9 @@ BUILT_SOURCES= $(top_builddir)/include/mysqld_error.h \
$(top_builddir)/include/mysqld_ername.h
pkginclude_HEADERS= $(BUILT_SOURCES)
CLEANFILES = $(BUILT_SOURCES)
# We never use SUBDIRS here, but needed for automake 1.6.3
# to generate code to handle DIST_SUBDIRS
SUBDIRS=
DIST_SUBDIRS= yassl
# This will build mysqld_error.h and sql_state.h

View File

@ -1,2 +1,2 @@
SUBDIRS = taocrypt src
EXTRA_DIST = yassl.dsp yassl.dsw mySTL/*.hpp
EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp)

View File

@ -4,5 +4,5 @@ noinst_LIBRARIES = libyassl.a
libyassl_a_SOURCES = buffer.cpp cert_wrapper.cpp crypto_wrapper.cpp \
handshake.cpp lock.cpp log.cpp socket_wrapper.cpp ssl.cpp \
template_instnt.cpp timer.cpp yassl_imp.cpp yassl_error.cpp yassl_int.cpp
EXTRA_DIST = ../include/*.hpp ../include/openssl/*.h
EXTRA_DIST = $(wildcard ../include/*.hpp) $(wildcard ../include/openssl/*.h)
AM_CXXFLAGS = -DYASSL_PURE_C

View File

@ -11,5 +11,5 @@ libtaocrypt_a_SOURCES = aes.cpp aestables.cpp algebra.cpp arc4.cpp asn.cpp \
template_instnt.cpp
libtaocrypt_a_LIBADD = libtaoint_a-integer.o
EXTRA_DIST = ../include/*.hpp
EXTRA_DIST = $(wildcard ../include/*.hpp)
AM_CXXFLAGS = -DYASSL_PURE_C

View File

@ -38,20 +38,12 @@ CLEANFILES = mysql_version.h my_config.h readline
# Some include files that may be moved and patched by configure
DISTCLEANFILES = sched.h $(CLEANFILES)
all-local: my_config.h
# Since we include my_config.h it better exist from the beginning
link_sources:
$(CP) ../config.h my_config.h
-$(RM) -fr readline
@readline_h_ln_cmd@
# Keep automake happy
my_config.h: ../config.h
$(CP) ../config.h my_config.h
-$(RM) -fr readline
@readline_h_ln_cmd@
# These files should not be included in distributions since they are
# generated by configure from the .h.in files

View File

@ -43,33 +43,33 @@ link_sources:
vs=`echo $(vio_objects) | sed "s;\.lo;.c;g"`; \
scs=`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"`; \
for f in $$ss; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \
done; \
for f in $$vs $(vioheaders); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../vio/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/vio/$$f $$f; \
done; \
for f in $$scs; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql-common/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/sql-common/$$f $$f; \
done; \
for f in $(mystringsextra); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../strings/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/strings/$$f $$f; \
done; \
for f in $$ds; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../dbug/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/dbug/$$f $$f; \
done; \
for f in $$ms $(mysysheaders); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../mysys/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/mysys/$$f $$f; \
done; \
rm -f $(srcdir)/net.c; \
@LN_CP_F@ $(srcdir)/../sql/net_serv.cc $(srcdir)/net.c ; \
rm -f $(srcdir)/password.c; \
@LN_CP_F@ $(srcdir)/../sql/password.c $(srcdir)/password.c
rm -f net.c; \
@LN_CP_F@ $(top_srcdir)/sql/net_serv.cc net.c ; \
rm -f password.c; \
@LN_CP_F@ $(top_srcdir)/sql/password.c password.c
# This part requires GNUmake
#

View File

@ -39,6 +39,6 @@ libmysqlclient_r_la_LDFLAGS = $(target_ldflags)
link_sources:
set -x; \
for f in `cd $(libmysql_dir) && echo *.[ch]`; do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(libmysql_dir)/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(libmysql_dir)/$$f $$f; \
done

View File

@ -143,19 +143,19 @@ endif
link_sources:
set -x; \
for f in $(sqlsources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../sql/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/sql/$$f $$f; \
done; \
for f in $(libmysqlsources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../libmysql/$$f $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/libmysql/$$f $$f; \
done; \
for f in $(sqlstoragesources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ `find $(srcdir)/../sql -name $$f` $(srcdir)/$$f; \
rm -f $$f; \
@LN_CP_F@ `find $(srcdir)/../sql -name $$f` $$f; \
done; \
rm -f $(srcdir)/client_settings.h; \
@LN_CP_F@ $(srcdir)/../libmysql/client_settings.h $(srcdir)/client_settings.h;
rm -f client_settings.h; \
@LN_CP_F@ $(top_srcdir)/libmysql/client_settings.h client_settings.h
clean-local:

View File

@ -21,14 +21,15 @@ tests_sources = $(mysql_client_test_embedded_SOURCES)
CLEANFILES = $(client_sources) $(tests_sources)
link_sources:
set -x; \
for f in $(client_sources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../../client/$$f $(srcdir)/$$f; \
done;
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/client/$$f $$f; \
done; \
for f in $(tests_sources); do \
rm -f $(srcdir)/$$f; \
@LN_CP_F@ $(srcdir)/../../tests/$$f $(srcdir)/$$f; \
done;
rm -f $$f; \
@LN_CP_F@ $(top_srcdir)/tests/$$f $$f; \
done
DEFS = -DEMBEDDED_LIBRARY
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -I$(srcdir) \

View File

@ -85,6 +85,9 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
uninstall-local:
@RM@ -f -r $(DESTDIR)$(testdir)
std_data/client-key.pem:
@CP@ $(top_srcdir)/SSL/$(@F) $(srcdir)/std_data
std_data/client-cert.pem:

View File

@ -0,0 +1,4 @@
-- require r/is_debug_build.require
--disable_query_log
select instr(version(), "debug") > 0;
--enable_query_log

View File

@ -68,12 +68,12 @@ select CONVERT(DATE "2004-01-22 21:45:33",BINARY(4));
CONVERT(DATE "2004-01-22 21:45:33",BINARY(4))
2004
Warnings:
Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33'
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
select CAST(DATE "2004-01-22 21:45:33" AS BINARY(4));
CAST(DATE "2004-01-22 21:45:33" AS BINARY(4))
2004
Warnings:
Warning 1292 Truncated incorrect CHAR(4) value: '2004-01-22 21:45:33'
Warning 1292 Truncated incorrect BINARY(4) value: '2004-01-22 21:45:33'
select CAST(0xb3 as signed);
CAST(0xb3 as signed)
179
@ -165,17 +165,17 @@ cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
hex(cast(_latin1'a' AS char(2))) as c5;
c1 c2 c3 c4 c5
ab a ab a a
ab a ab a 6100
Warnings:
Warning 1292 Truncated incorrect CHAR(2) value: 'abc'
Warning 1292 Truncated incorrect CHAR(2) value: 'a '
Warning 1292 Truncated incorrect BINARY(2) value: 'abc'
Warning 1292 Truncated incorrect BINARY(2) value: 'a '
select cast(1000 as CHAR(3));
cast(1000 as CHAR(3))
100
Warnings:
Warning 1292 Truncated incorrect CHAR(3) value: '1000'
Warning 1292 Truncated incorrect BINARY(3) value: '1000'
create table t1 select
cast(_latin1'ab' AS char) as c1,
cast(_latin1'a ' AS char) as c2,
@ -183,11 +183,11 @@ cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
Warnings:
Warning 1292 Truncated incorrect CHAR(2) value: 'abc'
Warning 1292 Truncated incorrect CHAR(2) value: 'a '
select * from t1;
c1 c2 c3 c4 c5
ab a ab a a
Warning 1292 Truncated incorrect BINARY(2) value: 'abc'
Warning 1292 Truncated incorrect BINARY(2) value: 'a '
select c1,c2,c3,c4,hex(c5) from t1;
c1 c2 c3 c4 hex(c5)
ab a ab a 6100
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
@ -274,9 +274,9 @@ aac aac
aab aab
aaa aaa
Warnings:
Warning 1292 Truncated incorrect CHAR(2) value: 'aaa'
Warning 1292 Truncated incorrect CHAR(2) value: 'aab'
Warning 1292 Truncated incorrect CHAR(2) value: 'aac'
Warning 1292 Truncated incorrect BINARY(2) value: 'aaa'
Warning 1292 Truncated incorrect BINARY(2) value: 'aab'
Warning 1292 Truncated incorrect BINARY(2) value: 'aac'
SELECT a, CAST(a AS UNSIGNED) FROM t1 ORDER BY CAST(a AS CHAR) ;
a CAST(a AS UNSIGNED)
aaa 3
@ -288,9 +288,9 @@ aaa aa
aab aa
aac aa
Warnings:
Warning 1292 Truncated incorrect CHAR(2) value: 'aaa'
Warning 1292 Truncated incorrect CHAR(2) value: 'aab'
Warning 1292 Truncated incorrect CHAR(2) value: 'aac'
Warning 1292 Truncated incorrect BINARY(2) value: 'aaa'
Warning 1292 Truncated incorrect BINARY(2) value: 'aab'
Warning 1292 Truncated incorrect BINARY(2) value: 'aac'
DROP TABLE t1;
select date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour);
date_add(cast('2004-12-30 12:00:00' as date), interval 0 hour)

View File

@ -0,0 +1,2 @@
instr(version(), "debug") > 0
1

View File

@ -2494,3 +2494,59 @@ drop view v2;
drop view v0;
drop view v1;
drop table t1;
SET @old_sql_mode = @@SQL_MODE;
SET SQL_MODE = IGNORE_SPACE;
CREATE TABLE t1 (a INT);
CREATE TRIGGER tr1 BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
SET new.a = 0;
END|
SET SQL_MODE = @old_sql_mode;
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
USE `test`;
DROP TABLE IF EXISTS `t1`;
CREATE TABLE `t1` (
`a` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
LOCK TABLES `t1` WRITE;
UNLOCK TABLES;
/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER ;;
/*!50003 SET SESSION SQL_MODE="IGNORE_SPACE" */;;
/*!50003 CREATE TRIGGER `tr1` BEFORE INSERT ON `t1` FOR EACH ROW BEGIN
SET new.a = 0;
END */;;
DELIMITER ;
/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
DROP TRIGGER tr1;
DROP TABLE t1;

View File

@ -179,8 +179,7 @@ a b c
2 two two
alter table t1 drop index c;
select * from t1 where b = 'two';
a b c
2 two two
ERROR HY000: Table definition has changed, please retry transaction
select * from t1 where b = 'two';
a b c
2 two two

View File

@ -0,0 +1,62 @@
create procedure empty()
begin
end;
show procedure code empty;
Pos Instruction
drop procedure empty;
create function almost_empty()
returns int
return 0;
show function code almost_empty;
Pos Instruction
0 freturn 3 0
drop function almost_empty;
create procedure code_sample(x int, out err int, out nulls int)
begin
declare count int default 0;
set nulls = 0;
begin
declare c cursor for select name from t1;
declare exit handler for not found close c;
open c;
loop
begin
declare n varchar(20);
declare continue handler for sqlexception set err=1;
fetch c into n;
if isnull(n) then
set nulls = nulls + 1;
else
set count = count + 1;
update t2 set idx = count where name=n;
end if;
end;
end loop;
end;
select t.name, t.idx from t2 t order by idx asc;
end//
show procedure code code_sample;
Pos Instruction
0 set count@3 0
1 set nulls@2 0
2 cpush c@0
3 hpush_jump 6 4 EXIT
4 cclose c@0
5 hreturn 0 19
6 copen c@0
7 set n@4 NULL
8 hpush_jump 11 5 CONTINUE
9 set err@1 1
10 hreturn 5
11 cfetch c@0 n@4
12 jump_if_not 15 isnull(n@4)
13 set nulls@2 (nulls@2 + 1)
14 jump 17
15 set count@3 (count@3 + 1)
16 stmt 4 "update t2 set idx = count where name=n"
17 hpop 1
18 jump 7
19 hpop 1
20 cpop 1
21 stmt 0 "select t.name, t.idx from t2 t order ..."
drop procedure code_sample;

View File

@ -33,6 +33,8 @@ begin
execute stmt;
end|
prepare stmt from "call p1()"|
set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth|
set @@max_sp_recursion_depth=100|
execute stmt|
ERROR HY000: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner
execute stmt|
@ -40,11 +42,18 @@ ERROR HY000: The prepared statement contains a stored routine call that refers t
execute stmt|
ERROR HY000: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner
call p1()|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner
call p1()|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner
call p1()|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: The prepared statement contains a stored routine call that refers to that same statement. It's not allowed to execute a prepared statement in such a recursive manner
set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS|
call p1()|
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1
call p1()|
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1
call p1()|
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine p1
drop procedure p1|
create procedure p1()
begin

View File

@ -708,7 +708,7 @@ return (i in (100, 200, bug11394(i-1), 400));
end if;
end|
select bug11394(2)|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: Recursive stored functions and triggers are not allowed.
drop function bug11394|
create function bug11394_1(i int) returns int
begin
@ -719,7 +719,7 @@ return (select bug11394_1(i-1));
end if;
end|
select bug11394_1(2)|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: Recursive stored functions and triggers are not allowed.
drop function bug11394_1|
create function bug11394_2(i int) returns int return i|
select bug11394_2(bug11394_2(10))|
@ -733,7 +733,10 @@ call bug11394(i - 1,(select 1));
end if;
end|
call bug11394(2, 1)|
ERROR HY000: Recursive stored routines are not allowed.
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug11394
set @@max_sp_recursion_depth=10|
call bug11394(2, 1)|
set @@max_sp_recursion_depth=default|
drop procedure bug11394|
CREATE PROCEDURE BUG_12490() HELP CONTENTS;
ERROR 0A000: HELP is not allowed in stored procedures

View File

@ -3417,6 +3417,9 @@ Table Create Table
tm1 CREATE TEMPORARY TABLE `tm1` (
`spv1` decimal(6,3) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop procedure bug12589_1|
drop procedure bug12589_2|
drop procedure bug12589_3|
drop table if exists t3|
drop procedure if exists bug7049_1|
drop procedure if exists bug7049_2|
@ -3667,4 +3670,203 @@ call bug14845()|
a
0
drop procedure bug14845|
drop procedure if exists bug13549_1|
drop procedure if exists bug13549_2|
CREATE PROCEDURE `bug13549_2`()
begin
call bug13549_1();
end|
CREATE PROCEDURE `bug13549_1`()
begin
declare done int default 0;
set done= not done;
end|
CALL bug13549_2()|
drop procedure bug13549_2|
drop procedure bug13549_1|
drop function if exists bug10100f|
drop procedure if exists bug10100p|
drop procedure if exists bug10100t|
drop procedure if exists bug10100pt|
drop procedure if exists bug10100pv|
drop procedure if exists bug10100pd|
drop procedure if exists bug10100pc|
create function bug10100f(prm int) returns int
begin
if prm > 1 then
return prm * bug10100f(prm - 1);
end if;
return 1;
end|
create procedure bug10100p(prm int, inout res int)
begin
set res = res * prm;
if prm > 1 then
call bug10100p(prm - 1, res);
end if;
end|
create procedure bug10100t(prm int)
begin
declare res int;
set res = 1;
call bug10100p(prm, res);
select res;
end|
create table t3 (a int)|
insert into t3 values (0)|
create view v1 as select a from t3;
create procedure bug10100pt(level int, lim int)
begin
if level < lim then
update t3 set a=level;
FLUSH TABLES;
call bug10100pt(level+1, lim);
else
select * from t3;
end if;
end|
create procedure bug10100pv(level int, lim int)
begin
if level < lim then
update v1 set a=level;
FLUSH TABLES;
call bug10100pv(level+1, lim);
else
select * from v1;
end if;
end|
prepare stmt2 from "select * from t3;";
create procedure bug10100pd(level int, lim int)
begin
if level < lim then
select level;
prepare stmt1 from "update t3 set a=a+2";
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
deallocate prepare stmt1;
execute stmt2;
select * from t3;
call bug10100pd(level+1, lim);
else
execute stmt2;
end if;
end|
create procedure bug10100pc(level int, lim int)
begin
declare lv int;
declare c cursor for select a from t3;
open c;
if level < lim then
select level;
fetch c into lv;
select lv;
update t3 set a=level+lv;
FLUSH TABLES;
call bug10100pc(level+1, lim);
else
select * from t3;
end if;
close c;
end|
set @@max_sp_recursion_depth=4|
select @@max_sp_recursion_depth|
@@max_sp_recursion_depth
4
select bug10100f(3)|
ERROR HY000: Recursive stored functions and triggers are not allowed.
select bug10100f(6)|
ERROR HY000: Recursive stored functions and triggers are not allowed.
call bug10100t(5)|
res
120
call bug10100pt(1,5)|
a
4
call bug10100pv(1,5)|
a
4
update t3 set a=1|
call bug10100pd(1,5)|
level
1
a
7
a
7
level
2
a
13
a
13
level
3
a
19
a
19
level
4
a
25
a
25
a
25
select * from t3|
a
25
update t3 set a=1|
call bug10100pc(1,5)|
level
1
lv
1
level
2
lv
2
level
3
lv
4
level
4
lv
7
a
11
select * from t3|
a
11
set @@max_sp_recursion_depth=0|
select @@max_sp_recursion_depth|
@@max_sp_recursion_depth
0
select bug10100f(5)|
ERROR HY000: Recursive stored functions and triggers are not allowed.
call bug10100t(5)|
ERROR HY000: Recursive limit 0 (as set by the max_sp_recursion_depth variable) was exceeded for routine bug10100p
set @@max_sp_recursion_depth=255|
set @var=1|
call bug10100p(255, @var)|
call bug10100pt(1,255)|
call bug10100pv(1,255)|
call bug10100pd(1,255)|
call bug10100pc(1,255)|
set @@max_sp_recursion_depth=0|
deallocate prepare stmt2|
drop function bug10100f|
drop procedure bug10100p|
drop procedure bug10100t|
drop procedure bug10100pt|
drop procedure bug10100pv|
drop procedure bug10100pd|
drop procedure bug10100pc|
drop view v1|
drop table t3|
drop table t1,t2;

View File

@ -174,3 +174,198 @@ ERROR HY000: Explicit or implicit commit is not allowed in stored function or tr
drop procedure bug10015_8|
drop function bug10015_7|
drop table t1, t2|
drop function if exists bug13825_0|
drop function if exists bug13825_1|
drop function if exists bug13825_2|
drop function if exists bug13825_3|
drop function if exists bug13825_4|
drop function if exists bug13825_5|
drop procedure if exists bug13825_0|
drop procedure if exists bug13825_1|
drop procedure if exists bug13825_2|
drop table if exists t1|
create table t1 (i int) engine=innodb|
create table t2 (i int) engine=innodb|
create function bug13825_0() returns int
begin
rollback to savepoint x;
return 1;
end|
create function bug13825_1() returns int
begin
release savepoint x;
return 1;
end|
create function bug13825_2() returns int
begin
insert into t1 values (2);
savepoint x;
insert into t1 values (3);
rollback to savepoint x;
insert into t1 values (4);
return 1;
end|
create procedure bug13825_0()
begin
rollback to savepoint x;
end|
create procedure bug13825_1()
begin
release savepoint x;
end|
create procedure bug13825_2()
begin
savepoint x;
end|
insert into t2 values (1)|
create trigger t2_bi before insert on t2 for each row
rollback to savepoint x|
create trigger t2_bu before update on t2 for each row
release savepoint x|
create trigger t2_bd before delete on t2 for each row
begin
insert into t1 values (2);
savepoint x;
insert into t1 values (3);
rollback to savepoint x;
insert into t1 values (4);
end|
create function bug13825_3(rb int) returns int
begin
insert into t1 values(1);
savepoint x;
insert into t1 values(2);
if rb then
rollback to savepoint x;
end if;
insert into t1 values(3);
return rb;
end|
create function bug13825_4() returns int
begin
savepoint x;
insert into t1 values(2);
rollback to savepoint x;
return 0;
end|
create function bug13825_5(p int) returns int
begin
savepoint x;
insert into t2 values(p);
rollback to savepoint x;
insert into t2 values(p+1);
return p;
end|
set autocommit= 0|
begin |
insert into t1 values (1)|
savepoint x|
set @a:= bug13825_0()|
ERROR 42000: SAVEPOINT x does not exist
insert into t2 values (2)|
ERROR 42000: SAVEPOINT x does not exist
set @a:= bug13825_1()|
ERROR 42000: SAVEPOINT x does not exist
update t2 set i = 2|
ERROR 42000: SAVEPOINT x does not exist
set @a:= bug13825_2()|
select * from t1|
i
1
2
4
rollback to savepoint x|
select * from t1|
i
1
delete from t2|
select * from t1|
i
1
2
4
rollback to savepoint x|
select * from t1|
i
1
release savepoint x|
set @a:= bug13825_2()|
select * from t1|
i
1
2
4
rollback to savepoint x|
ERROR 42000: SAVEPOINT x does not exist
delete from t1|
commit|
begin|
insert into t1 values (5)|
savepoint x|
insert into t1 values (6)|
call bug13825_0()|
select * from t1|
i
5
call bug13825_1()|
rollback to savepoint x|
ERROR 42000: SAVEPOINT x does not exist
savepoint x|
insert into t1 values (7)|
call bug13825_2()|
rollback to savepoint x|
select * from t1|
i
5
7
delete from t1|
commit|
set autocommit= 1|
select bug13825_3(0)|
bug13825_3(0)
0
select * from t1|
i
1
2
3
delete from t1|
select bug13825_3(1)|
bug13825_3(1)
1
select * from t1|
i
1
3
delete from t1|
set autocommit= 0|
begin|
insert into t1 values (1)|
set @a:= bug13825_4()|
select * from t1|
i
1
delete from t1|
commit|
set autocommit= 1|
drop table t2|
create table t2 (i int) engine=innodb|
insert into t1 values (1), (bug13825_5(2)), (3)|
select * from t1|
i
1
2
3
select * from t2|
i
3
drop function bug13825_0|
drop function bug13825_1|
drop function bug13825_2|
drop function bug13825_3|
drop function bug13825_4|
drop function bug13825_5|
drop procedure bug13825_0|
drop procedure bug13825_1|
drop procedure bug13825_2|
drop table t1, t2|

View File

@ -703,8 +703,11 @@ create trigger t1_ai after insert on t1
for each row insert into t2 values (new.f1+1);
create trigger t2_ai after insert on t2
for each row insert into t1 values (new.f2+1);
set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth;
set @@max_sp_recursion_depth=100;
insert into t1 values (1);
ERROR HY000: Can't update table 't1' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS;
select * from t1;
f1
1
@ -763,3 +766,17 @@ ERROR HY000: Table 't3' was not locked with LOCK TABLES
deallocate prepare stmt1;
drop procedure p1;
drop table t1, t2, t3;
create table t1 (a int);
drop procedure if exists p2;
CREATE PROCEDURE `p2`()
begin
insert into t1 values (1);
end//
create trigger trg before insert on t1 for each row
begin
declare done int default 0;
set done= not done;
end//
CALL p2();
drop procedure p2;
drop table t1;

View File

@ -111,3 +111,6 @@ select count(distinct s1) from t1;
count(distinct s1)
3
drop table t1;
select hex(cast(0x10 as binary(2)));
hex(cast(0x10 as binary(2)))
1000

View File

@ -351,6 +351,14 @@ set global rpl_recovery_rank=100;
set global server_id=100;
set global slow_launch_time=100;
set sort_buffer_size=100;
set @@max_sp_recursion_depth=10;
select @@max_sp_recursion_depth;
@@max_sp_recursion_depth
10
set @@max_sp_recursion_depth=0;
select @@max_sp_recursion_depth;
@@max_sp_recursion_depth
0
set sql_auto_is_null=1;
select @@sql_auto_is_null;
@@sql_auto_is_null

View File

@ -501,3 +501,20 @@ drop user test14256;
insert into mysql.user select * from t1;
flush privileges;
drop table t1;
create database mysqltest;
use mysqltest;
CREATE TABLE t1 (i INT);
CREATE VIEW v1 AS SELECT * FROM t1;
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1`
GRANT SELECT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost;
use mysqltest;
LOCK TABLES v1 READ;
SHOW CREATE TABLE v1;
ERROR 42000: SHOW VIEW command denied to user 'mysqltest_1'@'localhost' for table 'v1'
UNLOCK TABLES;
use test;
use test;
drop user mysqltest_1@localhost;
drop database mysqltest;

View File

@ -64,7 +64,7 @@ select
cast(_latin1'a ' AS char) as c2,
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
hex(cast(_latin1'a' AS char(2))) as c5;
select cast(1000 as CHAR(3));
create table t1 select
@ -73,7 +73,7 @@ create table t1 select
cast(_latin1'abc' AS char(2)) as c3,
cast(_latin1'a ' AS char(2)) as c4,
cast(_latin1'a' AS char(2)) as c5;
select * from t1;
select c1,c2,c3,c4,hex(c5) from t1;
show create table t1;
drop table t1;

View File

@ -999,3 +999,27 @@ drop view v2;
drop view v0;
drop view v1;
drop table t1;
#
# BUG#14554 - mysqldump does not separate words "ROW" and "BEGIN"
# for tables with trigger created in the IGNORE_SPACE sql mode.
#
SET @old_sql_mode = @@SQL_MODE;
SET SQL_MODE = IGNORE_SPACE;
CREATE TABLE t1 (a INT);
DELIMITER |;
CREATE TRIGGER tr1 BEFORE INSERT ON t1
FOR EACH ROW
BEGIN
SET new.a = 0;
END|
DELIMITER ;|
SET SQL_MODE = @old_sql_mode;
--exec $MYSQL_DUMP --skip-comments --databases test
DROP TRIGGER tr1;
DROP TABLE t1;

View File

@ -142,6 +142,7 @@ INSERT INTO t1 VALUES (1,2,0),(18,19,4),(20,21,0);
select c from t1 order by c;
drop table t1;
--disable_ps_protocol
create table t1 ( a int primary key, b varchar(10), c varchar(10), index (b) )
engine=ndb;
insert into t1 values (1,'one','one'), (2,'two','two'), (3,'three','three');
@ -151,10 +152,13 @@ select * from t1 where b = 'two';
connection server1;
alter table t1 drop index c;
connection server2;
# This should fail since index information is not automatically refreshed
--error 1412
select * from t1 where b = 'two';
select * from t1 where b = 'two';
connection server1;
drop table t1;
--enable_ps_protocol
#--disable_warnings
#DROP TABLE IF EXISTS t2;

49
mysql-test/t/sp-code.test Normal file
View File

@ -0,0 +1,49 @@
#
# Test the debugging feature "show procedure/function code <name>"
#
-- source include/is_debug_build.inc
create procedure empty()
begin
end;
show procedure code empty;
drop procedure empty;
create function almost_empty()
returns int
return 0;
show function code almost_empty;
drop function almost_empty;
delimiter //;
create procedure code_sample(x int, out err int, out nulls int)
begin
declare count int default 0;
set nulls = 0;
begin
declare c cursor for select name from t1;
declare exit handler for not found close c;
open c;
loop
begin
declare n varchar(20);
declare continue handler for sqlexception set err=1;
fetch c into n;
if isnull(n) then
set nulls = nulls + 1;
else
set count = count + 1;
update t2 set idx = count where name=n;
end if;
end;
end loop;
end;
select t.name, t.idx from t2 t order by idx asc;
end//
delimiter ;//
show procedure code code_sample;
drop procedure code_sample;

View File

@ -26,18 +26,29 @@ begin
execute stmt;
end|
prepare stmt from "call p1()"|
# Allow SP resursion to be show that it has not influence here
set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth|
set @@max_sp_recursion_depth=100|
--error ER_PS_NO_RECURSION
execute stmt|
--error ER_PS_NO_RECURSION
execute stmt|
--error ER_PS_NO_RECURSION
execute stmt|
--error ER_SP_NO_RECURSION
--error ER_PS_NO_RECURSION
call p1()|
--error ER_SP_NO_RECURSION
--error ER_PS_NO_RECURSION
call p1()|
--error ER_SP_NO_RECURSION
--error ER_PS_NO_RECURSION
call p1()|
set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS|
--error ER_SP_RECURSION_LIMIT
call p1()|
--error ER_SP_RECURSION_LIMIT
call p1()|
--error ER_SP_RECURSION_LIMIT
call p1()|
drop procedure p1|
#
# C. Create/drop a stored procedure in Dynamic SQL.

View File

@ -1044,10 +1044,11 @@ begin
call bug11394(i - 1,(select 1));
end if;
end|
# Again if we allow recursion for stored procedures (without
# additional efforts) the following statement will crash the server.
--error 1424
--error ER_SP_RECURSION_LIMIT
call bug11394(2, 1)|
set @@max_sp_recursion_depth=10|
call bug11394(2, 1)|
set @@max_sp_recursion_depth=default|
drop procedure bug11394|
delimiter ;|

View File

@ -4291,6 +4291,9 @@ call bug12589_1()|
# No warnings here
call bug12589_2()|
call bug12589_3()|
drop procedure bug12589_1|
drop procedure bug12589_2|
drop procedure bug12589_3|
#
# BUG#7049: Stored procedure CALL errors are ignored
@ -4594,6 +4597,185 @@ end|
call bug14845()|
drop procedure bug14845|
#
# BUG#13549 "Server crash with nested stored procedures".
# Server should not crash when during execution of stored procedure
# we have to parse trigger/function definition and this new trigger/
# function has more local variables declared than invoking stored
# procedure and last of these variables is used in argument of NOT
# operator.
#
--disable_warnings
drop procedure if exists bug13549_1|
drop procedure if exists bug13549_2|
--enable_warnings
CREATE PROCEDURE `bug13549_2`()
begin
call bug13549_1();
end|
CREATE PROCEDURE `bug13549_1`()
begin
declare done int default 0;
set done= not done;
end|
CALL bug13549_2()|
drop procedure bug13549_2|
drop procedure bug13549_1|
#
# BUG#10100: function (and stored procedure?) recursivity problem
#
--disable_warnings
drop function if exists bug10100f|
drop procedure if exists bug10100p|
drop procedure if exists bug10100t|
drop procedure if exists bug10100pt|
drop procedure if exists bug10100pv|
drop procedure if exists bug10100pd|
drop procedure if exists bug10100pc|
--enable_warnings
# routines with simple recursion
create function bug10100f(prm int) returns int
begin
if prm > 1 then
return prm * bug10100f(prm - 1);
end if;
return 1;
end|
create procedure bug10100p(prm int, inout res int)
begin
set res = res * prm;
if prm > 1 then
call bug10100p(prm - 1, res);
end if;
end|
create procedure bug10100t(prm int)
begin
declare res int;
set res = 1;
call bug10100p(prm, res);
select res;
end|
# a procedure which use tables and recursion
create table t3 (a int)|
insert into t3 values (0)|
create view v1 as select a from t3;
create procedure bug10100pt(level int, lim int)
begin
if level < lim then
update t3 set a=level;
FLUSH TABLES;
call bug10100pt(level+1, lim);
else
select * from t3;
end if;
end|
# view & recursion
create procedure bug10100pv(level int, lim int)
begin
if level < lim then
update v1 set a=level;
FLUSH TABLES;
call bug10100pv(level+1, lim);
else
select * from v1;
end if;
end|
# dynamic sql & recursion
prepare stmt2 from "select * from t3;";
create procedure bug10100pd(level int, lim int)
begin
if level < lim then
select level;
prepare stmt1 from "update t3 set a=a+2";
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
execute stmt1;
FLUSH TABLES;
deallocate prepare stmt1;
execute stmt2;
select * from t3;
call bug10100pd(level+1, lim);
else
execute stmt2;
end if;
end|
# cursor & recursion
create procedure bug10100pc(level int, lim int)
begin
declare lv int;
declare c cursor for select a from t3;
open c;
if level < lim then
select level;
fetch c into lv;
select lv;
update t3 set a=level+lv;
FLUSH TABLES;
call bug10100pc(level+1, lim);
else
select * from t3;
end if;
close c;
end|
set @@max_sp_recursion_depth=4|
select @@max_sp_recursion_depth|
-- error ER_SP_NO_RECURSION
select bug10100f(3)|
-- error ER_SP_NO_RECURSION
select bug10100f(6)|
call bug10100t(5)|
call bug10100pt(1,5)|
call bug10100pv(1,5)|
update t3 set a=1|
call bug10100pd(1,5)|
select * from t3|
update t3 set a=1|
call bug10100pc(1,5)|
select * from t3|
set @@max_sp_recursion_depth=0|
select @@max_sp_recursion_depth|
-- error ER_SP_NO_RECURSION
select bug10100f(5)|
-- error ER_SP_RECURSION_LIMIT
call bug10100t(5)|
#end of the stack checking
set @@max_sp_recursion_depth=255|
set @var=1|
#disable log because error about stack overrun contains numbers which
#depend on a system
-- disable_result_log
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100p(255, @var)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pt(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pv(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pd(1,255)|
-- error ER_STACK_OVERRUN_NEED_MORE
call bug10100pc(1,255)|
-- enable_result_log
set @@max_sp_recursion_depth=0|
deallocate prepare stmt2|
drop function bug10100f|
drop procedure bug10100p|
drop procedure bug10100t|
drop procedure bug10100pt|
drop procedure bug10100pv|
drop procedure bug10100pd|
drop procedure bug10100pc|
drop view v1|
drop table t3|
#
# BUG#NNNN: New bug synopsis
#

View File

@ -175,6 +175,186 @@ drop function bug10015_7|
drop table t1, t2|
#
# BUG#13825 "Triggers: crash if release savepoint".
# Also general test for handling of savepoints in stored routines.
#
# According to SQL standard we should establish new savepoint
# level before executing stored function/trigger and destroy
# this savepoint level after execution. Stored procedures by
# default should be executed using the same savepoint level
# as their caller (to execute stored procedure using new
# savepoint level one should explicitly specify NEW SAVEPOINT
# LEVEL clause in procedure creation statement which MySQL
# does not support yet).
--disable_warnings
drop function if exists bug13825_0|
drop function if exists bug13825_1|
drop function if exists bug13825_2|
drop function if exists bug13825_3|
drop function if exists bug13825_4|
drop function if exists bug13825_5|
drop procedure if exists bug13825_0|
drop procedure if exists bug13825_1|
drop procedure if exists bug13825_2|
drop table if exists t1|
--enable_warnings
create table t1 (i int) engine=innodb|
create table t2 (i int) engine=innodb|
create function bug13825_0() returns int
begin
rollback to savepoint x;
return 1;
end|
create function bug13825_1() returns int
begin
release savepoint x;
return 1;
end|
create function bug13825_2() returns int
begin
insert into t1 values (2);
savepoint x;
insert into t1 values (3);
rollback to savepoint x;
insert into t1 values (4);
return 1;
end|
create procedure bug13825_0()
begin
rollback to savepoint x;
end|
create procedure bug13825_1()
begin
release savepoint x;
end|
create procedure bug13825_2()
begin
savepoint x;
end|
insert into t2 values (1)|
create trigger t2_bi before insert on t2 for each row
rollback to savepoint x|
create trigger t2_bu before update on t2 for each row
release savepoint x|
create trigger t2_bd before delete on t2 for each row
begin
insert into t1 values (2);
savepoint x;
insert into t1 values (3);
rollback to savepoint x;
insert into t1 values (4);
end|
create function bug13825_3(rb int) returns int
begin
insert into t1 values(1);
savepoint x;
insert into t1 values(2);
if rb then
rollback to savepoint x;
end if;
insert into t1 values(3);
return rb;
end|
create function bug13825_4() returns int
begin
savepoint x;
insert into t1 values(2);
rollback to savepoint x;
return 0;
end|
create function bug13825_5(p int) returns int
begin
savepoint x;
insert into t2 values(p);
rollback to savepoint x;
insert into t2 values(p+1);
return p;
end|
set autocommit= 0|
# Test of savepoint level handling for stored functions and triggers
begin |
insert into t1 values (1)|
savepoint x|
--error ER_SP_DOES_NOT_EXIST
set @a:= bug13825_0()|
--error ER_SP_DOES_NOT_EXIST
insert into t2 values (2)|
--error ER_SP_DOES_NOT_EXIST
set @a:= bug13825_1()|
--error ER_SP_DOES_NOT_EXIST
update t2 set i = 2|
set @a:= bug13825_2()|
select * from t1|
rollback to savepoint x|
select * from t1|
delete from t2|
select * from t1|
rollback to savepoint x|
select * from t1|
# Of course savepoints set in function should not be visible from its caller
release savepoint x|
set @a:= bug13825_2()|
select * from t1|
--error ER_SP_DOES_NOT_EXIST
rollback to savepoint x|
delete from t1|
commit|
# Test of savepoint level handling for stored procedures
begin|
insert into t1 values (5)|
savepoint x|
insert into t1 values (6)|
call bug13825_0()|
select * from t1|
call bug13825_1()|
--error ER_SP_DOES_NOT_EXIST
rollback to savepoint x|
savepoint x|
insert into t1 values (7)|
call bug13825_2()|
rollback to savepoint x|
select * from t1|
delete from t1|
commit|
set autocommit= 1|
# Let us test that savepoints work inside of functions
# even in auto-commit mode
select bug13825_3(0)|
select * from t1|
delete from t1|
select bug13825_3(1)|
select * from t1|
delete from t1|
# Curious case: rolling back to savepoint which is set by first
# statement in function should not rollback whole transaction.
set autocommit= 0|
begin|
insert into t1 values (1)|
set @a:= bug13825_4()|
select * from t1|
delete from t1|
commit|
set autocommit= 1|
# Other curious case: savepoint in the middle of statement
drop table t2|
create table t2 (i int) engine=innodb|
insert into t1 values (1), (bug13825_5(2)), (3)|
select * from t1|
select * from t2|
# Cleanup
drop function bug13825_0|
drop function bug13825_1|
drop function bug13825_2|
drop function bug13825_3|
drop function bug13825_4|
drop function bug13825_5|
drop procedure bug13825_0|
drop procedure bug13825_1|
drop procedure bug13825_2|
drop table t1, t2|
#
# BUG#NNNN: New bug synopsis
#

View File

@ -743,8 +743,12 @@ create trigger t1_ai after insert on t1
for each row insert into t2 values (new.f1+1);
create trigger t2_ai after insert on t2
for each row insert into t1 values (new.f2+1);
# Allow SP resursion to be show that it has not influence here
set @SAVE_SP_RECURSION_LEVELS=@@max_sp_recursion_depth;
set @@max_sp_recursion_depth=100;
--error ER_CANT_UPDATE_USED_TABLE_IN_SF_OR_TRG
insert into t1 values (1);
set @@max_sp_recursion_depth=@SAVE_SP_RECURSION_LEVELS;
select * from t1;
select * from t2;
drop trigger t1_ai;
@ -914,3 +918,31 @@ call p1();
deallocate prepare stmt1;
drop procedure p1;
drop table t1, t2, t3;
#
# BUG#13549 "Server crash with nested stored procedures".
# Server should not crash when during execution of stored procedure
# we have to parse trigger/function definition and this new trigger/
# function has more local variables declared than invoking stored
# procedure and last of these variables is used in argument of NOT
# operator.
#
create table t1 (a int);
--disable_warnings
drop procedure if exists p2;
--enable_warnings
DELIMITER //;
CREATE PROCEDURE `p2`()
begin
insert into t1 values (1);
end//
create trigger trg before insert on t1 for each row
begin
declare done int default 0;
set done= not done;
end//
DELIMITER ;//
CALL p2();
drop procedure p2;
drop table t1;

View File

@ -65,3 +65,6 @@ select hex(s1) from t1 where s1=0x0120;
select hex(s1) from t1 where s1=0x0100;
select count(distinct s1) from t1;
drop table t1;
# check that cast appends trailing zeros
select hex(cast(0x10 as binary(2)));

View File

@ -237,6 +237,10 @@ set global rpl_recovery_rank=100;
set global server_id=100;
set global slow_launch_time=100;
set sort_buffer_size=100;
set @@max_sp_recursion_depth=10;
select @@max_sp_recursion_depth;
set @@max_sp_recursion_depth=0;
select @@max_sp_recursion_depth;
set sql_auto_is_null=1;
select @@sql_auto_is_null;
set @@sql_auto_is_null=0;

View File

@ -664,3 +664,39 @@ insert into mysql.user select * from t1;
flush privileges;
drop table t1;
#
# BUG#14726: freeing stack variable in case of an error of opening
# a view when we have locked tables with LOCK TABLES statement.
#
connection root;
--disable_warnings
create database mysqltest;
--enable_warnings
use mysqltest;
CREATE TABLE t1 (i INT);
CREATE VIEW v1 AS SELECT * FROM t1;
SHOW CREATE VIEW v1;
GRANT SELECT, LOCK TABLES ON mysqltest.* TO mysqltest_1@localhost;
connection user1;
use mysqltest;
LOCK TABLES v1 READ;
-- error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE v1;
UNLOCK TABLES;
use test;
connection root;
use test;
drop user mysqltest_1@localhost;
drop database mysqltest;
#
# switch to default connaction
#
disconnect user1;
disconnect root;
connection default;

View File

@ -40,10 +40,10 @@ netware_build_files = client/mysql.def client/mysqladmin.def \
link_sources:
set -x; \
for f in $(netware_build_files); do \
rm -f $(srcdir)/../$$f; \
rm -f ../$$f; \
org=`echo $$f | sed -e 's/.*\/\(.*\)/\1/g'`; \
@LN_CP_F@ $(srcdir)/$$org $(srcdir)/../$$f; \
done;
@LN_CP_F@ $(srcdir)/$$org ../$$f; \
done
else
EXTRA_DIST= comp_err.def init_db.sql install_test_db.ncf \
libmysql.def libmysql.imp \

View File

@ -1173,6 +1173,9 @@ void setup(char *file)
setenv("MYSQL",file_path,1);
snprintf(file_path, PATH_MAX*2, "%s/mysqlshow --no-defaults --user=root --port=%u", bin_dir, master_port);
setenv("MYSQL_SHOW",file_path,1);
snprintf(file_path, PATH_MAX*2, "%s/mysqlcheck --no-defaults -uroot --port=%u", bin_dir, master_port);
setenv("MYSQL_CHECK",file_path,1);
}
/******************************************************************************

View File

@ -20,7 +20,7 @@
#
SUBDIRS = aout
INCLUDES = -I$(top_srcdir)/include
INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_HEADERS = bucomm.h debug.h ieee.h budbg.h demangle.h \
linuxthreads.h pstack.h pstacktrace.h
SRC= bucomm.c filemode.c linuxthreads.c rddbg.c \

View File

@ -83,9 +83,10 @@ CLEANFILES = @server_scripts@ \
mysql_find_rows \
mysqlhotcopy \
mysqldumpslow \
mysql_explain_log \
mysql_tableinfo \
mysqld_multi \
make_win_src_distribution \
make_win_binary_distribution \
mysql_create_system_tables
DISTCLEANFILES = mysqlbug

View File

@ -53,12 +53,12 @@ libnet_a_LIBADD= $(top_builddir)/sql/password.$(OBJEXT) \
CLEANFILES= net_serv.cc client_settings.h
net_serv.cc:
rm -f $(srcdir)/net_serv.cc
@LN_CP_F@ $(top_srcdir)/sql/net_serv.cc $(srcdir)/net_serv.cc
rm -f net_serv.cc
@LN_CP_F@ $(top_srcdir)/sql/net_serv.cc net_serv.cc
client_settings.h:
rm -f $(srcdir)/client_settings.h
@LN_CP_F@ $(top_srcdir)/sql/client_settings.h $(srcdir)/client_settings.h
rm -f client_settings.h
@LN_CP_F@ $(top_srcdir)/sql/client_settings.h client_settings.h
libexec_PROGRAMS= mysqlmanager

View File

@ -60,6 +60,8 @@ install-data-local:
for i in $(srcdir)/limits/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/limits; done
for i in $(srcdir)/Comments/*.* ; do $(INSTALL_DATA) $$i $(DESTDIR)$(benchdir)/Comments; done
uninstall-local:
@RM@ -f -r $(DESTDIR)$(benchdir)
SUFFIXES = .sh

View File

@ -124,17 +124,17 @@ AM_YFLAGS = -d
mysql_tzinfo_to_sql.cc:
rm -f mysql_tzinfo_to_sql.cc
@LN_CP_F@ tztime.cc mysql_tzinfo_to_sql.cc
@LN_CP_F@ $(srcdir)/tztime.cc mysql_tzinfo_to_sql.cc
link_sources: mysql_tzinfo_to_sql.cc
rm -f mini_client_errors.c
@LN_CP_F@ ../libmysql/errmsg.c mini_client_errors.c
@LN_CP_F@ $(top_srcdir)/libmysql/errmsg.c mini_client_errors.c
rm -f pack.c
@LN_CP_F@ ../sql-common/pack.c pack.c
@LN_CP_F@ $(top_srcdir)/sql-common/pack.c pack.c
rm -f client.c
@LN_CP_F@ ../sql-common/client.c client.c
@LN_CP_F@ $(top_srcdir)/sql-common/client.c client.c
rm -f my_time.c
@LN_CP_F@ ../sql-common/my_time.c my_time.c
@LN_CP_F@ $(top_srcdir)/sql-common/my_time.c my_time.c
mysql_tzinfo_to_sql.o: $(mysql_tzinfo_to_sql_SOURCES)
$(CXXCOMPILE) -c $(INCLUDES) -DTZINFO2SQL $<

View File

@ -1274,9 +1274,9 @@ my_decimal *Field::val_decimal(my_decimal *decimal)
void Field_num::add_zerofill_and_unsigned(String &res) const
{
if (unsigned_flag)
res.append(" unsigned");
res.append(STRING_WITH_LEN(" unsigned"));
if (zerofill)
res.append(" zerofill");
res.append(STRING_WITH_LEN(" zerofill"));
}
@ -1657,7 +1657,7 @@ bool Field::needs_quotes(void)
void Field_null::sql_type(String &res) const
{
res.set_ascii("null", 4);
res.set_ascii(STRING_WITH_LEN("null"));
}
@ -1669,7 +1669,7 @@ void Field_null::sql_type(String &res) const
void
Field_decimal::reset(void)
{
Field_decimal::store("0",1,&my_charset_bin);
Field_decimal::store(STRING_WITH_LEN("0"),&my_charset_bin);
}
void Field_decimal::overflow(bool negative)
@ -4115,7 +4115,7 @@ void Field_float::sql_type(String &res) const
{
if (dec == NOT_FIXED_DEC)
{
res.set_ascii("float", 5);
res.set_ascii(STRING_WITH_LEN("float"));
}
else
{
@ -4386,7 +4386,7 @@ void Field_double::sql_type(String &res) const
CHARSET_INFO *cs=res.charset();
if (dec == NOT_FIXED_DEC)
{
res.set_ascii("double",6);
res.set_ascii(STRING_WITH_LEN("double"));
}
else
{
@ -4675,7 +4675,7 @@ String *Field_timestamp::val_str(String *val_buffer, String *val_ptr)
if (temp == 0L)
{ /* Zero time is "000000" */
val_ptr->set("0000-00-00 00:00:00", 19, &my_charset_bin);
val_ptr->set(STRING_WITH_LEN("0000-00-00 00:00:00"), &my_charset_bin);
return val_ptr;
}
val_buffer->set_charset(&my_charset_bin); // Safety
@ -4807,7 +4807,7 @@ void Field_timestamp::sort_string(char *to,uint length __attribute__((unused)))
void Field_timestamp::sql_type(String &res) const
{
res.set_ascii("timestamp", 9);
res.set_ascii(STRING_WITH_LEN("timestamp"));
}
@ -5076,7 +5076,7 @@ void Field_time::sort_string(char *to,uint length __attribute__((unused)))
void Field_time::sql_type(String &res) const
{
res.set_ascii("time", 4);
res.set_ascii(STRING_WITH_LEN("time"));
}
/****************************************************************************
@ -5383,7 +5383,7 @@ void Field_date::sort_string(char *to,uint length __attribute__((unused)))
void Field_date::sql_type(String &res) const
{
res.set_ascii("date", 4);
res.set_ascii(STRING_WITH_LEN("date"));
}
@ -5566,7 +5566,7 @@ void Field_newdate::sort_string(char *to,uint length __attribute__((unused)))
void Field_newdate::sql_type(String &res) const
{
res.set_ascii("date", 4);
res.set_ascii(STRING_WITH_LEN("date"));
}
@ -5840,7 +5840,7 @@ void Field_datetime::sort_string(char *to,uint length __attribute__((unused)))
void Field_datetime::sql_type(String &res) const
{
res.set_ascii("datetime", 8);
res.set_ascii(STRING_WITH_LEN("datetime"));
}
/****************************************************************************
@ -6083,7 +6083,7 @@ void Field_string::sql_type(String &res) const
res.length(length);
if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
has_charset() && (charset()->state & MY_CS_BINSORT))
res.append(" binary");
res.append(STRING_WITH_LEN(" binary"));
}
@ -6216,6 +6216,8 @@ uint Field_string::max_packed_col_length(uint max_length)
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
{
Field *new_field;
if (type() != MYSQL_TYPE_VAR_STRING || table == new_table)
return Field::new_field(root, new_table);
@ -6224,15 +6226,16 @@ Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table)
This is done to ensure that ALTER TABLE will convert old VARCHAR fields
to now VARCHAR fields.
*/
Field *new_field= new Field_varstring(field_length, maybe_null(),
field_name, new_table,
charset());
/*
delayed_insert::get_local_table() needs a ptr copied from old table.
This is what other new_field() methods do too. The above method of
Field_varstring sets ptr to NULL.
*/
new_field->ptr= ptr;
if (new_field= new Field_varstring(field_length, maybe_null(),
field_name, new_table, charset()))
{
/*
delayed_insert::get_local_table() needs a ptr copied from old table.
This is what other new_field() methods do too. The above method of
Field_varstring sets ptr to NULL.
*/
new_field->ptr= ptr;
}
return new_field;
}
@ -6479,7 +6482,7 @@ void Field_varstring::sql_type(String &res) const
res.length(length);
if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
has_charset() && (charset()->state & MY_CS_BINSORT))
res.append(" binary");
res.append(STRING_WITH_LEN(" binary"));
}
@ -7218,10 +7221,10 @@ void Field_blob::sql_type(String &res) const
}
res.set_ascii(str,length);
if (charset() == &my_charset_bin)
res.append("blob");
res.append(STRING_WITH_LEN("blob"));
else
{
res.append("text");
res.append(STRING_WITH_LEN("text"));
}
}
@ -7441,28 +7444,28 @@ void Field_geom::sql_type(String &res) const
switch (geom_type)
{
case GEOM_POINT:
res.set("point", 5, cs);
res.set(STRING_WITH_LEN("point"), cs);
break;
case GEOM_LINESTRING:
res.set("linestring", 10, cs);
res.set(STRING_WITH_LEN("linestring"), cs);
break;
case GEOM_POLYGON:
res.set("polygon", 7, cs);
res.set(STRING_WITH_LEN("polygon"), cs);
break;
case GEOM_MULTIPOINT:
res.set("multipoint", 10, cs);
res.set(STRING_WITH_LEN("multipoint"), cs);
break;
case GEOM_MULTILINESTRING:
res.set("multilinestring", 15, cs);
res.set(STRING_WITH_LEN("multilinestring"), cs);
break;
case GEOM_MULTIPOLYGON:
res.set("multipolygon", 12, cs);
res.set(STRING_WITH_LEN("multipolygon"), cs);
break;
case GEOM_GEOMETRYCOLLECTION:
res.set("geometrycollection", 18, cs);
res.set(STRING_WITH_LEN("geometrycollection"), cs);
break;
default:
res.set("geometry", 8, cs);
res.set(STRING_WITH_LEN("geometry"), cs);
}
}
@ -7739,7 +7742,7 @@ void Field_enum::sql_type(String &res) const
String enum_item(buffer, sizeof(buffer), res.charset());
res.length(0);
res.append("enum(");
res.append(STRING_WITH_LEN("enum("));
bool flag=0;
uint *len= typelib->type_lengths;
@ -7853,7 +7856,7 @@ void Field_set::sql_type(String &res) const
String set_item(buffer, sizeof(buffer), res.charset());
res.length(0);
res.append("set(");
res.append(STRING_WITH_LEN("set("));
bool flag=0;
uint *len= typelib->type_lengths;

View File

@ -2612,7 +2612,7 @@ int ha_federated::stash_remote_error()
{
DBUG_ENTER("ha_federated::stash_remote_error()");
remote_error_number= mysql_errno(mysql);
my_snprintf(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE,
my_snprintf(remote_error_buf, sizeof(remote_error_buf), "%s",
mysql_error(mysql));
DBUG_RETURN(HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM);
}
@ -2624,10 +2624,10 @@ bool ha_federated::get_error_message(int error, String* buf)
DBUG_PRINT("enter", ("error: %d", error));
if (error == HA_FEDERATED_ERROR_WITH_REMOTE_SYSTEM)
{
buf->append("Error on remote system: ");
buf->append(STRING_WITH_LEN("Error on remote system: "));
buf->qs_append(remote_error_number);
buf->append(": ");
buf->append(remote_error_buf, FEDERATED_QUERY_BUFFER_SIZE);
buf->append(STRING_WITH_LEN(": "));
buf->append(remote_error_buf);
remote_error_number= 0;
remote_error_buf[0]= '\0';

View File

@ -2219,11 +2219,13 @@ innobase_savepoint(
DBUG_ENTER("innobase_savepoint");
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* In the autocommit state there is no sense to set a
savepoint: we return immediate success */
DBUG_RETURN(0);
}
/*
In the autocommit mode there is no sense to set a savepoint
(unless we are in sub-statement), so SQL layer ensures that
this method is never called in such situation.
*/
DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
thd->in_sub_stmt);
trx = check_trx_exists(thd);

View File

@ -506,10 +506,10 @@ void ha_myisammrg::append_create_info(String *packet)
if (file->merge_insert_method != MERGE_INSERT_DISABLED)
{
packet->append(" INSERT_METHOD=",15);
packet->append(STRING_WITH_LEN(" INSERT_METHOD="));
packet->append(get_type(&merge_insert_method,file->merge_insert_method-1));
}
packet->append(" UNION=(",8);
packet->append(STRING_WITH_LEN(" UNION=("));
MYRG_TABLE *open_table,*first;
current_db= table->s->db;

View File

@ -101,6 +101,8 @@ static handler *ndbcluster_create_handler(TABLE *table)
#define NDB_FAILED_AUTO_INCREMENT ~(Uint64)0
#define NDB_AUTO_INCREMENT_RETRIES 10
#define NDB_INVALID_SCHEMA_OBJECT 241
#define ERR_PRINT(err) \
DBUG_PRINT("error", ("%d message: %s", err.code, err.message))
@ -368,7 +370,21 @@ Thd_ndb::Thd_ndb()
Thd_ndb::~Thd_ndb()
{
if (ndb)
{
#ifndef DBUG_OFF
Ndb::Free_list_usage tmp; tmp.m_name= 0;
while (ndb->get_free_list_usage(&tmp))
{
uint leaked= (uint) tmp.m_created - tmp.m_free;
if (leaked)
fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n",
leaked, tmp.m_name,
(leaked == 1)?"":"'s",
(leaked == 1)?"has":"have");
}
#endif
delete ndb;
}
ndb= NULL;
changed_tables.empty();
}
@ -3415,15 +3431,18 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
DBUG_PRINT("info", ("Table schema version: %d",
tab->getObjectVersion()));
}
if (m_table != (void *)tab || m_table_version < tab->getObjectVersion())
if (m_table != (void *)tab)
{
/*
The table has been altered, refresh the index list
*/
build_index_list(ndb, table, ILBP_OPEN);
m_table= (void *)tab;
m_table_version = tab->getObjectVersion();
}
else if (m_table_version < tab->getObjectVersion())
{
/*
The table has been altered, caller has to retry
*/
DBUG_RETURN(my_errno= HA_ERR_TABLE_DEF_CHANGED);
}
m_table_info= tab_info;
}
no_uncommitted_rows_init(thd);
@ -5118,7 +5137,21 @@ int ndbcluster_end(ha_panic_function type)
(void) pthread_mutex_unlock(&LOCK_ndb_util_thread);
if (g_ndb)
{
#ifndef DBUG_OFF
Ndb::Free_list_usage tmp; tmp.m_name= 0;
while (g_ndb->get_free_list_usage(&tmp))
{
uint leaked= (uint) tmp.m_created - tmp.m_free;
if (leaked)
fprintf(stderr, "NDB: Found %u %s%s that %s not been released\n",
leaked, tmp.m_name,
(leaked == 1)?"":"'s",
(leaked == 1)?"has":"have");
}
#endif
delete g_ndb;
}
g_ndb= NULL;
if (g_ndb_cluster_connection)
delete g_ndb_cluster_connection;

View File

@ -1026,10 +1026,10 @@ int ha_update_statistics()
int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
THD_TRANS *trans=&thd->transaction.all;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_rollback_to_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
trans->nht=sv->nht;
trans->no_2pc=0;
@ -1057,7 +1057,7 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
for (; *ht ; ht++)
{
int err;
if ((err= (*(*ht)->rollback)(thd, 1)))
if ((err= (*(*ht)->rollback)(thd, !thd->in_sub_stmt)))
{ // cannot happen
my_error(ER_ERROR_DURING_ROLLBACK, MYF(0), err);
error=1;
@ -1077,10 +1077,10 @@ int ha_rollback_to_savepoint(THD *thd, SAVEPOINT *sv)
int ha_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
THD_TRANS *trans=&thd->transaction.all;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht;
DBUG_ENTER("ha_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
#ifdef USING_TRANSACTIONS
for (; *ht; ht++)
{
@ -1106,9 +1106,10 @@ int ha_savepoint(THD *thd, SAVEPOINT *sv)
int ha_release_savepoint(THD *thd, SAVEPOINT *sv)
{
int error=0;
handlerton **ht=thd->transaction.all.ht, **end_ht;
THD_TRANS *trans= (thd->in_sub_stmt ? &thd->transaction.stmt :
&thd->transaction.all);
handlerton **ht=trans->ht, **end_ht;
DBUG_ENTER("ha_release_savepoint");
DBUG_ASSERT(thd->transaction.stmt.ht[0] == 0);
end_ht=ht+sv->nht;
for (; ht < end_ht; ht++)
@ -1680,7 +1681,7 @@ void handler::print_error(int error, myf errflag)
if (str.length() >= max_length)
{
str.length(max_length-4);
str.append("...");
str.append(STRING_WITH_LEN("..."));
}
my_error(ER_DUP_ENTRY, MYF(0), str.c_ptr(), key_nr+1);
DBUG_VOID_RETURN;

View File

@ -383,7 +383,7 @@ void Item::print_item_w_name(String *str)
if (name)
{
THD *thd= current_thd;
str->append(" AS ", 4);
str->append(STRING_WITH_LEN(" AS "));
append_identifier(thd, str, name, (uint) strlen(name));
}
}
@ -894,6 +894,7 @@ bool Item_splocal::is_null()
Item *
Item_splocal::this_item()
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item(m_offset);
}
@ -901,12 +902,14 @@ Item_splocal::this_item()
Item **
Item_splocal::this_item_addr(THD *thd, Item **addr)
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item_addr(m_offset);
}
Item *
Item_splocal::this_const_item() const
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item(m_offset);
}
@ -914,7 +917,10 @@ Item::Type
Item_splocal::type() const
{
if (thd && thd->spcont)
{
DBUG_ASSERT(owner == thd->spcont->owner);
return thd->spcont->get_item(m_offset)->type();
}
return NULL_ITEM; // Anything but SUBSELECT_ITEM
}
@ -1031,7 +1037,7 @@ void Item_name_const::cleanup()
void Item_name_const::print(String *str)
{
str->append("NAME_CONST(");
str->append(STRING_WITH_LEN("NAME_CONST("));
name_item->print(str);
str->append(',');
value_item->print(str);
@ -4857,7 +4863,7 @@ void Item_ref::make_field(Send_field *field)
void Item_ref_null_helper::print(String *str)
{
str->append("<ref_null_helper>(", 18);
str->append(STRING_WITH_LEN("<ref_null_helper>("));
if (ref)
(*ref)->print(str);
else
@ -4983,7 +4989,7 @@ bool Item_direct_view_ref::eq(const Item *item, bool binary_cmp) const
void Item_null_helper::print(String *str)
{
str->append("<null_helper>(", 14);
str->append(STRING_WITH_LEN("<null_helper>("));
store->print(str);
str->append(')');
}
@ -5043,10 +5049,10 @@ void Item_default_value::print(String *str)
{
if (!arg)
{
str->append("default", 7);
str->append(STRING_WITH_LEN("default"));
return;
}
str->append("default(", 8);
str->append(STRING_WITH_LEN("default("));
arg->print(str);
str->append(')');
}
@ -5140,7 +5146,7 @@ bool Item_insert_value::fix_fields(THD *thd, Item **items)
void Item_insert_value::print(String *str)
{
str->append("values(", 7);
str->append(STRING_WITH_LEN("values("));
arg->print(str);
str->append(')');
}
@ -5401,7 +5407,7 @@ Item_cache* Item_cache::get_cache(Item_result type)
void Item_cache::print(String *str)
{
str->append("<cache>(", 8);
str->append(STRING_WITH_LEN("<cache>("));
if (example)
example->print(str);
else

View File

@ -704,6 +704,8 @@ public:
};
class sp_head;
/*
A reference to local SP variable (incl. reference to SP parameter), used in
runtime.
@ -721,6 +723,13 @@ class Item_splocal : public Item
uint m_offset;
public:
#ifndef DBUG_OFF
/*
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
sp_head *owner;
#endif
LEX_STRING m_name;
THD *thd;
@ -1055,7 +1064,7 @@ public:
bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; }
void print(String *str) { str->append("NULL", 4); }
void print(String *str) { str->append(STRING_WITH_LEN("NULL")); }
Item *safe_charset_converter(CHARSET_INFO *tocs);
};

View File

@ -1175,10 +1175,10 @@ void Item_func_between::print(String *str)
str->append('(');
args[0]->print(str);
if (negated)
str->append(" not", 4);
str->append(" between ", 9);
str->append(STRING_WITH_LEN(" not"));
str->append(STRING_WITH_LEN(" between "));
args[1]->print(str);
str->append(" and ", 5);
str->append(STRING_WITH_LEN(" and "));
args[2]->print(str);
str->append(')');
}
@ -1793,7 +1793,7 @@ uint Item_func_case::decimal_precision() const
void Item_func_case::print(String *str)
{
str->append("(case ", 6);
str->append(STRING_WITH_LEN("(case "));
if (first_expr_num != -1)
{
args[first_expr_num]->print(str);
@ -1801,19 +1801,19 @@ void Item_func_case::print(String *str)
}
for (uint i=0 ; i < ncases ; i+=2)
{
str->append("when ", 5);
str->append(STRING_WITH_LEN("when "));
args[i]->print(str);
str->append(" then ", 6);
str->append(STRING_WITH_LEN(" then "));
args[i+1]->print(str);
str->append(' ');
}
if (else_expr_num != -1)
{
str->append("else ", 5);
str->append(STRING_WITH_LEN("else "));
args[else_expr_num]->print(str);
str->append(' ');
}
str->append("end)", 4);
str->append(STRING_WITH_LEN("end)"));
}
/*
@ -2419,10 +2419,10 @@ void Item_func_in::print(String *str)
str->append('(');
args[0]->print(str);
if (negated)
str->append(" not", 4);
str->append(" in (", 5);
str->append(STRING_WITH_LEN(" not"));
str->append(STRING_WITH_LEN(" in ("));
print_args(str, 1);
str->append("))", 2);
str->append(STRING_WITH_LEN("))"));
}
@ -2894,7 +2894,7 @@ void Item_func_isnotnull::print(String *str)
{
str->append('(');
args[0]->print(str);
str->append(" is not null)", 13);
str->append(STRING_WITH_LEN(" is not null)"));
}

View File

@ -794,9 +794,9 @@ my_decimal *Item_func_numhybrid::val_decimal(my_decimal *decimal_value)
void Item_func_signed::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as signed)", 11);
str->append(STRING_WITH_LEN(" as signed)"));
}
@ -855,9 +855,9 @@ longlong Item_func_signed::val_int()
void Item_func_unsigned::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as unsigned)", 13);
str->append(STRING_WITH_LEN(" as unsigned)"));
}
@ -927,9 +927,9 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
void Item_decimal_typecast::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as decimal)", 12);
str->append(STRING_WITH_LEN(" as decimal)"));
}
@ -2234,7 +2234,7 @@ longlong Item_func_locate::val_int()
void Item_func_locate::print(String *str)
{
str->append("locate(", 7);
str->append(STRING_WITH_LEN("locate("));
args[1]->print(str);
str->append(',');
args[0]->print(str);
@ -3297,7 +3297,7 @@ longlong Item_func_benchmark::val_int()
void Item_func_benchmark::print(String *str)
{
str->append("benchmark(", 10);
str->append(STRING_WITH_LEN("benchmark("));
char buffer[20];
// my_charset_bin is good enough for numbers
String st(buffer, sizeof(buffer), &my_charset_bin);
@ -3811,9 +3811,9 @@ my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
void Item_func_set_user_var::print(String *str)
{
str->append("(@", 2);
str->append(STRING_WITH_LEN("(@"));
str->append(name.str, name.length);
str->append(":=", 2);
str->append(STRING_WITH_LEN(":="));
args[0]->print(str);
str->append(')');
}
@ -3821,9 +3821,9 @@ void Item_func_set_user_var::print(String *str)
void Item_func_set_user_var::print_as_stmt(String *str)
{
str->append("set @", 5);
str->append(STRING_WITH_LEN("set @"));
str->append(name.str, name.length);
str->append(":=", 2);
str->append(STRING_WITH_LEN(":="));
args[0]->print(str);
str->append(')');
}
@ -4054,7 +4054,7 @@ enum Item_result Item_func_get_user_var::result_type() const
void Item_func_get_user_var::print(String *str)
{
str->append("(@", 2);
str->append(STRING_WITH_LEN("(@"));
str->append(name.str,name.length);
str->append(')');
}
@ -4479,15 +4479,15 @@ double Item_func_match::val_real()
void Item_func_match::print(String *str)
{
str->append("(match ", 7);
str->append(STRING_WITH_LEN("(match "));
print_args(str, 1);
str->append(" against (", 10);
str->append(STRING_WITH_LEN(" against ("));
args[0]->print(str);
if (flags & FT_BOOL)
str->append(" in boolean mode", 16);
str->append(STRING_WITH_LEN(" in boolean mode"));
else if (flags & FT_EXPAND)
str->append(" with query expansion", 21);
str->append("))", 2);
str->append(STRING_WITH_LEN(" with query expansion"));
str->append(STRING_WITH_LEN("))"));
}
longlong Item_func_bit_xor::val_int()
@ -4690,10 +4690,16 @@ Item_func_sp::sp_result_field(void) const
{
Field *field;
DBUG_ENTER("Item_func_sp::sp_result_field");
DBUG_PRINT("info", ("sp: %s, flags: %x, level: %lu",
(m_sp ? "YES" : "NO"),
(m_sp ? m_sp->m_flags : (uint)0),
(m_sp ? m_sp->m_recursion_level : (ulong)0)));
if (!m_sp)
{
if (!(m_sp= sp_find_function(current_thd, m_name, TRUE)))
THD *thd= current_thd;
if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
&thd->sp_func_cache, TRUE)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
DBUG_RETURN(0);
@ -4919,7 +4925,8 @@ Item_func_sp::find_and_check_access(THD *thd, ulong want_access,
bool res= TRUE;
*save= 0; // Safety if error
if (! m_sp && ! (m_sp= sp_find_function(thd, m_name, TRUE)))
if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name,
&thd->sp_func_cache, TRUE)))
{
my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str);
goto error;

View File

@ -1790,7 +1790,7 @@ String *Item_func_format::val_str(String *str)
void Item_func_format::print(String *str)
{
str->append("format(", 7);
str->append(STRING_WITH_LEN("format("));
args[0]->print(str);
str->append(',');
// my_charset_bin is good enough for numbers
@ -1950,7 +1950,7 @@ String *Item_func_make_set::val_str(String *str)
void Item_func_make_set::print(String *str)
{
str->append("make_set(", 9);
str->append(STRING_WITH_LEN("make_set("));
item->print(str);
if (arg_count)
{
@ -2331,9 +2331,9 @@ void Item_func_conv_charset::fix_length_and_dec()
void Item_func_conv_charset::print(String *str)
{
str->append("convert(", 8);
str->append(STRING_WITH_LEN("convert("));
args[0]->print(str);
str->append(" using ", 7);
str->append(STRING_WITH_LEN(" using "));
str->append(conv_charset->csname);
str->append(')');
}
@ -2403,7 +2403,7 @@ void Item_func_set_collation::print(String *str)
{
str->append('(');
args[0]->print(str);
str->append(" collate ", 9);
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);
@ -2523,9 +2523,9 @@ String *Item_func_unhex::val_str(String *str)
void Item_func_binary::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as binary)", 11);
str->append(STRING_WITH_LEN(" as binary)"));
}
@ -2630,7 +2630,7 @@ String* Item_func_export_set::val_str(String* str)
}
break;
case 3:
sep_buf.set(",", 1, default_charset());
sep_buf.set(STRING_WITH_LEN(","), default_charset());
sep = &sep_buf;
break;
default:
@ -2745,7 +2745,8 @@ String *Item_func_quote::val_str(String *str)
uint arg_length, new_length;
if (!arg) // Null argument
{
str->copy("NULL", 4, collation.collation); // Return the string 'NULL'
/* Return the string 'NULL' */
str->copy(STRING_WITH_LEN("NULL"), collation.collation);
null_value= 0;
return str;
}

View File

@ -533,7 +533,7 @@ Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex):
void Item_exists_subselect::print(String *str)
{
str->append("exists", 6);
str->append(STRING_WITH_LEN("exists"));
Item_subselect::print(str);
}
@ -1339,11 +1339,11 @@ err:
void Item_in_subselect::print(String *str)
{
if (transformed)
str->append("<exists>", 8);
str->append(STRING_WITH_LEN("<exists>"));
else
{
left_expr->print(str);
str->append(" in ", 4);
str->append(STRING_WITH_LEN(" in "));
}
Item_subselect::print(str);
}
@ -1362,7 +1362,7 @@ Item_allany_subselect::select_transformer(JOIN *join)
void Item_allany_subselect::print(String *str)
{
if (transformed)
str->append("<exists>", 8);
str->append(STRING_WITH_LEN("<exists>"));
else
{
left_expr->print(str);
@ -1794,16 +1794,16 @@ void subselect_union_engine::print(String *str)
void subselect_uniquesubquery_engine::print(String *str)
{
str->append("<primary_index_lookup>(", 23);
str->append(STRING_WITH_LEN("<primary_index_lookup>("));
tab->ref.items[0]->print(str);
str->append(" in ", 4);
str->append(STRING_WITH_LEN(" in "));
str->append(tab->table->s->table_name);
KEY *key_info= tab->table->key_info+ tab->ref.key;
str->append(" on ", 4);
str->append(STRING_WITH_LEN(" on "));
str->append(key_info->name);
if (cond)
{
str->append(" where ", 7);
str->append(STRING_WITH_LEN(" where "));
cond->print(str);
}
str->append(')');
@ -1812,18 +1812,18 @@ void subselect_uniquesubquery_engine::print(String *str)
void subselect_indexsubquery_engine::print(String *str)
{
str->append("<index_lookup>(", 15);
str->append(STRING_WITH_LEN("<index_lookup>("));
tab->ref.items[0]->print(str);
str->append(" in ", 4);
str->append(STRING_WITH_LEN(" in "));
str->append(tab->table->s->table_name);
KEY *key_info= tab->table->key_info+ tab->ref.key;
str->append(" on ", 4);
str->append(STRING_WITH_LEN(" on "));
str->append(key_info->name);
if (check_null)
str->append(" checking NULL", 14);
str->append(STRING_WITH_LEN(" checking NULL"));
if (cond)
{
str->append(" where ", 7);
str->append(STRING_WITH_LEN(" where "));
cond->print(str);
}
str->append(')');

View File

@ -3156,9 +3156,9 @@ String* Item_func_group_concat::val_str(String* str)
void Item_func_group_concat::print(String *str)
{
str->append("group_concat(", 13);
str->append(STRING_WITH_LEN("group_concat("));
if (distinct)
str->append("distinct ", 9);
str->append(STRING_WITH_LEN("distinct "));
for (uint i= 0; i < arg_count_field; i++)
{
if (i)
@ -3167,19 +3167,19 @@ void Item_func_group_concat::print(String *str)
}
if (arg_count_order)
{
str->append(" order by ", 10);
str->append(STRING_WITH_LEN(" order by "));
for (uint i= 0 ; i < arg_count_order ; i++)
{
if (i)
str->append(',');
(*order[i]->item)->print(str);
if (order[i]->asc)
str->append(" ASC");
str->append(STRING_WITH_LEN(" ASC"));
else
str->append(" DESC");
str->append(STRING_WITH_LEN(" DESC"));
}
}
str->append(" separator \'", 12);
str->append(STRING_WITH_LEN(" separator \'"));
str->append(*separator);
str->append("\')", 2);
str->append(STRING_WITH_LEN("\')"));
}

View File

@ -506,7 +506,7 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
str->set_charset(&my_charset_bin);
if (l_time->neg)
str->append("-", 1);
str->append('-');
end= (ptr= format->format.str) + format->format.length;
for (; ptr != end ; ptr++)
@ -546,21 +546,21 @@ bool make_date_time(DATE_TIME_FORMAT *format, TIME *l_time,
length= int10_to_str(l_time->day, intbuff, 10) - intbuff;
str->append_with_prefill(intbuff, length, 1, '0');
if (l_time->day >= 10 && l_time->day <= 19)
str->append("th", 2);
str->append(STRING_WITH_LEN("th"));
else
{
switch (l_time->day %10) {
case 1:
str->append("st",2);
str->append(STRING_WITH_LEN("st"));
break;
case 2:
str->append("nd",2);
str->append(STRING_WITH_LEN("nd"));
break;
case 3:
str->append("rd",2);
str->append(STRING_WITH_LEN("rd"));
break;
default:
str->append("th",2);
str->append(STRING_WITH_LEN("th"));
break;
}
}
@ -2142,9 +2142,9 @@ void Item_date_add_interval::print(String *str)
void Item_extract::print(String *str)
{
str->append("extract(", 8);
str->append(STRING_WITH_LEN("extract("));
str->append(interval_names[int_type]);
str->append(" from ", 6);
str->append(STRING_WITH_LEN(" from "));
args[0]->print(str);
str->append(')');
}
@ -2286,9 +2286,9 @@ bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
void Item_typecast::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as ", 4);
str->append(STRING_WITH_LEN(" as "));
str->append(cast_type());
str->append(')');
}
@ -2296,9 +2296,9 @@ void Item_typecast::print(String *str)
void Item_char_typecast::print(String *str)
{
str->append("cast(", 5);
str->append(STRING_WITH_LEN("cast("));
args[0]->print(str);
str->append(" as char", 8);
str->append(STRING_WITH_LEN(" as char"));
if (cast_length >= 0)
{
str->append('(');
@ -2311,7 +2311,7 @@ void Item_char_typecast::print(String *str)
}
if (cast_cs)
{
str->append(" charset ", 9);
str->append(STRING_WITH_LEN(" charset "));
str->append(cast_cs->csname);
}
str->append(')');
@ -2352,22 +2352,37 @@ String *Item_char_typecast::val_str(String *str)
and the result is longer than cast length, e.g.
CAST('string' AS CHAR(1))
*/
if (cast_length >= 0 &&
(res->length() > (length= (uint32) res->charpos(cast_length))))
{ // Safe even if const arg
char char_type[40];
my_snprintf(char_type, sizeof(char_type), "CHAR(%lu)", length);
if (cast_length >= 0)
{
if (res->length() > (length= (uint32) res->charpos(cast_length)))
{ // Safe even if const arg
char char_type[40];
my_snprintf(char_type, sizeof(char_type), "%s(%lu)",
cast_cs == &my_charset_bin ? "BINARY" : "CHAR", length);
if (!res->alloced_length())
{ // Don't change const str
str_value= *res; // Not malloced string
res= &str_value;
if (!res->alloced_length())
{ // Don't change const str
str_value= *res; // Not malloced string
res= &str_value;
}
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
res->c_ptr_safe());
res->length((uint) length);
}
else if (cast_cs == &my_charset_bin && res->length() < (uint) cast_length)
{
if (res->alloced_length() < (uint) cast_length)
{
str->alloc(cast_length);
str->copy(*res);
res= str;
}
bzero((char*) res->ptr() + res->length(),
(uint) cast_length - res->length());
res->length(cast_length);
}
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), char_type,
res->c_ptr_safe());
res->length((uint) length);
}
null_value= 0;
return res;
@ -2609,14 +2624,14 @@ void Item_func_add_time::print(String *str)
if (is_date)
{
DBUG_ASSERT(sign > 0);
str->append("timestamp(", 10);
str->append(STRING_WITH_LEN("timestamp("));
}
else
{
if (sign > 0)
str->append("addtime(", 8);
str->append(STRING_WITH_LEN("addtime("));
else
str->append("subtime(", 8);
str->append(STRING_WITH_LEN("subtime("));
}
args[0]->print(str);
str->append(',');
@ -2825,31 +2840,31 @@ void Item_func_timestamp_diff::print(String *str)
switch (int_type) {
case INTERVAL_YEAR:
str->append("YEAR");
str->append(STRING_WITH_LEN("YEAR"));
break;
case INTERVAL_QUARTER:
str->append("QUARTER");
str->append(STRING_WITH_LEN("QUARTER"));
break;
case INTERVAL_MONTH:
str->append("MONTH");
str->append(STRING_WITH_LEN("MONTH"));
break;
case INTERVAL_WEEK:
str->append("WEEK");
str->append(STRING_WITH_LEN("WEEK"));
break;
case INTERVAL_DAY:
str->append("DAY");
str->append(STRING_WITH_LEN("DAY"));
break;
case INTERVAL_HOUR:
str->append("HOUR");
str->append(STRING_WITH_LEN("HOUR"));
break;
case INTERVAL_MINUTE:
str->append("MINUTE");
str->append(STRING_WITH_LEN("MINUTE"));
break;
case INTERVAL_SECOND:
str->append("SECOND");
str->append(STRING_WITH_LEN("SECOND"));
break;
case INTERVAL_MICROSECOND:
str->append("SECOND_FRAC");
str->append(STRING_WITH_LEN("SECOND_FRAC"));
break;
default:
break;
@ -2905,13 +2920,13 @@ void Item_func_get_format::print(String *str)
switch (type) {
case MYSQL_TIMESTAMP_DATE:
str->append("DATE, ");
str->append(STRING_WITH_LEN("DATE, "));
break;
case MYSQL_TIMESTAMP_DATETIME:
str->append("DATETIME, ");
str->append(STRING_WITH_LEN("DATETIME, "));
break;
case MYSQL_TIMESTAMP_TIME:
str->append("TIME, ");
str->append(STRING_WITH_LEN("TIME, "));
break;
default:
DBUG_ASSERT(0);

View File

@ -29,7 +29,7 @@ public:
:Item_real_func(list) {}
double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
void print(String *str) { str->append("0.0", 3); }
void print(String *str) { str->append(STRING_WITH_LEN("0.0")); }
const char *func_name() const { return "unique_users"; }
};
@ -57,7 +57,7 @@ public:
{
return new Item_sum_unique_users(thd, this);
}
void print(String *str) { str->append("0.0", 3); }
void print(String *str) { str->append(STRING_WITH_LEN("0.0")); }
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
const char *func_name() const { return "sum_unique_users"; }
};

View File

@ -322,7 +322,7 @@ void key_unpack(String *to,TABLE *table,uint idx)
{
if (table->record[0][key_part->null_offset] & key_part->null_bit)
{
to->append("NULL", 4);
to->append(STRING_WITH_LEN("NULL"));
continue;
}
}
@ -334,7 +334,7 @@ void key_unpack(String *to,TABLE *table,uint idx)
to->append(tmp);
}
else
to->append("???", 3);
to->append(STRING_WITH_LEN("???"));
}
DBUG_VOID_RETURN;
}

View File

@ -112,6 +112,7 @@ static SYMBOL symbols[] = {
{ "CLIENT", SYM(CLIENT_SYM)},
{ "CLOSE", SYM(CLOSE_SYM)},
{ "COALESCE", SYM(COALESCE)},
{ "CODE", SYM(CODE_SYM)},
{ "COLLATE", SYM(COLLATE_SYM)},
{ "COLLATION", SYM(COLLATION_SYM)},
{ "COLUMN", SYM(COLUMN_SYM)},

View File

@ -142,7 +142,7 @@ static int binlog_commit(THD *thd, bool all)
// we're here because trans_log was flushed in MYSQL_LOG::log()
DBUG_RETURN(0);
}
Query_log_event qev(thd, "COMMIT", 6, TRUE, FALSE);
Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev));
}
@ -166,7 +166,7 @@ static int binlog_rollback(THD *thd, bool all)
*/
if (unlikely(thd->options & OPTION_STATUS_NO_TRANS_UPDATE))
{
Query_log_event qev(thd, "ROLLBACK", 8, TRUE, FALSE);
Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
error= binlog_end_trans(thd, trans_log, &qev);
}
else
@ -1833,7 +1833,7 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
*/
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
Query_log_event qinfo(thd, "BEGIN", 5, TRUE, FALSE);
Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
/*
Imagine this is rollback due to net timeout, after all statements of
the transaction succeeded. Then we want a zero-error code in BEGIN.

View File

@ -161,7 +161,7 @@ static void cleanup_load_tmpdir()
we cannot meet Start_log event in the middle of events from one
LOAD DATA.
*/
p= strmake(prefbuf,"SQL_LOAD-",9);
p= strmake(prefbuf, STRING_WITH_LEN("SQL_LOAD-"));
p= int10_to_str(::server_id, p, 10);
*(p++)= '-';
*p= 0;
@ -902,14 +902,16 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Pretty-print event common header if header is exactly 19 bytes */
if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
{
DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from);
fprintf(file, "# Position Timestamp Type Master ID "
"Size Master Pos Flags \n");
fprintf(file, "# %8.8lx %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x %02x %02x "
"%02x %02x %02x %02x %02x %02x\n",
hexdump_from, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4],
ptr[5], ptr[6], ptr[7], ptr[8], ptr[9], ptr[10], ptr[11],
ptr[12], ptr[13], ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
(unsigned long) hexdump_from,
ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
}
@ -926,8 +928,10 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
if (i % 16 == 15)
{
DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from);
fprintf(file, "# %8.8lx %-48.48s |%16s|\n",
hexdump_from + (i & 0xfffffff0), hex_string, char_string);
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
hex_string[0]= 0;
char_string[0]= 0;
c= char_string;
@ -939,8 +943,10 @@ void Log_event::print_header(FILE* file, PRINT_EVENT_INFO* print_event_info)
/* Non-full last line */
if (hex_string[0]) {
printf("# %8.8lx %-48.48s |%s|\n# ",
hexdump_from + (i & 0xfffffff0), hex_string, char_string);
DBUG_ASSERT(hexdump_from == (unsigned long) hexdump_from);
fprintf(file, "# %8.8lx %-48.48s |%s|\n# ",
(unsigned long) (hexdump_from + (i & 0xfffffff0)),
hex_string, char_string);
}
}
}
@ -2992,7 +2998,7 @@ void Rotate_log_event::pack_info(Protocol *protocol)
String tmp(buf1, sizeof(buf1), log_cs);
tmp.length(0);
tmp.append(new_log_ident, ident_len);
tmp.append(";pos=");
tmp.append(STRING_WITH_LEN(";pos="));
tmp.append(llstr(pos,buf));
protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
}
@ -4164,7 +4170,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
bzero((char*)&file, sizeof(file));
p = slave_load_file_stem(fname_buf, file_id, server_id);
strmov(p, ".info"); // strmov takes less code than memcpy
strnmov(proc_info, "Making temp file ", 17); // no end 0
strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0
thd->proc_info= proc_info;
my_delete(fname_buf, MYF(0)); // old copy may exist already
if ((fd= my_create(fname_buf, CREATE_MODE,
@ -4333,7 +4339,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
DBUG_ENTER("Append_block_log_event::exec_event");
memcpy(p, ".data", 6);
strnmov(proc_info, "Making temp file ", 17); // no end 0
strnmov(proc_info, STRING_WITH_LEN("Making temp file ")); // no end 0
thd->proc_info= proc_info;
if (get_create_or_append())
{
@ -4817,23 +4823,23 @@ Execute_load_query_log_event::exec_event(struct st_relay_log_info* rli)
p= buf;
memcpy(p, query, fn_pos_start);
p+= fn_pos_start;
fname= (p= strmake(p, " INFILE \'", 9));
fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
p= slave_load_file_stem(p, file_id, server_id);
fname_end= (p= strmake(p, ".data", 5));
fname_end= (p= strmake(p, STRING_WITH_LEN(".data")));
*(p++)='\'';
switch (dup_handling)
{
case LOAD_DUP_IGNORE:
p= strmake(p, " IGNORE", 7);
p= strmake(p, STRING_WITH_LEN(" IGNORE"));
break;
case LOAD_DUP_REPLACE:
p= strmake(p, " REPLACE", 8);
p= strmake(p, STRING_WITH_LEN(" REPLACE"));
break;
default:
/* Ordinary load data */
break;
}
p= strmake(p, " INTO", 5);
p= strmake(p, STRING_WITH_LEN(" INTO"));
p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
error= Query_log_event::exec_event(rli, buf, p-buf);

View File

@ -550,6 +550,8 @@ 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;
@ -4621,6 +4623,7 @@ enum options_mysqld
OPT_OPTIMIZER_PRUNE_LEVEL,
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,
@ -5876,6 +5879,11 @@ The minimum value for this variable is 4096.",
(gptr*) &global_system_variables.read_buff_size,
(gptr*) &max_system_variables.read_buff_size,0, GET_ULONG, REQUIRED_ARG,
128*1024L, IO_SIZE*2+MALLOC_OVERHEAD, ~0L, MALLOC_OVERHEAD, IO_SIZE, 0},
{"max_sp_recursion_depth", OPT_MAX_SP_RECURSION_DEPTH,
"Maximum stored procedure recursion depth. (discussed with docs).",
(gptr*) &global_system_variables.max_sp_recursion_depth,
(gptr*) &max_system_variables.max_sp_recursion_depth, 0, GET_ULONG,
OPT_ARG, 0, 0, 255, 0, 1, 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.",

View File

@ -6696,7 +6696,7 @@ void QUICK_INDEX_MERGE_SELECT::add_info_string(String *str)
QUICK_RANGE_SELECT *quick;
bool first= TRUE;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
str->append("sort_union(");
str->append(STRING_WITH_LEN("sort_union("));
while ((quick= it++))
{
if (!first)
@ -6718,7 +6718,7 @@ void QUICK_ROR_INTERSECT_SELECT::add_info_string(String *str)
bool first= TRUE;
QUICK_RANGE_SELECT *quick;
List_iterator_fast<QUICK_RANGE_SELECT> it(quick_selects);
str->append("intersect(");
str->append(STRING_WITH_LEN("intersect("));
while ((quick= it++))
{
KEY *key_info= head->key_info + quick->index;
@ -6742,7 +6742,7 @@ void QUICK_ROR_UNION_SELECT::add_info_string(String *str)
bool first= TRUE;
QUICK_SELECT_I *quick;
List_iterator_fast<QUICK_SELECT_I> it(quick_selects);
str->append("union(");
str->append(STRING_WITH_LEN("union("));
while ((quick= it++))
{
if (!first)
@ -8882,7 +8882,7 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map,
}
}
if (!tmp.length())
tmp.append("(empty)");
tmp.append(STRING_WITH_LEN("(empty)"));
DBUG_PRINT("info", ("SEL_TREE %p (%s) scans:%s", tree, msg, tmp.ptr()));
@ -8908,7 +8908,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg,
tmp.append(table->key_info[(*start)->keynr].name);
}
if (!tmp.length())
tmp.append("(empty)");
tmp.append(STRING_WITH_LEN("(empty)"));
DBUG_PRINT("info", ("ROR key scans (%s): %s", msg, tmp.ptr()));
DBUG_VOID_RETURN;
}

View File

@ -50,23 +50,23 @@ write_escaped_string(IO_CACHE *file, LEX_STRING *val_s)
*/
switch(*ptr) {
case '\\': // escape character
if (my_b_append(file, (const byte *)"\\\\", 2))
if (my_b_append(file, (const byte *)STRING_WITH_LEN("\\\\")))
return TRUE;
break;
case '\n': // parameter value delimiter
if (my_b_append(file, (const byte *)"\\n", 2))
if (my_b_append(file, (const byte *)STRING_WITH_LEN("\\n")))
return TRUE;
break;
case '\0': // problem for some string processing utilities
if (my_b_append(file, (const byte *)"\\0", 2))
if (my_b_append(file, (const byte *)STRING_WITH_LEN("\\0")))
return TRUE;
break;
case 26: // problem for windows utilities (Ctrl-Z)
if (my_b_append(file, (const byte *)"\\z", 2))
if (my_b_append(file, (const byte *)STRING_WITH_LEN("\\z")))
return TRUE;
break;
case '\'': // list of string delimiter
if (my_b_append(file, (const byte *)"\\\'", 2))
if (my_b_append(file, (const byte *)STRING_WITH_LEN("\\\'")))
return TRUE;
break;
default:
@ -155,10 +155,10 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
while ((str= it++))
{
// We need ' ' after string to detect list continuation
if ((!first && my_b_append(file, (const byte *)" ", 1)) ||
my_b_append(file, (const byte *)"\'", 1) ||
if ((!first && my_b_append(file, (const byte *)STRING_WITH_LEN(" "))) ||
my_b_append(file, (const byte *)STRING_WITH_LEN("\'")) ||
write_escaped_string(file, str) ||
my_b_append(file, (const byte *)"\'", 1))
my_b_append(file, (const byte *)STRING_WITH_LEN("\'")))
{
DBUG_RETURN(TRUE);
}
@ -176,7 +176,7 @@ write_parameter(IO_CACHE *file, gptr base, File_option *parameter,
{
num.set(*val, &my_charset_bin);
// We need ' ' after string to detect list continuation
if ((!first && my_b_append(file, (const byte *)" ", 1)) ||
if ((!first && my_b_append(file, (const byte *)STRING_WITH_LEN(" "))) ||
my_b_append(file, (const byte *)num.ptr(), num.length()))
{
DBUG_RETURN(TRUE);
@ -242,9 +242,9 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
goto err_w_file;
// write header (file signature)
if (my_b_append(&file, (const byte *)"TYPE=", 5) ||
if (my_b_append(&file, (const byte *)STRING_WITH_LEN("TYPE=")) ||
my_b_append(&file, (const byte *)type->str, type->length) ||
my_b_append(&file, (const byte *)"\n", 1))
my_b_append(&file, (const byte *)STRING_WITH_LEN("\n")))
goto err_w_file;
// write parameters to temporary file
@ -252,9 +252,9 @@ sql_create_definition_file(const LEX_STRING *dir, const LEX_STRING *file_name,
{
if (my_b_append(&file, (const byte *)param->name.str,
param->name.length) ||
my_b_append(&file, (const byte *)"=", 1) ||
my_b_append(&file, (const byte *)STRING_WITH_LEN("=")) ||
write_parameter(&file, base, param, &old_version) ||
my_b_append(&file, (const byte *)"\n", 1))
my_b_append(&file, (const byte *)STRING_WITH_LEN("\n")))
goto err_w_cache;
}
@ -663,6 +663,61 @@ parse_quoted_escaped_string(char *ptr, char *end,
}
/*
Parser for FILE_OPTIONS_ULLLIST type value.
SYNOPSIS
get_file_options_ulllist()
ptr [in/out] pointer to parameter
end [in] end of the configuration
line [in] pointer to the line begining
base [in] base address for parameter writing (structure
like TABLE)
parameter [in] description
mem_root [in] MEM_ROOT for parameters allocation
*/
bool get_file_options_ulllist(char *&ptr, char *end, char *line,
gptr base, File_option *parameter,
MEM_ROOT *mem_root)
{
List<ulonglong> *nlist= (List<ulonglong>*)(base + parameter->offset);
ulonglong *num;
nlist->empty();
// list parsing
while (ptr < end)
{
int not_used;
char *num_end= end;
if (!(num= (ulonglong*)alloc_root(mem_root, sizeof(ulonglong))) ||
nlist->push_back(num, mem_root))
goto nlist_err;
*num= my_strtoll10(ptr, &num_end, &not_used);
ptr= num_end;
switch (*ptr) {
case '\n':
goto end_of_nlist;
case ' ':
// we cant go over buffer bounds, because we have \0 at the end
ptr++;
break;
default:
goto nlist_err_w_message;
}
}
end_of_nlist:
if (*(ptr++) != '\n')
goto nlist_err;
return FALSE;
nlist_err_w_message:
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0), parameter->name.str, line);
nlist_err:
return TRUE;
}
/*
parse parameters
@ -673,6 +728,8 @@ parse_quoted_escaped_string(char *ptr, char *end,
mem_root MEM_ROOT for parameters allocation
parameters parameters description
required number of required parameters in above list
hook hook called for unknown keys
hook_data some data specific for the hook
RETURN
FALSE - OK
@ -681,15 +738,15 @@ parse_quoted_escaped_string(char *ptr, char *end,
my_bool
File_parser::parse(gptr base, MEM_ROOT *mem_root,
struct File_option *parameters, uint required)
struct File_option *parameters, uint required,
Unknown_key_hook *hook)
{
uint first_param= 0, found= 0;
register char *ptr= start;
char *ptr= start;
char *eol;
LEX_STRING *str;
List<LEX_STRING> *list;
ulonglong *num;
List<ulonglong> *nlist;
DBUG_ENTER("File_parser::parse");
while (ptr < end && found < required)
@ -829,58 +886,64 @@ list_err:
DBUG_RETURN(TRUE);
}
case FILE_OPTIONS_ULLLIST:
{
nlist= (List<ulonglong>*)(base + parameter->offset);
nlist->empty();
// list parsing
while (ptr < end)
{
int not_used;
char *num_end= end;
if (!(num= (ulonglong*)alloc_root(mem_root, sizeof(ulonglong))) ||
nlist->push_back(num, mem_root))
goto nlist_err;
*num= my_strtoll10(ptr, &num_end, &not_used);
ptr= num_end;
switch (*ptr) {
case '\n':
goto end_of_nlist;
case ' ':
// we cant go over buffer bounds, because we have \0 at the end
ptr++;
break;
default:
goto nlist_err_w_message;
}
}
end_of_nlist:
if (*(ptr++) != '\n')
goto nlist_err;
if (get_file_options_ulllist(ptr, end, line, base,
parameter, mem_root))
DBUG_RETURN(TRUE);
break;
nlist_err_w_message:
my_error(ER_FPARSER_ERROR_IN_PARAMETER, MYF(0),
parameter->name.str, line);
nlist_err:
DBUG_RETURN(TRUE);
}
default:
DBUG_ASSERT(0); // never should happened
}
}
else
{
// skip unknown parameter
if (!(ptr= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), line);
DBUG_RETURN(TRUE);
}
ptr++;
ptr= line;
if (hook->process_unknown_string(ptr, base, mem_root, end))
{
DBUG_RETURN(TRUE);
}
// skip unknown parameter
if (!(ptr= strchr(ptr, '\n')))
{
my_error(ER_FPARSER_EOF_IN_UNKNOWN_PARAMETER, MYF(0), line);
DBUG_RETURN(TRUE);
}
ptr++;
}
}
}
DBUG_RETURN(FALSE);
}
/*
Dummy unknown key hook
SYNOPSIS
File_parser_dummy_hook::process_unknown_string()
unknown_key [in/out] reference on the line with unknown
parameter and the parsing point
base [in] base address for parameter writing (structure like
TABLE)
mem_root [in] MEM_ROOT for parameters allocation
end [in] the end of the configuration
NOTE
This hook used to catch no longer supported keys and process them for
backward compatibility, but it will not slow down processing of modern
format files.
This hook does nothing except debug output.
RETURN
FALSE OK
TRUE Error
*/
bool
File_parser_dummy_hook::process_unknown_string(char *&unknown_key,
gptr base, MEM_ROOT *mem_root,
char *end)
{
DBUG_ENTER("file_parser_dummy_hook::process_unknown_string");
DBUG_PRINT("info", ("unknown key:%60s", unknown_key));
DBUG_RETURN(FALSE);
}

View File

@ -40,6 +40,35 @@ struct File_option
file_opt_type type; /* Option type */
};
/*
This hook used to catch no longer supported keys and process them for
backward compatibility.
*/
class Unknown_key_hook
{
public:
virtual bool process_unknown_string(char *&unknown_key, gptr base,
MEM_ROOT *mem_root, char *end)= 0;
};
/* Dummy hook for parsers which do not need hook for unknown keys */
class File_parser_dummy_hook: public Unknown_key_hook
{
public:
virtual bool process_unknown_string(char *&unknown_key, gptr base,
MEM_ROOT *mem_root, char *end);
};
extern File_parser_dummy_hook file_parser_dummy_hook;
bool get_file_options_ulllist(char *&ptr, char *end, char *line,
gptr base, File_option *parameter,
MEM_ROOT *mem_root);
class File_parser;
File_parser *sql_parse_prepare(const LEX_STRING *file_name,
MEM_ROOT *mem_root, bool bad_format_errors);
@ -64,7 +93,8 @@ public:
my_bool ok() { return content_ok; }
LEX_STRING *type() { return &file_type; }
my_bool parse(gptr base, MEM_ROOT *mem_root,
struct File_option *parameters, uint required);
struct File_option *parameters, uint required,
Unknown_key_hook *hook);
friend File_parser *sql_parse_prepare(const LEX_STRING *file_name,
MEM_ROOT *mem_root,

View File

@ -498,7 +498,7 @@ void Protocol::init(THD *thd_arg)
thd=thd_arg;
packet= &thd->packet;
convert= &thd->convert_buffer;
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_types= 0;
#endif
}
@ -551,7 +551,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
(void) my_net_write(&thd->net, buff,(uint) (pos-buff));
}
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_types= (enum_field_types*) thd->alloc(sizeof(field_types) *
list->elements);
uint count= 0;
@ -572,7 +572,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
if (thd->client_capabilities & CLIENT_PROTOCOL_41)
{
if (prot.store("def", 3, cs, thd_charset) ||
if (prot.store(STRING_WITH_LEN("def"), cs, thd_charset) ||
prot.store(field.db_name, (uint) strlen(field.db_name),
cs, thd_charset) ||
prot.store(field.table_name, (uint) strlen(field.table_name),
@ -648,7 +648,7 @@ bool Protocol::send_fields(List<Item> *list, uint flags)
item->send(&prot, &tmp); // Send default value
if (prot.write())
break; /* purecov: inspected */
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_types[count++]= field.type;
#endif
}
@ -732,14 +732,14 @@ bool Protocol::store(I_List<i_string>* str_list)
void Protocol_simple::prepare_for_resend()
{
packet->length(0);
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_pos= 0;
#endif
}
bool Protocol_simple::store_null()
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_pos++;
#endif
char buff[1];
@ -773,7 +773,7 @@ bool Protocol::store_string_aux(const char *from, uint length,
bool Protocol_simple::store(const char *from, uint length,
CHARSET_INFO *fromcs, CHARSET_INFO *tocs)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
field_types[field_pos] == MYSQL_TYPE_BIT ||
@ -790,7 +790,7 @@ bool Protocol_simple::store(const char *from, uint length,
CHARSET_INFO *fromcs)
{
CHARSET_INFO *tocs= this->thd->variables.character_set_results;
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DECIMAL ||
field_types[field_pos] == MYSQL_TYPE_BIT ||
@ -805,7 +805,7 @@ bool Protocol_simple::store(const char *from, uint length,
bool Protocol_simple::store_tiny(longlong from)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 || field_types[field_pos] == MYSQL_TYPE_TINY);
field_pos++;
#endif
@ -817,7 +817,7 @@ bool Protocol_simple::store_tiny(longlong from)
bool Protocol_simple::store_short(longlong from)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_YEAR ||
field_types[field_pos] == MYSQL_TYPE_SHORT);
@ -831,7 +831,7 @@ bool Protocol_simple::store_short(longlong from)
bool Protocol_simple::store_long(longlong from)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_INT24 ||
field_types[field_pos] == MYSQL_TYPE_LONG);
@ -845,7 +845,7 @@ bool Protocol_simple::store_long(longlong from)
bool Protocol_simple::store_longlong(longlong from, bool unsigned_flag)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_LONGLONG);
field_pos++;
@ -860,7 +860,7 @@ bool Protocol_simple::store_longlong(longlong from, bool unsigned_flag)
bool Protocol_simple::store_decimal(const my_decimal *d)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
field_pos++;
@ -874,7 +874,7 @@ bool Protocol_simple::store_decimal(const my_decimal *d)
bool Protocol_simple::store(float from, uint32 decimals, String *buffer)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_FLOAT);
field_pos++;
@ -886,7 +886,7 @@ bool Protocol_simple::store(float from, uint32 decimals, String *buffer)
bool Protocol_simple::store(double from, uint32 decimals, String *buffer)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DOUBLE);
field_pos++;
@ -900,7 +900,7 @@ bool Protocol_simple::store(Field *field)
{
if (field->is_null())
return store_null();
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
field_pos++;
#endif
char buff[MAX_FIELD_WIDTH];
@ -921,7 +921,7 @@ bool Protocol_simple::store(Field *field)
bool Protocol_simple::store(TIME *tm)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DATETIME ||
field_types[field_pos] == MYSQL_TYPE_TIMESTAMP);
@ -944,7 +944,7 @@ bool Protocol_simple::store(TIME *tm)
bool Protocol_simple::store_date(TIME *tm)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_DATE);
field_pos++;
@ -963,7 +963,7 @@ bool Protocol_simple::store_date(TIME *tm)
bool Protocol_simple::store_time(TIME *tm)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_TIME);
field_pos++;
@ -1088,7 +1088,7 @@ bool Protocol_prep::store_longlong(longlong from, bool unsigned_flag)
bool Protocol_prep::store_decimal(const my_decimal *d)
{
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
DBUG_ASSERT(field_types == 0 ||
field_types[field_pos] == MYSQL_TYPE_NEWDECIMAL);
field_pos++;

View File

@ -31,7 +31,7 @@ protected:
String *packet;
String *convert;
uint field_pos;
#ifndef DEBUG_OFF
#ifndef DBUG_OFF
enum enum_field_types *field_types;
#endif
uint field_count;

View File

@ -503,7 +503,7 @@ int update_slave_list(MYSQL* mysql, MASTER_INFO* mi)
int port_ind;
DBUG_ENTER("update_slave_list");
if (mysql_real_query(mysql,"SHOW SLAVE HOSTS",16) ||
if (mysql_real_query(mysql, STRING_WITH_LEN("SHOW SLAVE HOSTS")) ||
!(res = mysql_store_result(mysql)))
{
error= mysql_error(mysql);
@ -796,7 +796,7 @@ bool load_master_data(THD* thd)
MYSQL_RES *db_res, **table_res, **table_res_end, **cur_table_res;
uint num_dbs;
if (mysql_real_query(&mysql, "SHOW DATABASES", 14) ||
if (mysql_real_query(&mysql, STRING_WITH_LEN("SHOW DATABASES")) ||
!(db_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
@ -822,8 +822,9 @@ bool load_master_data(THD* thd)
we wait to issue FLUSH TABLES WITH READ LOCK for as long as we
can to minimize the lock time.
*/
if (mysql_real_query(&mysql, "FLUSH TABLES WITH READ LOCK", 27) ||
mysql_real_query(&mysql, "SHOW MASTER STATUS",18) ||
if (mysql_real_query(&mysql,
STRING_WITH_LEN("FLUSH TABLES WITH READ LOCK")) ||
mysql_real_query(&mysql, STRING_WITH_LEN("SHOW MASTER STATUS")) ||
!(master_status_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
@ -876,7 +877,7 @@ bool load_master_data(THD* thd)
}
if (mysql_select_db(&mysql, db) ||
mysql_real_query(&mysql, "SHOW TABLES", 11) ||
mysql_real_query(&mysql, STRING_WITH_LEN("SHOW TABLES")) ||
!(*cur_table_res = mysql_store_result(&mysql)))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
@ -934,7 +935,7 @@ bool load_master_data(THD* thd)
mysql_free_result(master_status_res);
}
if (mysql_real_query(&mysql, "UNLOCK TABLES", 13))
if (mysql_real_query(&mysql, STRING_WITH_LEN("UNLOCK TABLES")))
{
my_error(error= ER_QUERY_ON_MASTER, MYF(0), mysql_error(&mysql));
goto err;

View File

@ -298,6 +298,8 @@ sys_var_long_ptr sys_max_relay_log_size("max_relay_log_size",
fix_max_relay_log_size);
sys_var_thd_ulong sys_max_sort_length("max_sort_length",
&SV::max_sort_length);
sys_var_thd_ulong sys_max_sp_recursion_depth("max_sp_recursion_depth",
&SV::max_sp_recursion_depth);
sys_var_max_user_conn sys_max_user_connections("max_user_connections");
sys_var_thd_ulong sys_max_tmp_tables("max_tmp_tables",
&SV::max_tmp_tables);
@ -770,6 +772,8 @@ struct show_var_st init_vars[]= {
{sys_max_relay_log_size.name, (char*) &sys_max_relay_log_size, SHOW_SYS},
{sys_max_seeks_for_key.name, (char*) &sys_max_seeks_for_key, SHOW_SYS},
{sys_max_sort_length.name, (char*) &sys_max_sort_length, SHOW_SYS},
{sys_max_sp_recursion_depth.name,
(char*) &sys_max_sp_recursion_depth, SHOW_SYS},
{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},

View File

@ -49,5 +49,15 @@ install-data-local:
$(INSTALL_DATA) $(srcdir)/charsets/README $(DESTDIR)$(pkgdatadir)/charsets/README
$(INSTALL_DATA) $(srcdir)/charsets/*.xml $(DESTDIR)$(pkgdatadir)/charsets
# FIXME maybe shouldn't remove, could be needed by other installation?
uninstall-local:
@RM@ -f -r $(DESTDIR)$(pkgdatadir)
distclean-local:
@RM@ -f */errmsg.sys
# Do nothing
link_sources:
# Don't update the files from bitkeeper
%::SCCS/s.%

View File

@ -5361,7 +5361,7 @@ ER_COMMIT_NOT_ALLOWED_IN_SF_OR_TRG
ER_NO_DEFAULT_FOR_VIEW_FIELD
eng "Field of view '%-.64s.%-.64s' underlying table doesn't have a default value"
ER_SP_NO_RECURSION
eng "Recursive stored routines are not allowed."
eng "Recursive stored functions and triggers are not allowed."
ER_TOO_BIG_SCALE 42000 S1009
eng "Too big scale %d specified for column '%-.64s'. Maximum is %d."
ER_TOO_BIG_PRECISION 42000 S1009
@ -5423,6 +5423,10 @@ ER_SP_BAD_VAR_SHADOW 42000
eng "Variable '%-.64s' must be quoted with `...`, or renamed"
ER_TRG_NO_DEFINER
eng "No definer attribute for trigger '%-.64s'.'%-.64s'. The trigger will be activated under the authorization of the invoker, which may have insufficient privileges. Please recreate the trigger."
ER_OLD_FILE_FORMAT
eng "'%-.64s' has an old format, you should re-create the '%s' object(s)"
ER_SP_RECURSION_LIMIT
eng "Recursive limit %d (as set by the max_sp_recursion_depth variable) was exceeded for routine %.64s"
ER_PARTITION_REQUIRES_VALUES_ERROR
eng "%s PARTITIONING requires definition of VALUES %s for each partition"
swe "%s PARTITIONering kräver definition av VALUES %s för varje partition"

View File

@ -1068,7 +1068,7 @@ static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi)
MYSQL_RES *master_res= 0;
MYSQL_ROW master_row;
if (!mysql_real_query(mysql, "SELECT UNIX_TIMESTAMP()", 23) &&
if (!mysql_real_query(mysql, STRING_WITH_LEN("SELECT UNIX_TIMESTAMP()")) &&
(master_res= mysql_store_result(mysql)) &&
(master_row= mysql_fetch_row(master_res)))
{
@ -1094,7 +1094,8 @@ do not trust column Seconds_Behind_Master of SHOW SLAVE STATUS");
Note: we could have put a @@SERVER_ID in the previous SELECT
UNIX_TIMESTAMP() instead, but this would not have worked on 3.23 masters.
*/
if (!mysql_real_query(mysql, "SHOW VARIABLES LIKE 'SERVER_ID'", 31) &&
if (!mysql_real_query(mysql,
STRING_WITH_LEN("SHOW VARIABLES LIKE 'SERVER_ID'")) &&
(master_res= mysql_store_result(mysql)))
{
if ((master_row= mysql_fetch_row(master_res)) &&
@ -1129,7 +1130,8 @@ not always make sense; please check the manual before using it).";
goto err;
if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.COLLATION_SERVER", 32) &&
!mysql_real_query(mysql,
STRING_WITH_LEN("SELECT @@GLOBAL.COLLATION_SERVER")) &&
(master_res= mysql_store_result(mysql)))
{
if ((master_row= mysql_fetch_row(master_res)) &&
@ -1156,7 +1158,7 @@ be equal for replication to work";
those were alpha).
*/
if ((*mysql->server_version == '4') &&
!mysql_real_query(mysql, "SELECT @@GLOBAL.TIME_ZONE", 25) &&
!mysql_real_query(mysql, STRING_WITH_LEN("SELECT @@GLOBAL.TIME_ZONE")) &&
(master_res= mysql_store_result(mysql)))
{
if ((master_row= mysql_fetch_row(master_res)) &&

315
sql/sp.cc
View File

@ -29,6 +29,11 @@ create_string(THD *thd, String *buf,
const char *returns, ulong returnslen,
const char *body, ulong bodylen,
st_sp_chistics *chistics);
static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified);
/*
*
@ -377,79 +382,10 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
close_proc_table(thd, &open_tables_state_backup);
table= 0;
{
String defstr;
LEX *oldlex= thd->lex;
char olddb[128];
bool dbchanged;
enum enum_sql_command oldcmd= thd->lex->sql_command;
ulong old_sql_mode= thd->variables.sql_mode;
ha_rows select_limit= thd->variables.select_limit;
thd->variables.sql_mode= sql_mode;
thd->variables.select_limit= HA_POS_ERROR;
defstr.set_charset(system_charset_info);
if (!create_string(thd, &defstr,
type,
name,
params, strlen(params),
returns, strlen(returns),
body, strlen(body),
&chistics))
{
ret= SP_INTERNAL_ERROR;
goto done;
}
dbchanged= FALSE;
if ((ret= sp_use_new_db(thd, name->m_db.str, olddb, sizeof(olddb),
1, &dbchanged)))
goto done;
{
/* This is something of a kludge. We need to initialize some fields
* in thd->lex (the unit and master stuff), and the easiest way to
* do it is, is to call mysql_init_query(), but this unfortunately
* resets teh value_list where we keep the CALL parameters. So we
* copy the list and then restore it. (... and found_semicolon too).
*/
List<Item> tmpvals= thd->lex->value_list;
char *tmpfsc= thd->lex->found_semicolon;
lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
thd->lex->value_list= tmpvals;
thd->lex->found_semicolon= tmpfsc;
}
if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL)
{
LEX *newlex= thd->lex;
sp_head *sp= newlex->sphead;
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto done;
if (sp)
{
delete sp;
newlex->sphead= NULL;
}
ret= SP_PARSE_ERROR;
}
else
{
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto done;
*sphp= thd->lex->sphead;
(*sphp)->set_definer((char*) definer, (uint) strlen(definer));
(*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize();
}
thd->lex->sql_command= oldcmd;
thd->variables.sql_mode= old_sql_mode;
thd->variables.select_limit= select_limit;
}
ret= db_load_routine(thd, type, name, sphp,
sql_mode, params, returns, body, chistics,
definer, created, modified);
done:
if (table)
close_proc_table(thd, &open_tables_state_backup);
@ -457,6 +393,72 @@ db_find_routine(THD *thd, int type, sp_name *name, sp_head **sphp)
}
static int
db_load_routine(THD *thd, int type, sp_name *name, sp_head **sphp,
ulong sql_mode, const char *params, const char *returns,
const char *body, st_sp_chistics &chistics,
const char *definer, longlong created, longlong modified)
{
LEX *oldlex= thd->lex, newlex;
sp_rcontext *save_spcont= thd->spcont;
String defstr;
char olddb[128];
bool dbchanged;
ulong old_sql_mode= thd->variables.sql_mode;
ha_rows select_limit= thd->variables.select_limit;
int ret= SP_INTERNAL_ERROR;
thd->variables.sql_mode= sql_mode;
thd->variables.select_limit= HA_POS_ERROR;
thd->lex= &newlex;
newlex.current_select= NULL;
defstr.set_charset(system_charset_info);
if (!create_string(thd, &defstr,
type,
name,
params, strlen(params),
returns, strlen(returns),
body, strlen(body),
&chistics))
goto end;
dbchanged= FALSE;
if ((ret= sp_use_new_db(thd, name->m_db.str, olddb, sizeof(olddb),
1, &dbchanged)))
goto end;
lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length());
thd->spcont= 0;
if (yyparse(thd) || thd->is_fatal_error || newlex.sphead == NULL)
{
sp_head *sp= newlex.sphead;
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto end;
delete sp;
ret= SP_PARSE_ERROR;
}
else
{
if (dbchanged && (ret= mysql_change_db(thd, olddb, 1)))
goto end;
*sphp= newlex.sphead;
(*sphp)->set_definer((char*) definer, (uint) strlen(definer));
(*sphp)->set_info(created, modified, &chistics, sql_mode);
(*sphp)->optimize();
}
end:
thd->spcont= save_spcont;
thd->variables.sql_mode= old_sql_mode;
thd->variables.select_limit= select_limit;
thd->lex= oldlex;
return ret;
}
static void
sp_returns_type(THD *thd, String &result, sp_head *sp)
{
@ -899,45 +901,106 @@ err:
******************************************************************************/
/*
Obtain object representing stored procedure by its name from
Obtain object representing stored procedure/function by its name from
stored procedures cache and looking into mysql.proc if needed.
SYNOPSIS
sp_find_procedure()
sp_find_routine()
thd - thread context
type - type of object (TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE)
name - name of procedure
cp - hash to look routine in
cache_only - if true perform cache-only lookup
(Don't look in mysql.proc).
TODO
We should consider merging of sp_find_procedure() and
sp_find_function() into one sp_find_routine() function
(the same applies to other similarly paired functions).
RETURN VALUE
Non-0 pointer to sp_head object for the procedure, or
0 - in case of error.
*/
sp_head *
sp_find_procedure(THD *thd, sp_name *name, bool cache_only)
sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp,
bool cache_only)
{
sp_head *sp;
DBUG_ENTER("sp_find_procedure");
DBUG_PRINT("enter", ("name: %.*s.%.*s",
name->m_db.length, name->m_db.str,
name->m_name.length, name->m_name.str));
ulong depth= (type == TYPE_ENUM_PROCEDURE ?
thd->variables.max_sp_recursion_depth :
0);
if (!(sp= sp_cache_lookup(&thd->sp_proc_cache, name)) && !cache_only)
DBUG_ENTER("sp_find_routine");
DBUG_PRINT("enter", ("name: %.*s.%.*s, type: %d, cache only %d",
name->m_db.length, name->m_db.str,
name->m_name.length, name->m_name.str,
type, cache_only));
if ((sp= sp_cache_lookup(cp, name)))
{
if (db_find_routine(thd, TYPE_ENUM_PROCEDURE, name, &sp) == SP_OK)
sp_cache_insert(&thd->sp_proc_cache, sp);
ulong level;
DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp));
if (sp->m_first_free_instance)
{
DBUG_PRINT("info", ("first free: 0x%lx, level: %lu, flags %x",
(ulong)sp->m_first_free_instance,
sp->m_first_free_instance->m_recursion_level,
sp->m_first_free_instance->m_flags));
DBUG_ASSERT(!(sp->m_first_free_instance->m_flags & sp_head::IS_INVOKED));
if (sp->m_first_free_instance->m_recursion_level > depth)
{
sp->recursion_level_error();
DBUG_RETURN(0);
}
DBUG_RETURN(sp->m_first_free_instance);
}
level= sp->m_last_cached_sp->m_recursion_level + 1;
if (level > depth)
{
sp->recursion_level_error();
DBUG_RETURN(0);
}
{
sp_head *new_sp;
const char *returns= "";
char definer[HOSTNAME_LENGTH+USERNAME_LENGTH+2];
String retstr(64);
strxmov(definer, sp->m_definer_user.str, "@",
sp->m_definer_host.str, NullS);
if (type == TYPE_ENUM_FUNCTION)
{
sp_returns_type(thd, retstr, sp);
returns= retstr.ptr();
}
if (db_load_routine(thd, type, name, &new_sp,
sp->m_sql_mode, sp->m_params.str, returns,
sp->m_body.str, *sp->m_chistics, definer,
sp->m_created, sp->m_modified) == SP_OK)
{
sp->m_last_cached_sp->m_next_cached_sp= new_sp;
new_sp->m_recursion_level= level;
new_sp->m_first_instance= sp;
sp->m_last_cached_sp= sp->m_first_free_instance= new_sp;
DBUG_PRINT("info", ("added level: 0x%lx, level: %lu, flags %x",
(ulong)new_sp, new_sp->m_recursion_level,
new_sp->m_flags));
DBUG_RETURN(new_sp);
}
DBUG_RETURN(0);
}
}
if (!cache_only)
{
if (db_find_routine(thd, type, name, &sp) == SP_OK)
{
sp_cache_insert(cp, sp);
DBUG_PRINT("info", ("added new: 0x%lx, level: %lu, flags %x",
(ulong)sp, sp->m_recursion_level,
sp->m_flags));
}
}
DBUG_RETURN(sp);
}
int
sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
{
@ -955,8 +1018,10 @@ sp_exists_routine(THD *thd, TABLE_LIST *tables, bool any, bool no_error)
lex_name.str= thd->strmake(table->table_name, lex_name.length);
name= new sp_name(lex_db, lex_name);
name->init_qname(thd);
if (sp_find_procedure(thd, name) != NULL ||
sp_find_function(thd, name) != NULL)
if (sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
&thd->sp_proc_cache, FALSE) != NULL ||
sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
&thd->sp_func_cache, FALSE) != NULL)
{
if (any)
DBUG_RETURN(1);
@ -1024,7 +1089,8 @@ sp_show_create_procedure(THD *thd, sp_name *name)
DBUG_ENTER("sp_show_create_procedure");
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if ((sp= sp_find_procedure(thd, name)))
if ((sp= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name,
&thd->sp_proc_cache, FALSE)))
{
int ret= sp->show_create_procedure(thd);
@ -1050,42 +1116,6 @@ sp_show_status_procedure(THD *thd, const char *wild)
FUNCTION
******************************************************************************/
/*
Obtain object representing stored function by its name from
stored functions cache and looking into mysql.proc if needed.
SYNOPSIS
sp_find_function()
thd - thread context
name - name of function
cache_only - if true perform cache-only lookup
(Don't look in mysql.proc).
NOTE
See TODO section for sp_find_procedure().
RETURN VALUE
Non-0 pointer to sp_head object for the function, or
0 - in case of error.
*/
sp_head *
sp_find_function(THD *thd, sp_name *name, bool cache_only)
{
sp_head *sp;
DBUG_ENTER("sp_find_function");
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if (!(sp= sp_cache_lookup(&thd->sp_func_cache, name)) &&
!cache_only)
{
if (db_find_routine(thd, TYPE_ENUM_FUNCTION, name, &sp) == SP_OK)
sp_cache_insert(&thd->sp_func_cache, sp);
}
DBUG_RETURN(sp);
}
int
sp_create_function(THD *thd, sp_head *sp)
{
@ -1133,7 +1163,8 @@ sp_show_create_function(THD *thd, sp_name *name)
DBUG_ENTER("sp_show_create_function");
DBUG_PRINT("enter", ("name: %.*s", name->m_name.length, name->m_name.str));
if ((sp= sp_find_function(thd, name)))
if ((sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, name,
&thd->sp_func_cache, FALSE)))
{
int ret= sp->show_create_function(thd);
@ -1443,10 +1474,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
&thd->sp_func_cache : &thd->sp_proc_cache),
&name)))
{
LEX *oldlex= thd->lex;
LEX *newlex= new st_lex;
thd->lex= newlex;
newlex->current_select= NULL;
name.m_name.str= strchr(name.m_qname.str, '.');
name.m_db.length= name.m_name.str - name.m_qname.str;
name.m_db.str= strmake_root(thd->mem_root, name.m_qname.str,
@ -1461,8 +1488,6 @@ sp_cache_routines_and_add_tables_aux(THD *thd, LEX *lex,
else
sp_cache_insert(&thd->sp_proc_cache, sp);
}
delete newlex;
thd->lex= oldlex;
}
if (sp)
{
@ -1585,30 +1610,30 @@ create_string(THD *thd, String *buf,
chistics->comment.length))
return FALSE;
buf->append("CREATE ", 7);
buf->append(STRING_WITH_LEN("CREATE "));
if (type == TYPE_ENUM_FUNCTION)
buf->append("FUNCTION ", 9);
buf->append(STRING_WITH_LEN("FUNCTION "));
else
buf->append("PROCEDURE ", 10);
buf->append(STRING_WITH_LEN("PROCEDURE "));
append_identifier(thd, buf, name->m_name.str, name->m_name.length);
buf->append('(');
buf->append(params, paramslen);
buf->append(')');
if (type == TYPE_ENUM_FUNCTION)
{
buf->append(" RETURNS ", 9);
buf->append(STRING_WITH_LEN(" RETURNS "));
buf->append(returns, returnslen);
}
buf->append('\n');
switch (chistics->daccess) {
case SP_NO_SQL:
buf->append(" NO SQL\n");
buf->append(STRING_WITH_LEN(" NO SQL\n"));
break;
case SP_READS_SQL_DATA:
buf->append(" READS SQL DATA\n");
buf->append(STRING_WITH_LEN(" READS SQL DATA\n"));
break;
case SP_MODIFIES_SQL_DATA:
buf->append(" MODIFIES SQL DATA\n");
buf->append(STRING_WITH_LEN(" MODIFIES SQL DATA\n"));
break;
case SP_DEFAULT_ACCESS:
case SP_CONTAINS_SQL:
@ -1616,12 +1641,12 @@ create_string(THD *thd, String *buf,
break;
}
if (chistics->detistic)
buf->append(" DETERMINISTIC\n", 18);
buf->append(STRING_WITH_LEN(" DETERMINISTIC\n"));
if (chistics->suid == SP_IS_NOT_SUID)
buf->append(" SQL SECURITY INVOKER\n", 25);
buf->append(STRING_WITH_LEN(" SQL SECURITY INVOKER\n"));
if (chistics->comment.length)
{
buf->append(" COMMENT ");
buf->append(STRING_WITH_LEN(" COMMENT "));
append_unescaped(buf, chistics->comment.str, chistics->comment.length);
buf->append('\n');
}

View File

@ -36,7 +36,8 @@ int
sp_drop_db_routines(THD *thd, char *db);
sp_head *
sp_find_procedure(THD *thd, sp_name *name, bool cache_only = 0);
sp_find_routine(THD *thd, int type, sp_name *name,
sp_cache **cp, bool cache_only);
int
sp_exists_routine(THD *thd, TABLE_LIST *procs, bool any, bool no_error);
@ -57,9 +58,6 @@ sp_show_create_procedure(THD *thd, sp_name *name);
int
sp_show_status_procedure(THD *thd, const char *wild);
sp_head *
sp_find_function(THD *thd, sp_name *name, bool cache_only = 0);
int
sp_create_function(THD *thd, sp_head *sp);

View File

@ -105,6 +105,8 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_SHOW_TABLES:
case SQLCOM_SHOW_VARIABLES:
case SQLCOM_SHOW_WARNS:
case SQLCOM_SHOW_PROC_CODE:
case SQLCOM_SHOW_FUNC_CODE:
flags= sp_head::MULTI_RESULTS;
break;
/*
@ -476,7 +478,8 @@ sp_head::operator delete(void *ptr, size_t size)
sp_head::sp_head()
:Query_arena(&main_mem_root, INITIALIZED_FOR_SP),
m_flags(0), m_returns_cs(NULL)
m_flags(0), m_returns_cs(NULL), m_recursion_level(0), m_next_cached_sp(0),
m_first_instance(this), m_first_free_instance(this), m_last_cached_sp(this)
{
extern byte *
sp_table_key(const byte *ptr, uint *plen, my_bool first);
@ -657,6 +660,7 @@ sp_head::create(THD *thd)
sp_head::~sp_head()
{
destroy();
delete m_next_cached_sp;
if (m_thd)
restore_thd_mem_root(m_thd);
}
@ -858,9 +862,9 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
prev_pos= (*splocal)->pos_in_query + (*splocal)->m_name.length;
/* append the spvar substitute */
res|= qbuf.append(" NAME_CONST('");
res|= qbuf.append(STRING_WITH_LEN(" NAME_CONST('"));
res|= qbuf.append((*splocal)->m_name.str, (*splocal)->m_name.length);
res|= qbuf.append("',");
res|= qbuf.append(STRING_WITH_LEN("',"));
val= (*splocal)->this_item();
DBUG_PRINT("info", ("print %p", val));
val->print(&qbuf);
@ -882,6 +886,31 @@ static bool subst_spvars(THD *thd, sp_instr *instr, LEX_STRING *query_str)
}
/*
Return appropriate error about recursion limit reaching
SYNOPSIS
sp_head::recursion_level_error()
NOTE
For functions and triggers we return error about prohibited recursion.
For stored procedures we return about reaching recursion limit.
*/
void sp_head::recursion_level_error()
{
if (m_type == TYPE_ENUM_PROCEDURE)
{
THD *thd= current_thd;
my_error(ER_SP_RECURSION_LIMIT, MYF(0),
thd->variables.max_sp_recursion_depth,
m_name);
}
else
my_error(ER_SP_NO_RECURSION, MYF(0));
}
/*
Execute the routine. The main instruction jump loop is there
Assume the parameters already set.
@ -911,37 +940,31 @@ int sp_head::execute(THD *thd)
Item_change_list old_change_list;
String old_packet;
/* Use some extra margin for possible SP recursion and functions */
if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char*)&old_packet))
{
DBUG_RETURN(-1);
}
/* init per-instruction memroot */
init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
/* Use some extra margin for possible SP recursion and functions */
if (check_stack_overrun(thd, 4*STACK_MIN_SIZE, olddb))
{
DBUG_RETURN(-1);
}
if (m_flags & IS_INVOKED)
{
/*
We have to disable recursion for stored routines since in
many cases LEX structure and many Item's can't be used in
reentrant way now.
TODO: We can circumvent this problem by using separate
sp_head instances for each recursive invocation.
NOTE: Theoretically arguments of procedure can be evaluated
before its invocation so there should be no problem with
recursion. But since we perform cleanup for CALL statement
as for any other statement only after its execution, its LEX
structure is not reusable for recursive calls. Thus we have
to prohibit recursion for stored procedures too.
*/
my_error(ER_SP_NO_RECURSION, MYF(0));
DBUG_RETURN(-1);
}
DBUG_ASSERT(!(m_flags & IS_INVOKED));
m_flags|= IS_INVOKED;
m_first_instance->m_first_free_instance= m_next_cached_sp;
DBUG_PRINT("info", ("first free for 0x%lx ++: 0x%lx->0x%lx, level: %lu, flags %x",
(ulong)m_first_instance, this, m_next_cached_sp,
m_next_cached_sp->m_recursion_level,
m_next_cached_sp->m_flags));
/*
Check that if there are not any instances after this one then
pointer to the last instance points on this instance or if there are
some instances after this one then recursion level of next instance
greater then recursion level of current instance on 1
*/
DBUG_ASSERT((m_next_cached_sp == 0 &&
m_first_instance->m_last_cached_sp == this) ||
(m_recursion_level + 1 == m_next_cached_sp->m_recursion_level));
dbchanged= FALSE;
if (m_db.length &&
@ -1116,6 +1139,29 @@ int sp_head::execute(THD *thd)
ret= mysql_change_db(thd, olddb, 1);
}
m_flags&= ~IS_INVOKED;
DBUG_PRINT("info", ("first free for 0x%lx --: 0x%lx->0x%lx, level: %lu, flags %x",
(ulong)m_first_instance,
m_first_instance->m_first_free_instance, this,
m_recursion_level, m_flags));
/*
Check that we have one of following:
1) there are not free instances which means that this instance is last
in the list of instances (pointer to the last instance point on it and
ther are not other instances after this one in the list)
2) There are some free instances which mean that first free instance
should go just after this one and recursion level of that free instance
should be on 1 more then recursion leven of this instance.
*/
DBUG_ASSERT((m_first_instance->m_first_free_instance == 0 &&
this == m_first_instance->m_last_cached_sp &&
m_next_cached_sp == 0) ||
(m_first_instance->m_first_free_instance != 0 &&
m_first_instance->m_first_free_instance == m_next_cached_sp &&
m_first_instance->m_first_free_instance->m_recursion_level ==
m_recursion_level + 1));
m_first_instance->m_first_free_instance= this;
DBUG_RETURN(ret);
}
@ -1173,6 +1219,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
// QQ Should have some error checking here? (types, etc...)
if (!(nctx= new sp_rcontext(octx, csize, hmax, cmax)))
goto end;
#ifndef DBUG_OFF
nctx->owner= this;
#endif
for (i= 0 ; i < argcount ; i++)
{
sp_pvar_t *pvar = m_pcont->find_pvar(i);
@ -1215,7 +1264,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
char buf[256];
String bufstr(buf, sizeof(buf), &my_charset_bin);
bufstr.length(0);
bufstr.append("DO ", 3);
bufstr.append(STRING_WITH_LEN("DO "));
append_identifier(thd, &bufstr, m_name.str, m_name.length);
bufstr.append('(');
for (uint i=0; i < argcount; i++)
@ -1317,6 +1366,9 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
{ // Create a temporary old context
if (!(octx= new sp_rcontext(octx, csize, hmax, cmax)))
DBUG_RETURN(-1);
#ifndef DBUG_OFF
octx->owner= 0;
#endif
thd->spcont= octx;
/* set callers_arena to thd, for upper-level function to work */
@ -1328,6 +1380,9 @@ int sp_head::execute_procedure(THD *thd, List<Item> *args)
thd->spcont= save_spcont;
DBUG_RETURN(-1);
}
#ifndef DBUG_OFF
nctx->owner= this;
#endif
if (csize > 0 || hmax > 0 || cmax > 0)
{
@ -1740,7 +1795,7 @@ sp_head::show_create_procedure(THD *thd)
LINT_INIT(sql_mode_len);
if (check_show_routine_access(thd, this, &full_access))
return 1;
DBUG_RETURN(1);
sql_mode_str=
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
@ -1753,10 +1808,7 @@ sp_head::show_create_procedure(THD *thd)
max(buffer.length(), 1024)));
if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
{
res= 1;
goto done;
}
DBUG_RETURN(1);
protocol->prepare_for_resend();
protocol->store(m_name.str, m_name.length, system_charset_info);
protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
@ -1765,7 +1817,6 @@ sp_head::show_create_procedure(THD *thd)
res= protocol->write();
send_eof(thd);
done:
DBUG_RETURN(res);
}
@ -1810,7 +1861,7 @@ sp_head::show_create_function(THD *thd)
LINT_INIT(sql_mode_len);
if (check_show_routine_access(thd, this, &full_access))
return 1;
DBUG_RETURN(1);
sql_mode_str=
sys_var_thd_sql_mode::symbolic_mode_representation(thd,
@ -1822,10 +1873,7 @@ sp_head::show_create_function(THD *thd)
max(buffer.length(),1024)));
if (protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
{
res= 1;
goto done;
}
DBUG_RETURN(1);
protocol->prepare_for_resend();
protocol->store(m_name.str, m_name.length, system_charset_info);
protocol->store((char*) sql_mode_str, sql_mode_len, system_charset_info);
@ -1834,7 +1882,6 @@ sp_head::show_create_function(THD *thd)
res= protocol->write();
send_eof(thd);
done:
DBUG_RETURN(res);
}
@ -1894,6 +1941,50 @@ sp_head::opt_mark(uint ip)
}
#ifndef DBUG_OFF
int
sp_head::show_routine_code(THD *thd)
{
Protocol *protocol= thd->protocol;
char buff[2048];
String buffer(buff, sizeof(buff), system_charset_info);
List<Item> field_list;
sp_instr *i;
bool full_access;
int res= 0;
uint ip;
DBUG_ENTER("sp_head::show_routine_code");
DBUG_PRINT("info", ("procedure: %s", m_name.str));
if (check_show_routine_access(thd, this, &full_access) || !full_access)
DBUG_RETURN(1);
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)));
if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
Protocol::SEND_EOF))
DBUG_RETURN(1);
for (ip= 0; (i = get_instr(ip)) ; ip++)
{
protocol->prepare_for_resend();
protocol->store((longlong)ip);
buffer.set("", 0, system_charset_info);
i->print(&buffer);
protocol->store(buffer.ptr(), buffer.length(), system_charset_info);
if ((res= protocol->write()))
break;
}
send_eof(thd);
DBUG_RETURN(res);
}
#endif // ifndef DBUG_OFF
/*
Prepare LEX and thread for execution of instruction, if requested open
and lock LEX's tables, execute instruction's core function, perform
@ -2052,14 +2143,43 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
DBUG_RETURN(res);
}
/*
Sufficient max length of printed destinations and frame offsets (all uints).
*/
#define SP_INSTR_UINT_MAXLEN 8
#define SP_STMT_PRINT_MAXLEN 40
void
sp_instr_stmt::print(String *str)
{
str->reserve(12);
str->append("stmt ");
str->qs_append((uint)m_lex_keeper.sql_command());
}
uint i, len;
/* stmt CMD "..." */
if (str->reserve(SP_STMT_PRINT_MAXLEN+SP_INSTR_UINT_MAXLEN+8))
return;
str->qs_append(STRING_WITH_LEN("stmt "));
str->qs_append((uint)m_lex_keeper.sql_command());
str->qs_append(STRING_WITH_LEN(" \""));
len= m_query.length;
/*
Print the query string (but not too much of it), just to indicate which
statement it is.
*/
if (len > SP_STMT_PRINT_MAXLEN)
len= SP_STMT_PRINT_MAXLEN-3;
/* Copy the query string and replace '\n' with ' ' in the process */
for (i= 0 ; i < len ; i++)
{
if (m_query.str[i] == '\n')
str->qs_append(' ');
else
str->qs_append(m_query.str[i]);
}
if (m_query.length > SP_STMT_PRINT_MAXLEN)
str->qs_append(STRING_WITH_LEN("...")); /* Indicate truncated string */
str->qs_append('"');
}
#undef SP_STMT_PRINT_MAXLEN
int
sp_instr_stmt::exec_core(THD *thd, uint *nextp)
@ -2096,10 +2216,23 @@ sp_instr_set::exec_core(THD *thd, uint *nextp)
void
sp_instr_set::print(String *str)
{
str->reserve(12);
str->append("set ");
/* set name@offset ... */
int rsrv = SP_INSTR_UINT_MAXLEN+6;
sp_pvar_t *var = m_ctx->find_pvar(m_offset);
/* 'var' should always be non-null, but just in case... */
if (var)
rsrv+= var->name.length;
if (str->reserve(rsrv))
return;
str->qs_append(STRING_WITH_LEN("set "));
if (var)
{
str->qs_append(var->name.str, var->name.length);
str->qs_append('@');
}
str->qs_append(m_offset);
str->append(' ');
str->qs_append(' ');
m_value->print(str);
}
@ -2132,9 +2265,9 @@ sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
void
sp_instr_set_trigger_field::print(String *str)
{
str->append("set ", 4);
str->append(STRING_WITH_LEN("set_trigger_field "));
trigger_field->print(str);
str->append(":=", 2);
str->append(STRING_WITH_LEN(":="));
value->print(str);
}
@ -2156,8 +2289,10 @@ sp_instr_jump::execute(THD *thd, uint *nextp)
void
sp_instr_jump::print(String *str)
{
str->reserve(12);
str->append("jump ");
/* jump dest */
if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
return;
str->qs_append(STRING_WITH_LEN("jump "));
str->qs_append(m_dest);
}
@ -2238,10 +2373,12 @@ sp_instr_jump_if::exec_core(THD *thd, uint *nextp)
void
sp_instr_jump_if::print(String *str)
{
str->reserve(12);
str->append("jump_if ");
/* jump_if dest ... */
if (str->reserve(SP_INSTR_UINT_MAXLEN+8+32)) // Add some for the expr. too
return;
str->qs_append(STRING_WITH_LEN("jump_if "));
str->qs_append(m_dest);
str->append(' ');
str->qs_append(' ');
m_expr->print(str);
}
@ -2299,10 +2436,12 @@ sp_instr_jump_if_not::exec_core(THD *thd, uint *nextp)
void
sp_instr_jump_if_not::print(String *str)
{
str->reserve(16);
str->append("jump_if_not ");
/* jump_if_not dest ... */
if (str->reserve(SP_INSTR_UINT_MAXLEN+12+32)) // Add some for the expr. too
return;
str->qs_append(STRING_WITH_LEN("jump_if_not "));
str->qs_append(m_dest);
str->append(' ');
str->qs_append(' ');
m_expr->print(str);
}
@ -2357,10 +2496,12 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp)
void
sp_instr_freturn::print(String *str)
{
str->reserve(12);
str->append("freturn ");
/* freturn type expr... */
if (str->reserve(UINT_MAX+8+32)) // Add some for the expr. too
return;
str->qs_append(STRING_WITH_LEN("freturn "));
str->qs_append((uint)m_type);
str->append(' ');
str->qs_append(' ');
m_value->print(str);
}
@ -2385,15 +2526,31 @@ sp_instr_hpush_jump::execute(THD *thd, uint *nextp)
void
sp_instr_hpush_jump::print(String *str)
{
str->reserve(32);
str->append("hpush_jump ");
/* hpush_jump dest fsize type */
if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 21))
return;
str->qs_append(STRING_WITH_LEN("hpush_jump "));
str->qs_append(m_dest);
str->append(" t=");
str->qs_append(m_type);
str->append(" f=");
str->qs_append(' ');
str->qs_append(m_frame);
str->append(" h=");
str->qs_append(m_ip+1);
switch (m_type)
{
case SP_HANDLER_NONE:
str->qs_append(STRING_WITH_LEN(" NONE")); // This would be a bug
break;
case SP_HANDLER_EXIT:
str->qs_append(STRING_WITH_LEN(" EXIT"));
break;
case SP_HANDLER_CONTINUE:
str->qs_append(STRING_WITH_LEN(" CONTINUE"));
break;
case SP_HANDLER_UNDO:
str->qs_append(STRING_WITH_LEN(" UNDO"));
break;
default:
str->qs_append(STRING_WITH_LEN(" UNKNOWN:")); // This would be a bug as well
str->qs_append(m_type);
}
}
uint
@ -2428,8 +2585,10 @@ sp_instr_hpop::execute(THD *thd, uint *nextp)
void
sp_instr_hpop::print(String *str)
{
str->reserve(12);
str->append("hpop ");
/* hpop count */
if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
return;
str->qs_append(STRING_WITH_LEN("hpop "));
str->qs_append(m_count);
}
@ -2463,12 +2622,14 @@ sp_instr_hreturn::execute(THD *thd, uint *nextp)
void
sp_instr_hreturn::print(String *str)
{
str->reserve(16);
str->append("hreturn ");
/* hreturn framesize dest */
if (str->reserve(SP_INSTR_UINT_MAXLEN*2 + 9))
return;
str->qs_append(STRING_WITH_LEN("hreturn "));
str->qs_append(m_frame);
if (m_dest)
{
str->append(' ');
str->qs_append(' ');
str->qs_append(m_dest);
}
}
@ -2516,7 +2677,22 @@ sp_instr_cpush::execute(THD *thd, uint *nextp)
void
sp_instr_cpush::print(String *str)
{
str->append("cpush");
LEX_STRING n;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
/* cpush name@offset */
uint rsrv= SP_INSTR_UINT_MAXLEN+7;
if (found)
rsrv+= n.length;
if (str->reserve(rsrv))
return;
str->qs_append(STRING_WITH_LEN("cpush "));
if (found)
{
str->qs_append(n.str, n.length);
str->qs_append('@');
}
str->qs_append(m_cursor);
}
@ -2537,8 +2713,10 @@ sp_instr_cpop::execute(THD *thd, uint *nextp)
void
sp_instr_cpop::print(String *str)
{
str->reserve(12);
str->append("cpop ");
/* cpop count */
if (str->reserve(SP_INSTR_UINT_MAXLEN+5))
return;
str->qs_append(STRING_WITH_LEN("cpop "));
str->qs_append(m_count);
}
@ -2612,8 +2790,21 @@ sp_instr_copen::exec_core(THD *thd, uint *nextp)
void
sp_instr_copen::print(String *str)
{
str->reserve(12);
str->append("copen ");
LEX_STRING n;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
/* copen name@offset */
uint rsrv= SP_INSTR_UINT_MAXLEN+7;
if (found)
rsrv+= n.length;
if (str->reserve(rsrv))
return;
str->qs_append(STRING_WITH_LEN("copen "));
if (found)
{
str->qs_append(n.str, n.length);
str->qs_append('@');
}
str->qs_append(m_cursor);
}
@ -2641,8 +2832,21 @@ sp_instr_cclose::execute(THD *thd, uint *nextp)
void
sp_instr_cclose::print(String *str)
{
str->reserve(12);
str->append("cclose ");
LEX_STRING n;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
/* cclose name@offset */
uint rsrv= SP_INSTR_UINT_MAXLEN+8;
if (found)
rsrv+= n.length;
if (str->reserve(rsrv))
return;
str->qs_append(STRING_WITH_LEN("cclose "));
if (found)
{
str->qs_append(n.str, n.length);
str->qs_append('@');
}
str->qs_append(m_cursor);
}
@ -2671,14 +2875,29 @@ sp_instr_cfetch::print(String *str)
{
List_iterator_fast<struct sp_pvar> li(m_varlist);
sp_pvar_t *pv;
LEX_STRING n;
my_bool found= m_ctx->find_cursor(m_cursor, &n);
/* cfetch name@offset vars... */
uint rsrv= SP_INSTR_UINT_MAXLEN+8;
str->reserve(12);
str->append("cfetch ");
if (found)
rsrv+= n.length;
if (str->reserve(rsrv))
return;
str->qs_append(STRING_WITH_LEN("cfetch "));
if (found)
{
str->qs_append(n.str, n.length);
str->qs_append('@');
}
str->qs_append(m_cursor);
while ((pv= li++))
{
str->reserve(8);
str->append(' ');
if (str->reserve(pv->name.length+SP_INSTR_UINT_MAXLEN+2))
return;
str->qs_append(' ');
str->qs_append(pv->name.str, pv->name.length);
str->qs_append('@');
str->qs_append(pv->offset);
}
}
@ -2702,8 +2921,10 @@ sp_instr_error::execute(THD *thd, uint *nextp)
void
sp_instr_error::print(String *str)
{
str->reserve(12);
str->append("error ");
/* error code */
if (str->reserve(SP_INSTR_UINT_MAXLEN+6))
return;
str->qs_append(STRING_WITH_LEN("error "));
str->qs_append(m_errcode);
}

View File

@ -143,6 +143,32 @@ public:
LEX_STRING m_definer_host;
longlong m_created;
longlong m_modified;
/* Recursion level of the current SP instance. The levels are numbered from 0 */
ulong m_recursion_level;
/*
A list of diferent recursion level instances for the same procedure.
For every recursion level we have a sp_head instance. This instances
connected in the list. The list ordered by increasing recursion level
(m_recursion_level).
*/
sp_head *m_next_cached_sp;
/*
Pointer to the first element of the above list
*/
sp_head *m_first_instance;
/*
Pointer to the first free (non-INVOKED) routine in the list of
cached instances for this SP. This pointer is set only for the first
SP in the list of instences (see above m_first_cached_sp pointer).
The pointer equal to 0 if we have no free instances.
For non-first instance value of this pointer meanless (point to itself);
*/
sp_head *m_first_free_instance;
/*
Pointer to the last element in the list of instances of the SP.
For non-first instance value of this pointer meanless (point to itself);
*/
sp_head *m_last_cached_sp;
/*
Set containing names of stored routines used by this routine.
Note that unlike elements of similar set for statement elements of this
@ -266,6 +292,8 @@ public:
void optimize();
void opt_mark(uint ip);
void recursion_level_error();
inline sp_instr *
get_instr(uint i)
{
@ -304,6 +332,12 @@ public:
return test(m_flags &
(CONTAINS_DYNAMIC_SQL|MULTI_RESULTS|HAS_SET_AUTOCOMMIT_STMT));
}
#ifndef DBUG_OFF
int show_routine_code(THD *thd);
#endif
private:
MEM_ROOT *m_thd_root; // Temp. store for thd's mem_root
@ -865,8 +899,8 @@ class sp_instr_cpush : public sp_instr
public:
sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *lex)
: sp_instr(ip, ctx), m_lex_keeper(lex, TRUE)
sp_instr_cpush(uint ip, sp_pcontext *ctx, LEX *lex, uint offset)
: sp_instr(ip, ctx), m_lex_keeper(lex, TRUE), m_cursor(offset)
{}
virtual ~sp_instr_cpush()
@ -885,6 +919,7 @@ public:
private:
sp_lex_keeper m_lex_keeper;
uint m_cursor; /* Frame offset (for debugging) */
}; // class sp_instr_cpush : public sp_instr

View File

@ -169,6 +169,28 @@ sp_pcontext::find_pvar(LEX_STRING *name, my_bool scoped)
return NULL;
}
/*
Find a variable by offset from the top.
This used for two things:
- When evaluating parameters at the beginning, and setting out parameters
at the end, of invokation. (Top frame only, so no recursion then.)
- For printing of sp_instr_set. (Debug mode only.)
*/
sp_pvar_t *
sp_pcontext::find_pvar(uint offset)
{
if (m_poffset <= offset && offset < m_poffset + m_pvar.elements)
{ // This frame
sp_pvar_t *p;
get_dynamic(&m_pvar, (gptr)&p, offset - m_poffset);
return p;
}
if (m_parent)
return m_parent->find_pvar(offset); // Some previous frame
return NULL; // index out of bounds
}
void
sp_pcontext::push_pvar(LEX_STRING *name, enum enum_field_types type,
sp_param_mode_t mode)
@ -331,3 +353,21 @@ sp_pcontext::find_cursor(LEX_STRING *name, uint *poff, my_bool scoped)
return m_parent->find_cursor(name, poff, scoped);
return FALSE;
}
/*
Find a cursor by offset from the top.
This is only used for debugging.
*/
my_bool
sp_pcontext::find_cursor(uint offset, LEX_STRING *n)
{
if (m_coffset <= offset && offset < m_coffset + m_cursor.elements)
{ // This frame
get_dynamic(&m_cursor, (gptr)n, offset - m_coffset);
return TRUE;
}
if (m_parent)
return m_parent->find_cursor(offset, n); // Some previous frame
return FALSE; // index out of bounds
}

View File

@ -170,18 +170,9 @@ class sp_pcontext : public Sql_alloc
sp_pvar_t *
find_pvar(LEX_STRING *name, my_bool scoped=0);
// Find by index
// Find by offset
sp_pvar_t *
find_pvar(uint i)
{
sp_pvar_t *p;
if (i < m_pvar.elements)
get_dynamic(&m_pvar, (gptr)&p, i);
else
p= NULL;
return p;
}
find_pvar(uint offset);
//
// Labels
@ -261,6 +252,10 @@ class sp_pcontext : public Sql_alloc
my_bool
find_cursor(LEX_STRING *name, uint *poff, my_bool scoped=0);
/* Find by offset (for debugging only) */
my_bool
find_cursor(uint offset, LEX_STRING *n);
inline uint
max_cursors()
{

View File

@ -66,6 +66,14 @@ class sp_rcontext : public Sql_alloc
*/
Query_arena *callers_arena;
#ifndef DBUG_OFF
/*
Routine to which this Item_splocal belongs. Used for checking if correct
runtime context is used for variable handling.
*/
sp_head *owner;
#endif
sp_rcontext(sp_rcontext *prev, uint fsize, uint hmax, uint cmax);
~sp_rcontext()

View File

@ -1793,7 +1793,7 @@ bool Gis_geometry_collection::get_data_as_wkt(String *txt,
geom->set_data_ptr(data, (uint) (m_data_end - data));
if (geom->as_wkt(txt, &data))
return 1;
if (txt->append(",", 1, 512))
if (txt->append(STRING_WITH_LEN(","), 512))
return 1;
}
txt->length(txt->length() - 1);

View File

@ -1810,19 +1810,22 @@ static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo,
/* We write down SSL related ACL stuff */
switch (lex->ssl_type) {
case SSL_TYPE_ANY:
table->field[next_field]->store("ANY", 3, &my_charset_latin1);
table->field[next_field]->store(STRING_WITH_LEN("ANY"),
&my_charset_latin1);
table->field[next_field+1]->store("", 0, &my_charset_latin1);
table->field[next_field+2]->store("", 0, &my_charset_latin1);
table->field[next_field+3]->store("", 0, &my_charset_latin1);
break;
case SSL_TYPE_X509:
table->field[next_field]->store("X509", 4, &my_charset_latin1);
table->field[next_field]->store(STRING_WITH_LEN("X509"),
&my_charset_latin1);
table->field[next_field+1]->store("", 0, &my_charset_latin1);
table->field[next_field+2]->store("", 0, &my_charset_latin1);
table->field[next_field+3]->store("", 0, &my_charset_latin1);
break;
case SSL_TYPE_SPECIFIED:
table->field[next_field]->store("SPECIFIED", 9, &my_charset_latin1);
table->field[next_field]->store(STRING_WITH_LEN("SPECIFIED"),
&my_charset_latin1);
table->field[next_field+1]->store("", 0, &my_charset_latin1);
table->field[next_field+2]->store("", 0, &my_charset_latin1);
table->field[next_field+3]->store("", 0, &my_charset_latin1);
@ -4056,13 +4059,13 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
String global(buff,sizeof(buff),system_charset_info);
global.length(0);
global.append("GRANT ",6);
global.append(STRING_WITH_LEN("GRANT "));
want_access= acl_user->access;
if (test_all_bits(want_access, (GLOBAL_ACLS & ~ GRANT_ACL)))
global.append("ALL PRIVILEGES",14);
global.append(STRING_WITH_LEN("ALL PRIVILEGES"));
else if (!(want_access & ~GRANT_ACL))
global.append("USAGE",5);
global.append(STRING_WITH_LEN("USAGE"));
else
{
bool found=0;
@ -4072,16 +4075,16 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (test_access & j)
{
if (found)
global.append(", ",2);
global.append(STRING_WITH_LEN(", "));
found=1;
global.append(command_array[counter],command_lengths[counter]);
}
}
}
global.append (" ON *.* TO '",12);
global.append (STRING_WITH_LEN(" ON *.* TO '"));
global.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
global.append ("'@'",3);
global.append (STRING_WITH_LEN("'@'"));
global.append(lex_user->host.str,lex_user->host.length,
system_charset_info);
global.append ('\'');
@ -4092,23 +4095,23 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
make_password_from_salt(passwd_buff, acl_user->salt);
else
make_password_from_salt_323(passwd_buff, (ulong *) acl_user->salt);
global.append(" IDENTIFIED BY PASSWORD '",25);
global.append(STRING_WITH_LEN(" IDENTIFIED BY PASSWORD '"));
global.append(passwd_buff);
global.append('\'');
}
/* "show grants" SSL related stuff */
if (acl_user->ssl_type == SSL_TYPE_ANY)
global.append(" REQUIRE SSL",12);
global.append(STRING_WITH_LEN(" REQUIRE SSL"));
else if (acl_user->ssl_type == SSL_TYPE_X509)
global.append(" REQUIRE X509",13);
global.append(STRING_WITH_LEN(" REQUIRE X509"));
else if (acl_user->ssl_type == SSL_TYPE_SPECIFIED)
{
int ssl_options = 0;
global.append(" REQUIRE ",9);
global.append(STRING_WITH_LEN(" REQUIRE "));
if (acl_user->x509_issuer)
{
ssl_options++;
global.append("ISSUER \'",8);
global.append(STRING_WITH_LEN("ISSUER \'"));
global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer));
global.append('\'');
}
@ -4116,7 +4119,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
if (ssl_options++)
global.append(' ');
global.append("SUBJECT \'",9);
global.append(STRING_WITH_LEN("SUBJECT \'"));
global.append(acl_user->x509_subject,strlen(acl_user->x509_subject),
system_charset_info);
global.append('\'');
@ -4125,7 +4128,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
if (ssl_options++)
global.append(' ');
global.append("CIPHER '",8);
global.append(STRING_WITH_LEN("CIPHER '"));
global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher),
system_charset_info);
global.append('\'');
@ -4137,9 +4140,9 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
acl_user->user_resource.conn_per_hour ||
acl_user->user_resource.user_conn))
{
global.append(" WITH",5);
global.append(STRING_WITH_LEN(" WITH"));
if (want_access & GRANT_ACL)
global.append(" GRANT OPTION",13);
global.append(STRING_WITH_LEN(" GRANT OPTION"));
add_user_option(&global, acl_user->user_resource.questions,
"MAX_QUERIES_PER_HOUR");
add_user_option(&global, acl_user->user_resource.updates,
@ -4177,12 +4180,12 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
{
String db(buff,sizeof(buff),system_charset_info);
db.length(0);
db.append("GRANT ",6);
db.append(STRING_WITH_LEN("GRANT "));
if (test_all_bits(want_access,(DB_ACLS & ~GRANT_ACL)))
db.append("ALL PRIVILEGES",14);
db.append(STRING_WITH_LEN("ALL PRIVILEGES"));
else if (!(want_access & ~GRANT_ACL))
db.append("USAGE",5);
db.append(STRING_WITH_LEN("USAGE"));
else
{
int found=0, cnt;
@ -4192,23 +4195,23 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (test_access & j)
{
if (found)
db.append(", ",2);
db.append(STRING_WITH_LEN(", "));
found = 1;
db.append(command_array[cnt],command_lengths[cnt]);
}
}
}
db.append (" ON ",4);
db.append (STRING_WITH_LEN(" ON "));
append_identifier(thd, &db, acl_db->db, strlen(acl_db->db));
db.append (".* TO '",7);
db.append (STRING_WITH_LEN(".* TO '"));
db.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
db.append ("'@'",3);
db.append (STRING_WITH_LEN("'@'"));
db.append(lex_user->host.str, lex_user->host.length,
system_charset_info);
db.append ('\'');
if (want_access & GRANT_ACL)
db.append(" WITH GRANT OPTION",18);
db.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
protocol->prepare_for_resend();
protocol->store(db.ptr(),db.length(),db.charset());
if (protocol->write())
@ -4241,12 +4244,12 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
ulong test_access= (table_access | grant_table->cols) & ~GRANT_ACL;
global.length(0);
global.append("GRANT ",6);
global.append(STRING_WITH_LEN("GRANT "));
if (test_all_bits(table_access, (TABLE_ACLS & ~GRANT_ACL)))
global.append("ALL PRIVILEGES",14);
global.append(STRING_WITH_LEN("ALL PRIVILEGES"));
else if (!test_access)
global.append("USAGE",5);
global.append(STRING_WITH_LEN("USAGE"));
else
{
/* Add specific column access */
@ -4258,7 +4261,7 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
if (test_access & j)
{
if (found)
global.append(", ",2);
global.append(STRING_WITH_LEN(", "));
found= 1;
global.append(command_array[counter],command_lengths[counter]);
@ -4282,14 +4285,14 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
*/
if (table_access & j)
{
global.append(", ", 2);
global.append(STRING_WITH_LEN(", "));
global.append(command_array[counter],
command_lengths[counter]);
}
global.append(" (",2);
global.append(STRING_WITH_LEN(" ("));
}
else
global.append(", ",2);
global.append(STRING_WITH_LEN(", "));
global.append(grant_column->column,
grant_column->key_length,
system_charset_info);
@ -4301,21 +4304,21 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
}
}
global.append(" ON ",4);
global.append(STRING_WITH_LEN(" ON "));
append_identifier(thd, &global, grant_table->db,
strlen(grant_table->db));
global.append('.');
append_identifier(thd, &global, grant_table->tname,
strlen(grant_table->tname));
global.append(" TO '",5);
global.append(STRING_WITH_LEN(" TO '"));
global.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
global.append("'@'",3);
global.append(STRING_WITH_LEN("'@'"));
global.append(lex_user->host.str,lex_user->host.length,
system_charset_info);
global.append('\'');
if (table_access & GRANT_ACL)
global.append(" WITH GRANT OPTION",18);
global.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
if (protocol->write())
@ -4328,14 +4331,14 @@ bool mysql_show_grants(THD *thd,LEX_USER *lex_user)
}
if (show_routine_grants(thd, lex_user, &proc_priv_hash,
"PROCEDURE", 9, buff, sizeof(buff)))
STRING_WITH_LEN("PROCEDURE"), buff, sizeof(buff)))
{
error= -1;
goto end;
}
if (show_routine_grants(thd, lex_user, &func_priv_hash,
"FUNCTION", 8, buff, sizeof(buff)))
STRING_WITH_LEN("FUNCTION"), buff, sizeof(buff)))
{
error= -1;
goto end;
@ -4376,10 +4379,10 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
ulong test_access= proc_access & ~GRANT_ACL;
global.length(0);
global.append("GRANT ",6);
global.append(STRING_WITH_LEN("GRANT "));
if (!test_access)
global.append("USAGE",5);
global.append(STRING_WITH_LEN("USAGE"));
else
{
/* Add specific procedure access */
@ -4391,13 +4394,13 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
if (test_access & j)
{
if (found)
global.append(", ",2);
global.append(STRING_WITH_LEN(", "));
found= 1;
global.append(command_array[counter],command_lengths[counter]);
}
}
}
global.append(" ON ",4);
global.append(STRING_WITH_LEN(" ON "));
global.append(type,typelen);
global.append(' ');
append_identifier(thd, &global, grant_proc->db,
@ -4405,15 +4408,15 @@ static int show_routine_grants(THD* thd, LEX_USER *lex_user, HASH *hash,
global.append('.');
append_identifier(thd, &global, grant_proc->tname,
strlen(grant_proc->tname));
global.append(" TO '",5);
global.append(STRING_WITH_LEN(" TO '"));
global.append(lex_user->user.str, lex_user->user.length,
system_charset_info);
global.append("'@'",3);
global.append(STRING_WITH_LEN("'@'"));
global.append(lex_user->host.str,lex_user->host.length,
system_charset_info);
global.append('\'');
if (proc_access & GRANT_ACL)
global.append(" WITH GRANT OPTION",18);
global.append(STRING_WITH_LEN(" WITH GRANT OPTION"));
protocol->prepare_for_resend();
protocol->store(global.ptr(),global.length(),global.charset());
if (protocol->write())
@ -5068,7 +5071,7 @@ static void append_user(String *str, LEX_USER *user)
str->append(',');
str->append('\'');
str->append(user->user.str);
str->append("'@'");
str->append(STRING_WITH_LEN("'@'"));
str->append(user->host.str);
str->append('\'');
}
@ -5650,7 +5653,8 @@ int fill_schema_user_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
strxmov(buff,"'",user,"'@'",host,"'",NullS);
if (!(want_access & ~GRANT_ACL))
update_schema_privilege(table, buff, 0, 0, 0, 0, "USAGE", 5, is_grantable);
update_schema_privilege(table, buff, 0, 0, 0, 0,
STRING_WITH_LEN("USAGE"), is_grantable);
else
{
uint priv_id;
@ -5708,7 +5712,7 @@ int fill_schema_schema_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
strxmov(buff,"'",user,"'@'",host,"'",NullS);
if (!(want_access & ~GRANT_ACL))
update_schema_privilege(table, buff, acl_db->db, 0, 0,
0, "USAGE", 5, is_grantable);
0, STRING_WITH_LEN("USAGE"), is_grantable);
else
{
int cnt;
@ -5768,7 +5772,7 @@ int fill_schema_table_privileges(THD *thd, TABLE_LIST *tables, COND *cond)
strxmov(buff,"'",user,"'@'",grant_table->host.hostname,"'",NullS);
if (!test_access)
update_schema_privilege(table, buff, grant_table->db, grant_table->tname,
0, 0, "USAGE", 5, is_grantable);
0, 0, STRING_WITH_LEN("USAGE"), is_grantable);
else
{
ulong j;

View File

@ -733,13 +733,13 @@ bool analyse::end_of_records()
tree_info.found = 0;
tree_info.item = (*f)->item;
tmp_str.set("ENUM(", 5,&my_charset_bin);
tmp_str.set(STRING_WITH_LEN("ENUM("),&my_charset_bin);
tree_walk(&(*f)->tree, (*f)->collect_enum(), (char*) &tree_info,
left_root_right);
tmp_str.append(')');
if (!(*f)->nulls)
tmp_str.append(" NOT NULL");
tmp_str.append(STRING_WITH_LEN(" NOT NULL"));
output_str_length = tmp_str.length();
func_items[9]->set(tmp_str.ptr(), tmp_str.length(), tmp_str.charset());
if (result->send_data(result_fields))
@ -749,35 +749,35 @@ bool analyse::end_of_records()
ans.length(0);
if (!(*f)->treemem && !(*f)->tree_elements)
ans.append("CHAR(0)", 7);
ans.append(STRING_WITH_LEN("CHAR(0)"));
else if ((*f)->item->type() == Item::FIELD_ITEM)
{
switch (((Item_field*) (*f)->item)->field->real_type())
{
case FIELD_TYPE_TIMESTAMP:
ans.append("TIMESTAMP", 9);
ans.append(STRING_WITH_LEN("TIMESTAMP"));
break;
case FIELD_TYPE_DATETIME:
ans.append("DATETIME", 8);
ans.append(STRING_WITH_LEN("DATETIME"));
break;
case FIELD_TYPE_DATE:
case FIELD_TYPE_NEWDATE:
ans.append("DATE", 4);
ans.append(STRING_WITH_LEN("DATE"));
break;
case FIELD_TYPE_SET:
ans.append("SET", 3);
ans.append(STRING_WITH_LEN("SET"));
break;
case FIELD_TYPE_YEAR:
ans.append("YEAR", 4);
ans.append(STRING_WITH_LEN("YEAR"));
break;
case FIELD_TYPE_TIME:
ans.append("TIME", 4);
ans.append(STRING_WITH_LEN("TIME"));
break;
case FIELD_TYPE_DECIMAL:
ans.append("DECIMAL", 7);
ans.append(STRING_WITH_LEN("DECIMAL"));
// if item is FIELD_ITEM, it _must_be_ Field_num in this case
if (((Field_num*) ((Item_field*) (*f)->item)->field)->zerofill)
ans.append(" ZEROFILL");
ans.append(STRING_WITH_LEN(" ZEROFILL"));
break;
default:
(*f)->get_opt_type(&ans, rows);
@ -785,7 +785,7 @@ bool analyse::end_of_records()
}
}
if (!(*f)->nulls)
ans.append(" NOT NULL");
ans.append(STRING_WITH_LEN(" NOT NULL"));
func_items[9]->set(ans.ptr(), ans.length(), ans.charset());
if (result->send_data(result_fields))
return -1;
@ -829,18 +829,18 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
sprintf(buff, "BIGINT(%d)", num_info.integers);
answer->append(buff, (uint) strlen(buff));
if (ev_num_info.llval >= 0 && ev_num_info.min_dval >= 0)
answer->append(" UNSIGNED");
answer->append(STRING_WITH_LEN(" UNSIGNED"));
if (num_info.zerofill)
answer->append(" ZEROFILL");
answer->append(STRING_WITH_LEN(" ZEROFILL"));
}
else if (max_length < 256)
{
if (must_be_blob)
{
if (item->collation.collation == &my_charset_bin)
answer->append("TINYBLOB", 8);
answer->append(STRING_WITH_LEN("TINYBLOB"));
else
answer->append("TINYTEXT", 8);
answer->append(STRING_WITH_LEN("TINYTEXT"));
}
else if ((max_length * (total_rows - nulls)) < (sum + total_rows))
{
@ -856,23 +856,23 @@ void field_str::get_opt_type(String *answer, ha_rows total_rows)
else if (max_length < (1L << 16))
{
if (item->collation.collation == &my_charset_bin)
answer->append("BLOB", 4);
answer->append(STRING_WITH_LEN("BLOB"));
else
answer->append("TEXT", 4);
answer->append(STRING_WITH_LEN("TEXT"));
}
else if (max_length < (1L << 24))
{
if (item->collation.collation == &my_charset_bin)
answer->append("MEDIUMBLOB", 10);
answer->append(STRING_WITH_LEN("MEDIUMBLOB"));
else
answer->append("MEDIUMTEXT", 10);
answer->append(STRING_WITH_LEN("MEDIUMTEXT"));
}
else
{
if (item->collation.collation == &my_charset_bin)
answer->append("LONGBLOB", 8);
answer->append(STRING_WITH_LEN("LONGBLOB"));
else
answer->append("LONGTEXT", 8);
answer->append(STRING_WITH_LEN("LONGTEXT"));
}
} // field_str::get_opt_type
@ -902,14 +902,14 @@ void field_real::get_opt_type(String *answer,
sprintf(buff, "BIGINT(%d)", len);
answer->append(buff, (uint) strlen(buff));
if (min_arg >= 0)
answer->append(" UNSIGNED");
answer->append(STRING_WITH_LEN(" UNSIGNED"));
}
else if (item->decimals == NOT_FIXED_DEC)
{
if (min_arg >= -FLT_MAX && max_arg <= FLT_MAX)
answer->append("FLOAT", 5);
answer->append(STRING_WITH_LEN("FLOAT"));
else
answer->append("DOUBLE", 6);
answer->append(STRING_WITH_LEN("DOUBLE"));
}
else
{
@ -926,7 +926,7 @@ void field_real::get_opt_type(String *answer,
// a single number shouldn't be zerofill
(max_length - (item->decimals + 1)) != 1 &&
((Field_num*) ((Item_field*) item)->field)->zerofill)
answer->append(" ZEROFILL");
answer->append(STRING_WITH_LEN(" ZEROFILL"));
} // field_real::get_opt_type
@ -950,14 +950,14 @@ void field_longlong::get_opt_type(String *answer,
sprintf(buff, "BIGINT(%d)", (int) max_length);
answer->append(buff, (uint) strlen(buff));
if (min_arg >= 0)
answer->append(" UNSIGNED");
answer->append(STRING_WITH_LEN(" UNSIGNED"));
// if item is FIELD_ITEM, it _must_be_ Field_num in this class
if ((item->type() == Item::FIELD_ITEM) &&
// a single number shouldn't be zerofill
max_length != 1 &&
((Field_num*) ((Item_field*) item)->field)->zerofill)
answer->append(" ZEROFILL");
answer->append(STRING_WITH_LEN(" ZEROFILL"));
} // field_longlong::get_opt_type
@ -982,7 +982,7 @@ void field_ulonglong::get_opt_type(String *answer,
// a single number shouldn't be zerofill
max_length != 1 &&
((Field_num*) ((Item_field*) item)->field)->zerofill)
answer->append(" ZEROFILL");
answer->append(STRING_WITH_LEN(" ZEROFILL"));
} //field_ulonglong::get_opt_type

View File

@ -1088,6 +1088,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
/* find a unused table in the open table cache */
if (refresh)
*refresh=0;
/* an open table operation needs a lot of the stack space */
if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (char *)&alias))
return 0;
if (thd->killed)
DBUG_RETURN(0);
key_length= (uint) (strmov(strmov(key, table_list->db)+1,
@ -1200,17 +1205,16 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
(void) unpack_filename(path, path);
if (mysql_frm_type(thd, path, &not_used) == FRMTYPE_VIEW)
{
TABLE tab;// will not be used (because it's VIEW) but have to be passed
/*
Will not be used (because it's VIEW) but has to be passed.
Also we will not free it (because it is a stack variable).
*/
TABLE tab;
table= &tab;
VOID(pthread_mutex_lock(&LOCK_open));
if (open_unireg_entry(thd, table, table_list->db,
table_list->table_name,
alias, table_list, mem_root))
{
table->next=table->prev=table;
free_cache_entry(table);
}
else
if (!open_unireg_entry(thd, table, table_list->db,
table_list->table_name,
alias, table_list, mem_root))
{
DBUG_ASSERT(table_list->view != 0);
VOID(pthread_mutex_unlock(&LOCK_open));

View File

@ -412,7 +412,7 @@ protected:
/*
The following functions are only used when debugging
We don't protect these with ifndef DEBUG_OFF to not have to recompile
We don't protect these with ifndef DBUG_OFF to not have to recompile
everything if we want to add checks of the cache at some places.
*/
void wreck(uint line, const char *message);

View File

@ -1495,7 +1495,13 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u)
{
my_var *mv= gl++;
if (mv->local)
(void)local_vars.push_back(new Item_splocal(mv->s, mv->offset));
{
Item_splocal *var;
(void)local_vars.push_back(var= new Item_splocal(mv->s, mv->offset));
#ifndef DBUG_OFF
var->owner= mv->owner;
#endif
}
else
{
Item_func_set_user_var *var= new Item_func_set_user_var(mv->s, item);
@ -1916,6 +1922,7 @@ void THD::restore_backup_open_tables_state(Open_tables_state *backup)
- Value for found_rows() is reset and restored
- examined_row_count is added to the total
- cuted_fields is added to the total
- new savepoint level is created and destroyed
NOTES:
Seed for random() is saved for the first! usage of RAND()
@ -1939,6 +1946,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
backup->sent_row_count= sent_row_count;
backup->cuted_fields= cuted_fields;
backup->client_capabilities= client_capabilities;
backup->savepoints= transaction.savepoints;
if (!lex->requires_prelocking() || is_update_query(lex->sql_command))
options&= ~OPTION_BIN_LOG;
@ -1951,6 +1959,7 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
examined_row_count= 0;
sent_row_count= 0;
cuted_fields= 0;
transaction.savepoints= 0;
#ifndef EMBEDDED_LIBRARY
/* Surpress OK packets in case if we will execute statements */
@ -1961,6 +1970,21 @@ void THD::reset_sub_statement_state(Sub_statement_state *backup,
void THD::restore_sub_statement_state(Sub_statement_state *backup)
{
/*
To save resources we want to release savepoints which were created
during execution of function or trigger before leaving their savepoint
level. It is enough to release first savepoint set on this level since
all later savepoints will be released automatically.
*/
if (transaction.savepoints)
{
SAVEPOINT *sv;
for (sv= transaction.savepoints; sv->prev; sv= sv->prev)
{}
/* ha_release_savepoint() never returns error. */
(void)ha_release_savepoint(this, sv);
}
transaction.savepoints= backup->savepoints;
options= backup->options;
in_sub_stmt= backup->in_sub_stmt;
net.no_send_ok= backup->no_send_ok;

Some files were not shown because too many files have changed in this diff Show More