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:
commit
33a2716a85
@ -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.%
|
||||
|
31
Makefile.am
31
Makefile.am
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
/*
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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.",
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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"])
|
||||
|
14
configure.in
14
configure.in
@ -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
|
||||
|
@ -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
|
||||
|
@ -1,2 +1,2 @@
|
||||
SUBDIRS = taocrypt src
|
||||
EXTRA_DIST = yassl.dsp yassl.dsw mySTL/*.hpp
|
||||
EXTRA_DIST = yassl.dsp yassl.dsw $(wildcard mySTL/*.hpp)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
4
mysql-test/include/is_debug_build.inc
Normal file
4
mysql-test/include/is_debug_build.inc
Normal file
@ -0,0 +1,4 @@
|
||||
-- require r/is_debug_build.require
|
||||
--disable_query_log
|
||||
select instr(version(), "debug") > 0;
|
||||
--enable_query_log
|
@ -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)
|
||||
|
2
mysql-test/r/is_debug_build.require
Normal file
2
mysql-test/r/is_debug_build.require
Normal file
@ -0,0 +1,2 @@
|
||||
instr(version(), "debug") > 0
|
||||
1
|
@ -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;
|
||||
|
@ -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
|
||||
|
62
mysql-test/r/sp-code.result
Normal file
62
mysql-test/r/sp-code.result
Normal 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;
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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|
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
49
mysql-test/t/sp-code.test
Normal 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;
|
@ -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.
|
||||
|
@ -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 ;|
|
||||
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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
|
||||
#
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)));
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 \
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 $<
|
||||
|
73
sql/field.cc
73
sql/field.cc
@ -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;
|
||||
|
@ -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';
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
22
sql/item.cc
22
sql/item.cc
@ -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
|
||||
|
11
sql/item.h
11
sql/item.h
@ -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);
|
||||
};
|
||||
|
||||
|
@ -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)"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(')');
|
||||
|
@ -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("\')"));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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"; }
|
||||
};
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)},
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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.",
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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, ¬_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, ¬_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);
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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++;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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},
|
||||
|
@ -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.%
|
||||
|
@ -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"
|
||||
|
10
sql/slave.cc
10
sql/slave.cc
@ -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
315
sql/sp.cc
@ -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');
|
||||
}
|
||||
|
6
sql/sp.h
6
sql/sp.h
@ -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);
|
||||
|
||||
|
397
sql/sp_head.cc
397
sql/sp_head.cc
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
104
sql/sql_acl.cc
104
sql/sql_acl.cc
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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, ¬_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));
|
||||
|
@ -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);
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user