summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql.cc10
-rw-r--r--client/mysqlbinlog.cc6
-rw-r--r--config/ac-macros/openssl.m410
-rw-r--r--config/ac-macros/zlib.m49
-rw-r--r--dbug/dbug.c84
-rw-r--r--extra/yassl/taocrypt/include/runtime.hpp4
-rw-r--r--include/my_dbug.h3
-rw-r--r--include/my_pthread.h6
-rw-r--r--include/my_sys.h1
-rw-r--r--include/sslopt-longopts.h14
-rw-r--r--include/sslopt-vars.h19
-rw-r--r--innobase/os/os0file.c63
-rw-r--r--libmysql/libmysql.c2
-rw-r--r--mysql-test/lib/mtr_process.pl20
-rwxr-xr-xmysql-test/mysql-test-run.pl86
-rw-r--r--mysql-test/r/case.result8
-rw-r--r--mysql-test/r/explain.result4
-rw-r--r--mysql-test/r/func_in.result17
-rw-r--r--mysql-test/r/func_str.result13
-rw-r--r--mysql-test/r/having.result2
-rw-r--r--mysql-test/r/im_options_set.result6
-rw-r--r--mysql-test/r/im_options_unset.result6
-rw-r--r--mysql-test/r/information_schema.result17
-rw-r--r--mysql-test/r/join.result4
-rw-r--r--mysql-test/r/join_outer.result61
-rw-r--r--mysql-test/r/metadata.result2
-rw-r--r--mysql-test/r/mysqlbinlog.result1
-rw-r--r--mysql-test/r/ndb_autodiscover3.result45
-rw-r--r--mysql-test/r/ndb_blob.result66
-rw-r--r--mysql-test/r/outfile.resultbin1130 -> 1159 bytes
-rw-r--r--mysql-test/r/ps_2myisam.result4
-rw-r--r--mysql-test/r/ps_3innodb.result4
-rw-r--r--mysql-test/r/ps_4heap.result4
-rw-r--r--mysql-test/r/ps_5merge.result8
-rw-r--r--mysql-test/r/ps_6bdb.result4
-rw-r--r--mysql-test/r/ps_7ndb.result4
-rw-r--r--mysql-test/r/rpl_temporary.result17
-rw-r--r--mysql-test/r/rpl_until.result148
-rw-r--r--mysql-test/r/select.result19
-rw-r--r--mysql-test/r/sp-error.result4
-rw-r--r--mysql-test/r/sp.result56
-rw-r--r--mysql-test/r/subselect.result14
-rw-r--r--mysql-test/r/trigger-grant.result84
-rw-r--r--mysql-test/r/trigger.result92
-rw-r--r--mysql-test/r/type_float.result8
-rw-r--r--mysql-test/r/type_newdecimal.result14
-rw-r--r--mysql-test/r/variables.result30
-rw-r--r--mysql-test/r/view.result47
-rw-r--r--mysql-test/t/explain.test9
-rw-r--r--mysql-test/t/func_in.test12
-rw-r--r--mysql-test/t/func_str.test15
-rw-r--r--mysql-test/t/information_schema.test20
-rw-r--r--mysql-test/t/init_connect.test2
-rw-r--r--mysql-test/t/join_outer.test44
-rw-r--r--mysql-test/t/mysqlbinlog.test15
-rw-r--r--mysql-test/t/ndb_autodiscover3.test65
-rw-r--r--mysql-test/t/ndb_blob.test56
-rw-r--r--mysql-test/t/outfile.test1
-rw-r--r--mysql-test/t/rename.test8
-rw-r--r--mysql-test/t/rpl_temporary.test27
-rw-r--r--mysql-test/t/rpl_until.test8
-rw-r--r--mysql-test/t/select.test21
-rw-r--r--mysql-test/t/sp.test70
-rw-r--r--mysql-test/t/subselect.test24
-rw-r--r--mysql-test/t/trigger-grant.test173
-rw-r--r--mysql-test/t/trigger.test122
-rw-r--r--mysql-test/t/variables.test39
-rw-r--r--mysql-test/t/view.test55
-rw-r--r--mysql-test/valgrind.supp182
-rw-r--r--mysys/my_init.c4
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters.h1
-rw-r--r--ndb/include/ndbapi/ndb_cluster_connection.hpp1
-rw-r--r--ndb/include/util/SocketServer.hpp2
-rw-r--r--ndb/src/common/transporter/Transporter.cpp12
-rw-r--r--ndb/src/common/util/SocketServer.cpp4
-rw-r--r--ndb/src/kernel/blocks/backup/Backup.cpp5
-rw-r--r--ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp6
-rw-r--r--ndb/src/mgmapi/mgmapi.cpp3
-rw-r--r--ndb/src/mgmsrv/ConfigInfo.cpp14
-rw-r--r--ndb/src/mgmsrv/MgmtSrvr.cpp1
-rw-r--r--ndb/src/mgmsrv/Services.cpp6
-rw-r--r--ndb/src/ndbapi/ClusterMgr.cpp5
-rw-r--r--ndb/src/ndbapi/ClusterMgr.hpp1
-rw-r--r--ndb/src/ndbapi/DictCache.cpp36
-rw-r--r--ndb/src/ndbapi/DictCache.hpp3
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.hpp25
-rw-r--r--ndb/src/ndbapi/NdbOperationSearch.cpp14
-rw-r--r--ndb/src/ndbapi/SignalSender.cpp2
-rw-r--r--ndb/src/ndbapi/TransporterFacade.hpp6
-rw-r--r--ndb/src/ndbapi/ndb_cluster_connection.cpp6
-rw-r--r--ndb/src/ndbapi/ndb_cluster_connection_impl.hpp1
-rw-r--r--ndb/test/ndbapi/Makefile.am2
-rw-r--r--ndb/test/ndbapi/testInterpreter.cpp202
-rw-r--r--ndb/tools/waiter.cpp6
-rw-r--r--server-tools/instance-manager/manager.cc13
-rw-r--r--server-tools/instance-manager/manager.h2
-rw-r--r--server-tools/instance-manager/mysqlmanager.cc8
-rw-r--r--server-tools/instance-manager/options.cc59
-rw-r--r--server-tools/instance-manager/options.h1
-rw-r--r--sql/field_conv.cc3
-rw-r--r--sql/ha_innodb.cc3
-rw-r--r--sql/ha_ndbcluster.cc17
-rw-r--r--sql/item.cc47
-rw-r--r--sql/item.h104
-rw-r--r--sql/item_cmpfunc.cc33
-rw-r--r--sql/item_func.cc14
-rw-r--r--sql/item_func.h12
-rw-r--r--sql/item_strfunc.cc2
-rw-r--r--sql/item_strfunc.h2
-rw-r--r--sql/item_subselect.cc12
-rw-r--r--sql/item_subselect.h1
-rw-r--r--sql/item_timefunc.cc9
-rw-r--r--sql/mysql_priv.h20
-rw-r--r--sql/mysqld.cc10
-rw-r--r--sql/opt_range.cc109
-rw-r--r--sql/set_var.cc69
-rw-r--r--sql/set_var.h29
-rw-r--r--sql/share/errmsg.txt2
-rw-r--r--sql/sp_head.cc241
-rw-r--r--sql/sp_head.h2
-rw-r--r--sql/sp_rcontext.cc13
-rw-r--r--sql/sp_rcontext.h8
-rw-r--r--sql/sql_acl.cc5
-rw-r--r--sql/sql_base.cc163
-rw-r--r--sql/sql_class.cc2
-rw-r--r--sql/sql_insert.cc147
-rw-r--r--sql/sql_parse.cc3
-rw-r--r--sql/sql_show.cc25
-rw-r--r--sql/sql_table.cc99
-rw-r--r--sql/sql_yacc.yy38
-rw-r--r--support-files/mysql.spec.sh6
131 files changed, 3165 insertions, 654 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 50e5569a0ec..900df825b25 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -448,6 +448,14 @@ int main(int argc,char *argv[])
MYF(MY_WME));
if (histfile)
sprintf(histfile,"%s/.mysql_history",getenv("HOME"));
+ char link_name[FN_REFLEN];
+ if (my_readlink(link_name, histfile, 0) == 0 &&
+ strncmp(link_name, "/dev/null", 10) == 0)
+ {
+ /* The .mysql_history file is a symlink to /dev/null, don't use it */
+ my_free(histfile, MYF(MY_ALLOW_ZERO_PTR));
+ histfile= 0;
+ }
}
if (histfile)
{
@@ -484,7 +492,7 @@ sig_handler mysql_end(int sig)
{
mysql_close(&mysql);
#ifdef HAVE_READLINE
- if (!status.batch && !quick && !opt_html && !opt_xml)
+ if (!status.batch && !quick && !opt_html && !opt_xml && histfile)
{
/* write-history */
if (verbose)
diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc
index b1a931a9df1..60b54a2ed99 100644
--- a/client/mysqlbinlog.cc
+++ b/client/mysqlbinlog.cc
@@ -788,7 +788,8 @@ static void die(const char* fmt, ...)
fprintf(stderr, "\n");
va_end(args);
cleanup();
- my_end(0);
+ /* We cannot free DBUG, it is used in global destructors after exit(). */
+ my_end(MY_DONT_FREE_DBUG);
exit(1);
}
@@ -1460,7 +1461,8 @@ int main(int argc, char** argv)
cleanup();
free_defaults(defaults_argv);
my_free_open_file_info();
- my_end(0);
+ /* We cannot free DBUG, it is used in global destructors after exit(). */
+ my_end(MY_DONT_FREE_DBUG);
exit(exit_value);
DBUG_RETURN(exit_value); // Keep compilers happy
}
diff --git a/config/ac-macros/openssl.m4 b/config/ac-macros/openssl.m4
index a23c46eed00..af4305486a3 100644
--- a/config/ac-macros/openssl.m4
+++ b/config/ac-macros/openssl.m4
@@ -15,8 +15,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [
for d in /usr/ssl/lib /usr/local/ssl/lib /usr/lib/openssl \
/usr/lib /usr/lib64 /opt/ssl/lib /opt/openssl/lib \
/usr/freeware/lib32 /usr/local/lib/ ; do
- # Just to be safe, we test for ".so" anyway
- if test -f $d/libssl.a || test -f $d/libssl.so || test -f $d/libssl$shrext ; then
+ # Test for libssl using all known library file endings
+ if test -f $d/libssl.a || test -f $d/libssl.so || \
+ test -f $d/libssl.sl || test -f $d/libssl.dylib ; then
OPENSSL_LIB=$d
fi
done
@@ -28,8 +29,9 @@ AC_DEFUN([MYSQL_FIND_OPENSSL], [
if test -f $incs/openssl/ssl.h ; then
OPENSSL_INCLUDE=-I$incs
fi
- # Just to be safe, we test for ".so" anyway
- if test -f $libs/libssl.a || test -f $libs/libssl.so || test -f $libs/libssl$shrext ; then
+ # Test for libssl using all known library file endings
+ if test -f $d/libssl.a || test -f $d/libssl.so || \
+ test -f $d/libssl.sl || test -f $d/libssl.dylib ; then
OPENSSL_LIB=$libs
fi
;;
diff --git a/config/ac-macros/zlib.m4 b/config/ac-macros/zlib.m4
index c75bac58d7c..a01d13937ff 100644
--- a/config/ac-macros/zlib.m4
+++ b/config/ac-macros/zlib.m4
@@ -89,10 +89,11 @@ case $SYSTEM_TYPE in
fi
;;
*)
- # Just to be safe, we test for ".so" anyway
- eval shrexts=\"$shrext_cmds\"
- if test \( -f "$mysql_zlib_dir/lib/libz.a" -o -f "$mysql_zlib_dir/lib/libz.so" -o \
- -f "$mysql_zlib_dir/lib/libz$shrext" \) \
+ # Test for libz using all known library file endings
+ if test \( -f "$mysql_zlib_dir/lib/libz.a" -o \
+ -f "$mysql_zlib_dir/lib/libz.so" -o \
+ -f "$mysql_zlib_dir/lib/libz.sl" -o \
+ -f "$mysql_zlib_dir/lib/libz.dylib" \) \
-a -f "$mysql_zlib_dir/include/zlib.h"; then
ZLIB_INCLUDES="-I$mysql_zlib_dir/include"
ZLIB_LIBS="-L$mysql_zlib_dir/lib -lz"
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 91b7e7b6c4c..c991daf3617 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -271,6 +271,8 @@ static unsigned long Clock (void);
static void CloseFile(FILE *fp);
/* Push current debug state */
static void PushState(void);
+ /* Free memory associated with debug state. */
+static void FreeState (struct state *state);
/* Test for tracing enabled */
static BOOLEAN DoTrace(CODE_STATE *state);
/* Test to see if file is writable */
@@ -630,22 +632,7 @@ void _db_pop_ ()
stack = discard -> next_state;
_db_fp_ = stack -> out_file;
_db_pfp_ = stack -> prof_file;
- if (discard -> keywords != NULL) {
- FreeList (discard -> keywords);
- }
- if (discard -> functions != NULL) {
- FreeList (discard -> functions);
- }
- if (discard -> processes != NULL) {
- FreeList (discard -> processes);
- }
- if (discard -> p_functions != NULL) {
- FreeList (discard -> p_functions);
- }
- CloseFile (discard -> out_file);
- if (discard -> prof_file)
- CloseFile (discard -> prof_file);
- free ((char *) discard);
+ FreeState(discard);
if (!(stack->flags & DEBUG_ON))
_db_on_=0;
}
@@ -1160,6 +1147,71 @@ static void PushState ()
stack=new_malloc;
}
+/*
+ * FUNCTION
+ *
+ * FreeState Free memory associated with a struct state.
+ *
+ * SYNOPSIS
+ *
+ * static void FreeState (state)
+ * struct state *state;
+ *
+ * DESCRIPTION
+ *
+ * Deallocates the memory allocated for various information in a
+ * state.
+ *
+ */
+static void FreeState (
+struct state *state)
+{
+ if (state -> keywords != NULL) {
+ FreeList (state -> keywords);
+ }
+ if (state -> functions != NULL) {
+ FreeList (state -> functions);
+ }
+ if (state -> processes != NULL) {
+ FreeList (state -> processes);
+ }
+ if (state -> p_functions != NULL) {
+ FreeList (state -> p_functions);
+ }
+ CloseFile (state -> out_file);
+ if (state -> prof_file)
+ CloseFile (state -> prof_file);
+ free ((char *) state);
+}
+
+
+/*
+ * FUNCTION
+ *
+ * _db_end_ End debugging, freeing state stack memory.
+ *
+ * SYNOPSIS
+ *
+ * static VOID _db_end_ ()
+ *
+ * DESCRIPTION
+ *
+ * Ends debugging, de-allocating the memory allocated to the
+ * state stack.
+ *
+ * To be called at the very end of the program.
+ *
+ */
+void _db_end_ ()
+{
+ reg1 struct state *discard;
+ while((discard= stack) != NULL) {
+ stack= discard -> next_state;
+ FreeState (discard);
+ }
+ _db_on_=0;
+}
+
/*
* FUNCTION
diff --git a/extra/yassl/taocrypt/include/runtime.hpp b/extra/yassl/taocrypt/include/runtime.hpp
index 3a5cf62865a..09ca7524ef3 100644
--- a/extra/yassl/taocrypt/include/runtime.hpp
+++ b/extra/yassl/taocrypt/include/runtime.hpp
@@ -28,6 +28,10 @@
#ifndef yaSSL_NEW_HPP
#define yaSSL_NEW_HPP
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
#ifdef __sun
diff --git a/include/my_dbug.h b/include/my_dbug.h
index b76a3fcc8c9..6e60b599f53 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -40,6 +40,7 @@ extern void _db_doprnt_ _VARARGS((const char *format,...));
extern void _db_dump_(uint _line_,const char *keyword,const char *memory,
uint length);
extern void _db_output_(uint flag);
+extern void _db_end_(void);
extern void _db_lock_file(void);
extern void _db_unlock_file(void);
@@ -66,6 +67,7 @@ extern void _db_unlock_file(void);
#define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr)
#define DEBUGGER_OFF _no_db_=1;_db_on_=0;
#define DEBUGGER_ON _no_db_=0
+#define DBUG_END() _db_end_ ()
#define DBUG_LOCK_FILE { _db_lock_file(); }
#define DBUG_UNLOCK_FILE { _db_unlock_file(); }
#define DBUG_OUTPUT(A) { _db_output_(A); }
@@ -90,6 +92,7 @@ extern void _db_unlock_file(void);
#define DBUG_IN_USE 0
#define DEBUGGER_OFF
#define DEBUGGER_ON
+#define DBUG_END()
#define DBUG_LOCK_FILE
#define DBUG_UNLOCK_FILE
#define DBUG_OUTPUT(A)
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 202e047dc4e..3e4388413e0 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -332,12 +332,14 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
we want to make sure that no such flags are set.
*/
#if defined(HAVE_SIGACTION) && !defined(my_sigset)
-#define my_sigset(A,B) do { struct sigaction s; sigset_t set; \
+#define my_sigset(A,B) do { struct sigaction s; sigset_t set; int rc; \
+ DBUG_ASSERT((A) != 0); \
sigemptyset(&set); \
s.sa_handler = (B); \
s.sa_mask = set; \
s.sa_flags = 0; \
- sigaction((A), &s, (struct sigaction *) NULL); \
+ rc= sigaction((A), &s, (struct sigaction *) NULL);\
+ DBUG_ASSERT(rc == 0); \
} while (0)
#elif defined(HAVE_SIGSET) && !defined(my_sigset)
#define my_sigset(A,B) sigset((A),(B))
diff --git a/include/my_sys.h b/include/my_sys.h
index 65a295ee39e..229389f1ac5 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -75,6 +75,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */
#define MY_GIVE_INFO 2 /* Give time info about process*/
+#define MY_DONT_FREE_DBUG 4 /* Do not call DBUG_END() in my_end() */
#define ME_HIGHBYTE 8 /* Shift for colours */
#define ME_NOCUR 1 /* Don't use curses message */
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index f444a7eb7ce..0435ddb815a 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -20,12 +20,6 @@
"Enable SSL for connection (automatically enabled with other flags). Disable with --skip-ssl.",
(gptr*) &opt_use_ssl, (gptr*) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0,
0, 0, 0},
- {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).",
- (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
- {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).",
- (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG,
- 0, 0, 0, 0, 0, 0},
{"ssl-ca", OPT_SSL_CA,
"CA file in PEM format (check OpenSSL docs, implies --ssl).",
(gptr*) &opt_ssl_ca, (gptr*) &opt_ssl_ca, 0, GET_STR, REQUIRED_ARG,
@@ -34,12 +28,18 @@
"CA directory (check OpenSSL docs, implies --ssl).",
(gptr*) &opt_ssl_capath, (gptr*) &opt_ssl_capath, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
+ {"ssl-cert", OPT_SSL_CERT, "X509 cert in PEM format (implies --ssl).",
+ (gptr*) &opt_ssl_cert, (gptr*) &opt_ssl_cert, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
{"ssl-cipher", OPT_SSL_CIPHER, "SSL cipher to use (implies --ssl).",
(gptr*) &opt_ssl_cipher, (gptr*) &opt_ssl_cipher, 0, GET_STR, REQUIRED_ARG,
0, 0, 0, 0, 0, 0},
+ {"ssl-key", OPT_SSL_KEY, "X509 key in PEM format (implies --ssl).",
+ (gptr*) &opt_ssl_key, (gptr*) &opt_ssl_key, 0, GET_STR, REQUIRED_ARG,
+ 0, 0, 0, 0, 0, 0},
#ifdef MYSQL_CLIENT
{"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
- "Verify servers \"Common Name\" in it's cert against hostname used when connecting. This option is disabled by default.",
+ "Verify server's \"Common Name\" in its cert against hostname used when connecting. This option is disabled by default.",
(gptr*) &opt_ssl_verify_server_cert, (gptr*) &opt_ssl_verify_server_cert,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
#endif
diff --git a/include/sslopt-vars.h b/include/sslopt-vars.h
index 8e5f3434396..7204145fc28 100644
--- a/include/sslopt-vars.h
+++ b/include/sslopt-vars.h
@@ -15,13 +15,18 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifdef HAVE_OPENSSL
-static my_bool opt_use_ssl = 0;
-static char *opt_ssl_key = 0;
-static char *opt_ssl_cert = 0;
-static char *opt_ssl_ca = 0;
-static char *opt_ssl_capath = 0;
-static char *opt_ssl_cipher = 0;
+#ifdef SSL_VARS_NOT_STATIC
+#define SSL_STATIC
+#else
+#define SSL_STATIC static
+#endif
+SSL_STATIC my_bool opt_use_ssl = 0;
+SSL_STATIC char *opt_ssl_ca = 0;
+SSL_STATIC char *opt_ssl_capath = 0;
+SSL_STATIC char *opt_ssl_cert = 0;
+SSL_STATIC char *opt_ssl_cipher = 0;
+SSL_STATIC char *opt_ssl_key = 0;
#ifdef MYSQL_CLIENT
-static my_bool opt_ssl_verify_server_cert= 0;
+SSL_STATIC my_bool opt_ssl_verify_server_cert= 0;
#endif
#endif
diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c
index 3b8f7576049..df819b73ea6 100644
--- a/innobase/os/os0file.c
+++ b/innobase/os/os0file.c
@@ -3700,6 +3700,37 @@ os_aio_posix_handle(
#endif
/**************************************************************************
+Do a 'last millisecond' check that the page end is sensible;
+reported page checksum errors from Linux seem to wipe over the page end. */
+static
+void
+os_file_check_page_trailers(
+/*========================*/
+ byte* combined_buf, /* in: combined write buffer */
+ ulint total_len) /* in: size of combined_buf, in bytes
+ (a multiple of UNIV_PAGE_SIZE) */
+{
+ ulint len;
+
+ for (len = 0; len + UNIV_PAGE_SIZE <= total_len;
+ len += UNIV_PAGE_SIZE) {
+ byte* buf = combined_buf + len;
+
+ if (memcmp(buf + (FIL_PAGE_LSN + 4), buf + (UNIV_PAGE_SIZE
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4), 4)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+" InnoDB: ERROR: The page to be written seems corrupt!\n"
+"InnoDB: Writing a block of %lu bytes, currently at offset %lu\n",
+ (ulong)total_len, (ulong)len);
+ buf_page_print(buf);
+ fprintf(stderr,
+"InnoDB: ERROR: The page to be written seems corrupt!\n");
+ }
+ }
+}
+
+/**************************************************************************
Does simulated aio. This function should be called by an i/o-handler
thread. */
@@ -3736,7 +3767,6 @@ os_aio_simulated_handle(
ibool ret;
ulint n;
ulint i;
- ulint len2;
segment = os_aio_get_array_and_local_segment(&array, global_segment);
@@ -3943,33 +3973,16 @@ consecutive_loop:
(ulong) total_len);
ut_error;
}
-
- /* Do a 'last millisecond' check that the page end
- is sensible; reported page checksum errors from
- Linux seem to wipe over the page end */
-
- for (len2 = 0; len2 + UNIV_PAGE_SIZE <= total_len;
- len2 += UNIV_PAGE_SIZE) {
- if (mach_read_from_4(combined_buf + len2
- + FIL_PAGE_LSN + 4)
- != mach_read_from_4(combined_buf + len2
- + UNIV_PAGE_SIZE
- - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)) {
- ut_print_timestamp(stderr);
- fprintf(stderr,
-" InnoDB: ERROR: The page to be written seems corrupt!\n");
- fprintf(stderr,
-"InnoDB: Writing a block of %lu bytes, currently writing at offset %lu\n",
- (ulong)total_len, (ulong)len2);
- buf_page_print(combined_buf + len2);
- fprintf(stderr,
-"InnoDB: ERROR: The page to be written seems corrupt!\n");
- }
- }
+
+ os_file_check_page_trailers(combined_buf, total_len);
}
-
+
ret = os_file_write(slot->name, slot->file, combined_buf,
slot->offset, slot->offset_high, total_len);
+
+ if (array == os_aio_write_array) {
+ os_file_check_page_trailers(combined_buf, total_len);
+ }
} else {
ret = os_file_read(slot->file, combined_buf,
slot->offset, slot->offset_high, total_len);
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 7713fd8dd4d..c1e0703af10 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -178,7 +178,7 @@ void STDCALL mysql_server_end()
/* If library called my_init(), free memory allocated by it */
if (!org_my_init_done)
{
- my_end(0);
+ my_end(MY_DONT_FREE_DBUG);
#ifndef THREAD
/* Remove TRACING, if enabled by mysql_debug() */
DBUG_POP();
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 973655a3eb6..6fa6bc73bdb 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -20,6 +20,7 @@ sub mtr_record_dead_children ();
sub mtr_exit ($);
sub sleep_until_file_created ($$$);
sub mtr_kill_processes ($);
+sub mtr_kill_process ($$$$);
# static in C
sub spawn_impl ($$$$$$$$);
@@ -885,6 +886,25 @@ sub mtr_kill_processes ($) {
}
}
+
+sub mtr_kill_process ($$$$) {
+ my $pid= shift;
+ my $signal= shift;
+ my $retries= shift;
+ my $timeout= shift;
+
+ while (1)
+ {
+ kill($signal, $pid);
+
+ last unless kill (0, $pid) and $retries--;
+
+ mtr_debug("Sleep $timeout second waiting for processes to die");
+
+ sleep($timeout);
+ }
+}
+
##############################################################################
#
# When we exit, we kill off all children
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index e57a5da2c79..4a9628c0721 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -918,6 +918,7 @@ sub command_line_setup () {
path_err => "$opt_vardir/log/im.err",
path_log => "$opt_vardir/log/im.log",
path_pid => "$opt_vardir/run/im.pid",
+ path_angel_pid => "$opt_vardir/run/im.angel.pid",
path_sock => "$sockdir/im.sock",
port => $im_port,
start_timeout => $master->[0]->{'start_timeout'},
@@ -1188,6 +1189,7 @@ sub environment_setup () {
$ENV{'NDB_STATUS_OK'}= "YES";
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
+ $ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
$ENV{'IM_PORT'}= $instance_manager->{port};
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
@@ -1813,6 +1815,7 @@ sub im_create_defaults_file($) {
[manager]
pid-file = $instance_manager->{path_pid}
+angel-pid-file = $instance_manager->{path_angel_pid}
socket = $instance_manager->{path_sock}
port = $instance_manager->{port}
password-file = $instance_manager->{password_file}
@@ -1837,7 +1840,7 @@ log-slow-queries = $instance->{path_datadir}/mysqld$server_id.slow.log
language = $path_language
character-sets-dir = $path_charsetsdir
basedir = $path_my_basedir
-server_id =$server_id
+server_id = $server_id
skip-stack-trace
skip-innodb
skip-bdb
@@ -2805,6 +2808,18 @@ sub im_start($$) {
sub im_stop($) {
my $instance_manager = shift;
+ # Obtain mysqld-process pids before we start stopping IM (it can delete pid
+ # files).
+
+ my @mysqld_pids = ();
+ my $instances = $instance_manager->{'instances'};
+
+ push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}))
+ if -r $instances->[0]->{'path_pid'};
+
+ push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}))
+ if -r $instances->[1]->{'path_pid'};
+
# Re-read pid from the file, since during tests Instance Manager could have
# been restarted, so its pid could have been changed.
@@ -2812,34 +2827,79 @@ sub im_stop($) {
mtr_get_pid_from_file($instance_manager->{'path_pid'})
if -f $instance_manager->{'path_pid'};
+ if (-f $instance_manager->{'path_angel_pid'})
+ {
+ $instance_manager->{'angel_pid'} =
+ mtr_get_pid_from_file($instance_manager->{'path_angel_pid'})
+ }
+ else
+ {
+ $instance_manager->{'angel_pid'} = undef;
+ }
+
# Inspired from mtr_stop_mysqld_servers().
start_reap_all();
- # Create list of pids. We should stop Instance Manager and all started
- # mysqld-instances. Some of them may be nonguarded, so IM will not stop them
- # on shutdown.
+ # Try graceful shutdown.
- my @pids = ( $instance_manager->{'pid'} );
- my $instances = $instance_manager->{'instances'};
+ mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1);
+
+ # Check that all processes died.
+
+ my $clean_shutdown= 0;
- if ( -r $instances->[0]->{'path_pid'} )
+ while (1)
{
- push(@pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}));
+ last if kill (0, $instance_manager->{'pid'});
+
+ last if (defined $instance_manager->{'angel_pid'}) &&
+ kill (0, $instance_manager->{'angel_pid'});
+
+ foreach my $pid (@mysqld_pids)
+ {
+ last if kill (0, $pid);
+ }
+
+ $clean_shutdown= 1;
+ last;
}
- if ( -r $instances->[1]->{'path_pid'} )
+ # Kill leftovers (the order is important).
+
+ unless ($clean_shutdown)
{
- push(@pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}));
- }
+ mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1)
+ if defined $instance_manager->{'angel_pid'};
+
+ mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1);
- # Kill processes.
+ # Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM
+ # will not stop them on shutdown. So, we should firstly try to end them
+ # legally.
+
+ mtr_kill_processes(\@mysqld_pids);
+
+ # Complain in error log so that a warning will be shown.
+
+ my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
+
+ open (ERRLOG, ">>$errlog") ||
+ mtr_error("Can not open error log ($errlog)");
+
+ my $ts= localtime();
+ print ERRLOG
+ "Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
+
+ close ERRLOG;
+ }
- mtr_kill_processes(\@pids);
+ # That's all.
stop_reap_all();
$instance_manager->{'pid'} = undef;
+ $instance_manager->{'angel_pid'} = undef;
}
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index 8349d6e9338..cf358e6a404 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -103,8 +103,8 @@ t1 CREATE TABLE `t1` (
`c2` varchar(1) character set latin1 collate latin1_danish_ci NOT NULL default '',
`c3` varbinary(1) NOT NULL default '',
`c4` varbinary(1) NOT NULL default '',
- `c5` varbinary(3) NOT NULL default '',
- `c6` varbinary(3) NOT NULL default '',
+ `c5` varbinary(4) NOT NULL default '',
+ `c6` varbinary(4) NOT NULL default '',
`c7` decimal(2,1) NOT NULL default '0.0',
`c8` decimal(2,1) NOT NULL default '0.0',
`c9` decimal(2,1) default NULL,
@@ -152,11 +152,11 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`COALESCE(1)` int(1) NOT NULL default '0',
- `COALESCE(1.0)` decimal(2,1) unsigned NOT NULL default '0.0',
+ `COALESCE(1.0)` decimal(2,1) NOT NULL default '0.0',
`COALESCE('a')` varchar(1) NOT NULL default '',
`COALESCE(1,1.0)` decimal(2,1) NOT NULL default '0.0',
`COALESCE(1,'1')` varbinary(1) NOT NULL default '',
- `COALESCE(1.1,'1')` varbinary(3) NOT NULL default '',
+ `COALESCE(1.1,'1')` varbinary(4) NOT NULL default '',
`COALESCE('a' COLLATE latin1_bin,'b')` varchar(1) character set latin1 collate latin1_bin NOT NULL default ''
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result
index d66dec741bd..75e1548cdee 100644
--- a/mysql-test/r/explain.result
+++ b/mysql-test/r/explain.result
@@ -53,3 +53,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE ÔÁÂ ref ÉÎÄ0,ÉÎÄ01 ÉÎÄ0 5 const 1 Using where; Using index
drop table ÔÁÂ;
set names latin1;
+select 3 into @v1;
+explain select 3 into @v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index e3257ce5fd0..e38e2624e19 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -326,3 +326,20 @@ deallocate prepare s;
set @str=NULL;
drop table t2;
drop table t1;
+create table t1 (
+some_id smallint(5) unsigned,
+key (some_id)
+);
+insert into t1 values (1),(2);
+select some_id from t1 where some_id not in(2,-1);
+some_id
+1
+select some_id from t1 where some_id not in(-4,-1,-4);
+some_id
+1
+2
+select some_id from t1 where some_id not in(-4,-1,3423534,2342342);
+some_id
+1
+2
+drop table t1;
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index aed79e7f8fa..a17661d26d0 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -1017,6 +1017,13 @@ t
1000000
1
drop table t1;
+select load_file("lkjlkj");
+load_file("lkjlkj")
+NULL
+select ifnull(load_file("lkjlkj"),"it's null");
+ifnull(load_file("lkjlkj"),"it's null")
+it's null
+End of 4.1 tests
create table t1 (d decimal default null);
insert into t1 values (null);
select format(d, 2) from t1;
@@ -1039,4 +1046,10 @@ cast(ltrim(' 20.06 ') as decimal(19,2))
select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2))
20.06
+select conv("18383815659218730760",10,10) + 0;
+conv("18383815659218730760",10,10) + 0
+1.8383815659219e+19
+select "18383815659218730760" + 0;
+"18383815659218730760" + 0
+1.8383815659219e+19
End of 5.0 tests
diff --git a/mysql-test/r/having.result b/mysql-test/r/having.result
index a37f260ff31..68b13b5fc0a 100644
--- a/mysql-test/r/having.result
+++ b/mysql-test/r/having.result
@@ -12,7 +12,7 @@ explain extended select count(a) as b from t1 where a=0 having b >=0;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
Warnings:
-Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (count(`test`.`t1`.`a`) >= 0)
+Note 1003 select count(`test`.`t1`.`a`) AS `b` from `test`.`t1` where 0 having (`b` >= 0)
drop table t1;
CREATE TABLE t1 (
raw_id int(10) NOT NULL default '0',
diff --git a/mysql-test/r/im_options_set.result b/mysql-test/r/im_options_set.result
index 0d2fa699fc7..5e6c740624e 100644
--- a/mysql-test/r/im_options_set.result
+++ b/mysql-test/r/im_options_set.result
@@ -1,11 +1,11 @@
-server_id =1
-server_id =2
+server_id = 1
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
SET mysqld1.server_id = 11;
server_id =11
-server_id =2
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/im_options_unset.result b/mysql-test/r/im_options_unset.result
index 834152c35d2..bf54025edb7 100644
--- a/mysql-test/r/im_options_unset.result
+++ b/mysql-test/r/im_options_unset.result
@@ -1,10 +1,10 @@
-server_id =1
-server_id =2
+server_id = 1
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
UNSET mysqld1.server_id;
-server_id =2
+server_id = 2
SHOW VARIABLES LIKE 'server_id';
Variable_name Value
server_id 1
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 5224971890a..633b11e1f1b 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1091,3 +1091,20 @@ group by column_type order by num;
column_type group_concat(table_schema, '.', table_name) num
varchar(20) information_schema.COLUMNS 1
varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2
+create table t1(f1 char(1) not null, f2 char(9) not null)
+default character set utf8;
+select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from
+information_schema.columns where table_schema='test' and table_name = 't1';
+CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH
+1 3
+9 27
+drop table t1;
+use mysql;
+INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
+'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
+'2006-03-02 18:40:03','','');
+select routine_name from information_schema.routines;
+routine_name
+
+delete from proc where name='';
+use test;
diff --git a/mysql-test/r/join.result b/mysql-test/r/join.result
index ecf76d477a0..86288caf398 100644
--- a/mysql-test/r/join.result
+++ b/mysql-test/r/join.result
@@ -700,8 +700,8 @@ ERROR 42S22: Unknown column 't1.b' in 'on clause'
select * from information_schema.statistics join information_schema.columns
using(table_name,column_name) where table_name='user';
TABLE_NAME COLUMN_NAME TABLE_CATALOG TABLE_SCHEMA NON_UNIQUE INDEX_SCHEMA INDEX_NAME SEQ_IN_INDEX COLLATION CARDINALITY SUB_PART PACKED NULLABLE INDEX_TYPE COMMENT TABLE_CATALOG TABLE_SCHEMA ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
-user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 20 60 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
-user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 5 16 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
+user Host NULL mysql 0 mysql PRIMARY 1 A NULL NULL NULL BTREE NULL mysql 1 NO char 60 180 NULL NULL utf8 utf8_bin char(60) PRI select,insert,update,references
+user User NULL mysql 0 mysql PRIMARY 2 A 5 NULL NULL BTREE NULL mysql 2 NO char 16 48 NULL NULL utf8 utf8_bin char(16) PRI select,insert,update,references
drop table t1;
drop table t2;
drop table t3;
diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result
index 694bab2597c..eae023813b5 100644
--- a/mysql-test/r/join_outer.result
+++ b/mysql-test/r/join_outer.result
@@ -1151,6 +1151,63 @@ EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
-1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
+1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index
+1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where
+DROP TABLE t1,t2;
+DROP VIEW IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2;
+CREATE TABLE t1 (a int);
+CREATE table t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
+INSERT INTO t2 VALUES (2), (3);
+CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
+CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
+SELECT v1.a, v2. b
+FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+SELECT v1.a, v2. b
+FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
+GROUP BY v1.a;
+a b
+2 NULL
+3 3
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (2), (3);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
+a b
+1 NULL
+2 2
+3 3
+4 NULL
DROP TABLE t1,t2;
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 0a170e16188..50b0b6ae294 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -2,7 +2,7 @@ drop table if exists t1,t2;
select 1, 1.0, -1, "hello", NULL;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def 1 8 1 1 N 32897 0 63
-def 1.0 246 3 3 N 161 1 63
+def 1.0 246 4 3 N 129 1 63
def -1 8 2 2 N 32897 0 63
def hello 253 5 5 N 1 31 8
def NULL 6 0 0 Y 32896 0 63
diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result
index 50e4cc28d93..664833fab2a 100644
--- a/mysql-test/r/mysqlbinlog.result
+++ b/mysql-test/r/mysqlbinlog.result
@@ -189,4 +189,5 @@ HEX(f)
select HEX(f) from t4;
HEX(f)
835C
+flush logs;
drop table t1, t2, t03, t04, t3, t4;
diff --git a/mysql-test/r/ndb_autodiscover3.result b/mysql-test/r/ndb_autodiscover3.result
new file mode 100644
index 00000000000..8bc1b968436
--- /dev/null
+++ b/mysql-test/r/ndb_autodiscover3.result
@@ -0,0 +1,45 @@
+drop table if exists t1, t2;
+create table t1 (a int key) engine=ndbcluster;
+begin;
+insert into t1 values (1);
+insert into t1 values (2);
+ERROR HY000: Got temporary error 4025 'Node failure caused abort of transaction' from ndbcluster
+commit;
+ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
+drop table t1;
+create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster;
+insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1);
+select * from t2 order by a limit 3;
+a b
+1 1
+2 1
+3 1
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+select * from t2 order by a limit 3;
+ERROR HY000: Can't lock file (errno: 241)
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+show tables;
+Tables_in_test
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+select * from t2 order by a limit 3;
+a
+1
+2
+3
+drop table t2;
diff --git a/mysql-test/r/ndb_blob.result b/mysql-test/r/ndb_blob.result
index a6faafa9612..a5a40cffa91 100644
--- a/mysql-test/r/ndb_blob.result
+++ b/mysql-test/r/ndb_blob.result
@@ -500,3 +500,69 @@ select count(*) from t1;
count(*)
0
drop table t1;
+create table t1 (
+a varchar(40) not null,
+b mediumint not null,
+t text,
+c varchar(2) not null,
+d bigint not null,
+primary key (a,b,c),
+key (c,a),
+unique key (d)
+) engine=ndb;
+insert into t1 (a,b,c,d,t) values ('a',1110,'a',1,@v1);
+insert into t1 (a,b,c,d,t) values ('b',1110,'a',2,@v2);
+insert into t1 (a,b,c,d,t) values ('a',1110,'b',3,@v3);
+insert into t1 (a,b,c,d,t) values ('b',1110,'b',4,@v4);
+select a,b,c,d,sha1(t) from t1 order by c,a;
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+b 1110 a 2 b238654911689bfb626a3ef9dba4a1ca074e6a5e
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+b 1110 b 4 NULL
+select a,b,c,d,sha1(t) from t1 where a='a' and b=1110 and c='a';
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+select a,b,c,d,sha1(t) from t1 where a='a' and b=1110 and c='b';
+a b c d sha1(t)
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+update t1 set t=@v4 where a='b' and b=1110 and c='a';
+update t1 set t=@v2 where a='b' and b=1110 and c='b';
+select a,b,c,d,sha1(t) from t1 order by c,a;
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+b 1110 a 2 NULL
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+b 1110 b 4 b238654911689bfb626a3ef9dba4a1ca074e6a5e
+update t1 set t=@v2 where d=2;
+update t1 set t=@v4 where d=4;
+select a,b,c,d,sha1(t) from t1 order by c,a;
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+b 1110 a 2 b238654911689bfb626a3ef9dba4a1ca074e6a5e
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+b 1110 b 4 NULL
+update t1 set t=@v4 where a='b' and c='a';
+update t1 set t=@v2 where a='b' and c='b';
+select a,b,c,d,sha1(t) from t1 order by c,a;
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+b 1110 a 2 NULL
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+b 1110 b 4 b238654911689bfb626a3ef9dba4a1ca074e6a5e
+update t1 set t=@v2 where b+d=1112;
+update t1 set t=@v4 where b+d=1114;
+select a,b,c,d,sha1(t) from t1 order by c,a;
+a b c d sha1(t)
+a 1110 a 1 558a30713786aa72f66abc1e6a521d55aacdeeb5
+b 1110 a 2 b238654911689bfb626a3ef9dba4a1ca074e6a5e
+a 1110 b 3 2b6515f29c20b8e9e17cc597527e516c0de8d612
+b 1110 b 4 NULL
+delete from t1 where a='a' and b=1110 and c='a';
+delete from t1 where a='b' and c='a';
+delete from t1 where d=3;
+delete from t1 where b+d=1114;
+select count(*) from t1;
+count(*)
+0
+drop table t1;
diff --git a/mysql-test/r/outfile.result b/mysql-test/r/outfile.result
index ee8c3249c9d..040dff576f8 100644
--- a/mysql-test/r/outfile.result
+++ b/mysql-test/r/outfile.result
Binary files differ
diff --git a/mysql-test/r/ps_2myisam.result b/mysql-test/r/ps_2myisam.result
index 603de2afe4e..207d9ea7475 100644
--- a/mysql-test/r/ps_2myisam.result
+++ b/mysql-test/r/ps_2myisam.result
@@ -1777,7 +1777,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1807,7 +1807,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_3innodb.result b/mysql-test/r/ps_3innodb.result
index 9e635f60f14..13aa549949c 100644
--- a/mysql-test/r/ps_3innodb.result
+++ b/mysql-test/r/ps_3innodb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_4heap.result b/mysql-test/r/ps_4heap.result
index fd51c71cad6..a08dae945bd 100644
--- a/mysql-test/r/ps_4heap.result
+++ b/mysql-test/r/ps_4heap.result
@@ -1761,7 +1761,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1791,7 +1791,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_5merge.result b/mysql-test/r/ps_5merge.result
index 876f7615672..6682b085097 100644
--- a/mysql-test/r/ps_5merge.result
+++ b/mysql-test/r/ps_5merge.result
@@ -1697,7 +1697,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1727,7 +1727,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
@@ -4711,7 +4711,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -4741,7 +4741,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_6bdb.result b/mysql-test/r/ps_6bdb.result
index c39621d184f..dc3b984949d 100644
--- a/mysql-test/r/ps_6bdb.result
+++ b/mysql-test/r/ps_6bdb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/ps_7ndb.result b/mysql-test/r/ps_7ndb.result
index 7c83099311e..000a20da655 100644
--- a/mysql-test/r/ps_7ndb.result
+++ b/mysql-test/r/ps_7ndb.result
@@ -1760,7 +1760,7 @@ Table Create Table
t5 CREATE TABLE `t5` (
`const01` bigint(1) NOT NULL default '0',
`param01` bigint(20) default NULL,
- `const02` decimal(2,1) unsigned NOT NULL default '0.0',
+ `const02` decimal(2,1) NOT NULL default '0.0',
`param02` decimal(65,30) default NULL,
`const03` double NOT NULL default '0',
`param03` double default NULL,
@@ -1790,7 +1790,7 @@ select * from t5 ;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
def test t5 t5 const01 const01 8 1 1 N 32769 0 63
def test t5 t5 param01 param01 8 20 1 Y 32768 0 63
-def test t5 t5 const02 const02 246 3 3 N 33 1 63
+def test t5 t5 const02 const02 246 4 3 N 1 1 63
def test t5 t5 param02 param02 246 67 32 Y 0 30 63
def test t5 t5 const03 const03 5 17 1 N 32769 31 63
def test t5 t5 param03 param03 5 23 1 Y 32768 31 63
diff --git a/mysql-test/r/rpl_temporary.result b/mysql-test/r/rpl_temporary.result
index 42e7712750c..751dc7754f7 100644
--- a/mysql-test/r/rpl_temporary.result
+++ b/mysql-test/r/rpl_temporary.result
@@ -103,17 +103,24 @@ f
1
drop temporary table t4;
drop table t5;
-set @session.pseudo_thread_id=100;
+set @@session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
-set @session.pseudo_thread_id=200;
+set @@session.pseudo_thread_id=200;
create temporary table t201 (id int);
-create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
-set @con1_id=connection_id();
-kill @con1_id;
+create temporary table `t``201` (id int);
+create temporary table `#sql_not_user_table202` (id int);
+set @@session.pseudo_thread_id=300;
+create temporary table t301 (id int);
+create temporary table t302 (id int);
+create temporary table `#sql_not_user_table303` (id int);
create table t1(f int);
insert into t1 values (1);
select * from t1 /* must be 1 */;
f
1
drop table t1;
+select * from t1;
+a
+1
+drop table t1;
diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result
index b584e04ed57..60b956785ba 100644
--- a/mysql-test/r/rpl_until.result
+++ b/mysql-test/r/rpl_until.result
@@ -29,9 +29,40 @@ n
2
3
4
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-bin.000001 319 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 319
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-bin.000001
+Until_Log_Pos 319
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
select * from t1;
n
@@ -39,23 +70,116 @@ n
2
3
4
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 319 # Master master-no-such-bin.000001 291 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 319
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-no-such-bin.000001
+Until_Log_Pos 291
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
select * from t2;
n
1
2
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 # No 0 0 608 # Relay slave-relay-bin.000004 746 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running #
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 608
+Relay_Log_Space #
+Until_Condition Relay
+Until_Log_File slave-relay-bin.000004
+Until_Log_Pos 746
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave;
stop slave;
start slave until master_log_file='master-bin.000001', master_log_pos=776;
-show slave status;
-Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master
-# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 776 slave-relay-bin.000004 # master-bin.000001 Yes No 0 0 776 # Master master-bin.000001 776 No #
+SHOW SLAVE STATUS;
+Slave_IO_State #
+Master_Host 127.0.0.1
+Master_User root
+Master_Port MASTER_MYPORT
+Connect_Retry 1
+Master_Log_File master-bin.000001
+Read_Master_Log_Pos 776
+Relay_Log_File slave-relay-bin.000004
+Relay_Log_Pos #
+Relay_Master_Log_File master-bin.000001
+Slave_IO_Running Yes
+Slave_SQL_Running No
+Replicate_Do_DB
+Replicate_Ignore_DB
+Replicate_Do_Table
+Replicate_Ignore_Table
+Replicate_Wild_Do_Table
+Replicate_Wild_Ignore_Table
+Last_Errno 0
+Last_Error
+Skip_Counter 0
+Exec_Master_Log_Pos 776
+Relay_Log_Space #
+Until_Condition Master
+Until_Log_File master-bin.000001
+Until_Log_Pos 776
+Master_SSL_Allowed No
+Master_SSL_CA_File
+Master_SSL_CA_Path
+Master_SSL_Cert
+Master_SSL_Cipher
+Master_SSL_Key
+Seconds_Behind_Master #
start slave until master_log_file='master-bin', master_log_pos=561;
ERROR HY000: Incorrect parameter or combination of parameters for START SLAVE UNTIL
start slave until master_log_file='master-bin.000001', master_log_pos=561, relay_log_pos=12;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 3aae29a922e..335637b787f 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -3427,3 +3427,22 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE A range PRIMARY PRIMARY 12 NULL 3 Using where
1 SIMPLE B ref PRIMARY PRIMARY 8 const,test.A.e 10
drop table t1, t2;
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
+INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2),
+(3,1), (5,1), (8,9), (2,2), (0,9);
+CREATE TABLE t2 (c int, d int, f int, INDEX(c,f));
+INSERT INTO t2 VALUES
+(1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1),
+(5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1),
+(0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1);
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY,b b 5 NULL 3 Using where
+1 SIMPLE t2 ref c c 5 test.t1.a 2 Using where
+DROP TABLE t1, t2;
diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result
index a49b282ddb7..924963017eb 100644
--- a/mysql-test/r/sp-error.result
+++ b/mysql-test/r/sp-error.result
@@ -282,9 +282,9 @@ select @tmp_x, @tmp_y, @tmp_z|
@tmp_x @tmp_y @tmp_z
42 45 87
call p(42, 43, @tmp_z)|
-ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable
+ERROR 42000: OUT or INOUT argument 2 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
call p(42, @tmp_y, 43)|
-ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable
+ERROR 42000: OUT or INOUT argument 3 for routine test.p is not a variable or NEW pseudo-variable in BEFORE trigger
drop procedure p|
create procedure p() begin end|
lock table t1 read|
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 59ce1d13d2b..746cd8f00d4 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -4904,4 +4904,60 @@ schema_name
select routine_name,routine_schema from information_schema.routines where
routine_schema like 'bug18344%'|
routine_name routine_schema
+drop function if exists bug12472|
+create function bug12472() returns int return (select count(*) from t1)|
+create table t3 as select bug12472() as i|
+show create table t3|
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `i` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t3|
+i
+0
+drop table t3|
+create view v1 as select bug12472() as j|
+create table t3 as select * from v1|
+show create table t3|
+Table Create Table
+t3 CREATE TABLE `t3` (
+ `j` bigint(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+select * from t3|
+j
+0
+drop table t3|
+drop view v1|
+drop function bug12472|
+DROP FUNCTION IF EXISTS bug18589_f1|
+DROP PROCEDURE IF EXISTS bug18589_p1|
+DROP PROCEDURE IF EXISTS bug18589_p2|
+CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
+BEGIN
+RETURN CONCAT(arg, "");
+END|
+CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
+BEGIN
+SET ret = CONCAT(arg, "");
+END|
+CREATE PROCEDURE bug18589_p2(arg TEXT)
+BEGIN
+DECLARE v TEXT;
+CALL bug18589_p1(arg, v);
+SELECT v;
+END|
+SELECT bug18589_f1(REPEAT("a", 767))|
+bug18589_f1(REPEAT("a", 767))
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+SET @bug18589_v1 = ""|
+CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
+SELECT @bug18589_v1|
+@bug18589_v1
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+CALL bug18589_p2(REPEAT("a", 767))|
+v
+aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+DROP FUNCTION bug18589_f1|
+DROP PROCEDURE bug18589_p1|
+DROP PROCEDURE bug18589_p2|
drop table t1,t2;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index e3d65882f81..056457a4786 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -3169,3 +3169,17 @@ create table t2 (a int, b int);
insert into t2 values (2, 1), (1, 0);
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
drop table t1, t2;
+CREATE TABLE t1 (a INT);
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'where clause'
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+ERROR 42S22: Unknown column 'no_such_column' in 'IN/ALL/ANY subquery'
+DROP TABLE t1;
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+min(i)
+1
+drop table t1;
diff --git a/mysql-test/r/trigger-grant.result b/mysql-test/r/trigger-grant.result
index 87e5e11d779..f6384d479b7 100644
--- a/mysql-test/r/trigger-grant.result
+++ b/mysql-test/r/trigger-grant.result
@@ -310,3 +310,87 @@ SELECT @mysqltest_var;
Hello, world!
DROP USER mysqltest_u1@localhost;
DROP DATABASE mysqltest_db1;
+DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
+FLUSH PRIVILEGES;
+DROP DATABASE IF EXISTS mysqltest_db1;
+CREATE DATABASE mysqltest_db1;
+USE mysqltest_db1;
+CREATE TABLE t1 (i1 INT);
+CREATE TABLE t2 (i1 INT);
+CREATE USER mysqltest_dfn@localhost;
+CREATE USER mysqltest_inv@localhost;
+GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
+GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
+CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (7);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+INSERT INTO t2 VALUES (11);
+ERROR 42000: SELECT,UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (13);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+INSERT INTO t2 VALUES (17);
+ERROR 42000: UPDATE command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (19);
+INSERT INTO t2 VALUES (23);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't2'
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+CALL p2(NEW.i1);
+INSERT INTO t1 VALUES (29);
+INSERT INTO t2 VALUES (31);
+REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+INSERT INTO t1 VALUES (41);
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
+INSERT INTO t1 VALUES (47);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
+INSERT INTO t1 VALUES (53);
+ERROR 42000: SELECT command denied to user 'mysqltest_dfn'@'localhost' for column 'i1' in table 't1'
+DROP PROCEDURE p1;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+DROP TRIGGER t1_bi;
+DROP USER mysqltest_inv@localhost;
+DROP USER mysqltest_dfn@localhost;
+DROP TABLE t2;
+DROP TABLE t1;
+DROP DATABASE mysqltest_db1;
+USE test;
+End of 5.0 tests.
diff --git a/mysql-test/r/trigger.result b/mysql-test/r/trigger.result
index 6a689437482..8b4aba367fb 100644
--- a/mysql-test/r/trigger.result
+++ b/mysql-test/r/trigger.result
@@ -998,3 +998,95 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
conn_id trigger_conn_id
DROP TRIGGER t1_bi;
DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 (i1 INT);
+SET @save_sql_mode=@@sql_mode;
+SET SQL_MODE='';
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+SET @x = 5/0;
+SET SQL_MODE='traditional';
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+SET @x = 5/0;
+SET @x=1;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+@x
+NULL
+SET @x=2;
+UPDATE t1 SET i1 = @x;
+ERROR 22012: Division by 0
+SELECT @x;
+@x
+2
+SET SQL_MODE='';
+SET @x=3;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+@x
+NULL
+SET @x=4;
+UPDATE t1 SET i1 = @x;
+ERROR 22012: Division by 0
+SELECT @x;
+@x
+4
+SET @@sql_mode=@save_sql_mode;
+DROP TRIGGER t1_ai;
+DROP TRIGGER t1_au;
+DROP TABLE t1;
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+CREATE TABLE t1 (i1 INT);
+INSERT INTO t1 VALUES (3);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
+CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+CALL p1(NEW.i1);
+CALL p2(NEW.i1);
+END//
+UPDATE t1 SET i1 = 11 WHERE i1 = 3;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (13);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+CALL p1(OLD.i1);
+UPDATE t1 SET i1 = 19 WHERE i1 = 13;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (23);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+CALL p1(OLD.i1);
+UPDATE t1 SET i1 = 31 WHERE i1 = 23;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (37);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+UPDATE t1 SET i1 = 43 WHERE i1 = 37;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+INSERT INTO t1 VALUES (47);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+CALL p1(NEW.i1);
+UPDATE t1 SET i1 = 51 WHERE i1 = 47;
+ERROR 42000: OUT or INOUT argument 1 for routine test.p1 is not a variable or NEW pseudo-variable in BEFORE trigger
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+SELECT * FROM t1;
+i1
+35
+13
+23
+43
+51
+DROP TABLE t1;
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index e941e740fcb..61482ab282c 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -245,22 +245,22 @@ show warnings;
Level Code Message
desc t1;
Field Type Null Key Default Extra
-x decimal(21,2) unsigned NO 0.00
+x decimal(21,2) NO 0.00
drop table t1;
create table t1 select 0.0 x;
desc t1;
Field Type Null Key Default Extra
-x decimal(2,1) unsigned NO 0.0
+x decimal(2,1) NO 0.0
create table t2 select 105213674794682365.00 y;
desc t2;
Field Type Null Key Default Extra
-y decimal(20,2) unsigned NO 0.00
+y decimal(20,2) NO 0.00
create table t3 select x+y a from t1,t2;
show warnings;
Level Code Message
desc t3;
Field Type Null Key Default Extra
-a decimal(21,2) unsigned NO 0.00
+a decimal(21,2) NO 0.00
drop table t1,t2,t3;
create table t1 (s1 float(0,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index 938dccc864c..968c6d3ec6f 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -68,10 +68,10 @@ NULL 1.1 NULL NULL NULL 1
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `nullif(1.1, 1.1)` decimal(2,1) unsigned default NULL,
- `nullif(1.1, 1.2)` decimal(2,1) unsigned default NULL,
- `nullif(1.1, 0.11e1)` decimal(2,1) unsigned default NULL,
- `nullif(1.0, 1)` decimal(2,1) unsigned default NULL,
+ `nullif(1.1, 1.1)` decimal(2,1) default NULL,
+ `nullif(1.1, 1.2)` decimal(2,1) default NULL,
+ `nullif(1.1, 0.11e1)` decimal(2,1) default NULL,
+ `nullif(1.0, 1)` decimal(2,1) default NULL,
`nullif(1, 1.0)` int(1) default NULL,
`nullif(1, 1.1)` int(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
@@ -174,9 +174,9 @@ create table t1 select round(15.4,-1), truncate(-5678.123451,-3), abs(-1.1), -(-
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `round(15.4,-1)` decimal(3,0) unsigned NOT NULL default '0',
+ `round(15.4,-1)` decimal(3,0) NOT NULL default '0',
`truncate(-5678.123451,-3)` decimal(4,0) NOT NULL default '0',
- `abs(-1.1)` decimal(2,1) NOT NULL default '0.0',
+ `abs(-1.1)` decimal(3,1) NOT NULL default '0.0',
`-(-1.1)` decimal(2,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
@@ -771,7 +771,7 @@ create table t1 as select 0.5;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `0.5` decimal(2,1) unsigned NOT NULL default '0.0'
+ `0.5` decimal(2,1) NOT NULL default '0.0'
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
select round(1.5),round(2.5);
diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result
index 70282c5143e..8cee60cf49a 100644
--- a/mysql-test/r/variables.result
+++ b/mysql-test/r/variables.result
@@ -639,6 +639,35 @@ select @@version, @@version_comment, @@version_compile_machine,
@@version_compile_os;
@@version @@version_comment @@version_compile_machine @@version_compile_os
# # # #
+select @@basedir, @@datadir, @@tmpdir;
+@@basedir @@datadir @@tmpdir
+# # #
+show variables like 'basedir';
+Variable_name Value
+basedir #
+show variables like 'datadir';
+Variable_name Value
+datadir #
+show variables like 'tmpdir';
+Variable_name Value
+tmpdir #
+select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
+@@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key
+# # # # #
+show variables like 'ssl%';
+Variable_name Value
+ssl_ca #
+ssl_capath #
+ssl_cert #
+ssl_cipher #
+ssl_key #
+select @@log_queries_not_using_indexes;
+@@log_queries_not_using_indexes
+0
+show variables like 'log_queries_not_using_indexes';
+Variable_name Value
+log_queries_not_using_indexes OFF
+End of 5.0 tests
set global binlog_cache_size =@my_binlog_cache_size;
set global connect_timeout =@my_connect_timeout;
set global delayed_insert_timeout =@my_delayed_insert_timeout;
@@ -666,4 +695,3 @@ set global server_id =@my_server_id;
set global slow_launch_time =@my_slow_launch_time;
set global storage_engine =@my_storage_engine;
set global thread_cache_size =@my_thread_cache_size;
-End of 5.0 tests
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 667d10cd145..9c991c9c01c 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -706,7 +706,7 @@ create view v1 as select a from t1;
create view v2 as select a from t2 where a in (select a from v1);
show create view v2;
View Create View
-v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `a` in (select `v1`.`a` AS `a` from `v1`)
+v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t2`.`a` AS `a` from `t2` where `t2`.`a` in (select `v1`.`a` AS `a` from `v1`)
drop view v2, v1;
drop table t1, t2;
CREATE VIEW `v 1` AS select 5 AS `5`;
@@ -2649,3 +2649,48 @@ ldt
2006-01-01 03:00:00
drop view v1, v2;
drop table t1;
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
+CREATE VIEW v1 AS
+SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
+FROM t1 GROUP BY id, t;
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second) AS `t`,count(0) AS `COUNT(*)` from `t1` group by `t1`.`id`,(cast(`t1`.`d` as date) + interval time_to_sec(`t1`.`d`) second)
+SELECT * FROM v1;
+id t COUNT(*)
+DROP VIEW v1;
+DROP TABLE t1;
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
+CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
+SELECT * FROM v2;
+MIN(i)
+1
+DROP VIEW v2, v1;
+DROP TABLE t1;
+CREATE TABLE t1(
+fName varchar(25) NOT NULL,
+lName varchar(25) NOT NULL,
+DOB date NOT NULL,
+uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY);
+INSERT INTO t1(fName, lName, DOB) VALUES
+('Hank', 'Hill', '1964-09-29'),
+('Tom', 'Adams', '1908-02-14'),
+('Homer', 'Simpson', '1968-03-05');
+CREATE VIEW v1 AS
+SELECT (year(now())-year(DOB)) AS Age
+FROM t1 HAVING Age < 75;
+SHOW CREATE VIEW v1;
+View Create View
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_no_cache (year(now()) - year(`t1`.`DOB`)) AS `Age` from `t1` having (`Age` < 75)
+SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75;
+Age
+42
+38
+SELECT * FROM v1;
+Age
+42
+38
+DROP VIEW v1;
+DROP TABLE t1;
diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test
index 2a3a23c5f96..a38771db233 100644
--- a/mysql-test/t/explain.test
+++ b/mysql-test/t/explain.test
@@ -43,3 +43,12 @@ drop table ÔÁÂ;
set names latin1;
# End of 4.1 tests
+
+
+#
+# Bug#15463: EXPLAIN SELECT..INTO hangs the client (QB, command line)
+#
+select 3 into @v1;
+explain select 3 into @v1;
+
+# End of 5.0 tests.
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 351d1fc2c92..8ddf1fbe314 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -220,3 +220,15 @@ set @str=NULL;
drop table t2;
drop table t1;
+# BUG#19618: Crash in range optimizer for
+# "unsigned_keypart NOT IN(negative_number,...)"
+# (introduced in fix BUG#15872)
+create table t1 (
+ some_id smallint(5) unsigned,
+ key (some_id)
+);
+insert into t1 values (1),(2);
+select some_id from t1 where some_id not in(2,-1);
+select some_id from t1 where some_id not in(-4,-1,-4);
+select some_id from t1 where some_id not in(-4,-1,3423534,2342342);
+drop table t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 85cedee0f4a..7f809dbc4a1 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -666,7 +666,14 @@ select rpad(i, 7, ' ') as t from t1;
--disable_metadata
drop table t1;
-# End of 4.1 tests
+#
+# Bug #10418: LOAD_FILE does not behave like in manual if file does not exist
+#
+
+select load_file("lkjlkj");
+select ifnull(load_file("lkjlkj"),"it's null");
+
+--echo End of 4.1 tests
#
# Bug #13361: SELECT FORMAT(<decimal field with null>, 2) crashes
@@ -691,4 +698,10 @@ select cast(rtrim(' 20.06 ') as decimal(19,2));
select cast(ltrim(' 20.06 ') as decimal(19,2));
select cast(rtrim(ltrim(' 20.06 ')) as decimal(19,2));
+#
+# Bug #13975: "same string" + 0 has 2 different results
+#
+select conv("18383815659218730760",10,10) + 0;
+select "18383815659218730760" + 0;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 11178adbc9b..e96f1ef4bbd 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -802,3 +802,23 @@ from information_schema.columns where
table_schema='information_schema' and
(column_type = 'varchar(7)' or column_type = 'varchar(20)')
group by column_type order by num;
+
+#
+# Bug#19236 bad COLUMNS.CHARACTER_MAXIMUM_LENGHT and CHARACTER_OCTET_LENGTH
+#
+create table t1(f1 char(1) not null, f2 char(9) not null)
+default character set utf8;
+select CHARACTER_MAXIMUM_LENGTH, CHARACTER_OCTET_LENGTH from
+information_schema.columns where table_schema='test' and table_name = 't1';
+drop table t1;
+
+#
+# Bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes
+#
+use mysql;
+INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL',
+'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03',
+'2006-03-02 18:40:03','','');
+select routine_name from information_schema.routines;
+delete from proc where name='';
+use test;
diff --git a/mysql-test/t/init_connect.test b/mysql-test/t/init_connect.test
index 2e3c67a7d38..0ee6387d985 100644
--- a/mysql-test/t/init_connect.test
+++ b/mysql-test/t/init_connect.test
@@ -2,6 +2,8 @@
# Test of init_connect variable
#
+# should work with embedded server after mysqltest is fixed
+-- source include/not_embedded.inc
connect (con0,localhost,root,,);
connection con0;
select hex(@a);
diff --git a/mysql-test/t/join_outer.test b/mysql-test/t/join_outer.test
index c194213e0c9..dc4e240750c 100644
--- a/mysql-test/t/join_outer.test
+++ b/mysql-test/t/join_outer.test
@@ -779,3 +779,47 @@ SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE;
DROP TABLE t1,t2;
+
+#
+# Bug 19396: LEFT OUTER JOIN over views in curly braces
+#
+--disable_warnings
+DROP VIEW IF EXISTS v1,v2;
+DROP TABLE IF EXISTS t1,t2;
+--enable_warnings
+
+CREATE TABLE t1 (a int);
+CREATE table t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3);
+INSERT INTO t2 VALUES (2), (3);
+
+CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b;
+CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a;
+
+SELECT v1.a, v2. b
+ FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3)
+ GROUP BY v1.a;
+SELECT v1.a, v2. b
+ FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) }
+ GROUP BY v1.a;
+
+DROP VIEW v1,v2;
+DROP TABLE t1,t2;
+
+#
+# Bug 19816: LEFT OUTER JOIN with constant ORed predicates in WHERE clause
+#
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t2 (b int);
+INSERT INTO t1 VALUES (1), (2), (3), (4);
+INSERT INTO t2 VALUES (2), (3);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1);
+
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2);
+SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0);
+
+DROP TABLE t1,t2;
diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test
index 28074fba7e4..d74bb1c3a80 100644
--- a/mysql-test/t/mysqlbinlog.test
+++ b/mysql-test/t/mysqlbinlog.test
@@ -122,9 +122,22 @@ select HEX(f) from t3;
select HEX(f) from t04;
select HEX(f) from t4;
+#
+# BUG#14157: utf8 encoding in binlog without set character_set_client
+#
+# BUG:
+# This test only works on the MySQL-internal rpl machines.
+# Needs to be fixed. Problem is that koi8r is not installed
+# on many machines.
+#
+flush logs;
+# --exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=koi8r test -e 'create table if not exists t5 (a int); set names koi8r; create temporary table `ÑÝÉË` (a int); insert into `ÑÝÉË` values (1); insert into t5 select * from `ÑÝÉË`'
+# resulted log is client charset insensitive (latin1 not koi8r) as it must be
+# --exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000006 | $MYSQL --default-character-set=latin1
+#select * from t5 /* must be (1),(1) */;
# clean up
drop table t1, t2, t03, t04, t3, t4;
-# End of 4.1 tests
+# End of 5.0 tests
diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test
new file mode 100644
index 00000000000..73b4bf8b94f
--- /dev/null
+++ b/mysql-test/t/ndb_autodiscover3.test
@@ -0,0 +1,65 @@
+-- source include/have_ndb.inc
+-- source include/have_multi_ndb.inc
+-- source include/not_embedded.inc
+
+
+--disable_warnings
+drop table if exists t1, t2;
+--enable_warnings
+
+#
+# Transaction ongoing while cluster is restarted
+#
+--connection server1
+create table t1 (a int key) engine=ndbcluster;
+
+begin;
+insert into t1 values (1);
+
+--exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--error 1297
+insert into t1 values (2);
+--error 1296
+commit;
+
+drop table t1;
+
+#
+# Stale cache after restart -i
+#
+--connection server1
+create table t2 (a int, b int, primary key(a,b)) engine=ndbcluster;
+insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10,1);
+select * from t2 order by a limit 3;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--connection server2
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+
+# server 1 should have a stale cache, and in this case wrong frm, transaction must be retried
+--connection server1
+--error 1015
+select * from t2 order by a limit 3;
+select * from t2 order by a limit 3;
+
+--exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT
+--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT
+
+--connection server1
+show tables;
+create table t2 (a int key) engine=ndbcluster;
+insert into t2 values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+select * from t2 order by a limit 3;
+
+# server 2 should have a stale cache, but with right frm, transaction need not be retried
+--connection server2
+select * from t2 order by a limit 3;
+
+drop table t2;
+# End of 4.1 tests
diff --git a/mysql-test/t/ndb_blob.test b/mysql-test/t/ndb_blob.test
index bf82a793049..d6e0edc89f0 100644
--- a/mysql-test/t/ndb_blob.test
+++ b/mysql-test/t/ndb_blob.test
@@ -428,4 +428,60 @@ truncate t1;
select count(*) from t1;
drop table t1;
+# -- bug#19956 - var* key, complex key
+
+create table t1 (
+ a varchar(40) not null,
+ b mediumint not null,
+ t text,
+ c varchar(2) not null,
+ d bigint not null,
+ primary key (a,b,c),
+ key (c,a),
+ unique key (d)
+) engine=ndb;
+
+--disable_query_log
+set @s1 = 'rggurloniukyehuxdbfkkyzlceixzrehqhvxvxbpwizzvjzpucqmzrhzxzfau';
+set @s2 = 'ykyymbzqgqlcjhlhmyqelfoaaohvtbekvifukdtnvcrrjveevfakxarxexomz';
+set @s3 = 'dbnfqyzgtqxalcrwtfsqabknvtfcbpoonxsjiqvmhnfikxxhcgoexlkoezvah';
+set @v1 = repeat(@s1,123);
+set @v2 = repeat(@s2,234);
+set @v3 = repeat(@s3,345);
+set @v4 = NULL;
+--enable_query_log
+
+insert into t1 (a,b,c,d,t) values ('a',1110,'a',1,@v1);
+insert into t1 (a,b,c,d,t) values ('b',1110,'a',2,@v2);
+insert into t1 (a,b,c,d,t) values ('a',1110,'b',3,@v3);
+insert into t1 (a,b,c,d,t) values ('b',1110,'b',4,@v4);
+select a,b,c,d,sha1(t) from t1 order by c,a;
+
+select a,b,c,d,sha1(t) from t1 where a='a' and b=1110 and c='a';
+select a,b,c,d,sha1(t) from t1 where a='a' and b=1110 and c='b';
+
+update t1 set t=@v4 where a='b' and b=1110 and c='a';
+update t1 set t=@v2 where a='b' and b=1110 and c='b';
+select a,b,c,d,sha1(t) from t1 order by c,a;
+
+update t1 set t=@v2 where d=2;
+update t1 set t=@v4 where d=4;
+select a,b,c,d,sha1(t) from t1 order by c,a;
+
+update t1 set t=@v4 where a='b' and c='a';
+update t1 set t=@v2 where a='b' and c='b';
+select a,b,c,d,sha1(t) from t1 order by c,a;
+
+update t1 set t=@v2 where b+d=1112;
+update t1 set t=@v4 where b+d=1114;
+select a,b,c,d,sha1(t) from t1 order by c,a;
+
+delete from t1 where a='a' and b=1110 and c='a';
+delete from t1 where a='b' and c='a';
+delete from t1 where d=3;
+delete from t1 where b+d=1114;
+select count(*) from t1;
+
+drop table t1;
+
# End of 4.1 tests
diff --git a/mysql-test/t/outfile.test b/mysql-test/t/outfile.test
index d404a6fff9f..c48e6c9730d 100644
--- a/mysql-test/t/outfile.test
+++ b/mysql-test/t/outfile.test
@@ -40,7 +40,6 @@ eval select * into dumpfile "../tmp/outfile-test.2" from t1;
--error 1086
eval select * into dumpfile "../tmp/outfile-test.3" from t1;
enable_query_log;
---error 13,2
select load_file(concat(@tmpdir,"/outfile-test.not-exist"));
--exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.1
--exec rm $MYSQLTEST_VARDIR/tmp/outfile-test.2
diff --git a/mysql-test/t/rename.test b/mysql-test/t/rename.test
index 5caecef176e..86e4b6eed0a 100644
--- a/mysql-test/t/rename.test
+++ b/mysql-test/t/rename.test
@@ -61,9 +61,15 @@ connection con2;
sleep 1;
show tables;
UNLOCK TABLES;
-sleep 1;
+connection con1;
+reap;
+connection con2;
show tables;
drop table t2, t4;
+disconnect con2;
+disconnect con1;
+connection default;
+
# End of 4.1 tests
diff --git a/mysql-test/t/rpl_temporary.test b/mysql-test/t/rpl_temporary.test
index facf0d68d2b..81f0e8a0af7 100644
--- a/mysql-test/t/rpl_temporary.test
+++ b/mysql-test/t/rpl_temporary.test
@@ -163,14 +163,19 @@ drop table t5;
# value was set up at the moment of temp table creation
#
connection con1;
-set @session.pseudo_thread_id=100;
+set @@session.pseudo_thread_id=100;
create temporary table t101 (id int);
create temporary table t102 (id int);
-set @session.pseudo_thread_id=200;
+set @@session.pseudo_thread_id=200;
create temporary table t201 (id int);
-create temporary table `#not_user_table_prefixed_with_hash_sign_no_harm` (id int);
-set @con1_id=connection_id();
-kill @con1_id;
+create temporary table `t``201` (id int);
+# emulate internal temp table not to come to binlog
+create temporary table `#sql_not_user_table202` (id int);
+set @@session.pseudo_thread_id=300;
+create temporary table t301 (id int);
+create temporary table t302 (id int);
+create temporary table `#sql_not_user_table303` (id int);
+disconnect con1;
#now do something to show that slave is ok after DROP temp tables
connection master;
@@ -184,4 +189,16 @@ select * from t1 /* must be 1 */;
connection master;
drop table t1;
+#
+#14157: utf8 encoding in binlog without set character_set_client
+#
+--exec $MYSQL --character-sets-dir=../sql/share/charsets/ --default-character-set=latin1 test -e 'create table t1 (a int); set names latin1; create temporary table `äöüÄÖÜ` (a int); insert into `äöüÄÖÜ` values (1); insert into t1 select * from `äöüÄÖÜ`'
+
+sync_slave_with_master;
+#connection slave;
+select * from t1;
+
+connection master;
+drop table t1;
+
# End of 5.0 tests
diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test
index e0ecf981fea..c404ea7e58b 100644
--- a/mysql-test/t/rpl_until.test
+++ b/mysql-test/t/rpl_until.test
@@ -31,7 +31,7 @@ wait_for_slave_to_stop;
select * from t1;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# this should fail right after start
start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291;
@@ -41,7 +41,7 @@ sleep 2;
wait_for_slave_to_stop;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# try replicate all until second insert to t2;
start slave until relay_log_file='slave-relay-bin.000004', relay_log_pos=746;
@@ -50,7 +50,7 @@ wait_for_slave_to_stop;
select * from t2;
--replace_result $MASTER_MYPORT MASTER_MYPORT
--replace_column 1 # 9 # 11 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
# clean up
start slave;
@@ -67,7 +67,7 @@ wait_for_slave_to_stop;
# here the sql slave thread should be stopped
--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004
--replace_column 1 # 9 # 23 # 33 #
-show slave status;
+--query_vertical SHOW SLAVE STATUS
#testing various error conditions
--error 1277
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 033350d138a..4b6ae921b9b 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -2899,3 +2899,24 @@ select 'In next EXPLAIN, B.rows must be exactly 10:' Z;
explain select * from t2 A, t2 B where A.a=5 and A.b=5 and A.C<5
and B.a=5 and B.b=A.e and (B.b =1 or B.b = 3 or B.b=5);
drop table t1, t2;
+
+#
+#Bug #18940: selection of optimal execution plan caused by equality
+# propagation (the bug was fixed by the patch for bug #17379)
+
+CREATE TABLE t1 (a int PRIMARY KEY, b int, INDEX(b));
+INSERT INTO t1 VALUES (1, 3), (9,4), (7,5), (4,5), (6,2),
+ (3,1), (5,1), (8,9), (2,2), (0,9);
+
+CREATE TABLE t2 (c int, d int, f int, INDEX(c,f));
+INSERT INTO t2 VALUES
+ (1,0,0), (1,0,1), (2,0,0), (2,0,1), (3,0,0), (4,0,1),
+ (5,0,0), (5,0,1), (6,0,0), (0,0,1), (7,0,0), (7,0,1),
+ (0,0,0), (0,0,1), (8,0,0), (8,0,1), (9,0,0), (9,0,1);
+
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6;
+EXPLAIN
+SELECT a, c, d, f FROM t1,t2 WHERE a=c AND b BETWEEN 4 AND 6 AND a > 0;
+
+DROP TABLE t1, t2;
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 22500bbd280..9995ff5a9ad 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -5774,6 +5774,76 @@ select routine_name,routine_schema from information_schema.routines where
#
+# BUG#12472/BUG#15137 'CREATE TABLE ... SELECT ... which explicitly or
+# implicitly uses stored function gives "Table not locked" error'.
+#
+--disable_warnings
+drop function if exists bug12472|
+--enable_warnings
+create function bug12472() returns int return (select count(*) from t1)|
+# Check case when function is used directly
+create table t3 as select bug12472() as i|
+show create table t3|
+select * from t3|
+drop table t3|
+# Check case when function is used indirectly through view
+create view v1 as select bug12472() as j|
+create table t3 as select * from v1|
+show create table t3|
+select * from t3|
+drop table t3|
+drop view v1|
+drop function bug12472|
+
+
+#
+# BUG#18587: Function that accepts and returns TEXT garbles data if longer than
+# 766 chars
+#
+
+# Prepare.
+
+--disable_warnings
+DROP FUNCTION IF EXISTS bug18589_f1|
+DROP PROCEDURE IF EXISTS bug18589_p1|
+DROP PROCEDURE IF EXISTS bug18589_p2|
+--enable_warnings
+
+CREATE FUNCTION bug18589_f1(arg TEXT) RETURNS TEXT
+BEGIN
+ RETURN CONCAT(arg, "");
+END|
+
+CREATE PROCEDURE bug18589_p1(arg TEXT, OUT ret TEXT)
+BEGIN
+ SET ret = CONCAT(arg, "");
+END|
+
+CREATE PROCEDURE bug18589_p2(arg TEXT)
+BEGIN
+ DECLARE v TEXT;
+ CALL bug18589_p1(arg, v);
+ SELECT v;
+END|
+
+# Test case.
+
+SELECT bug18589_f1(REPEAT("a", 767))|
+
+SET @bug18589_v1 = ""|
+CALL bug18589_p1(REPEAT("a", 767), @bug18589_v1)|
+SELECT @bug18589_v1|
+
+CALL bug18589_p2(REPEAT("a", 767))|
+
+# Cleanup.
+
+DROP FUNCTION bug18589_f1|
+DROP PROCEDURE bug18589_p1|
+DROP PROCEDURE bug18589_p2|
+
+
+#
# BUG#NNNN: New bug synopsis
#
#--disable_warnings
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 1ef80bdd7ac..3f48b648f40 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -2085,3 +2085,27 @@ create table t2 (a int, b int);
insert into t2 values (2, 1), (1, 0);
delete from t1 where c <= 1140006215 and (select b from t2 where a = 2) = 1;
drop table t1, t2;
+
+#
+# Bug #7549: Missing error message for invalid view selection with subquery
+#
+
+CREATE TABLE t1 (a INT);
+
+--error 1054
+CREATE VIEW v1 AS SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+--error 1054
+CREATE VIEW v2 AS SELECT * FROM t1 WHERE no_such_column = (SELECT 1);
+--error 1054
+SELECT * FROM t1 WHERE no_such_column = ANY (SELECT 1);
+
+DROP TABLE t1;
+
+#
+# Bug#19077: A nested materialized derived table is used before being populated.
+#
+create table t1 (i int, j bigint);
+insert into t1 values (1, 2), (2, 2), (3, 2);
+select * from (select min(i) from t1 where j=(select * from (select min(j) from t1) t2)) t3;
+drop table t1;
+
diff --git a/mysql-test/t/trigger-grant.test b/mysql-test/t/trigger-grant.test
index 7a3f7a9fa94..12b929898a8 100644
--- a/mysql-test/t/trigger-grant.test
+++ b/mysql-test/t/trigger-grant.test
@@ -564,3 +564,176 @@ SELECT @mysqltest_var;
DROP USER mysqltest_u1@localhost;
DROP DATABASE mysqltest_db1;
+
+
+#
+# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
+# procedures from within triggers
+#
+# We require UPDATE privilege when NEW.x passed as OUT parameter, and
+# SELECT and UPDATE when NEW.x passed as INOUT parameter.
+#
+DELETE FROM mysql.user WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.db WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.tables_priv WHERE User LIKE 'mysqltest_%';
+DELETE FROM mysql.columns_priv WHERE User LIKE 'mysqltest_%';
+FLUSH PRIVILEGES;
+
+--disable_warnings
+DROP DATABASE IF EXISTS mysqltest_db1;
+--enable_warnings
+
+CREATE DATABASE mysqltest_db1;
+USE mysqltest_db1;
+
+CREATE TABLE t1 (i1 INT);
+CREATE TABLE t2 (i1 INT);
+
+CREATE USER mysqltest_dfn@localhost;
+CREATE USER mysqltest_inv@localhost;
+
+GRANT EXECUTE, CREATE ROUTINE, SUPER ON *.* TO mysqltest_dfn@localhost;
+GRANT INSERT ON mysqltest_db1.* TO mysqltest_inv@localhost;
+
+connect (definer,localhost,mysqltest_dfn,,mysqltest_db1);
+connect (invoker,localhost,mysqltest_inv,,mysqltest_db1);
+
+connection definer;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 3;
+CREATE PROCEDURE p2(INOUT i INT) DETERMINISTIC NO SQL SET i = i * 5;
+
+# Check that having no privilege won't work.
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (7);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (11);
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having only SELECT privilege is not enough.
+connection default;
+GRANT SELECT ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (13);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (17);
+
+connection default;
+REVOKE SELECT ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having only UPDATE privilege is enough for OUT parameter,
+# but not for INOUT parameter.
+connection default;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (19);
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t2 VALUES (23);
+
+connection default;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+# Check that having SELECT and UPDATE privileges is enough.
+connection default;
+GRANT SELECT, UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+CREATE TRIGGER t2_bi BEFORE INSERT ON t2 FOR EACH ROW
+ CALL p2(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (29);
+INSERT INTO t2 VALUES (31);
+
+connection default;
+REVOKE SELECT, UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t2_bi;
+DROP TRIGGER t1_bi;
+
+connection default;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+
+# Check that late procedure redefining won't open a security hole.
+connection default;
+GRANT UPDATE ON mysqltest_db1.* TO mysqltest_dfn@localhost;
+
+connection definer;
+CREATE PROCEDURE p1(OUT i INT) DETERMINISTIC NO SQL SET i = 37;
+CREATE TRIGGER t1_bi BEFORE INSERT ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+
+connection invoker;
+INSERT INTO t1 VALUES (41);
+
+connection definer;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(IN i INT) DETERMINISTIC NO SQL SET @v1 = i + 43;
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (47);
+
+connection definer;
+DROP PROCEDURE p1;
+CREATE PROCEDURE p1(INOUT i INT) DETERMINISTIC NO SQL SET i = i + 51;
+
+connection invoker;
+--error ER_COLUMNACCESS_DENIED_ERROR
+INSERT INTO t1 VALUES (53);
+
+connection default;
+DROP PROCEDURE p1;
+REVOKE UPDATE ON mysqltest_db1.* FROM mysqltest_dfn@localhost;
+
+connection definer;
+DROP TRIGGER t1_bi;
+
+# Cleanup.
+disconnect definer;
+disconnect invoker;
+connection default;
+DROP USER mysqltest_inv@localhost;
+DROP USER mysqltest_dfn@localhost;
+DROP TABLE t2;
+DROP TABLE t1;
+DROP DATABASE mysqltest_db1;
+USE test;
+
+--echo End of 5.0 tests.
diff --git a/mysql-test/t/trigger.test b/mysql-test/t/trigger.test
index 00c85a650d1..a5bd2ba0b38 100644
--- a/mysql-test/t/trigger.test
+++ b/mysql-test/t/trigger.test
@@ -1165,4 +1165,126 @@ SELECT * FROM t1 WHERE conn_id != trigger_conn_id;
DROP TRIGGER t1_bi;
DROP TABLE t1;
+
+#
+# Bug#6951: Triggers/Traditional: SET @ result wrong
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 (i1 INT);
+
+SET @save_sql_mode=@@sql_mode;
+
+SET SQL_MODE='';
+
+CREATE TRIGGER t1_ai AFTER INSERT ON t1 FOR EACH ROW
+ SET @x = 5/0;
+
+SET SQL_MODE='traditional';
+
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ SET @x = 5/0;
+
+SET @x=1;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+
+SET @x=2;
+--error 1365
+UPDATE t1 SET i1 = @x;
+SELECT @x;
+
+SET SQL_MODE='';
+
+SET @x=3;
+INSERT INTO t1 VALUES (@x);
+SELECT @x;
+
+SET @x=4;
+--error 1365
+UPDATE t1 SET i1 = @x;
+SELECT @x;
+
+SET @@sql_mode=@save_sql_mode;
+
+DROP TRIGGER t1_ai;
+DROP TRIGGER t1_au;
+DROP TABLE t1;
+
+
+#
+# Test for bug #14635 Accept NEW.x as INOUT parameters to stored
+# procedures from within triggers
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+--enable_warnings
+
+CREATE TABLE t1 (i1 INT);
+
+# Check that NEW.x pseudo variable is accepted as INOUT and OUT
+# parameter to stored routine.
+INSERT INTO t1 VALUES (3);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET i1 = 5;
+CREATE PROCEDURE p2(INOUT i1 INT) DETERMINISTIC NO SQL SET i1 = i1 * 7;
+delimiter //;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+BEGIN
+ CALL p1(NEW.i1);
+ CALL p2(NEW.i1);
+END//
+delimiter ;//
+UPDATE t1 SET i1 = 11 WHERE i1 = 3;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p2;
+DROP PROCEDURE p1;
+
+# Check that OLD.x pseudo variable is not accepted as INOUT and OUT
+# parameter to stored routine.
+INSERT INTO t1 VALUES (13);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 17;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ CALL p1(OLD.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 19 WHERE i1 = 13;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+
+INSERT INTO t1 VALUES (23);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 29;
+CREATE TRIGGER t1_bu BEFORE UPDATE ON t1 FOR EACH ROW
+ CALL p1(OLD.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 31 WHERE i1 = 23;
+DROP TRIGGER t1_bu;
+DROP PROCEDURE p1;
+
+# Check that NEW.x pseudo variable is read-only in the AFTER TRIGGER.
+INSERT INTO t1 VALUES (37);
+CREATE PROCEDURE p1(OUT i1 INT) DETERMINISTIC NO SQL SET @a = 41;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 43 WHERE i1 = 37;
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+
+INSERT INTO t1 VALUES (47);
+CREATE PROCEDURE p1(INOUT i1 INT) DETERMINISTIC NO SQL SET @a = i1 * 49;
+CREATE TRIGGER t1_au AFTER UPDATE ON t1 FOR EACH ROW
+ CALL p1(NEW.i1);
+--error ER_SP_NOT_VAR_ARG
+UPDATE t1 SET i1 = 51 WHERE i1 = 47;
+DROP TRIGGER t1_au;
+DROP PROCEDURE p1;
+
+# Post requisite.
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
# End of 5.0 tests
diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test
index 20928c7b6c1..be1731e7493 100644
--- a/mysql-test/t/variables.test
+++ b/mysql-test/t/variables.test
@@ -540,7 +540,42 @@ select @@version, @@version_comment, @@version_compile_machine,
@@version_compile_os;
#
-# Bug #19263: variables.test doesn't clean up after itself (II/II -- restore)
+# Bug #1039: make tmpdir and datadir available as @@variables (also included
+# basedir)
+#
+# Don't actually output, since it depends on the system
+--replace_column 1 # 2 # 3 #
+select @@basedir, @@datadir, @@tmpdir;
+--replace_column 2 #
+show variables like 'basedir';
+--replace_column 2 #
+show variables like 'datadir';
+--replace_column 2 #
+show variables like 'tmpdir';
+
+#
+# Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables
+#
+# Don't actually output, since it depends on the system
+--replace_column 1 # 2 # 3 # 4 # 5 #
+select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
+--replace_column 2 #
+show variables like 'ssl%';
+
+#
+# Bug #19616: make log_queries_not_using_indexes available in SHOW VARIABLES
+# and as @@log_queries_not_using_indexes
+#
+select @@log_queries_not_using_indexes;
+show variables like 'log_queries_not_using_indexes';
+
+--echo End of 5.0 tests
+
+# This is at the very after the versioned tests, since it involves doing
+# cleanup
+#
+# Bug #19263: variables.test doesn't clean up after itself (II/II --
+# restore)
#
set global binlog_cache_size =@my_binlog_cache_size;
set global connect_timeout =@my_connect_timeout;
@@ -569,5 +604,3 @@ set global server_id =@my_server_id;
set global slow_launch_time =@my_slow_launch_time;
set global storage_engine =@my_storage_engine;
set global thread_cache_size =@my_thread_cache_size;
-
---echo End of 5.0 tests
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 8f759c2d43e..f4798317fa1 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -2512,3 +2512,58 @@ create view v2 as select convert_tz(dt, 'UTC', 'Europe/Moscow') as ldt from v1;
select * from v2;
drop view v1, v2;
drop table t1;
+
+#
+# Bug #19490: usage of view specified by a query with GROUP BY
+# an expression containing non-constant interval
+
+CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, d datetime);
+
+CREATE VIEW v1 AS
+SELECT id, date(d) + INTERVAL TIME_TO_SEC(d) SECOND AS t, COUNT(*)
+ FROM t1 GROUP BY id, t;
+
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+#
+# Bug#19077: A nested materialized view is used before being populated.
+#
+CREATE TABLE t1 (i INT, j BIGINT);
+INSERT INTO t1 VALUES (1, 2), (2, 2), (3, 2);
+CREATE VIEW v1 AS SELECT MIN(j) AS j FROM t1;
+CREATE VIEW v2 AS SELECT MIN(i) FROM t1 WHERE j = ( SELECT * FROM v1 );
+SELECT * FROM v2;
+DROP VIEW v2, v1;
+DROP TABLE t1;
+
+#
+# Bug #19573: VIEW with HAVING that refers an alias name
+#
+
+CREATE TABLE t1(
+ fName varchar(25) NOT NULL,
+ lName varchar(25) NOT NULL,
+ DOB date NOT NULL,
+ uID int unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY);
+
+INSERT INTO t1(fName, lName, DOB) VALUES
+ ('Hank', 'Hill', '1964-09-29'),
+ ('Tom', 'Adams', '1908-02-14'),
+ ('Homer', 'Simpson', '1968-03-05');
+
+CREATE VIEW v1 AS
+ SELECT (year(now())-year(DOB)) AS Age
+ FROM t1 HAVING Age < 75;
+SHOW CREATE VIEW v1;
+
+SELECT (year(now())-year(DOB)) AS Age FROM t1 HAVING Age < 75;
+SELECT * FROM v1;
+
+DROP VIEW v1;
+DROP TABLE t1;
+
+
diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp
index 7737810653d..3c2ac1a7ea5 100644
--- a/mysql-test/valgrind.supp
+++ b/mysql-test/valgrind.supp
@@ -11,7 +11,7 @@
fun:calloc
fun:_dl_allocate_tls
fun:allocate_stack
- fun:pthread_create@@GLIBC_2.1
+ fun:pthread_create*
}
{
@@ -34,15 +34,6 @@
}
{
- pthread allocate_dtv memory loss second
- Memcheck:Leak
- fun:calloc
- fun:allocate_dtv
- fun:_dl_allocate_tls
- fun:pthread_create*
-}
-
-{
pthread memalign memory loss
Memcheck:Leak
fun:memalign
@@ -73,17 +64,6 @@
}
{
- pthread strstr uninit
- Memcheck:Cond
- fun:strstr
- obj:/lib/tls/libpthread.so.*
- obj:/lib/tls/libpthread.so.*
- fun:call_init
- fun:_dl_init
- obj:/lib/ld-*.so
-}
-
-{
pthread errno
Memcheck:Leak
fun:calloc
@@ -152,3 +132,163 @@
obj:*/libz.so.*
fun:gzflush
}
+
+#
+# Leaks reported in _dl_* internal functions on Linux amd64 / glibc2.3.2.
+#
+
+{
+ _dl_start invalid write8
+ Memcheck:Addr8
+ fun:_dl_start
+}
+
+{
+ _dl_start invalid write4
+ Memcheck:Addr4
+ fun:_dl_start
+}
+
+{
+ _dl_start/_dl_setup_hash invalid read8
+ Memcheck:Addr8
+ fun:_dl_setup_hash
+ fun:_dl_start
+}
+
+{
+ _dl_sysdep_start invalid write8
+ Memcheck:Addr8
+ fun:_dl_sysdep_start
+}
+
+{
+ _dl_init invalid write8
+ Memcheck:Addr8
+ fun:_dl_init
+}
+
+{
+ _dl_init invalid write4
+ Memcheck:Addr4
+ fun:_dl_init
+}
+
+{
+ _dl_init/_dl_init invalid read8
+ Memcheck:Addr8
+ fun:_dl_debug_initialize
+ fun:_dl_init
+}
+
+{
+ _dl_init/_dl_debug_state invalid read8
+ Memcheck:Addr8
+ fun:_dl_debug_state
+ fun:_dl_init
+}
+
+{
+ init invalid write8
+ Memcheck:Addr8
+ fun:init
+}
+
+{
+ fixup invalid write8
+ Memcheck:Addr8
+ fun:fixup
+}
+
+{
+ fixup/_dl_lookup_versioned_symbol invalid read8
+ Memcheck:Addr8
+ fun:_dl_lookup_versioned_symbol
+ fun:fixup
+}
+
+{
+ _dl_runtime_resolve invalid read8
+ Memcheck:Addr8
+ fun:_dl_runtime_resolve
+}
+
+{
+ __libc_start_main invalid write8
+ Memcheck:Addr8
+ fun:__libc_start_main
+}
+
+{
+ __libc_start_main/__sigjmp_save invalid write4
+ Memcheck:Addr4
+ fun:__sigjmp_save
+ fun:__libc_start_main
+}
+
+#
+# These seem to be libc threading stuff, not related to MySQL code (allocations
+# during pthread_exit()). Googling shows other projects also using these
+# suppressions.
+#
+# Note that these all stem from pthread_exit() deeper in the call stack, but
+# Valgrind only allows the top four calls in the suppressions.
+#
+
+{
+ libc pthread_exit 1
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+}
+
+{
+ libc pthread_exit 2
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 3
+ Memcheck:Leak
+ fun:malloc
+ fun:_dl_map_object_deps
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 4
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_check_map_versions
+ fun:dl_open_worker
+ fun:_dl_catch_error
+}
+
+{
+ libc pthread_exit 5
+ Memcheck:Leak
+ fun:calloc
+ fun:_dl_new_object
+ fun:_dl_map_object_from_fd
+ fun:_dl_map_object
+}
+
+
+
+#
+# This is seen internally in the system libraries on 64-bit RHAS3.
+#
+
+{
+ __lll_mutex_unlock_wake uninitialized
+ Memcheck:Param
+ futex(utime)
+ fun:__lll_mutex_unlock_wake
+}
diff --git a/mysys/my_init.c b/mysys/my_init.c
index c2bfdde0ddd..9b8d4db172f 100644
--- a/mysys/my_init.c
+++ b/mysys/my_init.c
@@ -196,8 +196,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n",
_CrtDumpMemoryLeaks();
#endif
}
+
+ if (!(infoflag & MY_DONT_FREE_DBUG))
+ DBUG_END(); /* Must be done before my_thread_end */
#ifdef THREAD
- DBUG_POP(); /* Must be done before my_thread_end */
my_thread_end();
my_thread_global_end();
#if defined(SAFE_MUTEX)
diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h
index 7c24c5d698d..410c811213b 100644
--- a/ndb/include/mgmapi/mgmapi_config_parameters.h
+++ b/ndb/include/mgmapi/mgmapi_config_parameters.h
@@ -65,6 +65,7 @@
#define CFG_DB_BACKUP_DATA_BUFFER_MEM 134
#define CFG_DB_BACKUP_LOG_BUFFER_MEM 135
#define CFG_DB_BACKUP_WRITE_SIZE 136
+#define CFG_DB_BACKUP_MAX_WRITE_SIZE 139
#define CFG_LOG_DESTINATION 147
diff --git a/ndb/include/ndbapi/ndb_cluster_connection.hpp b/ndb/include/ndbapi/ndb_cluster_connection.hpp
index c96300047d5..fcce53c90a0 100644
--- a/ndb/include/ndbapi/ndb_cluster_connection.hpp
+++ b/ndb/include/ndbapi/ndb_cluster_connection.hpp
@@ -95,6 +95,7 @@ public:
unsigned no_db_nodes();
unsigned node_id();
+ unsigned get_connect_count() const;
#endif
private:
diff --git a/ndb/include/util/SocketServer.hpp b/ndb/include/util/SocketServer.hpp
index 4c37e63adf0..c21673f932a 100644
--- a/ndb/include/util/SocketServer.hpp
+++ b/ndb/include/util/SocketServer.hpp
@@ -74,7 +74,7 @@ public:
/**
* Constructor / Destructor
*/
- SocketServer(int maxSessions = 32);
+ SocketServer(unsigned maxSessions = ~(unsigned)0);
~SocketServer();
/**
diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp
index 377fabe27ab..820aa4cfc18 100644
--- a/ndb/src/common/transporter/Transporter.cpp
+++ b/ndb/src/common/transporter/Transporter.cpp
@@ -105,10 +105,10 @@ Transporter::connect_server(NDB_SOCKET_TYPE sockfd) {
}
{
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r= getpeername(sockfd, &addr, &addrlen);
- m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
+ int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
+ m_connect_address= (&addr)->sin_addr;
}
bool res = connect_server_impl(sockfd);
@@ -198,10 +198,10 @@ Transporter::connect_client(NDB_SOCKET_TYPE sockfd) {
}
{
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r= getpeername(sockfd, &addr, &addrlen);
- m_connect_address= ((struct sockaddr_in *)&addr)->sin_addr;
+ int r= getpeername(sockfd, (struct sockaddr*)&addr, &addrlen);
+ m_connect_address= (&addr)->sin_addr;
}
bool res = connect_client_impl(sockfd);
diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp
index 481c656b78b..f0af925cf6d 100644
--- a/ndb/src/common/util/SocketServer.cpp
+++ b/ndb/src/common/util/SocketServer.cpp
@@ -27,7 +27,7 @@
#define DEBUG(x) ndbout << x << endl;
-SocketServer::SocketServer(int maxSessions) :
+SocketServer::SocketServer(unsigned maxSessions) :
m_sessions(10),
m_services(5)
{
@@ -136,7 +136,7 @@ SocketServer::setup(SocketServer::Service * service,
}
DBUG_PRINT("info",("bound to %u",ntohs(servaddr.sin_port)));
- if (listen(sock, m_maxSessions) == -1){
+ if (listen(sock, m_maxSessions > 32 ? 32 : m_maxSessions) == -1){
DBUG_PRINT("error",("listen() - %d - %s",
errno, strerror(errno)));
NDB_CLOSE_SOCKET(sock);
diff --git a/ndb/src/kernel/blocks/backup/Backup.cpp b/ndb/src/kernel/blocks/backup/Backup.cpp
index ea4009015cb..f9089355475 100644
--- a/ndb/src/kernel/blocks/backup/Backup.cpp
+++ b/ndb/src/kernel/blocks/backup/Backup.cpp
@@ -114,15 +114,16 @@ Backup::execREAD_CONFIG_REQ(Signal* signal)
Uint32 szDataBuf = (2 * 1024 * 1024);
Uint32 szLogBuf = (2 * 1024 * 1024);
- Uint32 szWrite = 32768;
+ Uint32 szWrite = 32768, maxWriteSize = (256 * 1024);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_DATA_BUFFER_MEM, &szDataBuf);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_LOG_BUFFER_MEM, &szLogBuf);
ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_WRITE_SIZE, &szWrite);
+ ndb_mgm_get_int_parameter(p, CFG_DB_BACKUP_MAX_WRITE_SIZE, &maxWriteSize);
c_defaults.m_logBufferSize = szLogBuf;
c_defaults.m_dataBufferSize = szDataBuf;
c_defaults.m_minWriteSize = szWrite;
- c_defaults.m_maxWriteSize = szWrite;
+ c_defaults.m_maxWriteSize = maxWriteSize;
{ // Init all tables
ArrayList<Table> tables(c_tablePool);
diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
index 761f959acdc..f83f21f14d8 100644
--- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
+++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp
@@ -1496,6 +1496,7 @@ int Dbtup::interpreterNextLab(Signal* signal,
// word read. Thus we set the register to be a 32 bit register.
/* ------------------------------------------------------------- */
TregMemBuffer[theRegister] = 0x50;
+ // arithmetic conversion if big-endian
* (Int64*)(TregMemBuffer+theRegister+2) = TregMemBuffer[theRegister+1];
} else if (TnoDataRW == 3) {
/* ------------------------------------------------------------- */
@@ -1554,6 +1555,11 @@ int Dbtup::interpreterNextLab(Signal* signal,
Tlen = TattrNoOfWords + 1;
if (Toptype == ZUPDATE) {
if (TattrNoOfWords <= 2) {
+ if (TattrNoOfWords == 1) {
+ // arithmetic conversion if big-endian
+ TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2];
+ TdataForUpdate[2] = 0;
+ }
if (TregType == 0) {
/* --------------------------------------------------------- */
// Write a NULL value into the attribute
diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp
index f99478a8cea..061360428af 100644
--- a/ndb/src/mgmapi/mgmapi.cpp
+++ b/ndb/src/mgmapi/mgmapi.cpp
@@ -695,10 +695,12 @@ ndb_mgm_get_status(NdbMgmHandle handle)
Vector<BaseString> split;
tmp.split(split, ":");
if(split.size() != 2){
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL;
}
if(!(split[0].trim() == "nodes")){
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, buf);
return NULL;
}
@@ -746,6 +748,7 @@ ndb_mgm_get_status(NdbMgmHandle handle)
if(i+1 != noOfNodes){
free(state);
+ SET_ERROR(handle, NDB_MGM_ILLEGAL_NODE_STATUS, "Node count mismatch");
return NULL;
}
diff --git a/ndb/src/mgmsrv/ConfigInfo.cpp b/ndb/src/mgmsrv/ConfigInfo.cpp
index 817943f5e51..e9093d59494 100644
--- a/ndb/src/mgmsrv/ConfigInfo.cpp
+++ b/ndb/src/mgmsrv/ConfigInfo.cpp
@@ -1199,7 +1199,19 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = {
false,
ConfigInfo::CI_INT,
"32K",
- "0",
+ "2K",
+ STR_VALUE(MAX_INT_RNIL) },
+
+ {
+ CFG_DB_BACKUP_MAX_WRITE_SIZE,
+ "BackupMaxWriteSize",
+ DB_TOKEN,
+ "Max size of filesystem writes made by backup (in bytes)",
+ ConfigInfo::CI_USED,
+ false,
+ ConfigInfo::CI_INT,
+ "256K",
+ "2K",
STR_VALUE(MAX_INT_RNIL) },
/***************************************************************************
diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp
index d40eaab7bd5..b713a3908ab 100644
--- a/ndb/src/mgmsrv/MgmtSrvr.cpp
+++ b/ndb/src/mgmsrv/MgmtSrvr.cpp
@@ -2408,6 +2408,7 @@ int
MgmtSrvr::abortBackup(Uint32 backupId)
{
SignalSender ss(theFacade);
+ ss.lock(); // lock will be released on exit
bool next;
NodeId nodeId = 0;
diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp
index 555c2082480..d28e0eba5b3 100644
--- a/ndb/src/mgmsrv/Services.cpp
+++ b/ndb/src/mgmsrv/Services.cpp
@@ -468,9 +468,9 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
return;
}
- struct sockaddr addr;
+ struct sockaddr_in addr;
SOCKET_SIZE_TYPE addrlen= sizeof(addr);
- int r = getpeername(m_socket, &addr, &addrlen);
+ int r = getpeername(m_socket, (struct sockaddr*)&addr, &addrlen);
if (r != 0 ) {
m_output->println(cmd);
m_output->println("result: getpeername(%d) failed, err= %d", m_socket, r);
@@ -485,7 +485,7 @@ MgmApiSession::get_nodeid(Parser_t::Context &,
NDB_TICKS tick= 0;
/* only report error on second attempt as not to clog the cluster log */
while (!m_mgmsrv.alloc_node_id(&tmp, (enum ndb_mgm_node_type)nodetype,
- &addr, &addrlen, error_code, error_string,
+ (struct sockaddr*)&addr, &addrlen, error_code, error_string,
tick == 0 ? 0 : log_event))
{
/* NDB_MGM_ALLOCID_CONFIG_MISMATCH is a non retriable error */
diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp
index 42b7c5b115d..fbff57d3168 100644
--- a/ndb/src/ndbapi/ClusterMgr.cpp
+++ b/ndb/src/ndbapi/ClusterMgr.cpp
@@ -70,6 +70,7 @@ ClusterMgr::ClusterMgr(TransporterFacade & _facade):
noOfAliveNodes= 0;
noOfConnectedNodes= 0;
theClusterMgrThread= 0;
+ m_connect_count = 0;
DBUG_VOID_RETURN;
}
@@ -469,6 +470,10 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){
theNode.nfCompleteRep = false;
if(noOfAliveNodes == 0)
{
+ theFacade.m_globalDictCache.lock();
+ theFacade.m_globalDictCache.invalidate_all();
+ theFacade.m_globalDictCache.unlock();
+ m_connect_count ++;
NFCompleteRep rep;
for(Uint32 i = 1; i<MAX_NODES; i++){
if(theNodes[i].defined && theNodes[i].nfCompleteRep == false){
diff --git a/ndb/src/ndbapi/ClusterMgr.hpp b/ndb/src/ndbapi/ClusterMgr.hpp
index da8f16d6789..1a1e622a889 100644
--- a/ndb/src/ndbapi/ClusterMgr.hpp
+++ b/ndb/src/ndbapi/ClusterMgr.hpp
@@ -79,6 +79,7 @@ public:
Uint32 getNoOfConnectedNodes() const;
void hb_received(NodeId);
+ Uint32 m_connect_count;
private:
Uint32 noOfAliveNodes;
Uint32 noOfConnectedNodes;
diff --git a/ndb/src/ndbapi/DictCache.cpp b/ndb/src/ndbapi/DictCache.cpp
index 57d9b361522..740f67da2df 100644
--- a/ndb/src/ndbapi/DictCache.cpp
+++ b/ndb/src/ndbapi/DictCache.cpp
@@ -300,6 +300,42 @@ GlobalDictCache::drop(NdbTableImpl * tab)
abort();
}
+
+unsigned
+GlobalDictCache::get_size()
+{
+ NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
+ int sz = 0;
+ while(curr != 0){
+ sz += curr->theData->size();
+ curr = m_tableHash.getNext(curr);
+ }
+ return sz;
+}
+
+void
+GlobalDictCache::invalidate_all()
+{
+ DBUG_ENTER("GlobalDictCache::invalidate_all");
+ NdbElement_t<Vector<TableVersion> > * curr = m_tableHash.getNext(0);
+ while(curr != 0){
+ Vector<TableVersion> * vers = curr->theData;
+ if (vers->size())
+ {
+ TableVersion * ver = & vers->back();
+ ver->m_impl->m_status = NdbDictionary::Object::Invalid;
+ ver->m_status = DROPPED;
+ if (ver->m_refCount == 0)
+ {
+ delete ver->m_impl;
+ vers->erase(vers->size() - 1);
+ }
+ }
+ curr = m_tableHash.getNext(curr);
+ }
+ DBUG_VOID_RETURN;
+}
+
void
GlobalDictCache::release(NdbTableImpl * tab)
{
diff --git a/ndb/src/ndbapi/DictCache.hpp b/ndb/src/ndbapi/DictCache.hpp
index 2df6a139542..6afa7946a8e 100644
--- a/ndb/src/ndbapi/DictCache.hpp
+++ b/ndb/src/ndbapi/DictCache.hpp
@@ -71,6 +71,9 @@ public:
void alter_table_rep(const char * name,
Uint32 tableId, Uint32 tableVersion, bool altered);
+
+ unsigned get_size();
+ void invalidate_all();
public:
enum Status {
OK = 0,
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index 754d0000718..59f5c4875c0 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -91,6 +91,10 @@ public:
NdbDictionary::Column * m_facade;
static NdbDictionary::Column * create_psuedo(const char *);
+
+ // Get total length in bytes, used by NdbOperation
+ // backported from 5.1
+ bool get_var_length(const void* value, Uint32& len) const;
};
class NdbTableImpl : public NdbDictionary::Table, public NdbDictObjectImpl {
@@ -490,6 +494,27 @@ NdbColumnImpl::getBlobType() const {
}
inline
+bool
+NdbColumnImpl::get_var_length(const void* value, Uint32& len) const
+{
+ Uint32 max_len = m_attrSize * m_arraySize;
+ switch (m_type) {
+ case NdbDictionary::Column::Varchar:
+ case NdbDictionary::Column::Varbinary:
+ len = 1 + *((Uint8*)value);
+ break;
+ case NdbDictionary::Column::Longvarchar:
+ case NdbDictionary::Column::Longvarbinary:
+ len = 2 + uint2korr((char*)value);
+ break;
+ default:
+ len = max_len;
+ return true;
+ }
+ return (len <= max_len);
+}
+
+inline
NdbTableImpl &
NdbTableImpl::getImpl(NdbDictionary::Table & t){
return t.m_impl;
diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp
index 06d8ddd412b..4be7ccb313c 100644
--- a/ndb/src/ndbapi/NdbOperationSearch.cpp
+++ b/ndb/src/ndbapi/NdbOperationSearch.cpp
@@ -71,6 +71,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
Uint32 tKeyInfoPosition;
const char* aValue = aValuePassed;
Uint64 tempData[512];
+ Uint64 tempData2[512];
if ((theStatus == OperationDefined) &&
(aValue != NULL) &&
@@ -131,6 +132,19 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
OperationType tOpType = theOperationType;
Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
+ Uint32 real_len;
+ if (! tAttrInfo->get_var_length(aValue, real_len)) {
+ setErrorCodeAbort(4209);
+ DBUG_RETURN(-1);
+ }
+
+ // 5.0 fixed storage + NdbBlob uses full size => pad var* with nulls
+ if (real_len < sizeInBytes && m_currentTable->m_noOfBlobs != 0) {
+ memcpy(tempData2, aValue, real_len);
+ memset((char*)tempData2 + real_len, 0, sizeInBytes - real_len);
+ aValue = (char*)tempData2;
+ }
+
{
/************************************************************************
* Check if the pointer of the value passed is aligned on a 4 byte
diff --git a/ndb/src/ndbapi/SignalSender.cpp b/ndb/src/ndbapi/SignalSender.cpp
index a29fe68937b..0ecc98f5f29 100644
--- a/ndb/src/ndbapi/SignalSender.cpp
+++ b/ndb/src/ndbapi/SignalSender.cpp
@@ -75,7 +75,9 @@ SignalSender::SignalSender(TransporterFacade *facade)
{
m_cond = NdbCondition_Create();
theFacade = facade;
+ lock();
m_blockNo = theFacade->open(this, execSignal, execNodeStatus);
+ unlock();
assert(m_blockNo > 0);
}
diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp
index bdd6fb3d05c..48e1c8ed25f 100644
--- a/ndb/src/ndbapi/TransporterFacade.hpp
+++ b/ndb/src/ndbapi/TransporterFacade.hpp
@@ -271,6 +271,12 @@ TransporterFacade::unlock_mutex()
#include "ClusterMgr.hpp"
inline
+unsigned Ndb_cluster_connection_impl::get_connect_count() const
+{
+ return TransporterFacade::instance()->theClusterMgr->m_connect_count;
+}
+
+inline
bool
TransporterFacade::check_send_size(Uint32 node_id, Uint32 send_size)
{
diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp
index 6c3d08d981d..1e53558f179 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection.cpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp
@@ -243,6 +243,12 @@ Ndb_cluster_connection::wait_until_ready(int timeout,
} while (1);
}
+unsigned Ndb_cluster_connection::get_connect_count() const
+{
+ return m_impl.get_connect_count();
+}
+
+
/*
diff --git a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
index b305b93fec1..a50d3004364 100644
--- a/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
+++ b/ndb/src/ndbapi/ndb_cluster_connection_impl.hpp
@@ -49,6 +49,7 @@ class Ndb_cluster_connection_impl : public Ndb_cluster_connection
void init_get_next_node(Ndb_cluster_connection_node_iter &iter);
Uint32 get_next_node(Ndb_cluster_connection_node_iter &iter);
+ inline unsigned get_connect_count() const;
private:
friend class Ndb;
friend class NdbImpl;
diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am
index 0533493ba09..7dfa239cb66 100644
--- a/ndb/test/ndbapi/Makefile.am
+++ b/ndb/test/ndbapi/Makefile.am
@@ -24,6 +24,7 @@ testOIBasic \
testOperations \
testRestartGci \
testScan \
+testInterpreter \
testScanInterpreter \
testScanPerf \
testSystemRestart \
@@ -65,6 +66,7 @@ testOIBasic_SOURCES = testOIBasic.cpp
testOperations_SOURCES = testOperations.cpp
testRestartGci_SOURCES = testRestartGci.cpp
testScan_SOURCES = testScan.cpp ScanFunctions.hpp
+testInterpreter_SOURCES = testInterpreter.cpp
testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp
testScanPerf_SOURCES = testScanPerf.cpp
testSystemRestart_SOURCES = testSystemRestart.cpp
diff --git a/ndb/test/ndbapi/testInterpreter.cpp b/ndb/test/ndbapi/testInterpreter.cpp
index 0baba33d2b2..5d930d3d555 100644
--- a/ndb/test/ndbapi/testInterpreter.cpp
+++ b/ndb/test/ndbapi/testInterpreter.cpp
@@ -79,46 +79,46 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
- NdbConnection* pTrans = pNdb->startTransaction();
- if (pTrans == NULL){
- ERR(pNdb->getNdbError());
- return NDBT_FAILED;
- }
-
- NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- int check = pOp->interpretedUpdateTuple();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
-
- // Primary keys
- Uint32 pkVal = 1;
- check = pOp->equal("KOL1", pkVal );
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- // Attributes
-
- // Update column
- Uint32 valToIncWith = 1;
- check = pOp->incValue("KOL2", valToIncWith);
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
+ NdbConnection* pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ int check = pOp->interpretedUpdateTuple();
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+
+ // Primary keys
+ Uint32 pkVal = 1;
+ check = pOp->equal("KOL1", pkVal );
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Attributes
+
+ // Update column
+ Uint32 valToIncWith = 1;
+ check = pOp->incValue("KOL2", valToIncWith);
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
NdbRecAttr* valueRec = pOp->getValue("KOL2");
if( valueRec == NULL ) {
@@ -142,6 +142,122 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ const NdbDictionary::Table * pTab = ctx->getTab();
+ Ndb* pNdb = GETNDB(step);
+
+ if (strcmp(pTab->getName(), "T1") != 0) {
+ g_err << "runTestBug19537: skip, table != T1" << endl;
+ return NDBT_OK;
+ }
+
+
+ NdbConnection* pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->interpretedUpdateTuple() == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+
+ // Primary keys
+ const Uint32 pkVal = 1;
+ if (pOp->equal("KOL1", pkVal) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Load 64-bit constant into register 1 and
+ // write from register 1 to 32-bit column KOL2
+ const Uint64 reg_val = 0x0102030405060708ULL;
+
+ const Uint32* reg_ptr32 = (const Uint32*)&reg_val;
+ if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
+ g_err << "runTestBug19537: platform is LITTLE endian" << endl;
+ } else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {
+ g_err << "runTestBug19537: platform is BIG endian" << endl;
+ } else {
+ g_err << "runTestBug19537: impossible platform"
+ << hex << " [0]=" << reg_ptr32[0] << " [1]=" <<reg_ptr32[1] << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pOp->load_const_u64(1, reg_val) == -1 ||
+ pOp->write_attr("KOL2", 1) == -1) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pTrans->execute(Commit) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Read value via a new transaction
+
+ pTrans = pNdb->startTransaction();
+ if (pTrans == NULL){
+ ERR(pNdb->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ pOp = pTrans->getNdbOperation(pTab->getName());
+ if (pOp == NULL) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ Uint32 kol2 = 0x09090909;
+ if (pOp->readTuple() == -1 ||
+ pOp->equal("KOL1", pkVal) == -1 ||
+ pOp->getValue("KOL2", (char*)&kol2) == 0) {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (pTrans->execute(Commit) == -1) {
+ ERR(pTrans->getNdbError());
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ // Expected conversion as in C - truncate to lower (logical) word
+
+ if (kol2 == 0x01020304) {
+ g_err << "runTestBug19537: the bug manifests itself !" << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ if (kol2 != 0x05060708) {
+ g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl;
+ pNdb->closeTransaction(pTrans);
+ return NDBT_FAILED;
+ }
+
+ pNdb->closeTransaction(pTrans);
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testInterpreter);
TESTCASE("IncValue32",
@@ -156,6 +272,12 @@ TESTCASE("IncValue64",
INITIALIZER(runTestIncValue64);
FINALIZER(runClearTable);
}
+TESTCASE("Bug19537",
+ "Test big-endian write_attr of 32 bit integer\n"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runTestBug19537);
+ FINALIZER(runClearTable);
+}
#if 0
TESTCASE("MaxTransactions",
"Start transactions until no more can be created\n"){
diff --git a/ndb/tools/waiter.cpp b/ndb/tools/waiter.cpp
index db90bd8bd90..cb02d5e7c36 100644
--- a/ndb/tools/waiter.cpp
+++ b/ndb/tools/waiter.cpp
@@ -124,6 +124,12 @@ getStatus(){
ndbout << "status==NULL, retries="<<retries<<endl;
MGMERR(handle);
retries++;
+ ndb_mgm_disconnect(handle);
+ if (ndb_mgm_connect(handle,0,0,1)) {
+ MGMERR(handle);
+ g_err << "Reconnect failed" << endl;
+ break;
+ }
continue;
}
int count = status->no_of_nodes;
diff --git a/server-tools/instance-manager/manager.cc b/server-tools/instance-manager/manager.cc
index 95f9029f648..90d9d04cd36 100644
--- a/server-tools/instance-manager/manager.cc
+++ b/server-tools/instance-manager/manager.cc
@@ -35,12 +35,12 @@
#endif
-static int create_pid_file(const char *pid_file_name)
+int create_pid_file(const char *pid_file_name, int pid)
{
if (FILE *pid_file= my_fopen(pid_file_name,
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
{
- fprintf(pid_file, "%d\n", (int) getpid());
+ fprintf(pid_file, "%d\n", (int) pid);
my_fclose(pid_file, MYF(0));
return 0;
}
@@ -138,8 +138,13 @@ void manager(const Options &options)
if (user_map.load(options.password_file_name))
return;
- /* write pid file */
- if (create_pid_file(options.pid_file_name))
+ /* write Instance Manager pid file */
+
+ log_info("IM pid file: '%s'; PID: %d.",
+ (const char *) options.pid_file_name,
+ (int) manager_pid);
+
+ if (create_pid_file(options.pid_file_name, manager_pid))
return;
sigset_t mask;
diff --git a/server-tools/instance-manager/manager.h b/server-tools/instance-manager/manager.h
index 12ed6b3b1ff..3ddf292132e 100644
--- a/server-tools/instance-manager/manager.h
+++ b/server-tools/instance-manager/manager.h
@@ -20,4 +20,6 @@ struct Options;
void manager(const Options &options);
+int create_pid_file(const char *pid_file_name, int pid);
+
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
diff --git a/server-tools/instance-manager/mysqlmanager.cc b/server-tools/instance-manager/mysqlmanager.cc
index d0b2cf2666c..ef714099de7 100644
--- a/server-tools/instance-manager/mysqlmanager.cc
+++ b/server-tools/instance-manager/mysqlmanager.cc
@@ -338,6 +338,14 @@ spawn:
/* Here we return to main, and fall into manager */
break;
default: // parent, success
+ pid= getpid(); /* Get our pid. */
+
+ log_info("Angel pid file: '%s'; PID: %d.",
+ (const char *) options.angel_pid_file_name,
+ (int) pid);
+
+ create_pid_file(Options::angel_pid_file_name, pid);
+
while (child_status == CHILD_OK && is_terminated == 0)
sigsuspend(&zeromask);
diff --git a/server-tools/instance-manager/options.cc b/server-tools/instance-manager/options.cc
index e7d366e7457..a98c0e291be 100644
--- a/server-tools/instance-manager/options.cc
+++ b/server-tools/instance-manager/options.cc
@@ -44,6 +44,7 @@ const char *Options::user= 0; /* No default value */
const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
+const char *Options::angel_pid_file_name= NULL;
#endif
const char *Options::log_file_name= default_log_file_name;
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
@@ -58,6 +59,9 @@ char **Options::saved_argv= NULL;
/* Remember if the config file was forced */
bool Options::is_forced_default_file= 0;
+static const char * const ANGEL_PID_FILE_SUFFIX= ".angel.pid";
+static const int ANGEL_PID_FILE_SUFFIX_LEN= strlen(ANGEL_PID_FILE_SUFFIX);
+
/*
List of options, accepted by the instance manager.
List must be closed with empty option.
@@ -72,6 +76,7 @@ enum options {
#ifndef __WIN__
OPT_RUN_AS_SERVICE,
OPT_USER,
+ OPT_ANGEL_PID_FILE,
#else
OPT_INSTALL_SERVICE,
OPT_REMOVE_SERVICE,
@@ -94,7 +99,14 @@ static struct my_option my_long_options[] =
{ "pid-file", OPT_PID_FILE, "Pid file to use.",
(gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+
+#ifndef __WIN__
+ { "angel-pid-file", OPT_ANGEL_PID_FILE, "Pid file for angel process.",
+ (gptr *) &Options::angel_pid_file_name,
+ (gptr *) &Options::angel_pid_file_name,
+ 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+#endif
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
@@ -290,6 +302,46 @@ int Options::load(int argc, char **argv)
get_one_option)) != 0)
goto err;
+#ifndef __WIN__
+ if (Options::run_as_service)
+ {
+ if (Options::angel_pid_file_name == NULL)
+ {
+ /*
+ Calculate angel pid file on the IM pid file basis: replace the
+ extension (everything after the last dot) of the pid file basename to
+ '.angel.pid'.
+ */
+
+ char *angel_pid_file_name;
+ char *base_name_ptr;
+ char *ext_ptr;
+
+ angel_pid_file_name= (char *) malloc(strlen(Options::pid_file_name) +
+ ANGEL_PID_FILE_SUFFIX_LEN);
+
+ strcpy(angel_pid_file_name, Options::pid_file_name);
+
+ base_name_ptr= strrchr(angel_pid_file_name, '/');
+
+ if (!base_name_ptr)
+ base_name_ptr= angel_pid_file_name + 1;
+
+ ext_ptr= strrchr(base_name_ptr, '.');
+ if (ext_ptr)
+ *ext_ptr= 0;
+
+ strcat(angel_pid_file_name, ANGEL_PID_FILE_SUFFIX);
+
+ Options::angel_pid_file_name= angel_pid_file_name;
+ }
+ else
+ {
+ Options::angel_pid_file_name= strdup(Options::angel_pid_file_name);
+ }
+ }
+#endif
+
return 0;
err:
@@ -301,6 +353,11 @@ void Options::cleanup()
/* free_defaults returns nothing */
if (Options::saved_argv != NULL)
free_defaults(Options::saved_argv);
+
+#ifndef __WIN__
+ if (Options::run_as_service)
+ free((void *) Options::angel_pid_file_name);
+#endif
}
#ifdef __WIN__
diff --git a/server-tools/instance-manager/options.h b/server-tools/instance-manager/options.h
index abb094eac93..ad3458869b6 100644
--- a/server-tools/instance-manager/options.h
+++ b/server-tools/instance-manager/options.h
@@ -35,6 +35,7 @@ struct Options
#else
static char run_as_service; /* handle_options doesn't support bool */
static const char *user;
+ static const char *angel_pid_file_name;
#endif
static bool is_forced_default_file;
static const char *log_file_name;
diff --git a/sql/field_conv.cc b/sql/field_conv.cc
index 895f022624c..4e977c06180 100644
--- a/sql/field_conv.cc
+++ b/sql/field_conv.cc
@@ -642,7 +642,8 @@ void (*Copy_field::get_copy_func(Field *to,Field *from))(Copy_field*)
void field_conv(Field *to,Field *from)
{
- if (to->real_type() == from->real_type())
+ if (to->real_type() == from->real_type() &&
+ !(to->type() == FIELD_TYPE_BLOB && to->table->copy_blobs))
{
if (to->pack_length() == from->pack_length() &&
!(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 934437e0c91..28cdfd23b6a 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -4048,6 +4048,9 @@ ha_innobase::index_prev(
mysql_byte* buf) /* in/out: buffer for previous row in MySQL
format */
{
+ statistic_increment(current_thd->status_var.ha_read_prev_count,
+ &LOCK_status);
+
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc
index 138e8c72e7a..3d9bd2dbe0f 100644
--- a/sql/ha_ndbcluster.cc
+++ b/sql/ha_ndbcluster.cc
@@ -3512,8 +3512,23 @@ int ha_ndbcluster::external_lock(THD *thd, int lock_type)
{
m_table= (void *)tab;
m_table_version = tab->getObjectVersion();
- if (!(my_errno= build_index_list(ndb, table, ILBP_OPEN)))
+ if ((my_errno= build_index_list(ndb, table, ILBP_OPEN)))
DBUG_RETURN(my_errno);
+
+ const void *data, *pack_data;
+ uint length, pack_length;
+ if (readfrm(table->s->path, &data, &length) ||
+ packfrm(data, length, &pack_data, &pack_length) ||
+ pack_length != tab->getFrmLength() ||
+ memcmp(pack_data, tab->getFrmData(), pack_length))
+ {
+ my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
+ NdbError err= ndb->getNdbError(NDB_INVALID_SCHEMA_OBJECT);
+ DBUG_RETURN(ndb_to_mysql_error(&err));
+ }
+ my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR));
+ my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR));
}
m_table_info= tab_info;
}
diff --git a/sql/item.cc b/sql/item.cc
index 31fbef0f053..24efc1f106f 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -304,6 +304,7 @@ Item::Item():
marker= 0;
maybe_null=null_value=with_sum_func=unsigned_flag=0;
decimals= 0; max_length= 0;
+ with_subselect= 0;
/* Put item in free list so that we can free all items at end */
THD *thd= current_thd;
@@ -958,6 +959,12 @@ void Item_splocal::print(String *str)
}
+bool Item_splocal::set_value(THD *thd, sp_rcontext *ctx, Item **it)
+{
+ return ctx->set_variable(thd, get_var_idx(), it);
+}
+
+
/*****************************************************************************
Item_case_expr methods
*****************************************************************************/
@@ -1883,7 +1890,6 @@ Item_decimal::Item_decimal(const char *str_arg, uint length,
name= (char*) str_arg;
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1893,7 +1899,6 @@ Item_decimal::Item_decimal(longlong val, bool unsig)
int2my_decimal(E_DEC_FATAL_ERROR, val, unsig, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1904,7 +1909,6 @@ Item_decimal::Item_decimal(double val, int precision, int scale)
double2my_decimal(E_DEC_FATAL_ERROR, val, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1917,7 +1921,6 @@ Item_decimal::Item_decimal(const char *str, const my_decimal *val_arg,
name= (char*) str;
decimals= (uint8) decimal_par;
max_length= length;
- unsigned_flag= !decimal_value.sign();
fixed= 1;
}
@@ -1927,7 +1930,6 @@ Item_decimal::Item_decimal(my_decimal *value_par)
my_decimal2decimal(value_par, &decimal_value);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(decimal_value.intg + decimals,
decimals, unsigned_flag);
}
@@ -1939,7 +1941,6 @@ Item_decimal::Item_decimal(const char *bin, int precision, int scale)
&decimal_value, precision, scale);
decimals= (uint8) decimal_value.frac;
fixed= 1;
- unsigned_flag= !decimal_value.sign();
max_length= my_decimal_precision_to_length(precision, decimals,
unsigned_flag);
}
@@ -4840,7 +4841,16 @@ void Item_ref::cleanup()
void Item_ref::print(String *str)
{
if (ref)
- (*ref)->print(str);
+ {
+ if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
+ name && alias_name_used)
+ {
+ THD *thd= current_thd;
+ append_identifier(thd, str, name, (uint) strlen(name));
+ }
+ else
+ (*ref)->print(str);
+ }
else
Item_ident::print(str);
}
@@ -5365,6 +5375,25 @@ bool Item_trigger_field::eq(const Item *item, bool binary_cmp) const
}
+void Item_trigger_field::set_required_privilege(bool rw)
+{
+ /*
+ Require SELECT and UPDATE privilege if this field will be read and
+ set, and only UPDATE privilege for setting the field.
+ */
+ want_privilege= (rw ? SELECT_ACL | UPDATE_ACL : UPDATE_ACL);
+}
+
+
+bool Item_trigger_field::set_value(THD *thd, sp_rcontext */*ctx*/, Item **it)
+{
+ Item *item= sp_prepare_func_item(thd, it);
+
+ return (!item || (!fixed && fix_fields(thd, 0)) ||
+ (item->save_in_field(field, 0) < 0));
+}
+
+
bool Item_trigger_field::fix_fields(THD *thd, Item **items)
{
/*
@@ -5387,8 +5416,7 @@ bool Item_trigger_field::fix_fields(THD *thd, Item **items)
if (table_grants)
{
- table_grants->want_privilege=
- access_type == AT_READ ? SELECT_ACL : UPDATE_ACL;
+ table_grants->want_privilege= want_privilege;
if (check_grant_column(thd, table_grants, triggers->table->s->db,
triggers->table->s->table_name, field_name,
@@ -5420,6 +5448,7 @@ void Item_trigger_field::print(String *str)
void Item_trigger_field::cleanup()
{
+ want_privilege= original_privilege;
/*
Since special nature of Item_trigger_field we should not do most of
things from Item_field::cleanup() or Item_ident::cleanup() here.
diff --git a/sql/item.h b/sql/item.h
index 24aca4a86d1..28b1f54add7 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -372,6 +372,42 @@ public:
/*************************************************************************/
+class sp_rcontext;
+
+
+class Settable_routine_parameter
+{
+public:
+ /*
+ Set required privileges for accessing the parameter.
+
+ SYNOPSIS
+ set_required_privilege()
+ rw if 'rw' is true then we are going to read and set the
+ parameter, so SELECT and UPDATE privileges might be
+ required, otherwise we only reading it and SELECT
+ privilege might be required.
+ */
+ virtual void set_required_privilege(bool rw) {};
+
+ /*
+ Set parameter value.
+
+ SYNOPSIS
+ set_value()
+ thd thread handle
+ ctx context to which parameter belongs (if it is local
+ variable).
+ it item which represents new value
+
+ RETURN
+ FALSE if parameter value has been set,
+ TRUE if error has occured.
+ */
+ virtual bool set_value(THD *thd, sp_rcontext *ctx, Item **it)= 0;
+};
+
+
typedef bool (Item::*Item_processor)(byte *arg);
typedef Item* (Item::*Item_transformer) (byte *arg);
typedef void (*Cond_traverser) (const Item *item, void *arg);
@@ -424,6 +460,9 @@ public:
my_bool is_autogenerated_name; /* indicate was name of this Item
autogenerated or set by user */
DTCollation collation;
+ my_bool with_subselect; /* If this item is a subselect or some
+ of its arguments is or contains a
+ subselect */
// alloc & destruct is done as start of select using sql_alloc
Item();
@@ -744,6 +783,15 @@ public:
}
virtual bool is_splocal() { return 0; } /* Needed for error checking */
+
+ /*
+ Return Settable_routine_parameter interface of the Item. Return 0
+ if this Item is not Settable_routine_parameter.
+ */
+ virtual Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return 0;
+ }
};
@@ -842,7 +890,8 @@ inline bool Item_sp_variable::send(Protocol *protocol, String *str)
runtime.
*****************************************************************************/
-class Item_splocal :public Item_sp_variable
+class Item_splocal :public Item_sp_variable,
+ private Settable_routine_parameter
{
uint m_var_idx;
@@ -880,6 +929,15 @@ public:
inline enum Type type() const;
inline Item_result result_type() const;
+
+private:
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return this;
+ }
};
/*****************************************************************************
@@ -2100,14 +2158,13 @@ class Table_triggers_list;
two Field instances representing either OLD or NEW version of this
field.
*/
-class Item_trigger_field : public Item_field
+class Item_trigger_field : public Item_field,
+ private Settable_routine_parameter
{
public:
/* Is this item represents row from NEW or OLD row ? */
enum row_version_type {OLD_ROW, NEW_ROW};
row_version_type row_version;
- /* Is this item used for reading or updating the value? */
- enum access_types { AT_READ = 0x1, AT_UPDATE = 0x2 };
/* Next in list of all Item_trigger_field's in trigger */
Item_trigger_field *next_trg_field;
/* Index of the field in the TABLE::field array */
@@ -2118,11 +2175,11 @@ public:
Item_trigger_field(Name_resolution_context *context_arg,
row_version_type row_ver_arg,
const char *field_name_arg,
- access_types access_type_arg)
+ ulong priv, const bool ro)
:Item_field(context_arg,
(const char *)NULL, (const char *)NULL, field_name_arg),
- row_version(row_ver_arg), field_idx((uint)-1),
- access_type(access_type_arg), table_grants(NULL)
+ row_version(row_ver_arg), field_idx((uint)-1), original_privilege(priv),
+ want_privilege(priv), table_grants(NULL), read_only (ro)
{}
void setup_field(THD *thd, TABLE *table, GRANT_INFO *table_grant_info);
enum Type type() const { return TRIGGER_FIELD_ITEM; }
@@ -2133,8 +2190,39 @@ public:
void cleanup();
private:
- access_types access_type;
+ void set_required_privilege(bool rw);
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return (read_only ? 0 : this);
+ }
+
+ bool set_value(THD *thd, Item **it)
+ {
+ return set_value(thd, NULL, it);
+ }
+
+private:
+ /*
+ 'want_privilege' holds privileges required to perform operation on
+ this trigger field (SELECT_ACL if we are going to read it and
+ UPDATE_ACL if we are going to update it). It is initialized at
+ parse time but can be updated later if this trigger field is used
+ as OUT or INOUT parameter of stored routine (in this case
+ set_required_privilege() is called to appropriately update
+ want_privilege and cleanup() is responsible for restoring of
+ original want_privilege once parameter's value is updated).
+ */
+ ulong original_privilege;
+ ulong want_privilege;
GRANT_INFO *table_grants;
+ /*
+ Trigger field is read-only unless it belongs to the NEW row in a
+ BEFORE INSERT of BEFORE UPDATE trigger.
+ */
+ bool read_only;
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 54e281a1f14..725be547a8a 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -204,10 +204,28 @@ longlong Item_func_nop_all::val_int()
/*
- Convert a constant expression or string to an integer.
- This is done when comparing DATE's of different formats and
- also when comparing bigint to strings (in which case the string
- is converted once to a bigint).
+ Convert a constant item to an int and replace the original item
+
+ SYNOPSIS
+ convert_constant_item()
+ thd thread handle
+ field item will be converted using the type of this field
+ item [in/out] reference to the item to convert
+
+ DESCRIPTION
+ The function converts a constant expression or string to an integer.
+ On successful conversion the original item is substituted for the
+ result of the item evaluation.
+ This is done when comparing DATE/TIME of different formats and
+ also when comparing bigint to strings (in which case strings
+ are converted to bigints).
+
+ NOTES
+ This function is called only at prepare stage.
+ As all derived tables are filled only after all derived tables
+ are prepared we do not evaluate items with subselects here because
+ they can contain derived tables and thus we may attempt to use a
+ table that has not been populated yet.
RESULT VALUES
0 Can't convert item
@@ -216,7 +234,7 @@ longlong Item_func_nop_all::val_int()
static bool convert_constant_item(THD *thd, Field *field, Item **item)
{
- if ((*item)->const_item())
+ if (!(*item)->with_subselect && (*item)->const_item())
{
/* For comparison purposes allow invalid dates like 2000-01-32 */
ulong orig_sql_mode= field->table->in_use->variables.sql_mode;
@@ -2570,7 +2588,9 @@ Item_cond::fix_fields(THD *thd, Item **ref)
(item= *li.ref())->check_cols(1))
return TRUE; /* purecov: inspected */
used_tables_cache|= item->used_tables();
- if (!item->const_item())
+ if (item->const_item())
+ and_tables_cache= (table_map) 0;
+ else
{
tmp_table_map= item->not_null_tables();
not_null_tables_cache|= tmp_table_map;
@@ -2578,6 +2598,7 @@ Item_cond::fix_fields(THD *thd, Item **ref)
const_item_cache= FALSE;
}
with_sum_func= with_sum_func || item->with_sum_func;
+ with_subselect|= item->with_subselect;
if (item->maybe_null)
maybe_null=1;
}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 6ec74560b91..2c770bec1ad 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -184,6 +184,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
used_tables_cache|= item->used_tables();
not_null_tables_cache|= item->not_null_tables();
const_item_cache&= item->const_item();
+ with_subselect|= item->with_subselect;
}
}
fix_length_and_dec();
@@ -4120,6 +4121,18 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
}
+bool Item_func_get_user_var::set_value(THD *thd,
+ sp_rcontext */*ctx*/, Item **it)
+{
+ Item_func_set_user_var *suv= new Item_func_set_user_var(get_name(), *it);
+ /*
+ Item_func_set_user_var is not fixed after construction, call
+ fix_fields().
+ */
+ return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update());
+}
+
+
bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
@@ -4752,6 +4765,7 @@ Item_func_sp::sp_result_field(void) const
dummy_table->alias = empty_name;
dummy_table->maybe_null = maybe_null;
dummy_table->in_use= current_thd;
+ dummy_table->copy_blobs= TRUE;
share->table_cache_key = empty_name;
share->table_name = empty_name;
}
diff --git a/sql/item_func.h b/sql/item_func.h
index a91d93be8c6..1d8a1bd5e22 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1179,7 +1179,8 @@ public:
};
-class Item_func_get_user_var :public Item_func
+class Item_func_get_user_var :public Item_func,
+ private Settable_routine_parameter
{
user_var_entry *var_entry;
@@ -1206,6 +1207,15 @@ public:
table_map used_tables() const
{ return const_item() ? 0 : RAND_TABLE_BIT; }
bool eq(const Item *item, bool binary_cmp) const;
+
+private:
+ bool set_value(THD *thd, sp_rcontext *ctx, Item **it);
+
+public:
+ Settable_routine_parameter *get_settable_routine_parameter()
+ {
+ return this;
+ }
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index a1743aa1181..ce9897afeed 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2579,7 +2579,7 @@ String *Item_load_file::val_str(String *str)
(void) fn_format(path, file_name->c_ptr(), mysql_real_data_home, "",
MY_RELATIVE_PATH | MY_UNPACK_FILENAME);
- if (!my_stat(path, &stat_info, MYF(MY_WME)))
+ if (!my_stat(path, &stat_info, MYF(0)))
goto err;
if (!(stat_info.st_mode & S_IROTH))
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 7d7b62df0dc..90d421a2c68 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -542,7 +542,7 @@ public:
void fix_length_and_dec()
{
collation.set(default_charset());
- decimals=0; max_length=64;
+ max_length= 64;
}
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index d93f6501ebb..87ef0fc080e 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -39,6 +39,7 @@ Item_subselect::Item_subselect():
engine(0), old_engine(0), used_tables_cache(0), have_to_be_excluded(0),
const_item_cache(1), engine_changed(0), changed(0)
{
+ with_subselect= 1;
reset();
/*
item value is NULL if select_subselect not changed this value
@@ -1351,6 +1352,17 @@ void Item_in_subselect::print(String *str)
}
+bool Item_in_subselect::fix_fields(THD *thd, Item **ref)
+{
+ bool result = 0;
+
+ if(thd->lex->view_prepare_mode && left_expr && !left_expr->fixed)
+ result = left_expr->fix_fields(thd, &left_expr);
+
+ return result || Item_subselect::fix_fields(thd, ref);
+}
+
+
Item_subselect::trans_res
Item_allany_subselect::select_transformer(JOIN *join)
{
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index a4dac5bda87..293408dc09e 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -258,6 +258,7 @@ public:
void top_level_item() { abort_on_null=1; }
bool test_limit(st_select_lex_unit *unit);
void print(String *str);
+ bool fix_fields(THD *thd, Item **ref);
friend class Item_ref_null_helper;
friend class Item_is_not_null_test;
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index e997d4ae70c..72c53272e0c 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2144,8 +2144,13 @@ bool Item_date_add_interval::eq(const Item *item, bool binary_cmp) const
Item_date_add_interval *other= (Item_date_add_interval*) item;
if ((int_type != other->int_type) ||
- (!args[0]->eq(other->args[0], binary_cmp)) ||
- (get_interval_value(args[1], int_type, &val, &interval)))
+ (!args[0]->eq(other->args[0], binary_cmp)))
+ return FALSE;
+
+ if (!args[1]->const_item() || !other->args[1]->const_item())
+ return (args[1]->eq(other->args[1], binary_cmp));
+
+ if (get_interval_value(args[1], int_type, &val, &interval))
return FALSE;
val= other->value;
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 1ce9dd78d2c..707a474b754 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -718,12 +718,6 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
List<create_field> &fields, List<Key> &keys,
bool tmp_table, uint select_field_count);
-TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
- TABLE_LIST *create_table,
- List<create_field> *extra_fields,
- List<Key> *keys,
- List<Item> *items,
- MYSQL_LOCK **lock);
bool mysql_alter_table(THD *thd, char *new_db, char *new_name,
HA_CREATE_INFO *create_info,
TABLE_LIST *table_list,
@@ -1185,6 +1179,7 @@ extern my_bool locked_in_memory;
extern bool opt_using_transactions, mysqld_embedded;
extern bool using_update_log, opt_large_files, server_id_supplied;
extern bool opt_log, opt_update_log, opt_bin_log, opt_slow_log, opt_error_log;
+extern my_bool opt_log_queries_not_using_indexes;
extern bool opt_disable_networking, opt_skip_show_db;
extern my_bool opt_character_set_client_handshake;
extern bool volatile abort_loop, shutdown_in_progress, grant_option;
@@ -1315,10 +1310,11 @@ extern struct st_VioSSLFd * ssl_acceptor_fd;
MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **table, uint count,
uint flags, bool *need_reopen);
-/* mysql_lock_tables() flags bits */
+/* mysql_lock_tables() and open_table() flags bits */
#define MYSQL_LOCK_IGNORE_GLOBAL_READ_LOCK 0x0001
#define MYSQL_LOCK_IGNORE_FLUSH 0x0002
#define MYSQL_LOCK_NOTIFY_IF_NEED_REOPEN 0x0004
+#define MYSQL_OPEN_IGNORE_LOCKED_TABLES 0x0008
void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock);
void mysql_unlock_read_tables(THD *thd, MYSQL_LOCK *sql_lock);
@@ -1582,6 +1578,16 @@ inline int hexchar_to_int(char c)
return -1;
}
+/*
+ is_user_table()
+ return true if the table was created explicitly
+*/
+
+inline bool is_user_table(TABLE * table)
+{
+ const char *name= table->s->table_name;
+ return strncmp(name, tmp_file_prefix, tmp_file_prefix_length);
+}
/*
Some functions that are different in the embedded library and the normal
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ef2f52a33df..50f19c15fc4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -311,7 +311,6 @@ static bool volatile ready_to_exit;
static my_bool opt_debugging= 0, opt_external_locking= 0, opt_console= 0;
static my_bool opt_bdb, opt_isam, opt_ndbcluster;
static my_bool opt_short_log_format= 0;
-static my_bool opt_log_queries_not_using_indexes= 0;
static uint kill_cached_threads, wake_thread;
static ulong killed_threads, thread_created;
static ulong max_used_connections;
@@ -337,6 +336,7 @@ static my_bool opt_sync_bdb_logs;
/* Global variables */
bool opt_log, opt_update_log, opt_bin_log, opt_slow_log;
+my_bool opt_log_queries_not_using_indexes= 0;
bool opt_error_log= IF_WIN(1,0);
bool opt_disable_networking=0, opt_skip_show_db=0;
my_bool opt_character_set_client_handshake= 1;
@@ -603,6 +603,7 @@ my_bool opt_enable_shared_memory;
HANDLE smem_event_connect_request= 0;
#endif
+#define SSL_VARS_NOT_STATIC
#include "sslopt-vars.h"
#ifdef HAVE_OPENSSL
#include <openssl/crypto.h>
@@ -954,7 +955,8 @@ static void __cdecl kill_server(int sig_ptr)
RETURN_FROM_KILL_SERVER;
kill_in_progress=TRUE;
abort_loop=1; // This should be set
- my_sigset(sig,SIG_IGN);
+ if (sig != 0) // 0 is not a valid signal number
+ my_sigset(sig,SIG_IGN);
if (sig == MYSQL_KILL_SIGNAL || sig == 0)
sql_print_information(ER(ER_NORMAL_SHUTDOWN),my_progname);
else
@@ -986,6 +988,10 @@ static void __cdecl kill_server(int sig_ptr)
pthread_join(select_thread, NULL); // wait for main thread
#endif /* __NETWARE__ */
+#if defined(__NETWARE__) || (defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2))
+ my_thread_end();
+#endif
+
pthread_exit(0); /* purecov: deadcode */
#endif /* EMBEDDED_LIBRARY */
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index fb4af4e7932..e36932cbc0c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -3503,17 +3503,46 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
if (inv)
{
- /*
- We get here for conditions like "t.keypart NOT IN (....)".
-
- If the IN-list contains only constants (and func->array is an ordered
- array of them), we construct the appropriate SEL_ARG tree manually,
- because constructing it using the range analyzer (as
- AND_i( t.keypart != c_i)) will cause lots of memory to be consumed
- (see BUG#15872).
- */
if (func->array && func->cmp_type != ROW_RESULT)
{
+ /*
+ We get here for conditions in form "t.key NOT IN (c1, c2, ...)"
+ (where c{i} are constants).
+ Our goal is to produce a SEL_ARG graph that represents intervals:
+
+ ($MIN<t.key<c1) OR (c1<t.key<c2) OR (c2<t.key<c3) OR ... (*)
+
+ where $MIN is either "-inf" or NULL.
+
+ The most straightforward way to handle NOT IN would be to convert
+ it to "(t.key != c1) AND (t.key != c2) AND ..." and let the range
+ optimizer to build SEL_ARG graph from that. However that will cause
+ the range optimizer to use O(N^2) memory (it's a bug, not filed),
+ and people do use big NOT IN lists (see BUG#15872). Also, for big
+ NOT IN lists constructing/using graph (*) does not make the query
+ faster.
+
+ So, we will handle NOT IN manually in the following way:
+ * if the number of entries in the NOT IN list is less then
+ NOT_IN_IGNORE_THRESHOLD, we will construct SEL_ARG graph (*)
+ manually.
+ * Otherwise, we will construct a smaller graph: for
+ "t.key NOT IN (c1,...cN)" we construct a graph representing
+ ($MIN < t.key) OR (cN < t.key) // here sequence of c_i is
+ // ordered.
+
+ A note about partially-covering indexes: for those (e.g. for
+ "a CHAR(10), KEY(a(5))") the handling is correct (albeit not very
+ efficient):
+ Instead of "t.key < c1" we get "t.key <= prefix-val(c1)".
+ Combining the intervals in (*) together, we get:
+ (-inf<=t.key<=c1) OR (c1<=t.key<=c2) OR (c2<=t.key<=c3) OR ...
+ i.e. actually we get intervals combined into one interval:
+ (-inf<=t.key<=+inf). This doesn't make much sense but it doesn't
+ cause any problems.
+ */
+ MEM_ROOT *tmp_root= param->mem_root;
+ param->thd->mem_root= param->old_root;
/*
Create one Item_type constant object. We'll need it as
get_mm_parts only accepts constant values wrapped in Item_Type
@@ -3522,25 +3551,35 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
per-statement mem_root (while thd->mem_root is currently pointing
to mem_root local to range optimizer).
*/
- MEM_ROOT *tmp_root= param->mem_root;
- param->thd->mem_root= param->old_root;
Item *value_item= func->array->create_item();
param->thd->mem_root= tmp_root;
if (!value_item)
break;
- /* Get a SEL_TREE for "-inf < X < c_0" interval */
- func->array->value_to_item(0, value_item);
- tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
- value_item, cmp_type);
- if (!tree)
+ /* Get a SEL_TREE for "(-inf|NULL) < X < c_0" interval. */
+ uint i=0;
+ do
+ {
+ func->array->value_to_item(i, value_item);
+ tree= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
+ value_item, cmp_type);
+ if (!tree)
+ break;
+ i++;
+ } while (i < func->array->count && tree->type == SEL_TREE::IMPOSSIBLE);
+
+ if (!tree || tree->type == SEL_TREE::IMPOSSIBLE)
+ {
+ /* We get here in cases like "t.unsigned NOT IN (-1,-2,-3) */
+ tree= NULL;
break;
+ }
#define NOT_IN_IGNORE_THRESHOLD 1000
SEL_TREE *tree2;
if (func->array->count < NOT_IN_IGNORE_THRESHOLD)
{
- for (uint i=1; i < func->array->count; i++)
+ for (; i < func->array->count; i++)
{
if (func->array->compare_elems(i, i-1))
{
@@ -3548,32 +3587,44 @@ static SEL_TREE *get_func_mm_tree(PARAM *param, Item_func *cond_func,
func->array->value_to_item(i, value_item);
tree2= get_mm_parts(param, cond_func, field, Item_func::LT_FUNC,
value_item, cmp_type);
-
+ if (!tree2)
+ {
+ tree= NULL;
+ break;
+ }
+
/* Change all intervals to be "c_{i-1} < X < c_i" */
for (uint idx= 0; idx < param->keys; idx++)
{
- SEL_ARG *new_interval;
- if ((new_interval= tree2->keys[idx]))
+ SEL_ARG *new_interval, *last_val;
+ if (((new_interval= tree2->keys[idx])) &&
+ ((last_val= tree->keys[idx]->last())))
{
- SEL_ARG *last_val= tree->keys[idx]->last();
new_interval->min_value= last_val->max_value;
new_interval->min_flag= NEAR_MIN;
}
}
+ /*
+ The following doesn't try to allocate memory so no need to
+ check for NULL.
+ */
tree= tree_or(param, tree, tree2);
}
}
}
else
func->array->value_to_item(func->array->count - 1, value_item);
-
- /*
- Get the SEL_TREE for the last "c_last < X < +inf" interval
- (value_item cotains c_last already)
- */
- tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
- value_item, cmp_type);
- tree= tree_or(param, tree, tree2);
+
+ if (tree && tree->type != SEL_TREE::IMPOSSIBLE)
+ {
+ /*
+ Get the SEL_TREE for the last "c_last < X < +inf" interval
+ (value_item cotains c_last already)
+ */
+ tree2= get_mm_parts(param, cond_func, field, Item_func::GT_FUNC,
+ value_item, cmp_type);
+ tree= tree_or(param, tree, tree2);
+ }
}
else
{
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 215d3cfc879..003dd4a8ab3 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -122,6 +122,7 @@ static byte *get_error_count(THD *thd);
static byte *get_warning_count(THD *thd);
static byte *get_prepared_stmt_count(THD *thd);
static byte *get_have_innodb(THD *thd);
+static byte *get_tmpdir(THD *thd);
/*
Variable definition list
@@ -138,6 +139,7 @@ sys_var_thd_ulong sys_auto_increment_offset("auto_increment_offset",
sys_var_bool_ptr sys_automatic_sp_privileges("automatic_sp_privileges",
&sp_automatic_privileges);
+sys_var_const_str sys_basedir("basedir", mysql_home);
sys_var_long_ptr sys_binlog_cache_size("binlog_cache_size",
&binlog_cache_size);
sys_var_thd_ulong sys_bulk_insert_buff_size("bulk_insert_buffer_size",
@@ -161,6 +163,7 @@ sys_var_long_ptr sys_concurrent_insert("concurrent_insert",
&myisam_concurrent_insert);
sys_var_long_ptr sys_connect_timeout("connect_timeout",
&connect_timeout);
+sys_var_const_str sys_datadir("datadir", mysql_real_data_home);
sys_var_enum sys_delay_key_write("delay_key_write",
&delay_key_write_options,
&delay_key_write_typelib,
@@ -208,6 +211,9 @@ sys_trust_routine_creators("log_bin_trust_routine_creators",
sys_var_bool_ptr
sys_trust_function_creators("log_bin_trust_function_creators",
&trust_function_creators);
+sys_var_bool_ptr
+ sys_log_queries_not_using_indexes("log_queries_not_using_indexes",
+ &opt_log_queries_not_using_indexes);
sys_var_thd_ulong sys_log_warnings("log_warnings", &SV::log_warnings);
sys_var_thd_ulong sys_long_query_time("long_query_time",
&SV::long_query_time);
@@ -331,6 +337,7 @@ sys_var_thd_ulong sys_query_alloc_block_size("query_alloc_block_size",
sys_var_thd_ulong sys_query_prealloc_size("query_prealloc_size",
&SV::query_prealloc_size,
0, fix_thd_mem_root);
+sys_var_readonly sys_tmpdir("tmpdir", OPT_GLOBAL, SHOW_CHAR, get_tmpdir);
sys_var_thd_ulong sys_trans_alloc_block_size("transaction_alloc_block_size",
&SV::trans_alloc_block_size,
0, fix_trans_mem_root);
@@ -367,6 +374,21 @@ sys_var_thd_ulong sys_sort_buffer("sort_buffer_size",
&SV::sortbuff_size);
sys_var_thd_sql_mode sys_sql_mode("sql_mode",
&SV::sql_mode);
+#ifdef HAVE_OPENSSL
+extern char *opt_ssl_ca, *opt_ssl_capath, *opt_ssl_cert, *opt_ssl_cipher,
+ *opt_ssl_key;
+sys_var_const_str_ptr sys_ssl_ca("ssl_ca", &opt_ssl_ca);
+sys_var_const_str_ptr sys_ssl_capath("ssl_capath", &opt_ssl_capath);
+sys_var_const_str_ptr sys_ssl_cert("ssl_cert", &opt_ssl_cert);
+sys_var_const_str_ptr sys_ssl_cipher("ssl_cipher", &opt_ssl_cipher);
+sys_var_const_str_ptr sys_ssl_key("ssl_key", &opt_ssl_key);
+#else
+sys_var_const_str sys_ssl_ca("ssl_ca", NULL);
+sys_var_const_str sys_ssl_capath("ssl_capath", NULL);
+sys_var_const_str sys_ssl_cert("ssl_cert", NULL);
+sys_var_const_str sys_ssl_cipher("ssl_cipher", NULL);
+sys_var_const_str sys_ssl_key("ssl_key", NULL);
+#endif
sys_var_thd_enum
sys_updatable_views_with_limit("updatable_views_with_limit",
&SV::updatable_views_with_limit,
@@ -582,6 +604,7 @@ sys_var *sys_variables[]=
&sys_auto_increment_offset,
&sys_autocommit,
&sys_automatic_sp_privileges,
+ &sys_basedir,
&sys_big_tables,
&sys_big_selects,
&sys_binlog_cache_size,
@@ -600,6 +623,7 @@ sys_var *sys_variables[]=
&sys_completion_type,
&sys_concurrent_insert,
&sys_connect_timeout,
+ &sys_datadir,
&sys_date_format,
&sys_datetime_format,
&sys_div_precincrement,
@@ -631,6 +655,7 @@ sys_var *sys_variables[]=
&sys_local_infile,
&sys_log_binlog,
&sys_log_off,
+ &sys_log_queries_not_using_indexes,
&sys_log_update,
&sys_log_warnings,
&sys_long_query_time,
@@ -710,6 +735,11 @@ sys_var *sys_variables[]=
&sys_sql_mode,
&sys_sql_warnings,
&sys_sql_notes,
+ &sys_ssl_ca,
+ &sys_ssl_capath,
+ &sys_ssl_cert,
+ &sys_ssl_cipher,
+ &sys_ssl_key,
&sys_storage_engine,
#ifdef HAVE_REPLICATION
&sys_sync_binlog_period,
@@ -724,6 +754,7 @@ sys_var *sys_variables[]=
&sys_timed_mutexes,
&sys_timestamp,
&sys_time_zone,
+ &sys_tmpdir,
&sys_tmp_table_size,
&sys_trans_alloc_block_size,
&sys_trans_prealloc_size,
@@ -775,7 +806,7 @@ struct show_var_st init_vars[]= {
{"auto_increment_offset", (char*) &sys_auto_increment_offset, SHOW_SYS},
{sys_automatic_sp_privileges.name,(char*) &sys_automatic_sp_privileges, SHOW_SYS},
{"back_log", (char*) &back_log, SHOW_LONG},
- {"basedir", mysql_home, SHOW_CHAR},
+ {sys_basedir.name, (char*) &sys_basedir, SHOW_SYS},
#ifdef HAVE_BERKELEY_DB
{"bdb_cache_size", (char*) &berkeley_cache_size, SHOW_LONG},
{"bdb_home", (char*) &berkeley_home, SHOW_CHAR_PTR},
@@ -801,7 +832,7 @@ struct show_var_st init_vars[]= {
{sys_completion_type.name, (char*) &sys_completion_type, SHOW_SYS},
{sys_concurrent_insert.name,(char*) &sys_concurrent_insert, SHOW_SYS},
{sys_connect_timeout.name, (char*) &sys_connect_timeout, SHOW_SYS},
- {"datadir", mysql_real_data_home, SHOW_CHAR},
+ {sys_datadir.name, (char*) &sys_datadir, SHOW_SYS},
{sys_date_format.name, (char*) &sys_date_format, SHOW_SYS},
{sys_datetime_format.name, (char*) &sys_datetime_format, SHOW_SYS},
{sys_default_week_format.name, (char*) &sys_default_week_format, SHOW_SYS},
@@ -899,6 +930,8 @@ struct show_var_st init_vars[]= {
{"log_bin", (char*) &opt_bin_log, SHOW_BOOL},
{sys_trust_function_creators.name,(char*) &sys_trust_function_creators, SHOW_SYS},
{"log_error", (char*) log_error_file, SHOW_CHAR},
+ {sys_log_queries_not_using_indexes.name,
+ (char*) &sys_log_queries_not_using_indexes, SHOW_SYS},
#ifdef HAVE_REPLICATION
{"log_slave_updates", (char*) &opt_log_slave_updates, SHOW_MY_BOOL},
#endif
@@ -1017,6 +1050,11 @@ struct show_var_st init_vars[]= {
{sys_sql_mode.name, (char*) &sys_sql_mode, SHOW_SYS},
{"sql_notes", (char*) &sys_sql_notes, SHOW_SYS},
{"sql_warnings", (char*) &sys_sql_warnings, SHOW_SYS},
+ {sys_ssl_ca.name, (char*) &sys_ssl_ca, SHOW_SYS},
+ {sys_ssl_capath.name, (char*) &sys_ssl_capath, SHOW_SYS},
+ {sys_ssl_cert.name, (char*) &sys_ssl_cert, SHOW_SYS},
+ {sys_ssl_cipher.name, (char*) &sys_ssl_cipher, SHOW_SYS},
+ {sys_ssl_key.name, (char*) &sys_ssl_key, SHOW_SYS},
{sys_storage_engine.name, (char*) &sys_storage_engine, SHOW_SYS},
#ifdef HAVE_REPLICATION
{sys_sync_binlog_period.name,(char*) &sys_sync_binlog_period, SHOW_SYS},
@@ -1037,7 +1075,7 @@ struct show_var_st init_vars[]= {
{"time_zone", (char*) &sys_time_zone, SHOW_SYS},
{sys_timed_mutexes.name, (char*) &sys_timed_mutexes, SHOW_SYS},
{sys_tmp_table_size.name, (char*) &sys_tmp_table_size, SHOW_SYS},
- {"tmpdir", (char*) &opt_mysql_tmpdir, SHOW_CHAR_PTR},
+ {sys_tmpdir.name, (char*) &sys_tmpdir, SHOW_SYS},
{sys_trans_alloc_block_size.name, (char*) &sys_trans_alloc_block_size,
SHOW_SYS},
{sys_trans_prealloc_size.name, (char*) &sys_trans_prealloc_size, SHOW_SYS},
@@ -2863,6 +2901,31 @@ static byte *get_prepared_stmt_count(THD *thd)
return (byte*) &thd->sys_var_tmp.ulong_value;
}
+
+/*
+ Get the tmpdir that was specified or chosen by default
+
+ SYNOPSIS
+ get_tmpdir()
+ thd thread handle
+
+ DESCRIPTION
+ This is necessary because if the user does not specify a temporary
+ directory via the command line, one is chosen based on the environment
+ or system defaults. But we can't just always use mysql_tmpdir, because
+ that is actually a call to my_tmpdir() which cycles among possible
+ temporary directories.
+
+ RETURN VALUES
+ ptr pointer to NUL-terminated string
+ */
+static byte *get_tmpdir(THD *thd)
+{
+ if (opt_mysql_tmpdir)
+ return (byte *)opt_mysql_tmpdir;
+ return (byte*)mysql_tmpdir;
+}
+
/****************************************************************************
Main handling of variables:
- Initialisation
diff --git a/sql/set_var.h b/sql/set_var.h
index 646a578ca36..8e5a94b1e1b 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -222,6 +222,35 @@ public:
};
+class sys_var_const_str_ptr :public sys_var
+{
+public:
+ char **value; // Pointer to const value
+ sys_var_const_str_ptr(const char *name_arg, char **value_arg)
+ :sys_var(name_arg),value(value_arg)
+ {}
+ bool check(THD *thd, set_var *var)
+ {
+ return 1;
+ }
+ bool update(THD *thd, set_var *var)
+ {
+ return 1;
+ }
+ SHOW_TYPE type() { return SHOW_CHAR; }
+ byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base)
+ {
+ return (byte*) *value;
+ }
+ bool check_update_type(Item_result type)
+ {
+ return 1;
+ }
+ bool check_default(enum_var_type type) { return 1; }
+ bool is_readonly() const { return 1; }
+};
+
+
class sys_var_enum :public sys_var
{
uint *value;
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 2892c5c8b01..4e7b9200d88 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5475,7 +5475,7 @@ ER_SP_DUP_HANDLER 42000
eng "Duplicate handler declared in the same block"
ger "Doppelter Handler im selben Block deklariert"
ER_SP_NOT_VAR_ARG 42000
- eng "OUT or INOUT argument %d for routine %s is not a variable"
+ eng "OUT or INOUT argument %d for routine %s is not a variable or NEW pseudo-variable in BEFORE trigger"
ger "OUT- oder INOUT-Argument %d für Routine %s ist keine Variable"
ER_SP_NO_RETSET 0A000
eng "Not allowed to return a result set from a %s"
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 6a7676c7bf2..174f62c9497 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -310,11 +310,13 @@ sp_prepare_func_item(THD* thd, Item **it_addr)
*/
bool
-sp_eval_expr(THD *thd, Field *result_field, Item *expr_item)
+sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr)
{
+ Item *expr_item;
+
DBUG_ENTER("sp_eval_expr");
- if (!(expr_item= sp_prepare_func_item(thd, &expr_item)))
+ if (!(expr_item= sp_prepare_func_item(thd, expr_item_ptr)))
DBUG_RETURN(TRUE);
bool err_status= FALSE;
@@ -936,6 +938,7 @@ sp_head::execute(THD *thd)
bool err_status= FALSE;
uint ip= 0;
ulong save_sql_mode;
+ bool save_abort_on_warning;
Query_arena *old_arena;
/* per-instruction arena */
MEM_ROOT execute_mem_root;
@@ -996,6 +999,10 @@ sp_head::execute(THD *thd)
thd->derived_tables= 0;
save_sql_mode= thd->variables.sql_mode;
thd->variables.sql_mode= m_sql_mode;
+ save_abort_on_warning= thd->abort_on_warning;
+ thd->abort_on_warning=
+ (m_sql_mode & (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES));
+
/*
It is also more efficient to save/restore current thd->lex once when
do it in each instruction
@@ -1128,6 +1135,7 @@ sp_head::execute(THD *thd)
DBUG_ASSERT(!thd->derived_tables);
thd->derived_tables= old_derived_tables;
thd->variables.sql_mode= save_sql_mode;
+ thd->abort_on_warning= save_abort_on_warning;
thd->stmt_arena= old_arena;
state= EXECUTED;
@@ -1204,130 +1212,144 @@ bool
sp_head::execute_function(THD *thd, Item **argp, uint argcount,
Field *return_value_fld)
{
- Item_cache **param_values;
ulonglong binlog_save_options;
bool need_binlog_call;
- uint params;
+ uint arg_no;
sp_rcontext *octx = thd->spcont;
sp_rcontext *nctx = NULL;
+ char buf[STRING_BUFFER_USUAL_SIZE];
+ String binlog_buf(buf, sizeof(buf), &my_charset_bin);
bool err_status= FALSE;
+ MEM_ROOT call_mem_root;
+ Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP);
+ Query_arena backup_arena;
DBUG_ENTER("sp_head::execute_function");
DBUG_PRINT("info", ("function %s", m_name.str));
- params = m_pcont->context_var_count();
-
/*
Check that the function is called with all specified arguments.
If it is not, use my_error() to report an error, or it will not terminate
the invoking query properly.
*/
-
- if (argcount != params)
+ if (argcount != m_pcont->context_var_count())
{
/*
Need to use my_error here, or it will not terminate the
invoking query properly.
*/
my_error(ER_SP_WRONG_NO_OF_ARGS, MYF(0),
- "FUNCTION", m_qname.str, params, argcount);
+ "FUNCTION", m_qname.str, m_pcont->context_var_count(), argcount);
DBUG_RETURN(TRUE);
}
-
- /* Allocate param_values to be used for dumping the call into binlog. */
-
- if (!(param_values= (Item_cache**)thd->alloc(sizeof(Item_cache*)*argcount)))
- DBUG_RETURN(TRUE);
-
- // QQ Should have some error checking here? (types, etc...)
+ /*
+ Prepare arena and memroot for objects which lifetime is whole
+ duration of function call (sp_rcontext, it's tables and items,
+ sp_cursor and Item_cache holders for case expressions).
+ We can't use caller's arena/memroot for those objects because
+ in this case some fixed amount of memory will be consumed for
+ each function/trigger invocation and so statements which involve
+ lot of them will hog memory.
+ TODO: we should create sp_rcontext once per command and reuse
+ it on subsequent executions of a function/trigger.
+ */
+ init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0);
+ thd->set_n_backup_active_arena(&call_arena, &backup_arena);
if (!(nctx= new sp_rcontext(m_pcont, return_value_fld, octx)) ||
nctx->init(thd))
{
- delete nctx; /* Delete nctx if it was init() that failed. */
- DBUG_RETURN(TRUE);
+ thd->restore_active_arena(&call_arena, &backup_arena);
+ err_status= TRUE;
+ goto err_with_cleanup;
}
+ /*
+ We have to switch temporarily back to callers arena/memroot.
+ Function arguments belong to the caller and so the may reference
+ memory which they will allocate during calculation long after
+ this function call will be finished (e.g. in Item::cleanup()).
+ */
+ thd->restore_active_arena(&call_arena, &backup_arena);
+
#ifndef DBUG_OFF
nctx->sp= this;
#endif
/* Pass arguments. */
+ for (arg_no= 0; arg_no < argcount; arg_no++)
+ {
+ /* Arguments must be fixed in Item_func_sp::fix_fields */
+ DBUG_ASSERT(argp[arg_no]->fixed);
+
+ if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no]))))
+ goto err_with_cleanup;
+ }
+
+ need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
+ /*
+ Remember the original arguments for unrolled replication of functions
+ before they are changed by execution.
+ */
+ if (need_binlog_call)
{
- uint i;
-
- for (i= 0 ; i < argcount ; i++)
+ binlog_buf.length(0);
+ binlog_buf.append(STRING_WITH_LEN("SELECT "));
+ append_identifier(thd, &binlog_buf, m_name.str, m_name.length);
+ binlog_buf.append('(');
+ for (arg_no= 0; arg_no < argcount; arg_no++)
{
- if (!argp[i]->fixed && argp[i]->fix_fields(thd, &argp[i]))
- {
- err_status= TRUE;
- break;
- }
+ String str_value_holder;
+ String *str_value;
- param_values[i]= Item_cache::get_cache(argp[i]->result_type());
- param_values[i]->store(argp[i]);
+ if (arg_no)
+ binlog_buf.append(',');
- if (nctx->set_variable(thd, i, param_values[i]))
- {
- err_status= TRUE;
- break;
- }
- }
- }
+ str_value= sp_get_item_value(nctx->get_item(arg_no),
+ &str_value_holder);
- if (err_status)
- {
- delete nctx;
- DBUG_RETURN(TRUE);
+ if (str_value)
+ binlog_buf.append(*str_value);
+ else
+ binlog_buf.append(STRING_WITH_LEN("NULL"));
+ }
+ binlog_buf.append(')');
}
-
thd->spcont= nctx;
binlog_save_options= thd->options;
- need_binlog_call= mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG);
if (need_binlog_call)
{
reset_dynamic(&thd->user_var_events);
mysql_bin_log.start_union_events(thd);
}
-
+
+ /*
+ Switch to call arena/mem_root so objects like sp_cursor or
+ Item_cache holders for case expressions can be allocated on it.
+
+ TODO: In future we should associate call arena/mem_root with
+ sp_rcontext and allocate all these objects (and sp_rcontext
+ itself) on it directly rather than juggle with arenas.
+ */
+ thd->set_n_backup_active_arena(&call_arena, &backup_arena);
+
thd->options&= ~OPTION_BIN_LOG;
err_status= execute(thd);
thd->options= binlog_save_options;
-
+
+ thd->restore_active_arena(&call_arena, &backup_arena);
+
if (need_binlog_call)
mysql_bin_log.stop_union_events(thd);
if (need_binlog_call && thd->binlog_evt_union.unioned_events)
{
- char buf[256];
- String bufstr(buf, sizeof(buf), &my_charset_bin);
- bufstr.length(0);
- bufstr.append(STRING_WITH_LEN("SELECT "));
- append_identifier(thd, &bufstr, m_name.str, m_name.length);
- bufstr.append('(');
- for (uint i=0; i < argcount; i++)
- {
- String str_value_holder;
- String *str_value;
-
- if (i)
- bufstr.append(',');
-
- str_value= sp_get_item_value(param_values[i], &str_value_holder);
-
- if (str_value)
- bufstr.append(*str_value);
- else
- bufstr.append(STRING_WITH_LEN("NULL"));
- }
- bufstr.append(')');
-
- Query_log_event qinfo(thd, bufstr.ptr(), bufstr.length(),
+ Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
thd->binlog_evt_union.unioned_events_trans, FALSE);
- if (mysql_bin_log.write(&qinfo) &&
+ if (mysql_bin_log.write(&qinfo) &&
thd->binlog_evt_union.unioned_events_trans)
{
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
@@ -1348,27 +1370,19 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
}
}
+
nctx->pop_all_cursors(); // To avoid memory leaks after an error
+
+err_with_cleanup:
delete nctx;
+ call_arena.free_items();
+ free_root(&call_mem_root, MYF(0));
thd->spcont= octx;
DBUG_RETURN(err_status);
}
-static Item_func_get_user_var *item_is_user_var(Item *it)
-{
- if (it->type() == Item::FUNC_ITEM)
- {
- Item_func *fi= static_cast<Item_func*>(it);
-
- if (fi->functype() == Item_func::GUSERVAR_FUNC)
- return static_cast<Item_func_get_user_var*>(fi);
- }
- return NULL;
-}
-
-
/*
Execute a procedure.
SYNOPSIS
@@ -1444,22 +1458,28 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
for (uint i= 0 ; i < params ; i++)
{
Item *arg_item= it_args++;
- sp_variable_t *spvar= m_pcont->find_variable(i);
if (!arg_item)
break;
+ sp_variable_t *spvar= m_pcont->find_variable(i);
+
if (!spvar)
continue;
if (spvar->mode != sp_param_in)
{
- if (!arg_item->is_splocal() && !item_is_user_var(arg_item))
+ Settable_routine_parameter *srp=
+ arg_item->get_settable_routine_parameter();
+
+ if (!srp)
{
my_error(ER_SP_NOT_VAR_ARG, MYF(0), i+1, m_qname.str);
err_status= TRUE;
break;
}
+
+ srp->set_required_privilege(spvar->mode == sp_param_inout);
}
if (spvar->mode == sp_param_out)
@@ -1467,7 +1487,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
Item_null *null_item= new Item_null();
if (!null_item ||
- nctx->set_variable(thd, i, null_item))
+ nctx->set_variable(thd, i, (struct Item **)&null_item))
{
err_status= TRUE;
break;
@@ -1475,7 +1495,7 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
}
else
{
- if (nctx->set_variable(thd, i, *it_args.ref()))
+ if (nctx->set_variable(thd, i, it_args.ref()))
{
err_status= TRUE;
break;
@@ -1527,36 +1547,16 @@ sp_head::execute_procedure(THD *thd, List<Item> *args)
if (spvar->mode == sp_param_in)
continue;
- if (arg_item->is_splocal())
- {
- if (octx->set_variable(thd,
- ((Item_splocal*) arg_item)->get_var_idx(),
- nctx->get_item(i)))
- {
- err_status= TRUE;
- break;
- }
- }
- else
+ Settable_routine_parameter *srp=
+ arg_item->get_settable_routine_parameter();
+
+ DBUG_ASSERT(srp);
+
+ if (srp->set_value(thd, octx, nctx->get_item_addr(i)))
{
- Item_func_get_user_var *guv= item_is_user_var(arg_item);
-
- if (guv)
- {
- Item *item= nctx->get_item(i);
- Item_func_set_user_var *suv;
-
- suv= new Item_func_set_user_var(guv->get_name(), item);
- /*
- Item_func_set_user_var is not fixed after construction,
- call fix_fields().
- */
- if ((err_status= test(!suv || suv->fix_fields(thd, &item) ||
- suv->check() || suv->update())))
- break;
- }
+ err_status= TRUE;
+ break;
}
-
}
}
@@ -2328,7 +2328,7 @@ sp_instr_set::execute(THD *thd, uint *nextp)
int
sp_instr_set::exec_core(THD *thd, uint *nextp)
{
- int res= thd->spcont->set_variable(thd, m_offset, m_value);
+ int res= thd->spcont->set_variable(thd, m_offset, &m_value);
if (res && thd->spcont->found_handler_here())
{
@@ -2393,12 +2393,7 @@ sp_instr_set_trigger_field::execute(THD *thd, uint *nextp)
int
sp_instr_set_trigger_field::exec_core(THD *thd, uint *nextp)
{
- int res= 0;
- Item *it= sp_prepare_func_item(thd, &value);
- if (!it ||
- !trigger_field->fixed && trigger_field->fix_fields(thd, 0) ||
- (it->save_in_field(trigger_field->field, 0) < 0))
- res= -1;
+ const int res= (trigger_field->set_value(thd, &value) ? -1 : 0);
*nextp = m_ip+1;
return res;
}
@@ -2603,7 +2598,7 @@ sp_instr_freturn::exec_core(THD *thd, uint *nextp)
do it in scope of execution the current context/block.
*/
- return thd->spcont->set_return_value(thd, m_value);
+ return thd->spcont->set_return_value(thd, &m_value);
}
void
@@ -3047,7 +3042,7 @@ sp_instr_set_case_expr::execute(THD *thd, uint *nextp)
int
sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
{
- int res= thd->spcont->set_case_expr(thd, m_case_expr_id, m_case_expr);
+ int res= thd->spcont->set_case_expr(thd, m_case_expr_id, &m_case_expr);
if (res &&
!thd->spcont->get_case_expr(m_case_expr_id) &&
@@ -3061,7 +3056,7 @@ sp_instr_set_case_expr::exec_core(THD *thd, uint *nextp)
Item *null_item= new Item_null();
if (!null_item ||
- thd->spcont->set_case_expr(thd, m_case_expr_id, null_item))
+ thd->spcont->set_case_expr(thd, m_case_expr_id, &null_item))
{
/* If this also failed, we have to abort. */
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 6a9cf97d739..d5f49d8a964 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -1169,6 +1169,6 @@ Item *
sp_prepare_func_item(THD* thd, Item **it_addr);
bool
-sp_eval_expr(THD *thd, Field *result_field, Item *expr_item);
+sp_eval_expr(THD *thd, Field *result_field, Item **expr_item_ptr);
#endif /* _SP_HEAD_H_ */
diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc
index 38b6de0e75a..3bc27a029d0 100644
--- a/sql/sp_rcontext.cc
+++ b/sql/sp_rcontext.cc
@@ -150,7 +150,7 @@ sp_rcontext::init_var_items()
bool
-sp_rcontext::set_return_value(THD *thd, Item *return_value_item)
+sp_rcontext::set_return_value(THD *thd, Item **return_value_item)
{
DBUG_ASSERT(m_return_value_fld);
@@ -279,14 +279,14 @@ sp_rcontext::pop_cursors(uint count)
int
-sp_rcontext::set_variable(THD *thd, uint var_idx, Item *value)
+sp_rcontext::set_variable(THD *thd, uint var_idx, Item **value)
{
return set_variable(thd, m_var_table->field[var_idx], value);
}
int
-sp_rcontext::set_variable(THD *thd, Field *field, Item *value)
+sp_rcontext::set_variable(THD *thd, Field *field, Item **value)
{
if (!value)
{
@@ -478,9 +478,10 @@ sp_rcontext::create_case_expr_holder(THD *thd, Item_result result_type)
*/
int
-sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item)
+sp_rcontext::set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr)
{
- if (!(case_expr_item= sp_prepare_func_item(thd, &case_expr_item)))
+ Item *case_expr_item= sp_prepare_func_item(thd, case_expr_item_ptr);
+ if (!case_expr_item)
return TRUE;
if (!m_case_expr_holders[case_expr_id] ||
@@ -542,7 +543,7 @@ bool Select_fetch_into_spvars::send_data(List<Item> &items)
*/
for (; spvar= spvar_iter++, item= item_iter++; )
{
- if (thd->spcont->set_variable(thd, spvar->offset, item))
+ if (thd->spcont->set_variable(thd, spvar->offset, &item))
return TRUE;
}
return FALSE;
diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h
index 20aaea3b7c1..30521f6da84 100644
--- a/sql/sp_rcontext.h
+++ b/sql/sp_rcontext.h
@@ -91,7 +91,7 @@ class sp_rcontext : public Sql_alloc
~sp_rcontext();
int
- set_variable(THD *thd, uint var_idx, Item *value);
+ set_variable(THD *thd, uint var_idx, Item **value);
Item *
get_item(uint var_idx);
@@ -100,7 +100,7 @@ class sp_rcontext : public Sql_alloc
get_item_addr(uint var_idx);
bool
- set_return_value(THD *thd, Item *return_value_item);
+ set_return_value(THD *thd, Item **return_value_item);
inline bool
is_return_value_set() const
@@ -200,7 +200,7 @@ class sp_rcontext : public Sql_alloc
*/
int
- set_case_expr(THD *thd, int case_expr_id, Item *case_expr_item);
+ set_case_expr(THD *thd, int case_expr_id, Item **case_expr_item_ptr);
Item *
get_case_expr(int case_expr_id);
@@ -254,7 +254,7 @@ private:
Item_cache *create_case_expr_holder(THD *thd, Item_result result_type);
- int set_variable(THD *thd, Field *field, Item *value);
+ int set_variable(THD *thd, Field *field, Item **value);
}; // class sp_rcontext : public Sql_alloc
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 5b40f93f002..02b2f88676f 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6023,20 +6023,21 @@ void fill_effective_table_privileges(THD *thd, GRANT_INFO *grant,
}
/* table privileges */
+ rw_rdlock(&LOCK_grant);
if (grant->version != grant_version)
{
- rw_rdlock(&LOCK_grant);
grant->grant_table=
table_hash_search(sctx->host, sctx->ip, db,
sctx->priv_user,
table, 0); /* purecov: inspected */
grant->version= grant_version; /* purecov: inspected */
- rw_unlock(&LOCK_grant);
}
if (grant->grant_table != 0)
{
grant->privilege|= grant->grant_table->privs;
}
+ rw_unlock(&LOCK_grant);
+
DBUG_PRINT("info", ("privilege 0x%lx", grant->privilege));
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 482a25acbd2..1f3b9e14631 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -617,118 +617,110 @@ static inline uint tmpkeyval(THD *thd, TABLE *table)
void close_temporary_tables(THD *thd)
{
- TABLE *next,
- *prev_table /* prev link is not maintained in TABLE's double-linked list */,
- *table;
- char *query= (gptr) 0, *end;
- uint query_buf_size, max_names_len;
- bool found_user_tables;
-
+ TABLE *table;
if (!thd->temporary_tables)
return;
-
- LINT_INIT(end);
- query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
- /*
- insertion sort of temp tables by pseudo_thread_id to build ordered list
+ if (!mysql_bin_log.is_open())
+ {
+ for (table= thd->temporary_tables; table; table= table->next)
+ {
+ close_temporary(table, 1);
+ }
+ thd->temporary_tables= 0;
+ return;
+ }
+
+ TABLE *next,
+ *prev_table /* prev link is not maintained in TABLE's double-linked list */;
+ bool was_quote_show= true; /* to assume thd->options has OPTION_QUOTE_SHOW_CREATE */
+ // Better add "if exists", in case a RESET MASTER has been done
+ const char stub[]= "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ";
+ uint stub_len= sizeof(stub) - 1;
+ char buf[256];
+ memcpy(buf, stub, stub_len);
+ String s_query= String(buf, sizeof(buf), system_charset_info);
+ bool found_user_tables= false;
+ LINT_INIT(next);
+
+ /*
+ insertion sort of temp tables by pseudo_thread_id to build ordered list
of sublists of equal pseudo_thread_id
*/
- for (prev_table= thd->temporary_tables,
- table= prev_table->next,
- found_user_tables= (prev_table->s->table_name[0] != '#');
+
+ for (prev_table= thd->temporary_tables, table= prev_table->next;
table;
prev_table= table, table= table->next)
{
- TABLE *prev_sorted /* same as for prev_table */,
- *sorted;
- /*
- table not created directly by the user is moved to the tail.
- Fixme/todo: nothing (I checked the manual) prevents user to create temp
- with `#'
- */
- if (table->s->table_name[0] == '#')
- continue;
- else
- {
- found_user_tables = 1;
- }
- for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
- prev_sorted= sorted, sorted= sorted->next)
+ TABLE *prev_sorted /* same as for prev_table */, *sorted;
+ if (is_user_table(table))
{
- if (sorted->s->table_name[0] == '#' || tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
+ if (!found_user_tables)
+ found_user_tables= true;
+ for (prev_sorted= NULL, sorted= thd->temporary_tables; sorted != table;
+ prev_sorted= sorted, sorted= sorted->next)
{
- /* move into the sorted part of the list from the unsorted */
- prev_table->next= table->next;
- table->next= sorted;
- if (prev_sorted)
+ if (!is_user_table(sorted) ||
+ tmpkeyval(thd, sorted) > tmpkeyval(thd, table))
{
- prev_sorted->next= table;
- }
- else
- {
- thd->temporary_tables= table;
+ /* move into the sorted part of the list from the unsorted */
+ prev_table->next= table->next;
+ table->next= sorted;
+ if (prev_sorted)
+ {
+ prev_sorted->next= table;
+ }
+ else
+ {
+ thd->temporary_tables= table;
+ }
+ table= prev_table;
+ break;
}
- table= prev_table;
- break;
}
}
- }
- /*
- calc query_buf_size as max per sublists, one sublist per pseudo thread id.
- Also stop at first occurence of `#'-named table that starts
- all implicitly created temp tables
- */
- for (max_names_len= 0, table=thd->temporary_tables;
- table && table->s->table_name[0] != '#';
- table=table->next)
+ }
+
+ /* We always quote db,table names though it is slight overkill */
+ if (found_user_tables &&
+ !(was_quote_show= (thd->options & OPTION_QUOTE_SHOW_CREATE)))
{
- uint tmp_names_len;
- for (tmp_names_len= table->s->key_length + 1;
- table->next && table->s->table_name[0] != '#' &&
- tmpkeyval(thd, table) == tmpkeyval(thd, table->next);
- table=table->next)
- {
- /*
- We are going to add 4 ` around the db/table names, so 1 might not look
- enough; indeed it is enough, because table->key_length is greater (by 8,
- because of server_id and thread_id) than db||table.
- */
- tmp_names_len += table->next->s->key_length + 1;
- }
- if (tmp_names_len > max_names_len) max_names_len= tmp_names_len;
+ thd->options |= OPTION_QUOTE_SHOW_CREATE;
}
-
- /* allocate */
- if (found_user_tables && mysql_bin_log.is_open() &&
- (query = alloc_root(thd->mem_root, query_buf_size+= max_names_len)))
- // Better add "if exists", in case a RESET MASTER has been done
- end= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
/* scan sorted tmps to generate sequence of DROP */
- for (table=thd->temporary_tables; table; table= next)
+ for (table= thd->temporary_tables; table; table= next)
{
- if (query // we might be out of memory, but this is not fatal
- && table->s->table_name[0] != '#')
+ if (is_user_table(table))
{
- char *end_cur;
/* Set pseudo_thread_id to be that of the processed table */
thd->variables.pseudo_thread_id= tmpkeyval(thd, table);
/* Loop forward through all tables within the sublist of
common pseudo_thread_id to create single DROP query */
- for (end_cur= end;
- table && table->s->table_name[0] != '#' &&
+ for (s_query.length(stub_len);
+ table && is_user_table(table) &&
tmpkeyval(thd, table) == thd->variables.pseudo_thread_id;
table= next)
{
- end_cur= strxmov(end_cur, "`", table->s->db, "`.`",
- table->s->table_name, "`,", NullS);
+ /*
+ We are going to add 4 ` around the db/table names and possible more
+ due to special characters in the names
+ */
+ append_identifier(thd, &s_query, table->s->db, strlen(table->s->db));
+ s_query.q_append('.');
+ append_identifier(thd, &s_query, table->s->table_name,
+ strlen(table->s->table_name));
+ s_query.q_append(',');
next= table->next;
close_temporary(table, 1);
}
thd->clear_error();
- /* The -1 is to remove last ',' */
- Query_log_event qinfo(thd, query, (ulong)(end_cur - query) - 1, 0, FALSE);
+ CHARSET_INFO *cs_save= thd->variables.character_set_client;
+ thd->variables.character_set_client= system_charset_info;
+ Query_log_event qinfo(thd, s_query.ptr(),
+ s_query.length() - 1 /* to remove trailing ',' */,
+ 0, FALSE);
+ thd->variables.character_set_client= cs_save;
/*
Imagine the thread had created a temp table, then was doing a SELECT, and
the SELECT was killed. Then it's not clever to mark the statement above as
@@ -741,12 +733,14 @@ void close_temporary_tables(THD *thd)
qinfo.error_code= 0;
mysql_bin_log.write(&qinfo);
}
- else
+ else
{
next= table->next;
close_temporary(table, 1);
}
}
+ if (!was_quote_show)
+ thd->options &= ~OPTION_QUOTE_SHOW_CREATE; /* restore option */
thd->temporary_tables=0;
}
@@ -1160,6 +1154,8 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list)
MYSQL_LOCK_IGNORE_FLUSH - Open table even if
someone has done a flush or namelock on it.
No version number checking is done.
+ MYSQL_OPEN_IGNORE_LOCKED_TABLES - Open table
+ ignoring set of locked tables and prelocked mode.
IMPLEMENTATION
Uses a cache of open tables to find a table not in use.
@@ -1219,7 +1215,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
}
}
- if (thd->locked_tables || thd->prelocked_mode)
+ if (!(flags & MYSQL_OPEN_IGNORE_LOCKED_TABLES) &&
+ (thd->locked_tables || thd->prelocked_mode))
{ // Using table locks
TABLE *best_table= 0;
int best_distance= INT_MIN;
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 026c3e0d515..65fd4d3ac19 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1877,7 +1877,7 @@ bool select_dumpvar::send_data(List<Item> &items)
if ((yy=var_li++))
{
if (thd->spcont->set_variable(current_thd, yy->get_var_idx(),
- *it.ref()))
+ it.ref()))
DBUG_RETURN(1);
}
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 320b8e1df9d..c054499ecd8 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -2437,6 +2437,153 @@ bool select_insert::send_eof()
CREATE TABLE (SELECT) ...
***************************************************************************/
+/*
+ Create table from lists of fields and items (or open existing table
+ with same name).
+
+ SYNOPSIS
+ create_table_from_items()
+ thd in Thread object
+ create_info in Create information (like MAX_ROWS, ENGINE or
+ temporary table flag)
+ create_table in Pointer to TABLE_LIST object providing database
+ and name for table to be created or to be open
+ extra_fields in/out Initial list of fields for table to be created
+ keys in List of keys for table to be created
+ items in List of items which should be used to produce rest
+ of fields for the table (corresponding fields will
+ be added to the end of 'extra_fields' list)
+ lock out Pointer to the MYSQL_LOCK object for table created
+ (open) will be returned in this parameter. Since
+ this table is not included in THD::lock caller is
+ responsible for explicitly unlocking this table.
+
+ NOTES
+ If 'create_info->options' bitmask has HA_LEX_CREATE_IF_NOT_EXISTS
+ flag and table with name provided already exists then this function will
+ simply open existing table.
+ Also note that create, open and lock sequence in this function is not
+ atomic and thus contains gap for deadlock and can cause other troubles.
+ Since this function contains some logic specific to CREATE TABLE ... SELECT
+ it should be changed before it can be used in other contexts.
+
+ RETURN VALUES
+ non-zero Pointer to TABLE object for table created or opened
+ 0 Error
+*/
+
+static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
+ TABLE_LIST *create_table,
+ List<create_field> *extra_fields,
+ List<Key> *keys, List<Item> *items,
+ MYSQL_LOCK **lock)
+{
+ TABLE tmp_table; // Used during 'create_field()'
+ TABLE *table= 0;
+ uint select_field_count= items->elements;
+ /* Add selected items to field list */
+ List_iterator_fast<Item> it(*items);
+ Item *item;
+ Field *tmp_field;
+ bool not_used;
+ DBUG_ENTER("create_table_from_items");
+
+ tmp_table.alias= 0;
+ tmp_table.timestamp_field= 0;
+ tmp_table.s= &tmp_table.share_not_to_be_used;
+ tmp_table.s->db_create_options=0;
+ tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
+ tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
+ create_info->db_type == DB_TYPE_HEAP);
+ tmp_table.null_row=tmp_table.maybe_null=0;
+
+ while ((item=it++))
+ {
+ create_field *cr_field;
+ Field *field;
+ if (item->type() == Item::FUNC_ITEM)
+ field=item->tmp_table_field(&tmp_table);
+ else
+ field=create_tmp_field(thd, &tmp_table, item, item->type(),
+ (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
+ if (!field ||
+ !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
+ ((Item_field *)item)->field :
+ (Field*) 0))))
+ DBUG_RETURN(0);
+ if (item->maybe_null)
+ cr_field->flags &= ~NOT_NULL_FLAG;
+ extra_fields->push_back(cr_field);
+ }
+ /*
+ create and lock table
+
+ We don't log the statement, it will be logged later.
+
+ If this is a HEAP table, the automatic DELETE FROM which is written to the
+ binlog when a HEAP table is opened for the first time since startup, must
+ not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
+ don't want to delete from it) 2) it would be written before the CREATE
+ TABLE, which is a wrong order. So we keep binary logging disabled when we
+ open_table().
+ NOTE: By locking table which we just have created (or for which we just have
+ have found that it already exists) separately from other tables used by the
+ statement we create potential window for deadlock.
+ TODO: create and open should be done atomic !
+ */
+ {
+ tmp_disable_binlog(thd);
+ if (!mysql_create_table(thd, create_table->db, create_table->table_name,
+ create_info, *extra_fields, *keys, 0,
+ select_field_count))
+ {
+ /*
+ If we are here in prelocked mode we either create temporary table
+ or prelocked mode is caused by the SELECT part of this statement.
+ */
+ DBUG_ASSERT(!thd->prelocked_mode ||
+ create_info->options & HA_LEX_CREATE_TMP_TABLE ||
+ thd->lex->requires_prelocking());
+
+ /*
+ NOTE: We don't want to ignore set of locked tables here if we are
+ under explicit LOCK TABLES since it will open gap for deadlock
+ too wide (and also is not backward compatible).
+ */
+ if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
+ (MYSQL_LOCK_IGNORE_FLUSH |
+ ((thd->prelocked_mode == PRELOCKED) ?
+ MYSQL_OPEN_IGNORE_LOCKED_TABLES:0)))))
+ quick_rm_table(create_info->db_type, create_table->db,
+ table_case_name(create_info, create_table->table_name));
+ }
+ reenable_binlog(thd);
+ if (!table) // open failed
+ DBUG_RETURN(0);
+ }
+
+ /*
+ FIXME: What happens if trigger manages to be created while we are
+ obtaining this lock ? May be it is sensible just to disable
+ trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
+ save us from that ?
+ */
+ table->reginfo.lock_type=TL_WRITE;
+ if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
+ MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
+ {
+ VOID(pthread_mutex_lock(&LOCK_open));
+ hash_delete(&open_cache,(byte*) table);
+ VOID(pthread_mutex_unlock(&LOCK_open));
+ quick_rm_table(create_info->db_type, create_table->db,
+ table_case_name(create_info, create_table->table_name));
+ DBUG_RETURN(0);
+ }
+ table->file->extra(HA_EXTRA_WRITE_CACHE);
+ DBUG_RETURN(table);
+}
+
+
int
select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
{
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index a8de7ff0154..7d62e5bb405 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5709,6 +5709,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
}
else
{
+ DBUG_ASSERT(thd->net.report_error);
DBUG_PRINT("info",("Command aborted. Fatal_error: %d",
thd->is_fatal_error));
query_cache_abort(&thd->net);
@@ -7226,7 +7227,7 @@ bool create_table_precheck(THD *thd, TABLE_LIST *tables,
lex->create_info.merge_list.first))
goto err;
if (grant_option && want_priv != CREATE_TMP_ACL &&
- check_grant(thd, want_priv, create_table, 0, UINT_MAX, 0))
+ check_grant(thd, want_priv, create_table, 0, 1, 0))
goto err;
if (select_lex->item_list.elements)
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 126abb96f61..70bdef302df 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2662,7 +2662,7 @@ static int get_schema_column_record(THD *thd, struct st_table_list *tables,
field->real_type() == MYSQL_TYPE_STRING) // For binary type
{
uint32 octet_max_length= field->max_length();
- if (octet_max_length != (uint32) 4294967295U)
+ if (is_blob && octet_max_length != (uint32) 4294967295U)
octet_max_length /= field->charset()->mbmaxlen;
longlong char_max_len= is_blob ?
(longlong) octet_max_length / field->charset()->mbminlen :
@@ -2854,17 +2854,18 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
const char *wild, bool full_access, const char *sp_user)
{
String tmp_string;
+ String sp_db, sp_name, definer;
TIME time;
LEX *lex= thd->lex;
CHARSET_INFO *cs= system_charset_info;
- const char *sp_db, *sp_name, *definer;
- sp_db= get_field(thd->mem_root, proc_table->field[0]);
- sp_name= get_field(thd->mem_root, proc_table->field[1]);
- definer= get_field(thd->mem_root, proc_table->field[11]);
+ get_field(thd->mem_root, proc_table->field[0], &sp_db);
+ get_field(thd->mem_root, proc_table->field[1], &sp_name);
+ get_field(thd->mem_root, proc_table->field[11], &definer);
if (!full_access)
- full_access= !strcmp(sp_user, definer);
- if (!full_access && check_some_routine_access(thd, sp_db, sp_name,
- proc_table->field[2]->val_int() == TYPE_ENUM_PROCEDURE))
+ full_access= !strcmp(sp_user, definer.ptr());
+ if (!full_access && check_some_routine_access(thd, sp_db.ptr(), sp_name.ptr(),
+ proc_table->field[2]->val_int() ==
+ TYPE_ENUM_PROCEDURE))
return 0;
if (lex->orig_sql_command == SQLCOM_SHOW_STATUS_PROC &&
@@ -2874,13 +2875,13 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
lex->orig_sql_command == SQLCOM_END)
{
restore_record(table, s->default_values);
- if (!wild || !wild[0] || !wild_compare(sp_name, wild, 0))
+ if (!wild || !wild[0] || !wild_compare(sp_name.ptr(), wild, 0))
{
int enum_idx= proc_table->field[5]->val_int();
- table->field[3]->store(sp_name, strlen(sp_name), cs);
+ table->field[3]->store(sp_name.ptr(), sp_name.length(), cs);
get_field(thd->mem_root, proc_table->field[3], &tmp_string);
table->field[0]->store(tmp_string.ptr(), tmp_string.length(), cs);
- table->field[2]->store(sp_db, strlen(sp_db), cs);
+ table->field[2]->store(sp_db.ptr(), sp_db.length(), cs);
get_field(thd->mem_root, proc_table->field[2], &tmp_string);
table->field[4]->store(tmp_string.ptr(), tmp_string.length(), cs);
if (proc_table->field[2]->val_int() == TYPE_ENUM_FUNCTION)
@@ -2912,7 +2913,7 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
table->field[17]->store(tmp_string.ptr(), tmp_string.length(), cs);
get_field(thd->mem_root, proc_table->field[15], &tmp_string);
table->field[18]->store(tmp_string.ptr(), tmp_string.length(), cs);
- table->field[19]->store(definer, strlen(definer), cs);
+ table->field[19]->store(definer.ptr(), definer.length(), cs);
return schema_table_store_record(thd, table);
}
}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 9eaadc58cb0..32a86b0f39a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1796,105 +1796,6 @@ make_unique_key_name(const char *field_name,KEY *start,KEY *end)
/****************************************************************************
-** Create table from a list of fields and items
-****************************************************************************/
-
-TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info,
- TABLE_LIST *create_table,
- List<create_field> *extra_fields,
- List<Key> *keys,
- List<Item> *items,
- MYSQL_LOCK **lock)
-{
- TABLE tmp_table; // Used during 'create_field()'
- TABLE *table= 0;
- uint select_field_count= items->elements;
- /* Add selected items to field list */
- List_iterator_fast<Item> it(*items);
- Item *item;
- Field *tmp_field;
- bool not_used;
- DBUG_ENTER("create_table_from_items");
-
- tmp_table.alias= 0;
- tmp_table.timestamp_field= 0;
- tmp_table.s= &tmp_table.share_not_to_be_used;
- tmp_table.s->db_create_options=0;
- tmp_table.s->blob_ptr_size= portable_sizeof_char_ptr;
- tmp_table.s->db_low_byte_first= test(create_info->db_type == DB_TYPE_MYISAM ||
- create_info->db_type == DB_TYPE_HEAP);
- tmp_table.null_row=tmp_table.maybe_null=0;
-
- while ((item=it++))
- {
- create_field *cr_field;
- Field *field;
- if (item->type() == Item::FUNC_ITEM)
- field=item->tmp_table_field(&tmp_table);
- else
- field=create_tmp_field(thd, &tmp_table, item, item->type(),
- (Item ***) 0, &tmp_field, 0, 0, 0, 0, 0);
- if (!field ||
- !(cr_field=new create_field(field,(item->type() == Item::FIELD_ITEM ?
- ((Item_field *)item)->field :
- (Field*) 0))))
- DBUG_RETURN(0);
- if (item->maybe_null)
- cr_field->flags &= ~NOT_NULL_FLAG;
- extra_fields->push_back(cr_field);
- }
- /*
- create and lock table
-
- We don't log the statement, it will be logged later.
-
- If this is a HEAP table, the automatic DELETE FROM which is written to the
- binlog when a HEAP table is opened for the first time since startup, must
- not be written: 1) it would be wrong (imagine we're in CREATE SELECT: we
- don't want to delete from it) 2) it would be written before the CREATE
- TABLE, which is a wrong order. So we keep binary logging disabled when we
- open_table().
- TODO: create and open should be done atomic !
- */
- {
- tmp_disable_binlog(thd);
- if (!mysql_create_table(thd, create_table->db, create_table->table_name,
- create_info, *extra_fields, *keys, 0,
- select_field_count))
- {
- if (! (table= open_table(thd, create_table, thd->mem_root, (bool*) 0,
- MYSQL_LOCK_IGNORE_FLUSH)))
- quick_rm_table(create_info->db_type, create_table->db,
- table_case_name(create_info, create_table->table_name));
- }
- reenable_binlog(thd);
- if (!table) // open failed
- DBUG_RETURN(0);
- }
-
- /*
- FIXME: What happens if trigger manages to be created while we are
- obtaining this lock ? May be it is sensible just to disable
- trigger execution in this case ? Or will MYSQL_LOCK_IGNORE_FLUSH
- save us from that ?
- */
- table->reginfo.lock_type=TL_WRITE;
- if (! ((*lock)= mysql_lock_tables(thd, &table, 1,
- MYSQL_LOCK_IGNORE_FLUSH, &not_used)))
- {
- VOID(pthread_mutex_lock(&LOCK_open));
- hash_delete(&open_cache,(byte*) table);
- VOID(pthread_mutex_unlock(&LOCK_open));
- quick_rm_table(create_info->db_type, create_table->db,
- table_case_name(create_info, create_table->table_name));
- DBUG_RETURN(0);
- }
- table->file->extra(HA_EXTRA_WRITE_CACHE);
- DBUG_RETURN(table);
-}
-
-
-/****************************************************************************
** Alter a table definition
****************************************************************************/
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 6473163a6ec..b2dbc517fa4 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -448,6 +448,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token NUMERIC_SYM
%token NVARCHAR_SYM
%token OFFSET_SYM
+%token OJ_SYM
%token OLD_PASSWORD
%token ON
%token ONE_SHOT_SYM
@@ -5246,11 +5247,14 @@ table_factor:
}
expr '}'
{
+ LEX *lex= Lex;
YYERROR_UNLESS($3 && $7);
add_join_on($7,$10);
Lex->pop_context();
$7->outer_join|=JOIN_TYPE_LEFT;
$$=$7;
+ if (!($$= lex->current_select->nest_last_join(lex->thd)))
+ YYABORT;
}
| select_derived_init get_select_lex select_derived2
{
@@ -5795,7 +5799,11 @@ select_var_ident:
if (lex->result)
((select_dumpvar *)lex->result)->var_list.push_back( new my_var($2,0,0,(enum_field_types)0));
else
- YYABORT;
+ /*
+ The parser won't create select_result instance only
+ if it's an EXPLAIN.
+ */
+ DBUG_ASSERT(lex->describe);
}
| ident_or_text
{
@@ -5807,10 +5815,8 @@ select_var_ident:
my_error(ER_SP_UNDECLARED_VAR, MYF(0), $1.str);
YYABORT;
}
- if (! lex->result)
- YYABORT;
- else
- {
+ if (lex->result)
+ {
my_var *var;
((select_dumpvar *)lex->result)->
var_list.push_back(var= new my_var($1,1,t->offset,t->type));
@@ -5818,6 +5824,14 @@ select_var_ident:
if (var)
var->sp= lex->sphead;
#endif
+ }
+ else
+ {
+ /*
+ The parser won't create select_result instance only
+ if it's an EXPLAIN.
+ */
+ DBUG_ASSERT(lex->describe);
}
}
;
@@ -7206,12 +7220,18 @@ simple_ident_q:
YYABORT;
}
+ DBUG_ASSERT(!new_row ||
+ (lex->trg_chistics.event == TRG_EVENT_INSERT ||
+ lex->trg_chistics.event == TRG_EVENT_UPDATE));
+ const bool read_only=
+ !(new_row && lex->trg_chistics.action_time == TRG_ACTION_BEFORE);
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
new_row ?
Item_trigger_field::NEW_ROW:
Item_trigger_field::OLD_ROW,
$3.str,
- Item_trigger_field::AT_READ)))
+ SELECT_ACL,
+ read_only)))
YYABORT;
/*
@@ -7847,11 +7867,13 @@ sys_option_value:
it= new Item_null();
}
+ DBUG_ASSERT(lex->trg_chistics.action_time == TRG_ACTION_BEFORE &&
+ (lex->trg_chistics.event == TRG_EVENT_INSERT ||
+ lex->trg_chistics.event == TRG_EVENT_UPDATE));
if (!(trg_fld= new Item_trigger_field(Lex->current_context(),
Item_trigger_field::NEW_ROW,
$2.base_name.str,
- Item_trigger_field::AT_UPDATE)
- ) ||
+ UPDATE_ACL, FALSE)) ||
!(sp_fld= new sp_instr_set_trigger_field(lex->sphead->
instructions(),
lex->spcont,
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 24f3a7318bd..202910f44e4 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -245,6 +245,7 @@ sh -c "PATH=\"${MYSQL_BUILD_PATH:-$PATH}\" \
--enable-local-infile \
--with-mysqld-user=%{mysqld_user} \
--with-unix-socket-path=/var/lib/mysql/mysql.sock \
+ --with-pic \
--prefix=/ \
%if %{YASSL_BUILD}
--with-yassl \
@@ -656,6 +657,7 @@ fi
%attr(755, root, root) %{_bindir}/ndb_desc
%attr(755, root, root) %{_bindir}/ndb_show_tables
%attr(755, root, root) %{_bindir}/ndb_test_platform
+%attr(755, root, root) %{_bindir}/ndb_config
%files ndb-extra
%defattr(-,root,root,0755)
@@ -721,6 +723,10 @@ fi
# itself - note that they must be ordered by date (important when
# merging BK trees)
%changelog
+* Sat May 20 2006 Kent Boortz <kent@mysql.com>
+
+- Always compile for PIC, position independent code.
+
* Wed May 10 2006 Kent Boortz <kent@mysql.com>
- Use character set "all" for the "max", to make Cluster nodes