diff --git a/.bzr-mysql/default.conf b/.bzr-mysql/default.conf
index 557df1b1ffe..f79c1cd6319 100644
--- a/.bzr-mysql/default.conf
+++ b/.bzr-mysql/default.conf
@@ -1,4 +1,4 @@
[MYSQL]
post_commit_to = "commits@lists.mysql.com"
post_push_to = "commits@lists.mysql.com"
-tree_name = "mysql-5.0-bugteam"
+tree_name = "mysql-5.0"
diff --git a/BitKeeper/etc/collapsed b/BitKeeper/etc/collapsed
index 8dcf561b845..64dfcb27d17 100644
--- a/BitKeeper/etc/collapsed
+++ b/BitKeeper/etc/collapsed
@@ -35,9 +35,25 @@
459a70691aYIfU2ohV0a3P5iTLpO2A
459a7422KF_P7PuU3YQ5qG6ZLEVpiA
459a74e4nRcXppMSBYeQQ5efDkTADg
+459c03b9N_mqF2XJKK6DwSrIt7e6_g
+459c1965_BQMBzBO8S_gVqjTHYQrmw
+459c2098XoAUsUn8N07IVRDD6CTM-A
+459ea845XenN-uWqEM5LFvUT60tW_A
45ae6628gqKTsUFfnoNExadETVIkbA
+45af88c9RIIJWPfBxs3o7zekI-ELPQ
45ba4faf2oqu6eR8fqecR3LfSNcYUg
45ba5238-NKl80QVXzdGo8hO9M75Xg
45c0fdfb2mz6NdOIsLenJtf6_ZelTA
+45c38d90tNwOTSaYKHXd3ccLtnytlQ
+45c390d6BbWrwyEi5T5VsWKYxl06Rg
+45c39d31g0iik6UE_oTK5N55ry-ycA
45d1ffcd-r3v8A7uh92hQaMfQM9UPQ
45d21437Vg_-i4uOWyvzYWHESXDP6A
+45da6370nnZlAAIieMCrXkxF9toOyQ
+45da6551zUuplwxuqcT2fhRgceC0CQ
+45db0d4bkGtxBk21sZFJgbCV1FcNRg
+45db468b-DKE8kUTV42eYMYmk8_g9g
+45dd21d1rVPnDfvZTNVHLalcjnbsZw
+45ddaf15_Ld7IAEpUUP3FJjJ-oSEFg
+45ddc763DodLG1BqH_wRBJXMbCSB5A
+45ddc8282KnaNGuijqCTphlXV_eeog
diff --git a/VC++Files/sql/mysqld.vcproj b/VC++Files/sql/mysqld.vcproj
index 97468c2045b..802ca638c90 100644
--- a/VC++Files/sql/mysqld.vcproj
+++ b/VC++Files/sql/mysqld.vcproj
@@ -1016,6 +1016,9 @@
+
+
diff --git a/client/mysql.cc b/client/mysql.cc
index 983d7719c3c..93aab390e5a 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -241,7 +241,7 @@ typedef struct {
static COMMANDS commands[] = {
{ "?", '?', com_help, 1, "Synonym for `help'." },
- { "clear", 'c', com_clear, 0, "Clear command."},
+ { "clear", 'c', com_clear, 0, "Clear the current input statement."},
{ "connect",'r', com_connect,1,
"Reconnect to the server. Optional arguments are db and host." },
{ "delimiter", 'd', com_delimiter, 1,
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 312012d7b8d..2f19fad9ea9 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -4087,19 +4087,26 @@ int select_connection_name(const char *name)
int select_connection(struct st_command *command)
{
- char *name;
+ int ret;
char *p= command->first_argument;
+ static DYNAMIC_STRING ds_connection;
+ const struct command_arg connection_args[] = {
+ { "connection_name", ARG_STRING, TRUE, &ds_connection, "Name of the connection that we switch to." }
+ };
DBUG_ENTER("select_connection");
if (!*p)
die("Missing connection name in connect");
- name= p;
- while (*p && !my_isspace(charset_info,*p))
- p++;
- if (*p)
- *p++= 0;
- command->last_argument= p;
- return select_connection_name(name);
+
+ check_command_args(command, command->first_argument, connection_args,
+ sizeof(connection_args)/sizeof(struct command_arg),
+ ',');
+
+ DBUG_PRINT("info", ("changing connection: %s", ds_connection.str));
+
+ ret= select_connection_name(ds_connection.str);
+ dynstr_free(&ds_connection);
+ return ret;
}
diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c
index 488c760da14..2f1aefa7117 100644
--- a/cmd-line-utils/libedit/term.c
+++ b/cmd-line-utils/libedit/term.c
@@ -61,7 +61,7 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#ifdef HAVE_NCURSES_H
#include
#endif
-/* Solaris's term.h does horrid things. */
+/* Don't use Solaris's term.h. */
#if (defined(HAVE_TERM_H) && !defined(__SunOS))
#include
#endif
diff --git a/configure.in b/configure.in
index b8856b19665..e4d7e0975d9 100644
--- a/configure.in
+++ b/configure.in
@@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
-AM_INIT_AUTOMAKE(mysql, 5.0.81)
+AM_INIT_AUTOMAKE(mysql, 5.0.82)
AM_CONFIG_HEADER([include/config.h:config.h.in])
PROTOCOL_VERSION=10
@@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
-NDB_VERSION_BUILD=81
+NDB_VERSION_BUILD=82
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@@ -661,7 +661,6 @@ then
fi
fi
-
AC_ARG_WITH(server-suffix,
[ --with-server-suffix Append value to the version string.],
[ MYSQL_SERVER_SUFFIX=`echo "$withval" | sed -e 's/^\(...................................\)..*$/\1/'` ],
@@ -724,6 +723,45 @@ else
AC_MSG_RESULT([no])
fi
+AC_MSG_CHECKING(whether features provided by the user community should be included.)
+AC_ARG_ENABLE(community-features,
+ AC_HELP_STRING(
+ [--enable-community-features],
+ [Enable additional features provided by the user community.]),
+ [ ENABLE_COMMUNITY_FEATURES=$enableval ],
+ [ ENABLE_COMMUNITY_FEATURES=no ]
+ )
+
+if test "$ENABLE_COMMUNITY_FEATURES" = "yes"
+then
+ AC_DEFINE([COMMUNITY_SERVER], [1],
+ [Whether features provided by the user community should be included])
+ AC_MSG_RESULT([yes])
+else
+ AC_MSG_RESULT([no])
+fi
+
+# Add query profiler
+AC_MSG_CHECKING(whether query profiling should be included)
+AC_ARG_ENABLE(profiling,
+ AS_HELP_STRING([--enable-profiling], [Add query-profiling code.]),
+ [ ENABLED_PROFILING=$enableval ],
+ [ ENABLED_PROFILING=no ])
+
+if test "$ENABLED_PROFILING" = "yes"
+then
+ if test "$ENABLE_COMMUNITY_FEATURES" = "yes";
+ then
+ AC_DEFINE([ENABLED_PROFILING], [1], [If SHOW PROFILE should be enabled])
+ AC_MSG_RESULT([yes])
+ else
+ ENABLED_PROFILING="no"
+ AC_MSG_RESULT([no, overridden because community-features disabled])
+ AC_MSG_ERROR([This is almost certainly wrong. Add --enable-community-features or remove --enable-profiling .])
+ fi
+else
+ AC_MSG_RESULT([no])
+fi
# Use this to set the place used for unix socket used to local communication.
AC_ARG_WITH(unix-socket-path,
@@ -1177,7 +1215,6 @@ case $SYSTEM_TYPE in
fi
;;
*darwin*)
- AC_DEFINE([DEFAULT_SKIP_THREAD_PRIORITY], [1], [default to skip thread priority])
if test "$ac_cv_prog_gcc" = "yes"
then
FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT"
diff --git a/include/config-netware.h b/include/config-netware.h
index 9c99305789a..85a5ef86829 100644
--- a/include/config-netware.h
+++ b/include/config-netware.h
@@ -45,7 +45,7 @@ extern "C" {
#undef HAVE_SYS_MMAN_H
#undef HAVE_SYNCH_H
#undef HAVE_MMAP
-#undef HAVE_RINT
+#undef HAVE_FESETROUND
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
#define HAVE_PTHREAD_SIGMASK 1
diff --git a/include/config-win.h b/include/config-win.h
index ab463a7c142..39affd3b8e9 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -206,6 +206,9 @@ typedef uint rf_SetTimer;
/* If LOAD DATA LOCAL INFILE should be enabled by default */
#define ENABLED_LOCAL_INFILE 1
+/* If query profiling should be enabled by default */
+#define ENABLED_PROFILING 1
+
/* Convert some simple functions to Posix */
#define my_sigset(A,B) signal((A),(B))
diff --git a/include/my_sys.h b/include/my_sys.h
index 35c4eb5f2b1..bfb1a672641 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -162,6 +162,7 @@ extern char *my_strdup_with_length(const char *from, size_t length,
#define ORIG_CALLER_INFO /* nothing */
#define TRASH(A,B) /* nothing */
#endif
+#define my_strndup(A,B,C) my_strdup_with_length((A), (B), (C))
#ifdef HAVE_LARGE_PAGES
extern uint my_get_large_page_size(void);
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 3c202c5a3bf..e8f294e9305 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -1101,12 +1101,20 @@ btr_search_drop_page_hash_when_freed(
page = buf_page_get_gen(space, page_no, RW_S_LATCH, NULL,
BUF_GET_IF_IN_POOL, __FILE__, __LINE__,
&mtr);
+ /* Because the buffer pool mutex was released by
+ buf_page_peek_if_search_hashed(), it is possible that the
+ block was removed from the buffer pool by another thread
+ before buf_page_get_gen() got a chance to acquire the buffer
+ pool mutex again. Thus, we must check for a NULL return. */
+
+ if (UNIV_LIKELY(page != NULL)) {
#ifdef UNIV_SYNC_DEBUG
- buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH);
+ buf_page_dbg_add_level(page, SYNC_TREE_NODE_FROM_HASH);
#endif /* UNIV_SYNC_DEBUG */
- btr_search_drop_page_hash_index(page);
+ btr_search_drop_page_hash_index(page);
+ }
mtr_commit(&mtr);
}
diff --git a/innobase/include/srv0srv.h b/innobase/include/srv0srv.h
index 97e9136040d..ece6b1d763f 100644
--- a/innobase/include/srv0srv.h
+++ b/innobase/include/srv0srv.h
@@ -253,6 +253,12 @@ extern ulint srv_read_ahead_seq;
/* variable to count the number of random read-aheads were done */
extern ulint srv_read_ahead_rnd;
+/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
+NOT update cardinality for indexes of InnoDB table". By default we are
+running with the fix disabled because MySQL 5.1 is frozen for such
+behavioral changes. */
+extern char srv_use_legacy_cardinality_algorithm;
+
/* In this structure we store status variables to be passed to MySQL */
typedef struct export_var_struct export_struc;
diff --git a/innobase/page/page0cur.c b/innobase/page/page0cur.c
index d0b89e81787..93082560001 100644
--- a/innobase/page/page0cur.c
+++ b/innobase/page/page0cur.c
@@ -15,6 +15,8 @@ Created 10/4/1994 Heikki Tuuri
#include "mtr0log.h"
#include "log0recv.h"
#include "rem0cmp.h"
+#include "srv0srv.h"
+#include "ut0ut.h"
static ulint page_rnd = 976722341;
@@ -23,6 +25,44 @@ static ulint page_rnd = 976722341;
ulint page_cur_short_succ = 0;
# endif /* UNIV_SEARCH_PERF_STAT */
+/***********************************************************************
+This is a linear congruential generator PRNG. Returns a pseudo random
+number between 0 and 2^64-1 inclusive. The formula and the constants
+being used are:
+X[n+1] = (a * X[n] + c) mod m
+where:
+X[0] = ut_usectime()
+a = 1103515245 (3^5 * 5 * 7 * 129749)
+c = 12345 (3 * 5 * 823)
+m = 18446744073709551616 (2^64)
+*/
+#define LCG_a 1103515245
+#define LCG_c 12345
+static
+unsigned long long
+page_cur_lcg_prng()
+/*===============*/
+ /* out: number between 0 and 2^64-1 */
+{
+ static unsigned long long lcg_current = 0;
+ static ibool initialized = FALSE;
+ ulint time_sec;
+ ulint time_ms;
+
+ if (!initialized) {
+ ut_usectime(&time_sec, &time_ms);
+ lcg_current = (unsigned long long) (time_sec * 1000000
+ + time_ms);
+ initialized = TRUE;
+ }
+
+ /* no need to "% 2^64" explicitly because lcg_current is
+ 64 bit and this will be done anyway */
+ lcg_current = LCG_a * lcg_current + LCG_c;
+
+ return(lcg_current);
+}
+
/********************************************************************
Tries a search shortcut based on the last insert. */
UNIV_INLINE
@@ -489,9 +529,13 @@ page_cur_open_on_rnd_user_rec(
return;
}
- page_rnd += 87584577;
+ if (srv_use_legacy_cardinality_algorithm) {
+ page_rnd += 87584577;
- rnd = page_rnd % page_get_n_recs(page);
+ rnd = page_rnd % page_get_n_recs(page);
+ } else {
+ rnd = (ulint) page_cur_lcg_prng() % page_get_n_recs(page);
+ }
rec = page_get_infimum_rec(page);
@@ -1419,3 +1463,30 @@ page_cur_delete_rec(
page_dir_balance_slot(page, cur_slot_no);
}
}
+
+#ifdef UNIV_COMPILE_TEST_FUNCS
+
+/***********************************************************************
+Print the first n numbers, generated by page_cur_lcg_prng() to make sure
+(visually) that it works properly. */
+void
+test_page_cur_lcg_prng(
+/*===================*/
+ int n) /* in: print first n numbers */
+{
+ int i;
+ unsigned long long rnd;
+
+ for (i = 0; i < n; i++) {
+ rnd = page_cur_lcg_prng();
+ printf("%llu\t%%2=%llu %%3=%llu %%5=%llu %%7=%llu %%11=%llu\n",
+ rnd,
+ rnd % 2,
+ rnd % 3,
+ rnd % 5,
+ rnd % 7,
+ rnd % 11);
+ }
+}
+
+#endif /* UNIV_COMPILE_TEST_FUNCS */
diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c
index 6b755ae9816..0974c616db3 100644
--- a/innobase/srv/srv0srv.c
+++ b/innobase/srv/srv0srv.c
@@ -239,6 +239,12 @@ ulint srv_read_ahead_seq = 0;
/* variable to count the number of random read-aheads */
ulint srv_read_ahead_rnd = 0;
+/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
+NOT update cardinality for indexes of InnoDB table". By default we are
+running with the fix disabled because MySQL 5.1 is frozen for such
+behavioral changes. */
+char srv_use_legacy_cardinality_algorithm = TRUE;
+
/* structure to pass status variables to MySQL */
export_struc export_vars;
diff --git a/libmysqld/Makefile.am b/libmysqld/Makefile.am
index 81da1e43cc9..17e308b3324 100644
--- a/libmysqld/Makefile.am
+++ b/libmysqld/Makefile.am
@@ -53,6 +53,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
protocol.cc net_serv.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
sql_load.cc discover.cc sql_locale.cc \
+ sql_profile.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \
diff --git a/myisam/mi_close.c b/myisam/mi_close.c
index 81d32be468a..43eebed520b 100644
--- a/myisam/mi_close.c
+++ b/myisam/mi_close.c
@@ -35,8 +35,6 @@ int mi_close(register MI_INFO *info)
if (info->lock_type == F_EXTRA_LCK)
info->lock_type=F_UNLCK; /* HA_EXTRA_NO_USER_CHANGE */
- if (share->reopen == 1 && share->kfile >= 0)
- _mi_decrement_open_count(info);
if (info->lock_type != F_UNLCK)
{
@@ -78,6 +76,8 @@ int mi_close(register MI_INFO *info)
*/
if (share->mode != O_RDONLY && mi_is_crashed(info))
mi_state_info_write(share->kfile, &share->state, 1);
+ /* Decrement open count must be last I/O on this file. */
+ _mi_decrement_open_count(info);
if (my_close(share->kfile,MYF(0)))
error = my_errno;
}
diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c
index ca8a537b322..e08e5097e33 100644
--- a/myisam/mi_delete.c
+++ b/myisam/mi_delete.c
@@ -250,7 +250,11 @@ static int d_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
if (info->ft1_to_ft2)
{
/* we're in ft1->ft2 conversion mode. Saving key data */
- insert_dynamic(info->ft1_to_ft2, (char*) (lastkey+off));
+ if (insert_dynamic(info->ft1_to_ft2, (char*) (lastkey+off)))
+ {
+ DBUG_PRINT("error",("Out of memory"));
+ DBUG_RETURN(-1);
+ }
}
else
{
diff --git a/myisam/mi_packrec.c b/myisam/mi_packrec.c
index df9a4d18a6c..68911d7f129 100644
--- a/myisam/mi_packrec.c
+++ b/myisam/mi_packrec.c
@@ -208,10 +208,17 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
This segment will be reallocated after construction of the tables.
*/
length=(uint) (elements*2+trees*(1 << myisam_quick_table_bits));
+ /*
+ To keep some algorithms simpler, we accept that they access
+ bytes beyond the end of the input data. This can affect up to
+ one byte less than the "word size" size used in this file,
+ which is BITS_SAVED / 8. To avoid accessing non-allocated
+ data, we add (BITS_SAVED / 8) - 1 bytes to the buffer size.
+ */
if (!(share->decode_tables=(uint16*)
my_malloc((length + OFFSET_TABLE_SIZE) * sizeof(uint16) +
- (uint) (share->pack.header_length - sizeof(header)),
- MYF(MY_WME | MY_ZEROFILL))))
+ (uint) (share->pack.header_length - sizeof(header) +
+ (BITS_SAVED / 8) - 1), MYF(MY_WME | MY_ZEROFILL))))
goto err1;
tmp_buff=share->decode_tables+length;
disk_cache=(byte*) (tmp_buff+OFFSET_TABLE_SIZE);
@@ -1430,31 +1437,6 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff)
bit_buff->current_byte=0;
return;
}
- else
- {
- uint len= 0;
- uint i= 0;
- /*
- Check if the remaining buffer/record to read is less than the word size.
- If so read byte by byte
-
- Note: if this branch becomes a bottleneck it can be removed, assuming
- that the second memory segment allocates 7 extra bytes (see
- _mi_read_pack_info()).
- */
- len= bit_buff->end - bit_buff->pos;
- if (len < (BITS_SAVED / 8))
- {
- bit_buff->current_byte= 0;
- for (i=0 ; i < len ; i++)
- {
- bit_buff->current_byte+= (((uint) ((uchar) bit_buff->pos[len - i - 1]))
- << (8 * i));
- }
- bit_buff->pos= bit_buff->end;
- return;
- }
- }
#if BITS_SAVED == 64
bit_buff->current_byte= ((((uint) ((uchar) bit_buff->pos[7]))) +
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index 4f11fc78ccf..b4843a748dd 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -550,7 +550,14 @@ int _mi_insert(register MI_INFO *info, register MI_KEYDEF *keyinfo,
we cannot easily dispatch an empty page here */
b+=blen+ft2len+2;
for (a=anc_buff+a_length ; b < a ; b+=ft2len+2)
- insert_dynamic(info->ft1_to_ft2, (char*) b);
+ {
+ if (insert_dynamic(info->ft1_to_ft2, (char*) b))
+ {
+ mi_print_error(info->s, HA_ERR_OUT_OF_MEM);
+ my_errno= HA_ERR_OUT_OF_MEM;
+ DBUG_RETURN(-1);
+ }
+ }
/* fixing the page's length - it contains only one key now */
mi_putint(anc_buff,2+blen+ft2len+2,0);
diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c
index 29fb2ea1a60..b1a61f2f373 100644
--- a/myisam/myisamchk.c
+++ b/myisam/myisamchk.c
@@ -1311,7 +1311,7 @@ static void descript(MI_CHECK *param, register MI_INFO *info, my_string name)
share->base.max_key_file_length != HA_OFFSET_ERROR)
printf("Max datafile length: %13s Max keyfile length: %13s\n",
llstr(share->base.max_data_file_length-1,llbuff),
- llstr(share->base.max_key_file_length-1,llbuff2));
+ ullstr(share->base.max_key_file_length - 1, llbuff2));
}
}
diff --git a/mysql-test/include/diff_master_slave.inc b/mysql-test/include/diff_master_slave.inc
new file mode 100644
index 00000000000..b6d79190671
--- /dev/null
+++ b/mysql-test/include/diff_master_slave.inc
@@ -0,0 +1,21 @@
+# ==== Purpose ====
+#
+# Diff the output of a statement on master and slave
+#
+# ==== Usage =====
+#
+# let $diff_statement= SELECT * FROM t1 WHERE a < 100;
+# source include/diff_master_slave.inc;
+
+--echo source include/diff_master_slave.inc;
+disable_query_log;
+disable_result_log;
+
+exec $MYSQL test -e "$diff_statement" > $MYSQLTEST_VARDIR/tmp/diff_master.out;
+sync_slave_with_master;
+exec $MYSQL_SLAVE test -e "$diff_statement" > $MYSQLTEST_VARDIR/tmp/diff_slave.out;
+
+diff_files $MYSQLTEST_VARDIR/tmp/diff_master.out $MYSQLTEST_VARDIR/tmp/diff_slave.out;
+
+enable_result_log;
+enable_query_log;
diff --git a/mysql-test/include/have_community_features.inc b/mysql-test/include/have_community_features.inc
new file mode 100644
index 00000000000..66697d8dd00
--- /dev/null
+++ b/mysql-test/include/have_community_features.inc
@@ -0,0 +1,4 @@
+--require r/have_community_features.require
+--disable_query_log
+show variables like 'have_community_features';
+--enable_query_log
diff --git a/mysql-test/include/have_profiling.inc b/mysql-test/include/have_profiling.inc
new file mode 100644
index 00000000000..48f6668ff92
--- /dev/null
+++ b/mysql-test/include/have_profiling.inc
@@ -0,0 +1,4 @@
+--require r/have_profiling.require
+--disable_query_log
+show variables like 'have_profiling';
+--enable_query_log
diff --git a/mysql-test/include/kill_query.inc b/mysql-test/include/kill_query.inc
new file mode 100644
index 00000000000..341c3b93535
--- /dev/null
+++ b/mysql-test/include/kill_query.inc
@@ -0,0 +1,68 @@
+# ==== Purpose ====
+#
+# Kill a query in the master connection, and then try to reap the
+# result of the killed query.
+#
+# ==== Usage ====
+#
+# The following variables should be set before sourcing this file.
+#
+# $debug_lock: name of the debug user lock, if set, will release/lock
+# the specified debug lock accordingly, and before
+# sourcing this, connection 'master' should get the user
+# lock and run a query in another thread, which will
+# block before creating statement event.
+#
+# $connection_name: name of the connection that is waiting for the
+# lock, this can not be 'master'
+#
+# $connection_id: id of the connection that is waiting for the lock
+#
+# Example:
+# let $debug_lock=;
+# connection master1;
+# let $connection_name= master1;
+# let $connection_id= `SELECT CONNECTION_ID()`;
+# send CREATE TABLE t1;
+# source kill_query.inc;
+#
+# let $debug_lock= "debug_lock.before_query_log_event";
+# connection master;
+# eval SELECT GET_LOCK($debug_lock, 10);
+# connection master1;
+# let $connection_name= master1;
+# let $connection_id= `SELECT CONNECTION_ID()`;
+# send CREATE TABLE t1;
+# source kill_query.inc;
+
+
+--echo source include/kill_query.inc;
+disable_query_log;
+disable_result_log;
+connection master;
+
+# kill the query that is waiting
+eval kill query $connection_id;
+
+if (`SELECT '$debug_lock' != ''`)
+{
+ # release the lock to allow binlog continue
+ eval SELECT RELEASE_LOCK($debug_lock);
+}
+
+# reap the result of the waiting query
+connection $connection_name;
+error 0, 1317, 1307, 1306, 1334, 1305;
+reap;
+
+connection master;
+
+if (`SELECT '$debug_lock' != ''`)
+{
+ # get lock again to make the next query wait
+ eval SELECT GET_LOCK($debug_lock, 10);
+}
+
+connection $connection_name;
+enable_query_log;
+enable_result_log;
diff --git a/mysql-test/include/kill_query_and_diff_master_slave.inc b/mysql-test/include/kill_query_and_diff_master_slave.inc
new file mode 100644
index 00000000000..611d6929c99
--- /dev/null
+++ b/mysql-test/include/kill_query_and_diff_master_slave.inc
@@ -0,0 +1,43 @@
+# ==== Purpose ====
+#
+# Kill a query, sync master with slave, and diff the output of a
+# statement on master and slave to check if statement is correctly
+# replicated.
+#
+# ==== Usage ====
+#
+# connection ;
+# let $connection_name=
+# let $connection_id=`SELECT CONNECTION_ID()`;
+# let $diff_statement=;
+# send ;
+# source include/kill_query_and_diff_master_slave.inc;
+#
+# Note: must not be 'master'.
+#
+# See also kill_query.inc and diff_master_slave.inc for more
+# information
+
+source include/kill_query.inc;
+
+# Release the debug lock if used, so that the statements in
+# diff_master_slave.inc will not be blocked.
+connection master;
+disable_query_log;
+disable_result_log;
+if (`SELECT '$debug_lock' != ''`)
+{
+ eval SELECT RELEASE_LOCK($debug_lock);
+}
+enable_result_log;
+enable_query_log;
+
+source include/diff_master_slave.inc;
+
+# Acquire the debug lock again if used
+connection master;
+disable_query_log; disable_result_log; if (`SELECT '$debug_lock' !=
+''`) { eval SELECT GET_LOCK($debug_lock, 10); } enable_result_log;
+enable_query_log;
+
+connection $connection_name;
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 0948c973e9b..ffa9b4cb1d3 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -2063,7 +2063,7 @@ sub environment_setup () {
$ENV{'MYSQL_BINLOG'}= $cmdline_mysqlbinlog;
# ----------------------------------------------------
- # Setup env so childs can execute mysql
+ # Setup env so childs can execute mysql against master
# ----------------------------------------------------
my $cmdline_mysql=
mtr_native_path($exe_mysql) .
@@ -2074,6 +2074,18 @@ sub environment_setup () {
$ENV{'MYSQL'}= $cmdline_mysql;
+ # ----------------------------------------------------
+ # Setup env so childs can execute mysql against slave
+ # ----------------------------------------------------
+ my $cmdline_mysql_slave=
+ mtr_native_path($exe_mysql) .
+ " --no-defaults --host=localhost --user=root --password= " .
+ "--port=$slave->[0]->{'port'} " .
+ "--socket=$slave->[0]->{'path_sock'} ".
+ "--character-sets-dir=$path_charsetsdir";
+
+ $ENV{'MYSQL_SLAVE'}= $cmdline_mysql_slave;
+
# ----------------------------------------------------
# Setup env so childs can execute bug25714
# ----------------------------------------------------
diff --git a/mysql-test/r/count_distinct3.result b/mysql-test/r/count_distinct3.result
index 086e1360b0c..840c26669a1 100644
--- a/mysql-test/r/count_distinct3.result
+++ b/mysql-test/r/count_distinct3.result
@@ -2,7 +2,8 @@ DROP TABLE IF EXISTS t1, t2;
CREATE TABLE t1 (id INTEGER, grp TINYINT, id_rev INTEGER);
SELECT COUNT(*) FROM t1;
COUNT(*)
-4181000
+4201000
SELECT COUNT(DISTINCT id) FROM t1 GROUP BY grp;
+# Begin cleanup
+SET session myisam_sort_buffer_size = @orig_myisam_sort_buffer_size;
DROP TABLE t1;
-set @@read_buffer_size=default;
diff --git a/mysql-test/r/func_des_encrypt.result b/mysql-test/r/func_des_encrypt.result
index 46b30bdab58..b81f96f6ef7 100644
--- a/mysql-test/r/func_des_encrypt.result
+++ b/mysql-test/r/func_des_encrypt.result
@@ -1,3 +1,37 @@
select des_encrypt('hello');
des_encrypt('hello')
€Ö2nV“Ø}
+#
+# Bug #11643: des_encrypt() causes server to die
+#
+CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM;
+INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567');
+UPDATE t1 SET des=DES_ENCRYPT('1234');
+SELECT LENGTH(des) FROM t1;
+LENGTH(des)
+9
+9
+9
+9
+SELECT DES_DECRYPT(des) FROM t1;
+DES_DECRYPT(des)
+1234
+1234
+1234
+1234
+SELECT
+LENGTH(DES_ENCRYPT('1234')),
+LENGTH(DES_ENCRYPT('12345')),
+LENGTH(DES_ENCRYPT('123456')),
+LENGTH(DES_ENCRYPT('1234567'));
+LENGTH(DES_ENCRYPT('1234')) LENGTH(DES_ENCRYPT('12345')) LENGTH(DES_ENCRYPT('123456')) LENGTH(DES_ENCRYPT('1234567'))
+9 9 9 9
+SELECT
+DES_DECRYPT(DES_ENCRYPT('1234')),
+DES_DECRYPT(DES_ENCRYPT('12345')),
+DES_DECRYPT(DES_ENCRYPT('123456')),
+DES_DECRYPT(DES_ENCRYPT('1234567'));
+DES_DECRYPT(DES_ENCRYPT('1234')) DES_DECRYPT(DES_ENCRYPT('12345')) DES_DECRYPT(DES_ENCRYPT('123456')) DES_DECRYPT(DES_ENCRYPT('1234567'))
+1234 12345 123456 1234567
+DROP TABLE t1;
+End of 5.0 tests
diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result
index 99bfede3ee0..a4fa929c32e 100644
--- a/mysql-test/r/gis-rtree.result
+++ b/mysql-test/r/gis-rtree.result
@@ -186,106 +186,106 @@ CREATE TABLE t2 (
fid INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
g GEOMETRY NOT NULL
) ENGINE=MyISAM;
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))));
-INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)));
+INSERT INTO t2 (g) VALUES (LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)));
ALTER TABLE t2 ADD SPATIAL KEY(g);
SHOW CREATE TABLE t2;
Table Create Table
@@ -309,406 +309,406 @@ fid AsText(g)
56 LINESTRING(41 41,50 50)
45 LINESTRING(51 51,60 60)
55 LINESTRING(41 51,50 60)
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10)))));
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 10 * 10 - 9), Point(10 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-99
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 9 * 10 - 9), Point(10 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-98
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 8 * 10 - 9), Point(10 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-97
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 7 * 10 - 9), Point(10 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-96
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 6 * 10 - 9), Point(10 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-95
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 5 * 10 - 9), Point(10 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-94
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 4 * 10 - 9), Point(10 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-93
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 3 * 10 - 9), Point(10 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-92
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 2 * 10 - 9), Point(10 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-91
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(10 * 10 - 9, 1 * 10 - 9), Point(10 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-90
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 10 * 10 - 9), Point(9 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-89
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 9 * 10 - 9), Point(9 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-88
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 8 * 10 - 9), Point(9 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-87
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 7 * 10 - 9), Point(9 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-86
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 6 * 10 - 9), Point(9 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-85
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 5 * 10 - 9), Point(9 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-84
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 4 * 10 - 9), Point(9 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-83
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 3 * 10 - 9), Point(9 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-82
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 2 * 10 - 9), Point(9 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-81
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(9 * 10 - 9, 1 * 10 - 9), Point(9 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-80
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 10 * 10 - 9), Point(8 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-79
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 9 * 10 - 9), Point(8 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-78
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 8 * 10 - 9), Point(8 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-77
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 7 * 10 - 9), Point(8 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-76
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 6 * 10 - 9), Point(8 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-75
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 5 * 10 - 9), Point(8 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-74
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 4 * 10 - 9), Point(8 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-73
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 3 * 10 - 9), Point(8 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-72
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 2 * 10 - 9), Point(8 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-71
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(8 * 10 - 9, 1 * 10 - 9), Point(8 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-70
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 10 * 10 - 9), Point(7 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-69
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 9 * 10 - 9), Point(7 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-68
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 8 * 10 - 9), Point(7 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-67
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 7 * 10 - 9), Point(7 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-66
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 6 * 10 - 9), Point(7 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-65
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 5 * 10 - 9), Point(7 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-64
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 4 * 10 - 9), Point(7 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-63
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 3 * 10 - 9), Point(7 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-62
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 2 * 10 - 9), Point(7 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-61
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(7 * 10 - 9, 1 * 10 - 9), Point(7 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-60
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 10 * 10 - 9), Point(6 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-59
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 9 * 10 - 9), Point(6 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-58
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 8 * 10 - 9), Point(6 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-57
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 7 * 10 - 9), Point(6 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-56
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 6 * 10 - 9), Point(6 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-55
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 5 * 10 - 9), Point(6 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-54
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 4 * 10 - 9), Point(6 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-53
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 3 * 10 - 9), Point(6 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-52
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 2 * 10 - 9), Point(6 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-51
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(6 * 10 - 9, 1 * 10 - 9), Point(6 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-50
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 10 * 10 - 9), Point(5 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-49
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 9 * 10 - 9), Point(5 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-48
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 8 * 10 - 9), Point(5 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-47
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 7 * 10 - 9), Point(5 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-46
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 6 * 10 - 9), Point(5 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-45
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 5 * 10 - 9), Point(5 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-44
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 4 * 10 - 9), Point(5 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-43
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 3 * 10 - 9), Point(5 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-42
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 2 * 10 - 9), Point(5 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-41
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(5 * 10 - 9, 1 * 10 - 9), Point(5 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-40
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 10 * 10 - 9), Point(4 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-39
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 9 * 10 - 9), Point(4 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-38
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 8 * 10 - 9), Point(4 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-37
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 7 * 10 - 9), Point(4 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-36
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 6 * 10 - 9), Point(4 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-35
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 5 * 10 - 9), Point(4 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-34
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 4 * 10 - 9), Point(4 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-33
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 3 * 10 - 9), Point(4 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-32
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 2 * 10 - 9), Point(4 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-31
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(4 * 10 - 9, 1 * 10 - 9), Point(4 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-30
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 10 * 10 - 9), Point(3 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-29
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 9 * 10 - 9), Point(3 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-28
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 8 * 10 - 9), Point(3 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-27
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 7 * 10 - 9), Point(3 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-26
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 6 * 10 - 9), Point(3 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-25
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 5 * 10 - 9), Point(3 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-24
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 4 * 10 - 9), Point(3 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-23
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 3 * 10 - 9), Point(3 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-22
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 2 * 10 - 9), Point(3 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-21
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(3 * 10 - 9, 1 * 10 - 9), Point(3 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-20
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 10 * 10 - 9), Point(2 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-19
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 9 * 10 - 9), Point(2 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-18
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 8 * 10 - 9), Point(2 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-17
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 7 * 10 - 9), Point(2 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-16
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 6 * 10 - 9), Point(2 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-15
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 5 * 10 - 9), Point(2 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-14
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 4 * 10 - 9), Point(2 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-13
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 3 * 10 - 9), Point(2 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-12
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 2 * 10 - 9), Point(2 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-11
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(2 * 10 - 9, 1 * 10 - 9), Point(2 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-10
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 10 * 10 - 9), Point(1 * 10, 10 * 10))));
SELECT count(*) FROM t2;
count(*)
-9
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 9 * 10 - 9), Point(1 * 10, 9 * 10))));
SELECT count(*) FROM t2;
count(*)
-8
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 8 * 10 - 9), Point(1 * 10, 8 * 10))));
SELECT count(*) FROM t2;
count(*)
-7
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 7 * 10 - 9), Point(1 * 10, 7 * 10))));
SELECT count(*) FROM t2;
count(*)
-6
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 6 * 10 - 9), Point(1 * 10, 6 * 10))));
SELECT count(*) FROM t2;
count(*)
-5
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 5 * 10 - 9), Point(1 * 10, 5 * 10))));
SELECT count(*) FROM t2;
count(*)
-4
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 4 * 10 - 9), Point(1 * 10, 4 * 10))));
SELECT count(*) FROM t2;
count(*)
-3
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 3 * 10 - 9), Point(1 * 10, 3 * 10))));
SELECT count(*) FROM t2;
count(*)
-2
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 2 * 10 - 9), Point(1 * 10, 2 * 10))));
SELECT count(*) FROM t2;
count(*)
-1
-DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10)))));
+100
+DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point(1 * 10 - 9, 1 * 10 - 9), Point(1 * 10, 1 * 10))));
SELECT count(*) FROM t2;
count(*)
-0
+100
DROP TABLE t2;
drop table if exists t1;
Warnings:
@@ -863,11 +863,11 @@ Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
-SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
+INSERT INTO t1 (foo) VALUES (POINT(1,1));
+INSERT INTO t1 (foo) VALUES (POINT(1,0));
+INSERT INTO t1 (foo) VALUES (POINT(0,1));
+INSERT INTO t1 (foo) VALUES (POINT(0,0));
+SELECT 1 FROM t1 WHERE foo != POINT(0,0);
1
1
1
@@ -1426,35 +1426,35 @@ Table Op Msg_type Msg_text
test.t1 check status OK
DROP TABLE t1;
create table t1 (a geometry not null, spatial index(a));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072)));
-insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284)));
-insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0)));
-insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53)));
-insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111)));
-insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241)));
-insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111)));
-insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231)));
-insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260)));
-insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236)));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125)));
-insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29)));
-insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86)));
-insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270)));
-insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19)));
-insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255)));
-insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130)));
-insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39)));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159)));
-insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270)));
-insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82)));
-insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34)));
-insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183)));
-insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192)));
-insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159)));
-insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178)));
+insert into t1 values (POINT(1.1517219314031e+164, 131072));
+insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284));
+insert into t1 values (POINT(4.7783097267365e-299, -0));
+insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53));
+insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111));
+insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241));
+insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111));
+insert into t1 values (POINT(0, 6.9835074892995e-251));
+insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231));
+insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260));
+insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236));
+insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125));
+insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275));
+insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29));
+insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86));
+insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270));
+insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19));
+insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255));
+insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130));
+insert into t1 values (POINT(0, 5.8774717541114e-39));
+insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159));
+insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270));
+insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82));
+insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34));
+insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53));
+insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183));
+insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192));
+insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159));
+insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178));
drop table t1;
CREATE TABLE t1(foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
INSERT INTO t1(foo) VALUES (NULL);
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index e3b2ea751d9..5b7a58add06 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -47,26 +47,26 @@ INSERT INTO gis_point VALUES
INSERT INTO gis_line VALUES
(105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
-(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10))));
+(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
INSERT INTO gis_polygon VALUES
(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
-(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))));
+(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
INSERT INTO gis_multi_point VALUES
(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
-(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10))));
+(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
INSERT INTO gis_multi_line VALUES
(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
-(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))));
+(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
INSERT INTO gis_multi_polygon VALUES
(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
-(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))));
+(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
INSERT INTO gis_geometrycollection VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
-(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))));
+(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))));
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
INSERT into gis_geometry SELECT * FROM gis_polygon;
diff --git a/mysql-test/r/handler.result b/mysql-test/r/handler.result
index dc3750e16ea..4906111982f 100644
--- a/mysql-test/r/handler.result
+++ b/mysql-test/r/handler.result
@@ -502,3 +502,7 @@ handler t1_alias READ a next where inexistent > 0;
ERROR 42S22: Unknown column 'inexistent' in 'field list'
handler t1_alias close;
drop table t1;
+USE information_schema;
+HANDLER COLUMNS OPEN;
+ERROR HY000: Incorrect usage of HANDLER OPEN and information_schema
+USE test;
diff --git a/mysql-test/r/have_community_features.require b/mysql-test/r/have_community_features.require
new file mode 100644
index 00000000000..9233bba91e1
--- /dev/null
+++ b/mysql-test/r/have_community_features.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_community_features YES
diff --git a/mysql-test/r/have_profiling.require b/mysql-test/r/have_profiling.require
new file mode 100644
index 00000000000..54caeba1dae
--- /dev/null
+++ b/mysql-test/r/have_profiling.require
@@ -0,0 +1,2 @@
+Variable_name Value
+have_profiling YES
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 6ced6bb373a..6d88527e104 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -42,6 +42,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
COLUMN_PRIVILEGES
KEY_COLUMN_USAGE
+PROFILING
ROUTINES
SCHEMATA
SCHEMA_PRIVILEGES
@@ -729,7 +730,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
count(*)
-101
+102
drop view a2, a1;
drop table t_crashme;
select table_schema,table_name, column_name from
@@ -800,7 +801,7 @@ delete from mysql.db where user='mysqltest_4';
flush privileges;
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
table_schema count(*)
-information_schema 16
+information_schema 17
mysql 17
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
@@ -1093,7 +1094,7 @@ table_schema='information_schema' and
(column_type = 'varchar(7)' or column_type = 'varchar(20)')
group by column_type order by num;
column_type group_concat(table_schema, '.', table_name) num
-varchar(20) information_schema.COLUMNS 1
+varchar(20) information_schema.COLUMNS,information_schema.PROFILING 2
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;
@@ -1191,6 +1192,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
COLUMNS TABLE_SCHEMA
COLUMN_PRIVILEGES TABLE_SCHEMA
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+PROFILING QUERY_ID
ROUTINES ROUTINE_SCHEMA
SCHEMATA SCHEMA_NAME
SCHEMA_PRIVILEGES TABLE_SCHEMA
@@ -1222,6 +1224,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
COLUMNS TABLE_SCHEMA
COLUMN_PRIVILEGES TABLE_SCHEMA
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
+PROFILING QUERY_ID
ROUTINES ROUTINE_SCHEMA
SCHEMATA SCHEMA_NAME
SCHEMA_PRIVILEGES TABLE_SCHEMA
@@ -1304,6 +1307,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET
COLUMNS information_schema.COLUMNS 1
COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
+PROFILING information_schema.PROFILING 1
ROUTINES information_schema.ROUTINES 1
SCHEMATA information_schema.SCHEMATA 1
SCHEMA_PRIVILEGES information_schema.SCHEMA_PRIVILEGES 1
@@ -1314,6 +1318,11 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
VIEWS information_schema.VIEWS 1
+show global status like "Uptime_%";
+Variable_name Value
+flush status;
+show global status like "Uptime_%";
+Variable_name Value
create table t1(f1 int);
create view v1 as select f1+1 as a from t1;
create table t2 (f1 int, f2 int);
diff --git a/mysql-test/r/information_schema_db.result b/mysql-test/r/information_schema_db.result
index 67c9921e1ca..786ba5716ec 100644
--- a/mysql-test/r/information_schema_db.result
+++ b/mysql-test/r/information_schema_db.result
@@ -11,6 +11,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY
COLUMNS
COLUMN_PRIVILEGES
KEY_COLUMN_USAGE
+PROFILING
ROUTINES
SCHEMATA
SCHEMA_PRIVILEGES
diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result
index 854712fdb1d..415fbe87f53 100644
--- a/mysql-test/r/innodb.result
+++ b/mysql-test/r/innodb.result
@@ -1803,15 +1803,12 @@ Innodb_buffer_pool_pages_total 512
show status like "Innodb_page_size";
Variable_name Value
Innodb_page_size 16384
-show status like "Innodb_rows_deleted";
-Variable_name Value
-Innodb_rows_deleted 73
-show status like "Innodb_rows_inserted";
-Variable_name Value
-Innodb_rows_inserted 29734
-show status like "Innodb_rows_updated";
-Variable_name Value
-Innodb_rows_updated 29532
+innodb_rows_deleted
+73
+innodb_rows_inserted
+29734
+innodb_rows_updated
+29532
show status like "Innodb_row_lock_waits";
Variable_name Value
Innodb_row_lock_waits 0
diff --git a/mysql-test/r/insert.result b/mysql-test/r/insert.result
index 2e49bd373d6..c98ed104a69 100644
--- a/mysql-test/r/insert.result
+++ b/mysql-test/r/insert.result
@@ -595,4 +595,9 @@ SELECT * FROM t2;
c1
15449237462
DROP TABLE t1, t2;
+CREATE TABLE t1(f1 FLOAT);
+INSERT INTO t1 VALUES (1.23);
+CREATE TABLE t2(f1 CHAR(1));
+INSERT INTO t2 SELECT f1 FROM t1;
+DROP TABLE t1, t2;
End of 5.0 tests.
diff --git a/mysql-test/r/insert_update.result b/mysql-test/r/insert_update.result
index 20cde86101e..b648531b455 100644
--- a/mysql-test/r/insert_update.result
+++ b/mysql-test/r/insert_update.result
@@ -393,6 +393,7 @@ id c1 cnt
1 0 3
2 2 1
DROP TABLE t1;
+DROP TABLE t2;
create table t1(f1 int primary key,
f2 timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP);
insert into t1(f1) values(1);
diff --git a/mysql-test/r/lock_multi.result b/mysql-test/r/lock_multi.result
index d1b50a0080c..037b375fe0b 100644
--- a/mysql-test/r/lock_multi.result
+++ b/mysql-test/r/lock_multi.result
@@ -133,3 +133,58 @@ ALTER TABLE t1 ADD COLUMN a INT;
# 2.2.1. normal mode
# 2.2.2. PS mode
DROP TABLE t1;
+create table t1 (a int);
+create table t2 like t1;
+# con1
+lock tables t1 write;
+# con2
+flush tables with read lock;
+# con5
+# global read lock is taken
+# con3
+select * from t2 for update;
+# waiting for release of read lock
+# con4
+# would hang and later cause a deadlock
+flush tables t2;
+# clean up
+unlock tables;
+unlock tables;
+a
+drop table t1,t2;
+#
+# Lightweight version:
+# Ensure that the wait for a GRL is done before opening tables.
+#
+create table t1 (a int);
+create table t2 like t1;
+#
+# UPDATE
+#
+# default
+flush tables with read lock;
+# con1
+update t2 set a = 1;
+# default
+# statement is waiting for release of read lock
+# con2
+flush table t2;
+# default
+unlock tables;
+# con1
+#
+# LOCK TABLES .. WRITE
+#
+# default
+flush tables with read lock;
+# con1
+lock tables t2 write;
+# default
+# statement is waiting for release of read lock
+# con2
+flush table t2;
+# default
+unlock tables;
+# con1
+unlock tables;
+drop table t1,t2;
diff --git a/mysql-test/r/myisampack.result b/mysql-test/r/myisampack.result
index b4b200549a5..736a550e32b 100644
--- a/mysql-test/r/myisampack.result
+++ b/mysql-test/r/myisampack.result
@@ -38,3 +38,25 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
1024
DROP TABLE t1;
+#
+# Bug #43973 - backup_myisam.test fails on 6.0-bugteam
+#
+CREATE DATABASE mysql_db1;
+CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int);
+CREATE INDEX i1 ON mysql_db1.t1 (c1, c2);
+INSERT INTO mysql_db1.t1 VALUES ('A',1);
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+FLUSH TABLE mysql_db1.t1;
+# Compress the table using MYISAMPACK tool
+# Run MYISAMCHK tool on the compressed table
+SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
+COUNT(*)
+128
+DROP TABLE mysql_db1.t1;
+DROP DATABASE mysql_db1;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 1897a7df799..ce24922db28 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -3557,7 +3557,6 @@ DROP TABLE t1,t2;
-- Dump completed on DATE
-SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
#
# Bug #42635: mysqldump includes views that were excluded using
# the --ignore-table option
@@ -3693,6 +3692,7 @@ UNLOCK TABLES;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`;
SET NAMES latin1;
+SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
#
# End of 5.0 tests
#
diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result
index 2bf8a58de4e..31b4940ec53 100644
--- a/mysql-test/r/mysqlshow.result
+++ b/mysql-test/r/mysqlshow.result
@@ -85,6 +85,7 @@ Database: information_schema
| COLUMNS |
| COLUMN_PRIVILEGES |
| KEY_COLUMN_USAGE |
+| PROFILING |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
@@ -106,6 +107,7 @@ Database: INFORMATION_SCHEMA
| COLUMNS |
| COLUMN_PRIVILEGES |
| KEY_COLUMN_USAGE |
+| PROFILING |
| ROUTINES |
| SCHEMATA |
| SCHEMA_PRIVILEGES |
diff --git a/mysql-test/r/not_embedded_server.result b/mysql-test/r/not_embedded_server.result
index edb698ade83..69175ca446f 100644
--- a/mysql-test/r/not_embedded_server.result
+++ b/mysql-test/r/not_embedded_server.result
@@ -4,9 +4,4 @@ Id User Host db Command Time State Info
number root localhost test Query time NULL show full processlist
deallocate prepare stmt1;
FLUSH STATUS;
-SHOW GLOBAL STATUS LIKE 'com_select';
-Variable_name Value
-Com_select 101
-SHOW GLOBAL STATUS LIKE 'com_select';
-Variable_name Value
-Com_select 101
+Value of com_select did not change
diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result
new file mode 100644
index 00000000000..a9ada576b4b
--- /dev/null
+++ b/mysql-test/r/profiling.result
@@ -0,0 +1,415 @@
+show profiles;
+Query_ID Duration Query
+show profile all;
+Status Duration CPU_user CPU_system Context_voluntary Context_involuntary Block_ops_in Block_ops_out Messages_sent Messages_received Page_faults_major Page_faults_minor Swaps Source_function Source_file Source_line
+show session variables like 'profil%';
+Variable_name Value
+profiling OFF
+profiling_history_size 15
+select @@profiling;
+@@profiling
+0
+set global profiling = ON;
+ERROR HY000: Variable 'profiling' is a SESSION variable and can't be used with SET GLOBAL
+set global profiling_history_size=100;
+show global variables like 'profil%';
+Variable_name Value
+profiling OFF
+profiling_history_size 100
+set session profiling = ON;
+set session profiling_history_size=30;
+show session variables like 'profil%';
+Variable_name Value
+profiling ON
+profiling_history_size 30
+select @@profiling;
+@@profiling
+1
+create table t1 (
+a int,
+b int
+);
+insert into t1 values (1,1), (2,null), (3, 4);
+insert into t1 values (5,1), (6,null), (7, 4);
+insert into t1 values (1,1), (2,null), (3, 4);
+insert into t1 values (5,1), (6,null), (7, 4);
+select max(x) from (select sum(a) as x from t1 group by b) as teeone;
+max(x)
+20
+insert into t1 select * from t1;
+select count(*) from t1;
+count(*)
+24
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+count(*)
+192
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+count(*)
+1536
+select sum(a) from t1;
+sum(a)
+6144
+select sum(a) from t1 group by b;
+sum(a)
+2048
+1536
+2560
+select sum(a) + sum(b) from t1 group by b;
+sum(a) + sum(b)
+NULL
+2048
+4608
+select max(x) from (select sum(a) as x from t1 group by b) as teeone;
+max(x)
+2560
+select '012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890' as big_string;
+big_string
+012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
+show profiles;
+Query_ID Duration Query
+1 # set session profiling_history_size=30
+2 # show session variables like 'profil%'
+3 # select @@profiling
+4 # create table t1 (
+a int,
+b int
+)
+5 # insert into t1 values (1,1), (2,null), (3, 4)
+6 # insert into t1 values (5,1), (6,null), (7, 4)
+7 # insert into t1 values (1,1), (2,null), (3, 4)
+8 # insert into t1 values (5,1), (6,null), (7, 4)
+9 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+10 # insert into t1 select * from t1
+11 # select count(*) from t1
+12 # insert into t1 select * from t1
+13 # insert into t1 select * from t1
+14 # insert into t1 select * from t1
+15 # select count(*) from t1
+16 # insert into t1 select * from t1
+17 # insert into t1 select * from t1
+18 # insert into t1 select * from t1
+19 # select count(*) from t1
+20 # select sum(a) from t1
+21 # select sum(a) from t1 group by b
+22 # select sum(a) + sum(b) from t1 group by b
+23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
+show profile for query 15;
+show profile cpu for query 15;
+show profile cpu, block io for query 15;
+show profile cpu for query 9 limit 2 offset 2;
+show profile cpu for query 10 limit 0;
+show profile cpu for query 65534;
+show profile memory;
+show profile block io;
+show profile context switches;
+show profile page faults;
+show profile ipc;
+show profile swaps limit 1 offset 2;
+show profile source;
+show profile all for query 0 limit 0;
+show profile all for query 15;
+select * from information_schema.profiling;
+select query_id, state, duration from information_schema.profiling;
+select query_id, sum(duration) from information_schema.profiling group by query_id;
+select query_id, count(*) from information_schema.profiling group by query_id;
+select sum(duration) from information_schema.profiling;
+select query_id, count(*), sum(duration) from information_schema.profiling group by query_id;
+select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling;
+drop table if exists t1, t2, t3;
+Warnings:
+Note 1051 Unknown table 't2'
+Note 1051 Unknown table 't3'
+create table t1 (id int );
+create table t2 (id int not null);
+create table t3 (id int not null primary key);
+insert into t1 values (1), (2), (3);
+insert into t2 values (1), (2), (3);
+insert into t3 values (1), (2), (3);
+show profiles;
+Query_ID Duration Query
+10 # insert into t1 select * from t1
+11 # select count(*) from t1
+12 # insert into t1 select * from t1
+13 # insert into t1 select * from t1
+14 # insert into t1 select * from t1
+15 # select count(*) from t1
+16 # insert into t1 select * from t1
+17 # insert into t1 select * from t1
+18 # insert into t1 select * from t1
+19 # select count(*) from t1
+20 # select sum(a) from t1
+21 # select sum(a) from t1 group by b
+22 # select sum(a) + sum(b) from t1 group by b
+23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
+25 # select * from information_schema.profiling
+26 # select query_id, state, duration from information_schema.profiling
+27 # select query_id, sum(duration) from information_schema.profiling group by query_id
+28 # select query_id, count(*) from information_schema.profiling group by query_id
+29 # select sum(duration) from information_schema.profiling
+30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
+31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
+32 # drop table if exists t1, t2, t3
+33 # SHOW WARNINGS
+34 # create table t1 (id int )
+35 # create table t2 (id int not null)
+36 # create table t3 (id int not null primary key)
+37 # insert into t1 values (1), (2), (3)
+38 # insert into t2 values (1), (2), (3)
+39 # insert into t3 values (1), (2), (3)
+select * from t1;
+id
+1
+2
+3
+show profiles;
+Query_ID Duration Query
+11 # select count(*) from t1
+12 # insert into t1 select * from t1
+13 # insert into t1 select * from t1
+14 # insert into t1 select * from t1
+15 # select count(*) from t1
+16 # insert into t1 select * from t1
+17 # insert into t1 select * from t1
+18 # insert into t1 select * from t1
+19 # select count(*) from t1
+20 # select sum(a) from t1
+21 # select sum(a) from t1 group by b
+22 # select sum(a) + sum(b) from t1 group by b
+23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
+25 # select * from information_schema.profiling
+26 # select query_id, state, duration from information_schema.profiling
+27 # select query_id, sum(duration) from information_schema.profiling group by query_id
+28 # select query_id, count(*) from information_schema.profiling group by query_id
+29 # select sum(duration) from information_schema.profiling
+30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
+31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
+32 # drop table if exists t1, t2, t3
+33 # SHOW WARNINGS
+34 # create table t1 (id int )
+35 # create table t2 (id int not null)
+36 # create table t3 (id int not null primary key)
+37 # insert into t1 values (1), (2), (3)
+38 # insert into t2 values (1), (2), (3)
+39 # insert into t3 values (1), (2), (3)
+40 # select * from t1
+This ^^ should end in "select * from t1;"
+delete from t1;
+insert into t1 values (1), (2), (3);
+insert into t1 values (1), (2), (3);
+select * from t1;
+id
+1
+2
+3
+1
+2
+3
+show profiles;
+Query_ID Duration Query
+15 # select count(*) from t1
+16 # insert into t1 select * from t1
+17 # insert into t1 select * from t1
+18 # insert into t1 select * from t1
+19 # select count(*) from t1
+20 # select sum(a) from t1
+21 # select sum(a) from t1 group by b
+22 # select sum(a) + sum(b) from t1 group by b
+23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
+25 # select * from information_schema.profiling
+26 # select query_id, state, duration from information_schema.profiling
+27 # select query_id, sum(duration) from information_schema.profiling group by query_id
+28 # select query_id, count(*) from information_schema.profiling group by query_id
+29 # select sum(duration) from information_schema.profiling
+30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
+31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
+32 # drop table if exists t1, t2, t3
+33 # SHOW WARNINGS
+34 # create table t1 (id int )
+35 # create table t2 (id int not null)
+36 # create table t3 (id int not null primary key)
+37 # insert into t1 values (1), (2), (3)
+38 # insert into t2 values (1), (2), (3)
+39 # insert into t3 values (1), (2), (3)
+40 # select * from t1
+41 # delete from t1
+42 # insert into t1 values (1), (2), (3)
+43 # insert into t1 values (1), (2), (3)
+44 # select * from t1
+set session profiling = OFF;
+select sum(id) from t1;
+sum(id)
+12
+show profiles;
+Query_ID Duration Query
+15 # select count(*) from t1
+16 # insert into t1 select * from t1
+17 # insert into t1 select * from t1
+18 # insert into t1 select * from t1
+19 # select count(*) from t1
+20 # select sum(a) from t1
+21 # select sum(a) from t1 group by b
+22 # select sum(a) + sum(b) from t1 group by b
+23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
+24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
+25 # select * from information_schema.profiling
+26 # select query_id, state, duration from information_schema.profiling
+27 # select query_id, sum(duration) from information_schema.profiling group by query_id
+28 # select query_id, count(*) from information_schema.profiling group by query_id
+29 # select sum(duration) from information_schema.profiling
+30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
+31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
+32 # drop table if exists t1, t2, t3
+33 # SHOW WARNINGS
+34 # create table t1 (id int )
+35 # create table t2 (id int not null)
+36 # create table t3 (id int not null primary key)
+37 # insert into t1 values (1), (2), (3)
+38 # insert into t2 values (1), (2), (3)
+39 # insert into t3 values (1), (2), (3)
+40 # select * from t1
+41 # delete from t1
+42 # insert into t1 values (1), (2), (3)
+43 # insert into t1 values (1), (2), (3)
+44 # select * from t1
+set session profiling = ON;
+select @@profiling;
+@@profiling
+1
+create function f1() returns varchar(50) return 'hello';
+select @@profiling;
+@@profiling
+1
+select * from t1 where id <> f1();
+id
+1
+2
+3
+1
+2
+3
+select @@profiling;
+@@profiling
+1
+set session profiling = OFF;
+drop table if exists profile_log;
+Warnings:
+Note 1051 Unknown table 'profile_log'
+create table profile_log (how_many int);
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+create procedure p1 ()
+modifies sql data
+begin
+set profiling = ON;
+select 'This p1 should show up in profiling';
+insert into profile_log select count(*) from information_schema.profiling;
+end//
+create procedure p2()
+deterministic
+begin
+set profiling = ON;
+call p1();
+select 'This p2 should show up in profiling';
+end//
+create procedure p3 ()
+reads sql data
+begin
+set profiling = ON;
+select 'This p3 should show up in profiling';
+show profile;
+end//
+first call to p1
+call p1;
+select * from profile_log;
+second call to p1
+call p1;
+select * from profile_log;
+third call to p1
+call p1;
+select * from profile_log;
+set session profiling = OFF;
+call p2;
+set session profiling = OFF;
+call p3;
+show profiles;
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop table if exists profile_log;
+set session profiling = ON;
+drop table if exists t2;
+create table t2 (id int not null);
+create trigger t2_bi before insert on t2 for each row set @x=0;
+select @@profiling;
+@@profiling
+1
+insert into t2 values (1), (2), (3);
+select @@profiling;
+@@profiling
+1
+set session profiling = ON;
+drop table if exists t1, t2;
+create table t1 (id int not null primary key);
+create table t2 (id int not null primary key, id1 int not null);
+select @@profiling;
+@@profiling
+1
+alter table t2 add foreign key (id1) references t1 (id) on delete cascade;
+select @@profiling;
+@@profiling
+1
+lock table t1 write;
+select @@profiling;
+@@profiling
+1
+unlock table;
+select @@profiling;
+@@profiling
+1
+set autocommit=0;
+select @@profiling, @@autocommit;
+@@profiling @@autocommit
+1 0
+begin;
+select @@profiling;
+@@profiling
+1
+insert into t1 values (1);
+insert into t2 values (1,1);
+testing referential integrity cascade
+delete from t1 where id = 1;
+select @@profiling;
+@@profiling
+1
+testing rollback
+rollback;
+select @@profiling;
+@@profiling
+1
+testing commit
+begin;
+select @@profiling;
+@@profiling
+1
+commit;
+select @@profiling;
+@@profiling
+1
+drop table if exists t1, t2, t3;
+drop view if exists v1;
+Warnings:
+Note 1051 Unknown table 'test.v1'
+drop function if exists f1;
+set session profiling = OFF;
+End of 5.0 tests
diff --git a/mysql-test/r/rpl_bug38694.result b/mysql-test/r/rpl_bug38694.result
new file mode 100644
index 00000000000..711c4a91c03
--- /dev/null
+++ b/mysql-test/r/rpl_bug38694.result
@@ -0,0 +1,6 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
diff --git a/mysql-test/r/rpl_drop_if_exists.result b/mysql-test/r/rpl_drop_if_exists.result
new file mode 100644
index 00000000000..f711a873122
--- /dev/null
+++ b/mysql-test/r/rpl_drop_if_exists.result
@@ -0,0 +1,80 @@
+RESET MASTER;
+DROP PROCEDURE IF EXISTS db_bug_13684.p;
+DROP FUNCTION IF EXISTS db_bug_13684.f;
+DROP TRIGGER IF EXISTS db_bug_13684.tr;
+DROP VIEW IF EXISTS db_bug_13684.v;
+DROP TABLE IF EXISTS db_bug_13684.t;
+DROP DATABASE IF EXISTS db_bug_13684;
+show binlog events from ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
+master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
+master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
+master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
+master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
+CREATE DATABASE db_bug_13684;
+CREATE TABLE db_bug_13684.t (a int);
+CREATE VIEW db_bug_13684.v
+AS SELECT * FROM db_bug_13684.t;
+CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
+FOR EACH ROW BEGIN
+END;
+CREATE PROCEDURE db_bug_13684.p (OUT p1 INT)
+BEGIN
+END;
+CREATE FUNCTION db_bug_13684.f (s CHAR(20))
+RETURNS CHAR(50) DETERMINISTIC
+RETURN s;
+show binlog events from ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
+master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
+master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
+master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
+master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
+master-bin.000001 # Query # # CREATE DATABASE db_bug_13684
+master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int)
+master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS select `db_bug_13684`.`t`.`a` AS `a` from `db_bug_13684`.`t`
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
+FOR EACH ROW BEGIN
+END
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT)
+BEGIN
+END
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1
+ DETERMINISTIC
+RETURN s
+DROP PROCEDURE IF EXISTS db_bug_13684.p;
+DROP FUNCTION IF EXISTS db_bug_13684.f;
+DROP TRIGGER IF EXISTS db_bug_13684.tr;
+DROP VIEW IF EXISTS db_bug_13684.v;
+DROP TABLE IF EXISTS db_bug_13684.t;
+DROP DATABASE IF EXISTS db_bug_13684;
+show binlog events from ;
+Log_name Pos Event_type Server_id End_log_pos Info
+master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
+master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
+master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
+master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
+master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
+master-bin.000001 # Query # # CREATE DATABASE db_bug_13684
+master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int)
+master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS select `db_bug_13684`.`t`.`a` AS `a` from `db_bug_13684`.`t`
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
+FOR EACH ROW BEGIN
+END
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT)
+BEGIN
+END
+master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1
+ DETERMINISTIC
+RETURN s
+master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
+master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
+master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
+master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
+master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
+master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
diff --git a/mysql-test/r/rpl_killed_ddl.result b/mysql-test/r/rpl_killed_ddl.result
new file mode 100644
index 00000000000..aa419a8556e
--- /dev/null
+++ b/mysql-test/r/rpl_killed_ddl.result
@@ -0,0 +1,146 @@
+stop slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+reset master;
+reset slave;
+drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
+start slave;
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+DROP DATABASE IF EXISTS d4;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+DROP TABLE IF EXISTS t4;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP TRIGGER IF EXISTS tr3;
+DROP TRIGGER IF EXISTS tr4;
+CREATE DATABASE d1;
+CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC
+RETURN 1;
+CREATE PROCEDURE p1 (OUT rows INT)
+BEGIN
+SELECT COUNT(*) INTO rows FROM t1;
+END;
+//
+CREATE TABLE t1 (a int);
+CREATE TABLE t3 (a int);
+CREATE TRIGGER tr1 BEFORE INSERT ON t1
+FOR EACH ROW BEGIN
+DELETE FROM t4 WHERE a=NEW.a;
+END;
+//
+CREATE INDEX i1 ON t1 (a);
+CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100;
+[on master]
+[on master1]
+CREATE DATABASE d2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+ALTER DATABASE d1
+DEFAULT CHARACTER SET = 'utf8';
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP DATABASE d1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP DATABASE d2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC
+RETURN 1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+ALTER FUNCTION f1 SQL SECURITY INVOKER;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP FUNCTION IF EXISTS f1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP FUNCTION IF EXISTS f2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE PROCEDURE p2 (OUT rows INT)
+BEGIN
+SELECT COUNT(*) INTO rows FROM t2;
+END;
+//
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1';
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP PROCEDURE IF EXISTS p1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP PROCEDURE IF EXISTS p2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE TABLE t2 (b int);
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+ALTER TABLE t1 ADD (d int);
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+RENAME TABLE t3 TO t4;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE INDEX i2 on t1 (a);
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP INDEX i1 on t1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE TRIGGER tr2 BEFORE INSERT ON t4
+FOR EACH ROW BEGIN
+DELETE FROM t1 WHERE a=NEW.a;
+END;
+//
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP TRIGGER tr1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP TRIGGER IF EXISTS tr2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP VIEW v1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP VIEW IF EXISTS v2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP TABLE t1;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP TABLE IF EXISTS t2;
+source include/kill_query.inc;
+source include/diff_master_slave.inc;
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+DROP DATABASE IF EXISTS d4;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+DROP TABLE IF EXISTS t4;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result
index ebe5f8b0be9..0f4d0fa8dad 100644
--- a/mysql-test/r/rpl_sp.result
+++ b/mysql-test/r/rpl_sp.result
@@ -483,6 +483,7 @@ master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # drop database mysqltest1
master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1
+master-bin.000001 # Query 1 # use `test`; drop function if exists f1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
READS SQL DATA
begin
@@ -498,12 +499,15 @@ master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
master-bin.000001 # Query 1 # use `test`; insert into t1 (a) values (f1())
master-bin.000001 # Query 1 # use `test`; drop view v1
master-bin.000001 # Query 1 # use `test`; drop function f1
+master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1
master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(col VARCHAR(10))
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10))
INSERT INTO t1 VALUES(arg)
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1
+master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1
+master-bin.000001 # Query 1 # use `test`; DROP FUNCTION IF EXISTS f1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SET @a = 1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
@@ -804,6 +808,9 @@ drop user "zedjzlcsjhd"@127.0.0.1
/*!*/;
use test/*!*/;
SET TIMESTAMP=t/*!*/;
+drop function if exists f1
+/*!*/;
+SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
READS SQL DATA
begin
@@ -831,6 +838,9 @@ SET TIMESTAMP=t/*!*/;
drop function f1
/*!*/;
SET TIMESTAMP=t/*!*/;
+DROP PROCEDURE IF EXISTS p1
+/*!*/;
+SET TIMESTAMP=t/*!*/;
DROP TABLE IF EXISTS t1
/*!*/;
SET TIMESTAMP=t/*!*/;
@@ -847,6 +857,12 @@ SET TIMESTAMP=t/*!*/;
DROP PROCEDURE p1
/*!*/;
SET TIMESTAMP=t/*!*/;
+DROP PROCEDURE IF EXISTS p1
+/*!*/;
+SET TIMESTAMP=t/*!*/;
+DROP FUNCTION IF EXISTS f1
+/*!*/;
+SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SET @a = 1
/*!*/;
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index 9558b0533ad..c9dd65108da 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4388,4 +4388,17 @@ f3 f4 count
1 abc 1
1 def 2
drop table t1, t2, t3;
+CREATE TABLE t1 (a INT KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`b` = `test`.`t1`.`a`) and (`test`.`t1`.`a` > 1)) limit 2
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 3 Using where
+Warnings:
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b` from `test`.`t1` where ((`test`.`t1`.`a` = `test`.`t1`.`b`) and (`test`.`t1`.`a` > 1)) limit 2
+DROP TABLE t1;
End of 5.0 tests
diff --git a/mysql-test/r/sp_trans_log.result b/mysql-test/r/sp_trans_log.result
index eb0770cb0a1..cce5a28fa2e 100644
--- a/mysql-test/r/sp_trans_log.result
+++ b/mysql-test/r/sp_trans_log.result
@@ -1,3 +1,5 @@
+drop function if exists bug23333|
+drop table if exists t1,t2|
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
insert into t2 values (1,1)|
@@ -20,4 +22,5 @@ master-bin.000001 # Query 1 # #
select count(*),@a from t1 /* must be 1,1 */|
count(*) @a
1 1
-drop table t1, t2|
+drop table t1,t2;
+drop function if exists bug23333;
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index 0c7f9ae959c..671e5d8f532 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -4407,7 +4407,7 @@ pk a
3 30
2 20
DROP TABLE t1,t2;
-CREATE TABLE t1 (s1 CHAR(1));
+CREATE TABLE t1 (s1 char(1));
INSERT INTO t1 VALUES ('a');
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
s1
diff --git a/mysql-test/r/varbinary.result b/mysql-test/r/varbinary.result
index f584c22f98a..01af6979ca3 100644
--- a/mysql-test/r/varbinary.result
+++ b/mysql-test/r/varbinary.result
@@ -78,6 +78,7 @@ alter table t1 modify a varchar(255);
select length(a) from t1;
length(a)
6
+drop table t1;
select 0b01000001;
0b01000001
A
diff --git a/mysql-test/suite/funcs_2/charset/charset_master.test b/mysql-test/suite/funcs_2/charset/charset_master.test
index 09e24e2c246..99ca4564a0b 100644
--- a/mysql-test/suite/funcs_2/charset/charset_master.test
+++ b/mysql-test/suite/funcs_2/charset/charset_master.test
@@ -86,6 +86,15 @@ let $check_std_csets= 1;
let $check_ucs2_csets= 1;
let $check_utf8_csets= 1;
+# Bug#32784: Timeout in test "innodb_charset": InnoDB much slower
+# than other handlers
+# NOTE: We turn autocommit off to improve the performance of the innodb variant
+# of this test. Per Innobase's recommendation.
+
+--disable_query_log
+SET autocommit=0;
+--enable_query_log
+
#
# Check all charsets/collation combinations
#
diff --git a/mysql-test/t/count_distinct3.test b/mysql-test/t/count_distinct3.test
index f817b2c635d..2f7cf7e5260 100644
--- a/mysql-test/t/count_distinct3.test
+++ b/mysql-test/t/count_distinct3.test
@@ -1,4 +1,4 @@
-#
+# Bug #958 a big table without indices and select with group by doesnt work
# this is a test for error 1032 in count(distinct) + group by, introduced in
# mysql-4.1
#
@@ -21,27 +21,16 @@ while ($1)
INSERT INTO t1 (id, grp, id_rev) VALUES (@id, @grp, @id_rev);
dec $1;
}
-set @@read_buffer_size=2*1024*1024;
-CREATE TABLE t2 SELECT * FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-INSERT INTO t1 (id, grp, id_rev) SELECT id, grp, id_rev FROM t2;
-INSERT INTO t2 (id, grp, id_rev) SELECT id, grp, id_rev FROM t1;
-DROP TABLE t2;
+
+# We increase the size of t1 here.
+SET @orig_myisam_sort_buffer_size = @@session.myisam_sort_buffer_size;
+SET session myisam_sort_buffer_size=20000000;
+INSERT INTO t1
+SELECT A.id, A.grp, A.id_rev
+FROM
+ t1 A,
+ (SELECT * FROM t1 B LIMIT 100) B,
+ (SELECT * FROM t1 Z LIMIT 42) Z;
--enable_query_log
SELECT COUNT(*) FROM t1;
@@ -49,12 +38,12 @@ SELECT COUNT(*) FROM t1;
# As t1 contains random numbers, results are different from test to test.
# That's okay, because we test only that select doesn't yield an
# error. Note, that --disable_result_log doesn't suppress error output.
-
--disable_result_log
SELECT COUNT(DISTINCT id) FROM t1 GROUP BY grp;
--enable_result_log
+
+--echo # Begin cleanup
+SET session myisam_sort_buffer_size = @orig_myisam_sort_buffer_size;
DROP TABLE t1;
-set @@read_buffer_size=default;
-
# End of 4.1 tests
diff --git a/mysql-test/t/func_des_encrypt.test b/mysql-test/t/func_des_encrypt.test
index b757a632adf..2c364a40090 100644
--- a/mysql-test/t/func_des_encrypt.test
+++ b/mysql-test/t/func_des_encrypt.test
@@ -9,3 +9,31 @@
select des_encrypt('hello');
# End of 4.1 tests
+
+--echo #
+--echo # Bug #11643: des_encrypt() causes server to die
+--echo #
+
+CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM;
+
+INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567');
+
+UPDATE t1 SET des=DES_ENCRYPT('1234');
+
+SELECT LENGTH(des) FROM t1;
+SELECT DES_DECRYPT(des) FROM t1;
+
+SELECT
+ LENGTH(DES_ENCRYPT('1234')),
+ LENGTH(DES_ENCRYPT('12345')),
+ LENGTH(DES_ENCRYPT('123456')),
+ LENGTH(DES_ENCRYPT('1234567'));
+SELECT
+ DES_DECRYPT(DES_ENCRYPT('1234')),
+ DES_DECRYPT(DES_ENCRYPT('12345')),
+ DES_DECRYPT(DES_ENCRYPT('123456')),
+ DES_DECRYPT(DES_ENCRYPT('1234567'));
+
+DROP TABLE t1;
+
+--Echo End of 5.0 tests
diff --git a/mysql-test/t/gis-rtree.test b/mysql-test/t/gis-rtree.test
index e68e5039adf..2c1632f8d40 100644
--- a/mysql-test/t/gis-rtree.test
+++ b/mysql-test/t/gis-rtree.test
@@ -41,7 +41,7 @@ while ($1)
let $2=10;
while ($2)
{
- eval INSERT INTO t2 (g) VALUES (GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))));
+ eval INSERT INTO t2 (g) VALUES (LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)));
dec $2;
}
dec $1;
@@ -61,7 +61,7 @@ while ($1)
let $2=10;
while ($2)
{
- eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(LineString(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10)))));
+ eval DELETE FROM t2 WHERE Within(g, Envelope(GeometryFromWKB(Point($1 * 10 - 9, $2 * 10 - 9), Point($1 * 10, $2 * 10))));
SELECT count(*) FROM t2;
dec $2;
}
@@ -235,11 +235,11 @@ DROP TABLE t1;
# Bug #21888: Query on GEOMETRY field using PointFromWKB() results in lost connection
#
CREATE TABLE t1 (foo GEOMETRY NOT NULL, SPATIAL INDEX(foo) );
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,1)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(1,0)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,1)));
-INSERT INTO t1 (foo) VALUES (PointFromWKB(POINT(0,0)));
-SELECT 1 FROM t1 WHERE foo != PointFromWKB(POINT(0,0));
+INSERT INTO t1 (foo) VALUES (POINT(1,1));
+INSERT INTO t1 (foo) VALUES (POINT(1,0));
+INSERT INTO t1 (foo) VALUES (POINT(0,1));
+INSERT INTO t1 (foo) VALUES (POINT(0,0));
+SELECT 1 FROM t1 WHERE foo != POINT(0,0);
DROP TABLE t1;
#
@@ -802,35 +802,35 @@ DROP TABLE t1;
#
create table t1 (a geometry not null, spatial index(a));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 131072)));
-insert into t1 values (PointFromWKB(POINT(9.1248812352444e+192, 2.9740338169556e+284)));
-insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, -0)));
-insert into t1 values (PointFromWKB(POINT(1.49166814624e-154, 2.0880974297595e-53)));
-insert into t1 values (PointFromWKB(POINT(4.0917382598702e+149, 1.2024538023802e+111)));
-insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 2.9993936277913e-241)));
-insert into t1 values (PointFromWKB(POINT(2.5243548967072e-29, 1.2024538023802e+111)));
-insert into t1 values (PointFromWKB(POINT(0, 6.9835074892995e-251)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 3.1050361846014e+231)));
-insert into t1 values (PointFromWKB(POINT(2.8728483499323e-188, 2.4600631144627e+260)));
-insert into t1 values (PointFromWKB(POINT(3.0517578125e-05, 2.0349165139404e+236)));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 1.1818212630766e-125)));
-insert into t1 values (PointFromWKB(POINT(2.481040258324e-265, 5.7766220027675e-275)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 2.5243548967072e-29)));
-insert into t1 values (PointFromWKB(POINT(5.7766220027675e-275, 9.9464647281957e+86)));
-insert into t1 values (PointFromWKB(POINT(2.2181357552967e+130, 3.7857669957337e-270)));
-insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.6893488147419e+19)));
-insert into t1 values (PointFromWKB(POINT(4.5767114681874e-246, 3.7537584144024e+255)));
-insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 1.8033161362863e-130)));
-insert into t1 values (PointFromWKB(POINT(0, 5.8774717541114e-39)));
-insert into t1 values (PointFromWKB(POINT(1.1517219314031e+164, 2.2761049594727e-159)));
-insert into t1 values (PointFromWKB(POINT(6.243497100632e+144, 3.7857669957337e-270)));
-insert into t1 values (PointFromWKB(POINT(3.7857669957337e-270, 2.6355494858076e-82)));
-insert into t1 values (PointFromWKB(POINT(2.0349165139404e+236, 3.8518598887745e-34)));
-insert into t1 values (PointFromWKB(POINT(4.6566128730774e-10, 2.0880974297595e-53)));
-insert into t1 values (PointFromWKB(POINT(2.0880974297595e-53, 1.8827498946116e-183)));
-insert into t1 values (PointFromWKB(POINT(1.8033161362863e-130, 9.1248812352444e+192)));
-insert into t1 values (PointFromWKB(POINT(4.7783097267365e-299, 2.2761049594727e-159)));
-insert into t1 values (PointFromWKB(POINT(1.94906280228e+289, 1.2338789709327e-178)));
+insert into t1 values (POINT(1.1517219314031e+164, 131072));
+insert into t1 values (POINT(9.1248812352444e+192, 2.9740338169556e+284));
+insert into t1 values (POINT(4.7783097267365e-299, -0));
+insert into t1 values (POINT(1.49166814624e-154, 2.0880974297595e-53));
+insert into t1 values (POINT(4.0917382598702e+149, 1.2024538023802e+111));
+insert into t1 values (POINT(2.0349165139404e+236, 2.9993936277913e-241));
+insert into t1 values (POINT(2.5243548967072e-29, 1.2024538023802e+111));
+insert into t1 values (POINT(0, 6.9835074892995e-251));
+insert into t1 values (POINT(2.0880974297595e-53, 3.1050361846014e+231));
+insert into t1 values (POINT(2.8728483499323e-188, 2.4600631144627e+260));
+insert into t1 values (POINT(3.0517578125e-05, 2.0349165139404e+236));
+insert into t1 values (POINT(1.1517219314031e+164, 1.1818212630766e-125));
+insert into t1 values (POINT(2.481040258324e-265, 5.7766220027675e-275));
+insert into t1 values (POINT(2.0880974297595e-53, 2.5243548967072e-29));
+insert into t1 values (POINT(5.7766220027675e-275, 9.9464647281957e+86));
+insert into t1 values (POINT(2.2181357552967e+130, 3.7857669957337e-270));
+insert into t1 values (POINT(4.5767114681874e-246, 3.6893488147419e+19));
+insert into t1 values (POINT(4.5767114681874e-246, 3.7537584144024e+255));
+insert into t1 values (POINT(3.7857669957337e-270, 1.8033161362863e-130));
+insert into t1 values (POINT(0, 5.8774717541114e-39));
+insert into t1 values (POINT(1.1517219314031e+164, 2.2761049594727e-159));
+insert into t1 values (POINT(6.243497100632e+144, 3.7857669957337e-270));
+insert into t1 values (POINT(3.7857669957337e-270, 2.6355494858076e-82));
+insert into t1 values (POINT(2.0349165139404e+236, 3.8518598887745e-34));
+insert into t1 values (POINT(4.6566128730774e-10, 2.0880974297595e-53));
+insert into t1 values (POINT(2.0880974297595e-53, 1.8827498946116e-183));
+insert into t1 values (POINT(1.8033161362863e-130, 9.1248812352444e+192));
+insert into t1 values (POINT(4.7783097267365e-299, 2.2761049594727e-159));
+insert into t1 values (POINT(1.94906280228e+289, 1.2338789709327e-178));
drop table t1;
# End of 4.1 tests
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index cc2ac5b7392..c01fa205349 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -36,32 +36,32 @@ INSERT INTO gis_point VALUES
INSERT INTO gis_line VALUES
(105, LineFromText('LINESTRING(0 0,0 10,10 0)')),
(106, LineStringFromText('LINESTRING(10 10,20 10,20 20,10 20,10 10)')),
-(107, LineStringFromWKB(LineString(Point(10, 10), Point(40, 10))));
+(107, LineStringFromWKB(AsWKB(LineString(Point(10, 10), Point(40, 10)))));
INSERT INTO gis_polygon VALUES
(108, PolygonFromText('POLYGON((10 10,20 10,20 20,10 20,10 10))')),
(109, PolyFromText('POLYGON((0 0,50 0,50 50,0 50,0 0), (10 10,20 10,20 20,10 20,10 10))')),
-(110, PolyFromWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0)))));
+(110, PolyFromWKB(AsWKB(Polygon(LineString(Point(0, 0), Point(30, 0), Point(30, 30), Point(0, 0))))));
INSERT INTO gis_multi_point VALUES
(111, MultiPointFromText('MULTIPOINT(0 0,10 10,10 20,20 20)')),
(112, MPointFromText('MULTIPOINT(1 1,11 11,11 21,21 21)')),
-(113, MPointFromWKB(MultiPoint(Point(3, 6), Point(4, 10))));
+(113, MPointFromWKB(AsWKB(MultiPoint(Point(3, 6), Point(4, 10)))));
INSERT INTO gis_multi_line VALUES
(114, MultiLineStringFromText('MULTILINESTRING((10 48,10 21,10 0),(16 0,16 23,16 48))')),
(115, MLineFromText('MULTILINESTRING((10 48,10 21,10 0))')),
-(116, MLineFromWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7)))));
+(116, MLineFromWKB(AsWKB(MultiLineString(LineString(Point(1, 2), Point(3, 5)), LineString(Point(2, 5), Point(5, 8), Point(21, 7))))));
INSERT INTO gis_multi_polygon VALUES
(117, MultiPolygonFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
(118, MPolyFromText('MULTIPOLYGON(((28 26,28 0,84 0,84 42,28 26),(52 18,66 23,73 9,48 6,52 18)),((59 18,67 18,67 13,59 13,59 18)))')),
-(119, MPolyFromWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3))))));
+(119, MPolyFromWKB(AsWKB(MultiPolygon(Polygon(LineString(Point(0, 3), Point(3, 3), Point(3, 0), Point(0, 3)))))));
INSERT INTO gis_geometrycollection VALUES
(120, GeomCollFromText('GEOMETRYCOLLECTION(POINT(0 0), LINESTRING(0 0,10 10))')),
-(121, GeometryFromWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9)))));
+(121, GeometryFromWKB(AsWKB(GeometryCollection(Point(44, 6), LineString(Point(3, 6), Point(7, 9))))));
INSERT into gis_geometry SELECT * FROM gis_point;
INSERT into gis_geometry SELECT * FROM gis_line;
diff --git a/mysql-test/t/handler.test b/mysql-test/t/handler.test
index 6ef216f6ed2..70d4157a272 100644
--- a/mysql-test/t/handler.test
+++ b/mysql-test/t/handler.test
@@ -460,3 +460,11 @@ handler t1_alias read a next;
handler t1_alias READ a next where inexistent > 0;
handler t1_alias close;
drop table t1;
+
+#
+# Bug#44151 using handler commands on information_schema tables crashes server
+#
+USE information_schema;
+--error ER_WRONG_USAGE
+HANDLER COLUMNS OPEN;
+USE test;
diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test
index 079f96777bf..95c816afae6 100644
--- a/mysql-test/t/information_schema.test
+++ b/mysql-test/t/information_schema.test
@@ -1028,6 +1028,14 @@ where t.table_schema = 'information_schema' and
(c2.column_type = 'varchar(7)' or c2.column_type = 'varchar(20)')
group by c2.column_type order by num limit 1)
group by t.table_name order by num1, t.table_name;
+# Bug#24822: Patch: uptime_since_flush_status
+#
+--replace_column 2 #
+show global status like "Uptime_%";
+flush status;
+--replace_column 2 #
+show global status like "Uptime_%"; # Almost certainly zero
+
#
# Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong
diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test
index d045bad39f7..f09901d1112 100644
--- a/mysql-test/t/innodb.test
+++ b/mysql-test/t/innodb.test
@@ -13,6 +13,18 @@
-- source include/have_innodb.inc
+# Save the original values of some variables in order to be able to
+# estimate how much they have changed during the tests. Previously this
+# test assumed that e.g. rows_deleted is 0 here and after deleting 23
+# rows it expected that rows_deleted will be 23. Now we do not make
+# assumptions about the values of the variables at the beginning, e.g.
+# rows_deleted should be 23 + "rows_deleted before the test". This allows
+# the test to be run multiple times without restarting the mysqld server.
+# See Bug#43309 Test main.innodb can't be run twice
+-- let $innodb_rows_deleted_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_deleted', Value, 1)
+-- let $innodb_rows_inserted_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_inserted', Value, 1)
+-- let $innodb_rows_updated_orig = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_updated', Value, 1)
+
#
# Small basic test with ignore
#
@@ -1344,9 +1356,14 @@ drop table t1;
# uses previous ones(pages_created, rows_deleted, ...).
show status like "Innodb_buffer_pool_pages_total";
show status like "Innodb_page_size";
-show status like "Innodb_rows_deleted";
-show status like "Innodb_rows_inserted";
-show status like "Innodb_rows_updated";
+-- let $innodb_rows_deleted = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_deleted', Value, 1)
+-- let $innodb_rows_inserted = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_inserted', Value, 1)
+-- let $innodb_rows_updated = query_get_value(SHOW STATUS WHERE variable_name = 'innodb_rows_updated', Value, 1)
+-- disable_query_log
+-- eval SELECT $innodb_rows_deleted - $innodb_rows_deleted_orig AS innodb_rows_deleted
+-- eval SELECT $innodb_rows_inserted - $innodb_rows_inserted_orig AS innodb_rows_inserted
+-- eval SELECT $innodb_rows_updated - $innodb_rows_updated_orig AS innodb_rows_updated
+-- enable_query_log
# Test for row locks InnoDB status variables.
show status like "Innodb_row_lock_waits";
@@ -1365,6 +1382,8 @@ set global innodb_sync_spin_loops=20;
show variables like "innodb_sync_spin_loops";
# Test for innodb_thread_concurrency variable
+# save the original value so we can restore it at the end
+-- let $innodb_thread_concurrency_orig = query_get_value(SHOW VARIABLES WHERE variable_name = 'innodb_thread_concurrency', Value, 1)
show variables like "innodb_thread_concurrency";
set global innodb_thread_concurrency=1001;
show variables like "innodb_thread_concurrency";
@@ -1372,6 +1391,10 @@ set global innodb_thread_concurrency=0;
show variables like "innodb_thread_concurrency";
set global innodb_thread_concurrency=16;
show variables like "innodb_thread_concurrency";
+# restore the orginal value, this way the test can be run multiple times
+-- disable_query_log
+-- eval set global innodb_thread_concurrency = $innodb_thread_concurrency_orig
+-- enable_query_log
# Test for innodb_concurrency_tickets variable
show variables like "innodb_concurrency_tickets";
diff --git a/mysql-test/t/insert.test b/mysql-test/t/insert.test
index 0b5a12fa523..a1735c1a91f 100644
--- a/mysql-test/t/insert.test
+++ b/mysql-test/t/insert.test
@@ -454,5 +454,14 @@ SELECT * FROM t2;
DROP TABLE t1, t2;
+#
+# Bug#43833 Simple INSERT crashes the server
+#
+CREATE TABLE t1(f1 FLOAT);
+INSERT INTO t1 VALUES (1.23);
+CREATE TABLE t2(f1 CHAR(1));
+INSERT INTO t2 SELECT f1 FROM t1;
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests.
diff --git a/mysql-test/t/insert_update.test b/mysql-test/t/insert_update.test
index 67108744ec6..de38ae0b0d3 100644
--- a/mysql-test/t/insert_update.test
+++ b/mysql-test/t/insert_update.test
@@ -12,7 +12,7 @@ INSERT t1 VALUES (8,4,50) ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
INSERT t1 VALUES (1,4,60) ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
--- error 1062
+-- error ER_DUP_ENTRY
INSERT t1 VALUES (1,9,70) ON DUPLICATE KEY UPDATE c=c+100000, b=4;
SELECT * FROM t1;
TRUNCATE TABLE t1;
@@ -63,7 +63,7 @@ INSERT t1 SELECT 8,4,50 FROM DUAL ON DUPLICATE KEY UPDATE c=c+1000;
SELECT * FROM t1;
INSERT t1 SELECT 1,4,60 FROM DUAL ON DUPLICATE KEY UPDATE c=c+10000;
SELECT * FROM t1;
--- error 1062
+-- error ER_DUP_ENTRY
INSERT t1 SELECT 1,9,70 FROM DUAL ON DUPLICATE KEY UPDATE c=c+100000, b=4;
SELECT * FROM t1;
TRUNCATE TABLE t1;
@@ -76,7 +76,7 @@ INSERT t1 SELECT a,b,c FROM t2 WHERE d=1 ON DUPLICATE KEY UPDATE c=t1.c+100;
SELECT * FROM t1;
INSERT t1 SET a=5 ON DUPLICATE KEY UPDATE b=0;
SELECT * FROM t1;
---error 1052
+--error ER_NON_UNIQ_ERROR
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=c+VALUES(a);
INSERT t1 SELECT a,b,c FROM t2 WHERE d=2 ON DUPLICATE KEY UPDATE c=t1.c+VALUES(t1.a);
SELECT *, VALUES(a) FROM t1;
@@ -95,9 +95,9 @@ insert ignore into t1 select a from t1 as t2 on duplicate key update a=t1.a+1 ;
select * from t1;
insert into t1 select 1 on duplicate key update a=2;
select * from t1;
---error 1052
+--error ER_NON_UNIQ_ERROR
insert into t1 select a from t1 on duplicate key update a=a+1 ;
---error 1052
+--error ER_NON_UNIQ_ERROR
insert ignore into t1 select a from t1 on duplicate key update a=t1.a+1 ;
drop table t1;
@@ -171,13 +171,13 @@ SET SQL_MODE = 'TRADITIONAL';
CREATE TABLE t1 (a INT PRIMARY KEY, b INT NOT NULL);
---error 1364
+--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t1 (a) VALUES (1);
---error 1364
+--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE a = b;
---error 1364
+--error ER_NO_DEFAULT_FOR_FIELD
INSERT INTO t1 (a) VALUES (1) ON DUPLICATE KEY UPDATE b = b;
SELECT * FROM t1;
@@ -278,7 +278,7 @@ INSERT INTO t1 (id,c1) VALUES (1,10);
SELECT * FROM t1;
CREATE TABLE t2 (id INT, c1 INT);
INSERT INTO t2 VALUES (1,NULL), (2,2);
---error 1048
+--error ER_BAD_NULL_ERROR
INSERT INTO t1 (id,c1) SELECT 1,NULL
ON DUPLICATE KEY UPDATE c1=NULL;
SELECT * FROM t1;
@@ -290,6 +290,7 @@ INSERT IGNORE INTO t1 (id,c1) SELECT * FROM t2
SELECT * FROM t1;
DROP TABLE t1;
+DROP TABLE t2;
#
# Bug#28904: INSERT .. ON DUPLICATE was silently updating rows when it
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test
index 6c3c942b046..fa6af85f29c 100644
--- a/mysql-test/t/lock_multi.test
+++ b/mysql-test/t/lock_multi.test
@@ -683,6 +683,134 @@ DROP TABLE t1;
--disconnect locker
--disconnect writer
+#
+# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely
+#
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+connect (con3,localhost,root,,);
+connect (con4,localhost,root,,);
+connect (con5,localhost,root,,);
+
+create table t1 (a int);
+create table t2 like t1;
+
+connection con1;
+--echo # con1
+lock tables t1 write;
+connection con2;
+--echo # con2
+send flush tables with read lock;
+connection con5;
+--echo # con5
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Flushing tables';
+--source include/wait_show_condition.inc
+--echo # global read lock is taken
+connection con3;
+--echo # con3
+send select * from t2 for update;
+connection con5;
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # waiting for release of read lock
+connection con4;
+--echo # con4
+--echo # would hang and later cause a deadlock
+flush tables t2;
+connection con1;
+--echo # clean up
+unlock tables;
+connection con2;
+--reap
+unlock tables;
+connection con3;
+--reap
+connection default;
+disconnect con5;
+disconnect con4;
+disconnect con3;
+disconnect con2;
+disconnect con1;
+
+drop table t1,t2;
+
+--echo #
+--echo # Lightweight version:
+--echo # Ensure that the wait for a GRL is done before opening tables.
+--echo #
+
+connect (con1,localhost,root,,);
+connect (con2,localhost,root,,);
+
+create table t1 (a int);
+create table t2 like t1;
+
+--echo #
+--echo # UPDATE
+--echo #
+
+connection default;
+--echo # default
+flush tables with read lock;
+connection con1;
+--echo # con1
+send update t2 set a = 1;
+connection default;
+--echo # default
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # statement is waiting for release of read lock
+connection con2;
+--echo # con2
+flush table t2;
+connection default;
+--echo # default
+unlock tables;
+connection con1;
+--echo # con1
+--reap
+
+--echo #
+--echo # LOCK TABLES .. WRITE
+--echo #
+
+connection default;
+--echo # default
+flush tables with read lock;
+connection con1;
+--echo # con1
+send lock tables t2 write;
+connection default;
+--echo # default
+let $show_statement= SHOW PROCESSLIST;
+let $field= State;
+let $condition= = 'Waiting for release of readlock';
+--source include/wait_show_condition.inc
+--echo # statement is waiting for release of read lock
+connection con2;
+--echo # con2
+flush table t2;
+connection default;
+--echo # default
+unlock tables;
+connection con1;
+--echo # con1
+--reap
+unlock tables;
+
+connection default;
+disconnect con2;
+disconnect con1;
+
+drop table t1,t2;
+
# End of 5.0 tests
# Wait till all disconnects are completed
diff --git a/mysql-test/t/myisampack.test b/mysql-test/t/myisampack.test
index ace7afce88a..ce27071bcf8 100644
--- a/mysql-test/t/myisampack.test
+++ b/mysql-test/t/myisampack.test
@@ -50,3 +50,28 @@ FLUSH TABLE t1;
--exec $MYISAMPACK $MYSQLTEST_VARDIR/master-data/test/t1
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # Bug #43973 - backup_myisam.test fails on 6.0-bugteam
+--echo #
+CREATE DATABASE mysql_db1;
+CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int);
+CREATE INDEX i1 ON mysql_db1.t1 (c1, c2);
+INSERT INTO mysql_db1.t1 VALUES ('A',1);
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
+FLUSH TABLE mysql_db1.t1;
+#
+--echo # Compress the table using MYISAMPACK tool
+--exec $MYISAMPACK -s $MYSQLTEST_VARDIR/master-data/mysql_db1/t1
+--echo # Run MYISAMCHK tool on the compressed table
+--exec $MYISAMCHK -srq $MYSQLTEST_VARDIR/master-data/mysql_db1/t1
+SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
+#
+DROP TABLE mysql_db1.t1;
+DROP DATABASE mysql_db1;
diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test
index 91006d280a8..3dbd17440d3 100644
--- a/mysql-test/t/mysqlcheck.test
+++ b/mysql-test/t/mysqlcheck.test
@@ -50,7 +50,7 @@ create view v_bug25347 as select * from t_bug25347;
flush tables;
--echo removing and creating
--remove_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
---write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
+--write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
EOF
--exec $MYSQL_CHECK --repair --databases --use-frm d_bug25347
drop view v_bug25347;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 52eecc62931..1e9090fdd01 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1646,9 +1646,6 @@ DROP TABLE t1,t2;
--replace_regex /-- [^D][^u][^m][^p].*// /\/\*!.*// / on [0-9 :-]+/ on DATE/
--exec $MYSQL_DUMP test
-# We reset concurrent_inserts value to whatever it was at the start of the test
-SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
-
--echo #
--echo # Bug #42635: mysqldump includes views that were excluded using
--echo # the --ignore-table option
@@ -1681,6 +1678,9 @@ CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( f1 INT );
DROP TABLE `כדשגכחךלדגכחשךדגחכךלדגכ`;
SET NAMES latin1;
+# We reset concurrent_inserts value to whatever it was at the start of the test
+# This line must be executed _after_ all test cases.
+SET @@GLOBAL.CONCURRENT_INSERT = @OLD_CONCURRENT_INSERT;
--echo #
--echo # End of 5.0 tests
diff --git a/mysql-test/t/not_embedded_server.test b/mysql-test/t/not_embedded_server.test
index 044d8665a18..fcbcc389b15 100644
--- a/mysql-test/t/not_embedded_server.test
+++ b/mysql-test/t/not_embedded_server.test
@@ -39,8 +39,14 @@ while ($i)
--enable_query_log
--enable_result_log
-SHOW GLOBAL STATUS LIKE 'com_select';
+let $before= query_get_value(SHOW GLOBAL STATUS LIKE 'com_select',Value,1);
--change_user
-SHOW GLOBAL STATUS LIKE 'com_select';
+let $after= query_get_value(SHOW GLOBAL STATUS LIKE 'com_select',Value,1);
+
+if (`select $after != $before`){
+ SHOW GLOBAL STATUS LIKE 'com_select';
+ die The value of com_select changed during change_user;
+}
+echo Value of com_select did not change;
diff --git a/mysql-test/t/profiling.test b/mysql-test/t/profiling.test
new file mode 100644
index 00000000000..29b694fa0bd
--- /dev/null
+++ b/mysql-test/t/profiling.test
@@ -0,0 +1,266 @@
+--source include/have_profiling.inc
+
+# Verify that the protocol isn't violated if we ask for profiling info
+# before profiling has recorded anything.
+show profiles;
+show profile all;
+
+# default is OFF
+show session variables like 'profil%';
+select @@profiling;
+
+# setting global variable is an error
+--error ER_LOCAL_VARIABLE
+set global profiling = ON;
+
+# But size is okay
+set global profiling_history_size=100;
+show global variables like 'profil%';
+
+# turn on for testing
+set session profiling = ON;
+set session profiling_history_size=30; # small enough to overflow
+
+# verify it is active
+show session variables like 'profil%';
+select @@profiling;
+
+# Profiling is a descriptive look into the way the server operated
+# in retrospect. Chad doesn't think it's wise to include the result
+# log, as this creates a proscriptive specification about how the
+# server should work in the future -- or it forces everyone who
+# changes the server significantly to record the test results again,
+# and that violates the spirit of our tests. Please don't include
+# execution-specific data here, as in all of the "show profile" and
+# information_schema.profiling results.
+
+create table t1 (
+ a int,
+ b int
+);
+insert into t1 values (1,1), (2,null), (3, 4);
+insert into t1 values (5,1), (6,null), (7, 4);
+insert into t1 values (1,1), (2,null), (3, 4);
+insert into t1 values (5,1), (6,null), (7, 4);
+select max(x) from (select sum(a) as x from t1 group by b) as teeone;
+insert into t1 select * from t1;
+select count(*) from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+insert into t1 select * from t1;
+select count(*) from t1;
+select sum(a) from t1;
+select sum(a) from t1 group by b;
+select sum(a) + sum(b) from t1 group by b;
+select max(x) from (select sum(a) as x from t1 group by b) as teeone;
+select '012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890' as big_string;
+
+--enable_result_log
+--replace_column 2 #
+show profiles;
+
+--disable_result_log
+###--replace_column 2 # 3 # 4 #
+show profile for query 15;
+###--replace_column 2 # 3 # 4 #
+show profile cpu for query 15;
+###--replace_column 2 # 3 # 4 # 5 # 6 #
+show profile cpu, block io for query 15;
+###--replace_column 2 # 3 # 4 #
+show profile cpu for query 9 limit 2 offset 2;
+show profile cpu for query 10 limit 0;
+--error 0,ER_WRONG_ARGUMENTS
+show profile cpu for query 65534;
+###--replace_column 2 #
+show profile memory;
+###--replace_column 2 # 3 # 4 #
+show profile block io;
+###--replace_column 2 # 3 # 4 #
+show profile context switches;
+###--replace_column 2 # 3 # 4 #
+show profile page faults;
+###--replace_column 2 # 3 # 4 #
+show profile ipc;
+###--replace_column 2 #
+show profile swaps limit 1 offset 2;
+###--replace_column 2 # 5 #
+show profile source;
+show profile all for query 0 limit 0;
+###--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 16 #
+show profile all for query 15;
+###--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 16 #
+
+select * from information_schema.profiling;
+select query_id, state, duration from information_schema.profiling;
+select query_id, sum(duration) from information_schema.profiling group by query_id;
+select query_id, count(*) from information_schema.profiling group by query_id;
+select sum(duration) from information_schema.profiling;
+
+# Broken down into number of stages and duration of each query.
+select query_id, count(*), sum(duration) from information_schema.profiling group by query_id;
+select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling;
+
+
+--enable_result_log
+drop table if exists t1, t2, t3;
+create table t1 (id int );
+create table t2 (id int not null);
+create table t3 (id int not null primary key);
+insert into t1 values (1), (2), (3);
+insert into t2 values (1), (2), (3);
+insert into t3 values (1), (2), (3);
+
+--replace_column 2 #
+show profiles;
+
+select * from t1;
+--replace_column 2 #
+show profiles;
+--echo This ^^ should end in "select * from t1;"
+
+delete from t1;
+insert into t1 values (1), (2), (3);
+insert into t1 values (1), (2), (3);
+
+select * from t1;
+--replace_column 2 #
+show profiles;
+
+# Turning profiling off does freeze it
+set session profiling = OFF;
+select sum(id) from t1;
+--replace_column 2 #
+show profiles;
+
+## Verify that the various juggling of THD contexts doesn't affect profiling.
+
+## Functions and procedures
+set session profiling = ON;
+select @@profiling;
+create function f1() returns varchar(50) return 'hello';
+select @@profiling;
+select * from t1 where id <> f1();
+select @@profiling;
+
+set session profiling = OFF;
+drop table if exists profile_log;
+create table profile_log (how_many int);
+
+--disable_warnings
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+--enable_warnings
+
+delimiter //;
+create procedure p1 ()
+ modifies sql data
+begin
+ set profiling = ON;
+ select 'This p1 should show up in profiling';
+ insert into profile_log select count(*) from information_schema.profiling;
+end//
+create procedure p2()
+ deterministic
+begin
+ set profiling = ON;
+ call p1();
+ select 'This p2 should show up in profiling';
+end//
+create procedure p3 ()
+ reads sql data
+begin
+ set profiling = ON;
+ select 'This p3 should show up in profiling';
+ show profile;
+end//
+delimiter ;//
+
+--disable_result_log
+--echo first call to p1
+call p1;
+select * from profile_log;
+--echo second call to p1
+call p1;
+select * from profile_log;
+--echo third call to p1
+call p1;
+select * from profile_log;
+set session profiling = OFF;
+call p2;
+set session profiling = OFF;
+call p3;
+
+--replace_column 1 # 2 #
+show profiles;
+--enable_result_log
+
+drop procedure if exists p1;
+drop procedure if exists p2;
+drop procedure if exists p3;
+drop table if exists profile_log;
+
+## Triggers
+set session profiling = ON;
+drop table if exists t2;
+create table t2 (id int not null);
+create trigger t2_bi before insert on t2 for each row set @x=0;
+select @@profiling;
+insert into t2 values (1), (2), (3);
+select @@profiling;
+
+## ALTER TABLE
+set session profiling = ON;
+drop table if exists t1, t2;
+create table t1 (id int not null primary key);
+create table t2 (id int not null primary key, id1 int not null);
+select @@profiling;
+alter table t2 add foreign key (id1) references t1 (id) on delete cascade;
+select @@profiling;
+
+## Table LOCKing
+lock table t1 write;
+select @@profiling;
+unlock table;
+select @@profiling;
+
+## Transactions
+set autocommit=0;
+select @@profiling, @@autocommit;
+begin;
+select @@profiling;
+insert into t1 values (1);
+insert into t2 values (1,1);
+--echo testing referential integrity cascade
+delete from t1 where id = 1;
+select @@profiling;
+--echo testing rollback
+--disable_warnings
+rollback;
+--enable_warnings
+select @@profiling;
+--echo testing commit
+begin;
+select @@profiling;
+commit;
+select @@profiling;
+
+drop table if exists t1, t2, t3;
+drop view if exists v1;
+drop function if exists f1;
+
+## Multiple queries in one packet. Combo statements don't work with ps-proto.
+#--eval select 1; select 2; select 3;
+## two continuations, one starting
+#select state from information_schema.profiling where seq=1 order by query_id desc limit 3;
+
+
+## last thing in the file
+set session profiling = OFF;
+
+##
+--echo End of 5.0 tests
diff --git a/mysql-test/t/rpl_bug38694-slave.opt b/mysql-test/t/rpl_bug38694-slave.opt
new file mode 100644
index 00000000000..d96e981b198
--- /dev/null
+++ b/mysql-test/t/rpl_bug38694-slave.opt
@@ -0,0 +1 @@
+--loose-debug=d,simulate_slave_delay_at_terminate_bug38694
diff --git a/mysql-test/t/rpl_bug38694.test b/mysql-test/t/rpl_bug38694.test
new file mode 100644
index 00000000000..41b11d271b9
--- /dev/null
+++ b/mysql-test/t/rpl_bug38694.test
@@ -0,0 +1,10 @@
+# Testing replication threads stopping concurrency issue
+# at the server shutdown
+# Related bugs: bug#38694, bug#29968, bug#25306
+# The test checks if a delay at the termination phase of slave threads
+# DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
+# could cause any issue.
+
+source include/master-slave.inc;
+
+# End of tests
diff --git a/mysql-test/t/rpl_drop_if_exists.test b/mysql-test/t/rpl_drop_if_exists.test
new file mode 100644
index 00000000000..a042fa8caff
--- /dev/null
+++ b/mysql-test/t/rpl_drop_if_exists.test
@@ -0,0 +1,77 @@
+# BUG#13684:
+# SP: DROP PROCEDURE|FUNCTION IF EXISTS not binlogged if routine
+# does not exist
+#
+# There is an inconsistency with DROP DATABASE IF EXISTS, DROP
+# TABLE IF EXISTS and DROP VIEW IF EXISTS: those are binlogged even
+# if the DB or TABLE does not exist, whereas DROP PROCEDURE IF
+# EXISTS does not. It would be nice or at least consistent if DROP
+# PROCEDURE/STATEMENT worked the same too.
+#
+# Description:
+# DROP PROCEDURE|FUNCTION IF EXISTS does not get binlogged whereas DROP
+# DATABASE|TABLE|TRIGGER|... IF EXISTS do.
+#
+# Fixed DROP PROCEDURE|FUNCTION IF EXISTS by adding a call to
+# mysql_bin_log.write in mysql_execute_command. Checked also if all
+# documented "DROP (...) IF EXISTS" get binlogged.
+#
+# Test is implemented as follows:
+#
+# i) test each "drop if exists" (DDL)
+# ii) show binlog events;
+# iii) create an object for each drop if exists statement;
+# iv) issue "drop if exists" in existent objects.
+# v) show binlog events;
+#
+
+--source include/have_log_bin.inc
+RESET MASTER;
+
+disable_warnings;
+
+# test all "drop if exists" in manual with inexistent objects
+DROP PROCEDURE IF EXISTS db_bug_13684.p;
+DROP FUNCTION IF EXISTS db_bug_13684.f;
+DROP TRIGGER IF EXISTS db_bug_13684.tr;
+DROP VIEW IF EXISTS db_bug_13684.v;
+DROP TABLE IF EXISTS db_bug_13684.t;
+DROP DATABASE IF EXISTS db_bug_13684;
+
+--source include/show_binlog_events.inc
+
+# test drop with existing values
+
+# create
+CREATE DATABASE db_bug_13684;
+
+CREATE TABLE db_bug_13684.t (a int);
+
+CREATE VIEW db_bug_13684.v
+ AS SELECT * FROM db_bug_13684.t;
+
+CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
+ FOR EACH ROW BEGIN
+ END;
+
+CREATE PROCEDURE db_bug_13684.p (OUT p1 INT)
+ BEGIN
+ END;
+
+CREATE FUNCTION db_bug_13684.f (s CHAR(20))
+ RETURNS CHAR(50) DETERMINISTIC
+ RETURN s;
+
+--source include/show_binlog_events.inc
+
+# drop existing
+DROP PROCEDURE IF EXISTS db_bug_13684.p;
+DROP FUNCTION IF EXISTS db_bug_13684.f;
+DROP TRIGGER IF EXISTS db_bug_13684.tr;
+DROP VIEW IF EXISTS db_bug_13684.v;
+DROP TABLE IF EXISTS db_bug_13684.t;
+DROP DATABASE IF EXISTS db_bug_13684;
+
+--source include/show_binlog_events.inc
+
+enable_warnings;
diff --git a/mysql-test/t/rpl_killed_ddl-master.opt b/mysql-test/t/rpl_killed_ddl-master.opt
new file mode 100644
index 00000000000..aaf2d8a4251
--- /dev/null
+++ b/mysql-test/t/rpl_killed_ddl-master.opt
@@ -0,0 +1 @@
+--debug=d,debug_lock_before_query_log_event
diff --git a/mysql-test/t/rpl_killed_ddl.test b/mysql-test/t/rpl_killed_ddl.test
new file mode 100644
index 00000000000..f4f2f6ac320
--- /dev/null
+++ b/mysql-test/t/rpl_killed_ddl.test
@@ -0,0 +1,271 @@
+# ==== Purpose ====
+#
+# This test check if DDL statements are correctly binlogged when the
+# thread is killed
+#
+# ==== Method ====
+#
+# Start a DDL query and kill it, check if the error code of the binlog
+# event is correct.
+#
+# DDL statements tested:
+# CREATE/ALTER/RENAME/DROP DATABASE
+# CREATE/ALTER/DROP FUNCTION
+# CREATE/ALTER/DROP PROCEDURE
+# CREATE/ALTER/RENAME/DROP TABLE
+# CREATE/DROP TRIGGER
+# CREATE/ALTER/DROP VIEW
+#
+# ==== Bugs =====
+#
+
+source include/have_debug.inc;
+source include/master-slave.inc;
+
+# Use the DBUG_SYNC_POINT to make sure the thread running the DDL is
+# waiting before creating the query log event
+
+let $debug_lock= "debug_lock.before_query_log_event";
+
+######## INITIALIZATION ########
+
+disable_warnings;
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+DROP DATABASE IF EXISTS d4;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+DROP TABLE IF EXISTS t4;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+DROP TRIGGER IF EXISTS tr1;
+DROP TRIGGER IF EXISTS tr2;
+DROP TRIGGER IF EXISTS tr3;
+DROP TRIGGER IF EXISTS tr4;
+enable_warnings;
+
+CREATE DATABASE d1;
+
+CREATE FUNCTION f1 () RETURNS INT DETERMINISTIC
+ RETURN 1;
+
+DELIMITER //;
+CREATE PROCEDURE p1 (OUT rows INT)
+ BEGIN
+ SELECT COUNT(*) INTO rows FROM t1;
+ END;
+ //
+DELIMITER ;//
+
+CREATE TABLE t1 (a int);
+CREATE TABLE t3 (a int);
+
+DELIMITER //;
+CREATE TRIGGER tr1 BEFORE INSERT ON t1
+ FOR EACH ROW BEGIN
+ DELETE FROM t4 WHERE a=NEW.a;
+ END;
+ //
+DELIMITER ;//
+
+CREATE INDEX i1 ON t1 (a);
+
+CREATE VIEW v1 AS SELECT a FROM t1 WHERE a < 100;
+
+sync_slave_with_master;
+
+connection master1;
+let $connection_name= master1;
+let $connection_id= `SELECT CONNECTION_ID()`;
+
+connection master;
+echo [on master];
+
+# This will block the execution of a statement at the DBUG_SYNC_POINT
+# with given lock name
+if (`SELECT '$debug_lock' != ''`)
+{
+ disable_query_log;
+ disable_result_log;
+ eval SELECT IS_FREE_LOCK($debug_lock);
+ eval SELECT GET_LOCK($debug_lock, 10);
+ eval SELECT IS_FREE_LOCK($debug_lock);
+ enable_query_log;
+ enable_result_log;
+}
+
+######## START TEST ########
+
+connection master1;
+echo [on master1];
+
+disable_warnings;
+
+######## DATABASE ########
+
+let $diff_statement= SHOW DATABASES LIKE 'd%';
+
+send CREATE DATABASE d2;
+source include/kill_query_and_diff_master_slave.inc;
+
+send ALTER DATABASE d1
+ DEFAULT CHARACTER SET = 'utf8';
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP DATABASE d1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP DATABASE d2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## FUNCTION ########
+
+let $diff_statement= SHOW FUNCTION STATUS LIKE 'f%';
+
+send CREATE FUNCTION f2 () RETURNS INT DETERMINISTIC
+ RETURN 1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send ALTER FUNCTION f1 SQL SECURITY INVOKER;
+source include/kill_query_and_diff_master_slave.inc;
+
+# function f1 probably does not exist because the ALTER query was
+# killed
+send DROP FUNCTION IF EXISTS f1;
+source include/kill_query_and_diff_master_slave.inc;
+
+# function f2 probably does not exist because the CREATE query was
+# killed
+send DROP FUNCTION IF EXISTS f2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## PROCEDURE ########
+
+let $diff_statement= SHOW PROCEDURE STATUS LIKE 'p%';
+
+DELIMITER //;
+send CREATE PROCEDURE p2 (OUT rows INT)
+ BEGIN
+ SELECT COUNT(*) INTO rows FROM t2;
+ END;
+ //
+DELIMITER ;//
+source include/kill_query_and_diff_master_slave.inc;
+
+send ALTER PROCEDURE p1 SQL SECURITY INVOKER COMMENT 'return rows of table t1';
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP PROCEDURE IF EXISTS p1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP PROCEDURE IF EXISTS p2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## TABLE ########
+
+let $diff_statement= SHOW TABLES LIKE 't%';
+
+send CREATE TABLE t2 (b int);
+source include/kill_query_and_diff_master_slave.inc;
+
+send ALTER TABLE t1 ADD (d int);
+source include/kill_query_and_diff_master_slave.inc;
+
+send RENAME TABLE t3 TO t4;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## INDEX ########
+
+let $diff_statement= SHOW INDEX FROM t1;
+
+send CREATE INDEX i2 on t1 (a);
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP INDEX i1 on t1;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## TRIGGER ########
+
+let $diff_statement= SHOW TRIGGERS LIKE 'v%';
+
+DELIMITER //;
+send CREATE TRIGGER tr2 BEFORE INSERT ON t4
+ FOR EACH ROW BEGIN
+ DELETE FROM t1 WHERE a=NEW.a;
+ END;
+ //
+DELIMITER ;//
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP TRIGGER tr1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP TRIGGER IF EXISTS tr2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## VIEW ########
+
+let $diff_statement= SHOW TABLES LIKE 'v%';
+
+send CREATE VIEW v2 AS SELECT a FROM t1 WHERE a > 100;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP VIEW v1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP VIEW IF EXISTS v2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## DROP TABLE ########
+
+# Because of BUG#43529, we cannot use the DBUG_SYNC_POINT for DROP
+# TABLE statements on 5.0
+connection master;
+disable_query_log;
+disable_result_log;
+eval SELECT RELEASE_LOCK($debug_lock);
+enable_result_log;
+enable_query_log;
+let $debug_lock=;
+
+connection master1;
+
+let $diff_statement= SHOW TABLES LIKE 't%';
+
+send DROP TABLE t1;
+source include/kill_query_and_diff_master_slave.inc;
+
+send DROP TABLE IF EXISTS t2;
+source include/kill_query_and_diff_master_slave.inc;
+
+######## CLEAN UP ########
+
+# The DROP statements above are killed during the process, so they
+# does not make sure the objects are dropped.
+
+disable_warnings;
+DROP DATABASE IF EXISTS d1;
+DROP DATABASE IF EXISTS d2;
+DROP DATABASE IF EXISTS d3;
+DROP DATABASE IF EXISTS d4;
+DROP FUNCTION IF EXISTS f1;
+DROP FUNCTION IF EXISTS f2;
+DROP FUNCTION IF EXISTS f3;
+DROP FUNCTION IF EXISTS f4;
+DROP TABLE IF EXISTS t1;
+DROP TABLE IF EXISTS t2;
+DROP TABLE IF EXISTS t3;
+DROP TABLE IF EXISTS t4;
+DROP PROCEDURE IF EXISTS p1;
+DROP PROCEDURE IF EXISTS p2;
+DROP PROCEDURE IF EXISTS p3;
+DROP PROCEDURE IF EXISTS p4;
+enable_warnings;
diff --git a/mysql-test/t/select.test b/mysql-test/t/select.test
index 1e8dc7ac2f6..60f2f191e0b 100644
--- a/mysql-test/t/select.test
+++ b/mysql-test/t/select.test
@@ -3737,4 +3737,18 @@ cr.f4 = cr2.f4
GROUP BY a.f3, cr.f4;
drop table t1, t2, t3;
+
+
+#
+# Bug #40925: Equality propagation takes non indexed attribute
+#
+
+CREATE TABLE t1 (a INT KEY, b INT);
+INSERT INTO t1 VALUES (1,1), (2,2), (3,3), (4,4);
+
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND a = b LIMIT 2;
+EXPLAIN EXTENDED SELECT a, b FROM t1 WHERE a > 1 AND b = a LIMIT 2;
+
+DROP TABLE t1;
+
--echo End of 5.0 tests
diff --git a/mysql-test/t/sp_trans_log.test b/mysql-test/t/sp_trans_log.test
index 93605722f6b..effa3ca80cf 100644
--- a/mysql-test/t/sp_trans_log.test
+++ b/mysql-test/t/sp_trans_log.test
@@ -4,11 +4,15 @@
delimiter |;
#
-# Bug #13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
-# Bug #23333 stored function + non-transac table + transac table =
-# breaks stmt-based binlog
-# Bug #27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
+# Bug#13270 INSERT,UPDATE,etc that calls func with side-effect does not binlog
+# Bug#23333 stored function + non-transac table + transac table =
+# breaks stmt-based binlog
+# Bug#27395 OPTION_STATUS_NO_TRANS_UPDATE is not preserved at the end of SF()
#
+--disable_warnings
+drop function if exists bug23333|
+drop table if exists t1,t2|
+--enable_warnings
CREATE TABLE t1 (a int NOT NULL auto_increment primary key) ENGINE=MyISAM|
CREATE TABLE t2 (a int NOT NULL auto_increment, b int, PRIMARY KEY (a)) ENGINE=InnoDB|
@@ -29,5 +33,10 @@ insert into t2 values (bug23333(),1)|
--replace_column 2 # 5 # 6 #
show binlog events from 98 /* with fixes for #23333 will show there are 2 queries */|
select count(*),@a from t1 /* must be 1,1 */|
-drop table t1, t2|
+delimiter ;|
+
+# clean-up
+
+drop table t1,t2;
+drop function if exists bug23333;
diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test
index 26bd7c9e8dd..96e5738526b 100644
--- a/mysql-test/t/subselect.test
+++ b/mysql-test/t/subselect.test
@@ -3375,16 +3375,14 @@ SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
DROP TABLE t1,t2;
-
#
# Bug#20835 (literal string with =any values)
#
-CREATE TABLE t1 (s1 CHAR(1));
+CREATE TABLE t1 (s1 char(1));
INSERT INTO t1 VALUES ('a');
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
DROP TABLE t1;
-
#
# Bug#40519 Subselect query using bigint fails
#
@@ -3395,7 +3393,6 @@ INSERT INTO t2 VALUES (2,1),(3,1);
SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1);
DROP TABLE t1, t2;
-
#
# Bug#37460 Assertion failed:
# !table->file || table->file->inited == handler::NONE
@@ -3409,13 +3406,13 @@ INSERT INTO t1 (id) VALUES (1);
INSERT INTO t2 (id) VALUES (1);
CREATE VIEW v1 AS
-SELECT t2.c AS c FROM t1, t2
-WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+ SELECT t2.c AS c FROM t1, t2
+ WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
UPDATE v1 SET c=1;
CREATE VIEW v2 (a,b) AS
-SELECT t2.id, t2.c AS c FROM t1, t2
-WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+ SELECT t2.id, t2.c AS c FROM t1, t2
+ WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
--error ER_VIEW_CHECK_FAILED
INSERT INTO v2(a,b) VALUES (2,2);
@@ -3423,8 +3420,8 @@ INSERT INTO v2(a,b) VALUES (1,2);
SELECT * FROM v1;
CREATE VIEW v3 AS
-SELECT t2.c AS c FROM t2
-WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
+ SELECT t2.c AS c FROM t2
+ WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
DELETE FROM v3;
diff --git a/mysql-test/t/varbinary.test b/mysql-test/t/varbinary.test
index 427c1a6b84a..a53a3b8d5b4 100644
--- a/mysql-test/t/varbinary.test
+++ b/mysql-test/t/varbinary.test
@@ -83,6 +83,7 @@ insert into t1 values("aaa ");
select length(a) from t1;
alter table t1 modify a varchar(255);
select length(a) from t1;
+drop table t1;
#
# Bug#35658 (An empty binary value leads to mysqld crash)
diff --git a/ndb/tools/restore/consumer_restore.cpp b/ndb/tools/restore/consumer_restore.cpp
index 811868f3e77..869dd0e9d8b 100644
--- a/ndb/tools/restore/consumer_restore.cpp
+++ b/ndb/tools/restore/consumer_restore.cpp
@@ -556,7 +556,7 @@ BackupRestore::logEntry(const LogEntry & tup)
NdbTransaction * trans = m_ndb->startTransaction();
if (trans == NULL)
{
- // Deep shit, TODO: handle the error
+ // TODO: handle the error
err << "Cannot start transaction" << endl;
exitHandler();
} // if
@@ -693,7 +693,7 @@ BackupRestore::tuple(const TupleS & tup)
NdbTransaction * trans = m_ndb->startTransaction();
if (trans == NULL)
{
- // Deep shit, TODO: handle the error
+ // TODO: handle the error
ndbout << "Cannot start transaction" << endl;
exitHandler();
} // if
diff --git a/ndb/tools/restore/consumer_restorem.cpp b/ndb/tools/restore/consumer_restorem.cpp
index 2dc0476b5a6..642c9e4acb4 100644
--- a/ndb/tools/restore/consumer_restorem.cpp
+++ b/ndb/tools/restore/consumer_restorem.cpp
@@ -373,7 +373,7 @@ BackupRestore::tuple(const TupleS & tup)
NdbTransaction * trans = m_ndb->startTransaction();
if (trans == NULL)
{
- // Deep shit, TODO: handle the error
+ // TODO: handle the error
ndbout << "Cannot start transaction" << endl;
exit(-1);
} // if
@@ -462,7 +462,7 @@ BackupRestore::logEntry(const LogEntry & tup)
NdbTransaction * trans = m_ndb->startTransaction();
if (trans == NULL)
{
- // Deep shit, TODO: handle the error
+ // TODO: handle the error
ndbout << "Cannot start transaction" << endl;
exit(-1);
} // if
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh
index 631e1e38cc7..3cb4665eb1c 100644
--- a/scripts/mysqld_multi.sh
+++ b/scripts/mysqld_multi.sh
@@ -293,12 +293,7 @@ sub start_mysqlds()
@groups = &find_groups($groupids);
for ($i = 0; defined($groups[$i]); $i++)
{
- # Defaults are made explicit parameters to server execution...
@options = defaults_for_group($groups[$i]);
- # ...so server MUST NOT try to read again from some config file, especially
- # as the "right" file may be unknown to the server if we are using
- # --defaults-file=... params in here.
- unshift(@options,"--no-defaults");
$mysqld_found= 1; # The default
$mysqld_found= 0 if (!length($mysqld));
diff --git a/scripts/mysqlhotcopy.sh b/scripts/mysqlhotcopy.sh
index 4819f512a65..21fca0c0848 100644
--- a/scripts/mysqlhotcopy.sh
+++ b/scripts/mysqlhotcopy.sh
@@ -49,11 +49,11 @@ $0 Ver $VERSION
Usage: $0 db_name[./table_regex/] [new_db_name | directory]
- -?, --help display this helpscreen and exit
+ -?, --help display this help-screen and exit
-u, --user=# user for database login if not current user
-p, --password=# password to use when connecting to server (if not set
in my.cnf, which is recommended)
- -h, --host=# Hostname for local server when connecting over TCP/IP
+ -h, --host=# hostname for local server when connecting over TCP/IP
-P, --port=# port to use when connecting to local server with TCP/IP
-S, --socket=# socket to use when connecting to local server
@@ -86,7 +86,7 @@ sub usage {
# Do not initialize user or password options; that way, any user/password
# options specified in option files will be used. If no values are specified
-# all, the defaults will be used (login name, no password).
+# at all, the defaults will be used (login name, no password).
my %opt = (
noindices => 0,
@@ -95,7 +95,7 @@ my %opt = (
method => "cp",
flushlog => 0,
);
-Getopt::Long::Configure(qw(no_ignore_case)); # disambuguate -p and -P
+Getopt::Long::Configure(qw(no_ignore_case)); # disambiguate -p and -P
GetOptions( \%opt,
"help",
"host|h=s",
@@ -453,7 +453,7 @@ else {
printf "Locked $num_tables tables in %d seconds.\n", time-$start unless $opt{quiet};
$hc_started = time; # count from time lock is granted
- # flush tables to make on-disk copy uptodate
+ # flush tables to make on-disk copy up to date
$start = time;
$dbh->do("FLUSH TABLES /*!32323 $hc_tables */");
printf "Flushed tables ($hc_tables) in %d seconds.\n", time-$start unless $opt{quiet};
@@ -895,7 +895,7 @@ tables and you don't want to have all the tables locked for the
whole duration.
In this situation, I you are happy for groups of tables to be
-backed up separately (and thus possibly not be logically consistant
+backed up separately (and thus possibly not be logically consistent
with one another) then you can run mysqlhotcopy several times on
the same database each with different db_name./table_regex/.
All but the first should use the --addtodest option so the tables
@@ -920,7 +920,7 @@ server in a mutual replication setup.
=item --regexp pattern
-Copy all databases with names matching the pattern
+Copy all databases with names matching the pattern.
=item --regexp /pattern1/./pattern2/
@@ -933,7 +933,7 @@ names begin with 'bar' from all databases which names end with 'foo':
=item db_name./pattern/
Copy only tables matching pattern. Shell metacharacters ( (, ), |, !,
-etc.) have to be escaped (e.g. \). For example, to select all tables
+etc.) have to be escaped (e.g., \). For example, to select all tables
in database db1 whose names begin with 'foo' or 'bar':
mysqlhotcopy --indices --method=cp db1./^\(foo\|bar\)/
@@ -947,19 +947,19 @@ that do not begin with foo nor bar:
=item -?, --help
-Display helpscreen and exit
+Display help-screen and exit.
=item -u, --user=#
-user for database login if not current user
+User for database login if not current user.
=item -p, --password=#
-password to use when connecting to the server. Note that you are strongly
+Password to use when connecting to the server. Note that you are strongly
encouraged *not* to use this option as every user would be able to see the
password in the process list. Instead use the '[mysqlhotcopy]' section in
one of the config files, normally /etc/my.cnf or your personal ~/.my.cnf.
-(See the chapter 'my.cnf Option Files' in the manual)
+(See the chapter 'my.cnf Option Files' in the manual.)
=item -h, -h, --host=#
@@ -968,12 +968,12 @@ different from 'localhost' will trigger mysqlhotcopy to use TCP/IP connection.
=item -P, --port=#
-port to use when connecting to MySQL server with TCP/IP. This is only used
+Port to use when connecting to MySQL server with TCP/IP. This is only used
when using the --host option.
=item -S, --socket=#
-UNIX domain socket to use when connecting to local server
+UNIX domain socket to use when connecting to local server.
=item --noindices
@@ -983,7 +983,7 @@ on the backup.
=item --method=#
-method for copy (only "cp" currently supported). Alpha support for
+Method for copy (only "cp" currently supported). Alpha support for
"scp" was added in November 2000. Your experience with the scp method
will vary with your ability to understand how scp works. 'man scp'
and 'man ssh' are your friends.
@@ -1000,15 +1000,15 @@ scp or rsync the files at your leisure.
=item -q, --quiet
-be silent except for errors
+Be silent except for errors.
=item --debug
-Debug messages are displayed
+Debug messages are displayed.
=item -n, --dryrun
-Display commands without actually doing them
+Display commands without actually doing them.
=back
@@ -1030,18 +1030,18 @@ to be specified on the command line:
mysqlhotcopy db newdb t1 t2 /^foo_/ : t3 /^bar_/ : +
where ":" delimits the subsets, the /^foo_/ indicates all tables
-with names begining with "foo_" and the "+" indicates all tables
+with names beginning with "foo_" and the "+" indicates all tables
not copied by the previous subsets.
-newdb is either another not existing database or a full path to a directory
-where we can create a directory 'db'
+'newdb' is either the name of the new database, or the full path name
+of the new database file. The database should not already exist.
Add option to lock each table in turn for people who don\'t need
cross-table integrity.
Add option to FLUSH STATUS just before UNLOCK TABLES.
-Add support for other copy methods (eg tar to single file?).
+Add support for other copy methods (e.g., tar to single file?).
Add support for forthcoming MySQL ``RAID'' table subdirectory layouts.
@@ -1049,26 +1049,26 @@ Add support for forthcoming MySQL ``RAID'' table subdirectory layouts.
Tim Bunce
-Martin Waite - added checkpoint, flushlog, regexp and dryrun options
+Martin Waite - Added checkpoint, flushlog, regexp and dryrun options.
Fixed cleanup of targets when hotcopy fails.
- Added --record_log_pos.
+ Added --record_log_pos.
RAID tables are now copied (don't know if this works over scp).
-Ralph Corderoy - added synonyms for commands
+Ralph Corderoy - Added synonyms for commands.
-Scott Wiersdorf - added table regex and scp support
+Scott Wiersdorf - Added table regex and scp support.
-Monty - working --noindex (copy only first 2048 bytes of index file)
- Fixes for --method=scp
+Monty - Working --noindex (copy only first 2048 bytes of index file).
+ Fixes for --method=scp.
Ask Bjoern Hansen - Cleanup code to fix a few bugs and enable -w again.
Emil S. Hansen - Added resetslave and resetmaster.
-Jeremy D. Zawodny - Removed depricated DBI calls. Fixed bug which
+Jeremy D. Zawodny - Removed deprecated DBI calls. Fixed bug which
resulted in nothing being copied when a regexp was specified but no
database name(s).
Martin Waite - Fix to handle database name that contains space.
-Paul DuBois - Remove end '/' from directory names
+Paul DuBois - Remove end '/' from directory names.
diff --git a/server-tools/instance-manager/instance_options.cc b/server-tools/instance-manager/instance_options.cc
index 9d88bb0e669..d495e240fb8 100644
--- a/server-tools/instance-manager/instance_options.cc
+++ b/server-tools/instance-manager/instance_options.cc
@@ -522,8 +522,7 @@ int Instance_options::add_option(const char* option)
switch (selected_options->type) {
case SAVE_WHOLE_AND_ADD:
*(selected_options->value)= tmp;
- insert_dynamic(&options_array,(gptr) &tmp);
- return 0;
+ return insert_dynamic(&options_array,(gptr) &tmp);
case SAVE_VALUE:
*(selected_options->value)= strchr(tmp, '=') + 1;
return 0;
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index 860afb42a27..b30014234a2 100755
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -73,6 +73,7 @@ ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX}
time.cc tztime.cc uniques.cc unireg.cc
../sql-common/my_user.c
sql_locale.cc
+ sql_profile.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
diff --git a/sql/Makefile.am b/sql/Makefile.am
index 96cdd04d5ba..2a0d59d0ab9 100644
--- a/sql/Makefile.am
+++ b/sql/Makefile.am
@@ -52,6 +52,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
procedure.h sql_class.h sql_lex.h sql_list.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
sql_error.h field.h handler.h mysqld_suffix.h \
+ sql_profile.h \
ha_myisammrg.h\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
ha_ndbcluster.h ha_ndbcluster_cond.h \
@@ -81,6 +82,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
set_var.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
+ sql_profile.cc \
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc item_uniq.cc sql_test.cc \
log.cc log_event.cc init.cc derror.cc sql_acl.cc \
diff --git a/sql/field.cc b/sql/field.cc
index 36cc4681dec..99e9d7803e1 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5987,13 +5987,13 @@ int Field_str::store(double nr)
calculate the maximum number of significant digits if the 'f'-format
would be used (+1 for decimal point if the number has a fractional part).
*/
- digits= max(0, (int) max_length - fractional);
+ digits= max(1, (int) max_length - fractional);
/*
If the exponent is negative, decrease digits by the number of leading zeros
after the decimal point that do not count as significant digits.
*/
if (exp < 0)
- digits= max(0, (int) digits + exp);
+ digits= max(1, (int) digits + exp);
/*
'e'-format is used only if the exponent is less than -4 or greater than or
equal to the precision. In this case we need to adjust the number of
@@ -6001,7 +6001,7 @@ int Field_str::store(double nr)
We also have to reserve one additional character if abs(exp) >= 100.
*/
if (exp >= (int) digits || exp < -4)
- digits= max(0, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
+ digits= max(1, (int) (max_length - 5 - (exp >= 100 || exp <= -100)));
/* Limit precision to DBL_DIG to avoid garbage past significant digits */
set_if_smaller(digits, DBL_DIG);
diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc
index 04dbe678d4d..410606704d8 100644
--- a/sql/ha_archive.cc
+++ b/sql/ha_archive.cc
@@ -1209,7 +1209,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
ha_rows count= share->rows_recorded;
DBUG_ENTER("ha_archive::check");
- thd->proc_info= "Checking table";
+ thd_proc_info(thd, "Checking table");
/* Flush any waiting data */
gzflush(share->archive_write, Z_SYNC_FLUSH);
@@ -1221,7 +1221,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
while (!(rc= get_row(archive, table->record[0])))
count--;
- thd->proc_info= old_proc_info;
+ thd_proc_info(thd, old_proc_info);
if ((rc && rc != HA_ERR_END_OF_FILE) || count)
{
diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc
index 1de40db2724..12766b42bc2 100644
--- a/sql/ha_berkeley.cc
+++ b/sql/ha_berkeley.cc
@@ -1865,8 +1865,8 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
OPTION_TABLE_LOCK)) && !trx->all)
{
/* We have to start a master transaction */
- DBUG_PRINT("trans",("starting transaction all: options: 0x%lx",
- (ulong) thd->options));
+ DBUG_PRINT("trans",("starting transaction all: options: 0x%llx",
+ thd->options));
if ((error=txn_begin(db_env, 0, &trx->all, 0)))
{
trx->bdb_lock_count--; // We didn't get the lock
diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h
index 3db983901b3..e27fb89d014 100644
--- a/sql/ha_innodb.h
+++ b/sql/ha_innodb.h
@@ -234,6 +234,11 @@ extern ulong srv_thread_sleep_delay;
extern ulong srv_thread_concurrency;
extern ulong srv_commit_concurrency;
extern ulong srv_flush_log_at_trx_commit;
+/* An option to enable the fix for "Bug#43660 SHOW INDEXES/ANALYZE does
+NOT update cardinality for indexes of InnoDB table". By default we are
+running with the fix disabled because MySQL 5.1 is frozen for such
+behavioral changes. */
+extern char srv_use_legacy_cardinality_algorithm;
}
bool innobase_init(void);
diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index 8c8f027bb6b..5ed791d0f68 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -681,7 +681,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info;
- thd->proc_info="Checking table";
+ thd_proc_info(thd, "Checking table");
myisamchk_init(¶m);
param.thd = thd;
param.op_name = "check";
@@ -755,7 +755,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
- thd->proc_info=old_proc_info;
+ thd_proc_info(thd, old_proc_info);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@@ -1037,22 +1037,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
char buf[40];
/* TODO: respect myisam_repair_threads variable */
my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
- thd->proc_info=buf;
+ thd_proc_info(thd, buf);
error = mi_repair_parallel(¶m, file, fixed_name,
param.testflag & T_QUICK);
- thd->proc_info="Repair done"; // to reset proc_info, as
+ thd_proc_info(thd, "Repair done"); // to reset proc_info, as
// it was pointing to local buffer
}
else
{
- thd->proc_info="Repair by sorting";
+ thd_proc_info(thd, "Repair by sorting");
error = mi_repair_by_sort(¶m, file, fixed_name,
param.testflag & T_QUICK);
}
}
else
{
- thd->proc_info="Repair with keycache";
+ thd_proc_info(thd, "Repair with keycache");
param.testflag &= ~T_REP_BY_SORT;
error= mi_repair(¶m, file, fixed_name,
param.testflag & T_QUICK);
@@ -1066,7 +1066,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
(share->state.changed & STATE_NOT_SORTED_PAGES))
{
optimize_done=1;
- thd->proc_info="Sorting index";
+ thd_proc_info(thd, "Sorting index");
error=mi_sort_index(¶m,file,fixed_name);
}
if (!statistics_done && (local_testflag & T_STATISTICS))
@@ -1074,14 +1074,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
if (share->state.changed & STATE_NOT_ANALYZED)
{
optimize_done=1;
- thd->proc_info="Analyzing";
+ thd_proc_info(thd, "Analyzing");
error = chk_key(¶m, file);
}
else
local_testflag&= ~T_STATISTICS; // Don't update statistics
}
}
- thd->proc_info="Saving state";
+ thd_proc_info(thd, "Saving state");
if (!error)
{
if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
@@ -1119,7 +1119,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_optimize)
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
update_state_info(¶m, file, 0);
}
- thd->proc_info=old_proc_info;
+ thd_proc_info(thd, old_proc_info);
if (!thd->locked_tables)
mi_lock_database(file,F_UNLCK);
DBUG_RETURN(error ? HA_ADMIN_FAILED :
@@ -1335,7 +1335,7 @@ int ha_myisam::enable_indexes(uint mode)
THD *thd=current_thd;
MI_CHECK param;
const char *save_proc_info=thd->proc_info;
- thd->proc_info="Creating index";
+ thd_proc_info(thd, "Creating index");
myisamchk_init(¶m);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
@@ -1360,7 +1360,7 @@ int ha_myisam::enable_indexes(uint mode)
thd->clear_error();
}
info(HA_STATUS_CONST);
- thd->proc_info=save_proc_info;
+ thd_proc_info(thd, save_proc_info);
}
else
{
diff --git a/sql/item.cc b/sql/item.cc
index c284e8b3bf4..13f09914ec6 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4341,7 +4341,7 @@ Item *Item_field::replace_equal_field(byte *arg)
return const_item;
}
Item_field *subst= item_equal->get_first();
- if (subst && !field->eq(subst->field))
+ if (subst && field->table != subst->field->table && !field->eq(subst->field))
return subst;
}
return this;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 47e16a1bcc3..3cbb278ea48 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3377,6 +3377,10 @@ longlong Item_master_pos_wait::val_int()
}
#ifdef EXTRA_DEBUG
+/**
+ This will release the user lock that the thread currently locked,
+ please see also the comment of DEBUG_SYNC_POINT.
+*/
void debug_sync_point(const char* lock_name, uint lock_timeout)
{
THD* thd=current_thd;
@@ -3410,7 +3414,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks
*/
- thd->proc_info="User lock";
+ thd_proc_info(thd, "User lock");
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
@@ -3435,7 +3439,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
}
pthread_mutex_unlock(&LOCK_user_locks);
pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);
@@ -3522,7 +3526,7 @@ longlong Item_func_get_lock::val_int()
Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks.
*/
- thd->proc_info="User lock";
+ thd_proc_info(thd, "User lock");
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
@@ -3565,7 +3569,7 @@ longlong Item_func_get_lock::val_int()
pthread_mutex_unlock(&LOCK_user_locks);
pthread_mutex_lock(&thd->mysys_var->mutex);
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);
diff --git a/sql/item_geofunc.cc b/sql/item_geofunc.cc
index d088f68fc0c..71bd1347f6e 100644
--- a/sql/item_geofunc.cc
+++ b/sql/item_geofunc.cc
@@ -70,10 +70,17 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
String arg_val;
- String *wkb= args[0]->val_str(&arg_val);
+ String *wkb;
Geometry_buffer buffer;
uint32 srid= 0;
+ if (args[0]->field_type() == MYSQL_TYPE_GEOMETRY)
+ {
+ return args[0]->val_str(str);
+ }
+
+ wkb= args[0]->val_str(&arg_val);
+
if ((arg_count == 2) && !args[1]->null_value)
srid= (uint32)args[1]->val_int();
@@ -83,8 +90,8 @@ String *Item_func_geometry_from_wkb::val_str(String *str)
str->length(0);
str->q_append(srid);
if ((null_value=
- (args[0]->null_value ||
- !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str))))
+ (args[0]->null_value ||
+ !Geometry::create_from_wkb(&buffer, wkb->ptr(), wkb->length(), str))))
return 0;
return str;
}
@@ -337,14 +344,16 @@ String *Item_func_point::val_str(String *str)
DBUG_ASSERT(fixed == 1);
double x= args[0]->val_real();
double y= args[1]->val_real();
+ uint32 srid= 0;
if ((null_value= (args[0]->null_value ||
args[1]->null_value ||
- str->realloc(1 + 4 + SIZEOF_STORED_DOUBLE*2))))
+ str->realloc(4/*SRID*/ + 1 + 4 + SIZEOF_STORED_DOUBLE*2))))
return 0;
str->set_charset(&my_charset_bin);
str->length(0);
+ str->q_append(srid);
str->q_append((char)Geometry::wkb_ndr);
str->q_append((uint32)Geometry::wkb_point);
str->q_append(x);
@@ -368,12 +377,14 @@ String *Item_func_spatial_collection::val_str(String *str)
DBUG_ASSERT(fixed == 1);
String arg_value;
uint i;
+ uint32 srid= 0;
str->set_charset(&my_charset_bin);
str->length(0);
- if (str->reserve(1 + 4 + 4, 512))
+ if (str->reserve(4/*SRID*/ + 1 + 4 + 4, 512))
goto err;
+ str->q_append(srid);
str->q_append((char) Geometry::wkb_ndr);
str->q_append((uint32) coll_type);
str->q_append((uint32) arg_count);
@@ -391,13 +402,13 @@ String *Item_func_spatial_collection::val_str(String *str)
In the case of GeometryCollection we don't need any checkings
for item types, so just copy them into target collection
*/
- if (str->append(res->ptr(), len, (uint32) 512))
+ if (str->append(res->ptr() + 4/*SRID*/, len - 4/*SRID*/, (uint32) 512))
goto err;
}
else
{
enum Geometry::wkbType wkb_type;
- const char *data= res->ptr() + 1;
+ const char *data= res->ptr() + 4/*SRID*/ + 1;
/*
In the case of named collection we must check that items
@@ -406,7 +417,7 @@ String *Item_func_spatial_collection::val_str(String *str)
wkb_type= (Geometry::wkbType) uint4korr(data);
data+= 4;
- len-= 5;
+ len-= 5 + 4/*SRID*/;
if (wkb_type != item_type)
goto err;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7edc1a62307..4640929b2bf 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -473,17 +473,21 @@ String *Item_func_des_encrypt::val_str(String *str)
string marking change of string length.
*/
- tail= (8-(res_length) % 8); // 1..8 marking extra length
+ tail= 8 - (res_length % 8); // 1..8 marking extra length
res_length+=tail;
+ tmp_arg.realloc(res_length);
+ tmp_arg.length(0);
+ tmp_arg.append(res->ptr(), res->length());
code= ER_OUT_OF_RESOURCES;
- if (tail && res->append(append_str, tail) || tmp_value.alloc(res_length+1))
+ if (tmp_arg.append(append_str, tail) || tmp_value.alloc(res_length+1))
goto error;
- (*res)[res_length-1]=tail; // save extra length
+ tmp_arg[res_length-1]=tail; // save extra length
+ tmp_value.realloc(res_length+1);
tmp_value.length(res_length+1);
tmp_value[0]=(char) (128 | key_number);
// Real encryption
bzero((char*) &ivec,sizeof(ivec));
- DES_ede3_cbc_encrypt((const uchar*) (res->ptr()),
+ DES_ede3_cbc_encrypt((const uchar*) (tmp_arg.ptr()),
(uchar*) (tmp_value.ptr()+1),
res_length,
&keyschedule.ks1,
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 9794a092648..1c5346ab074 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -306,13 +306,17 @@ public:
class Item_func_des_encrypt :public Item_str_func
{
- String tmp_value;
+ String tmp_value,tmp_arg;
public:
Item_func_des_encrypt(Item *a) :Item_str_func(a) {}
Item_func_des_encrypt(Item *a, Item *b): Item_str_func(a,b) {}
String *val_str(String *);
void fix_length_and_dec()
- { maybe_null=1; max_length = args[0]->max_length+8; }
+ {
+ maybe_null=1;
+ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
+ max_length = args[0]->max_length + 9;
+ }
const char *func_name() const { return "des_encrypt"; }
};
@@ -323,7 +327,12 @@ public:
Item_func_des_decrypt(Item *a) :Item_str_func(a) {}
Item_func_des_decrypt(Item *a, Item *b): Item_str_func(a,b) {}
String *val_str(String *);
- void fix_length_and_dec() { maybe_null=1; max_length = args[0]->max_length; }
+ void fix_length_and_dec()
+ {
+ maybe_null=1;
+ /* 9 = MAX ((8- (arg_len % 8)) + 1) */
+ max_length = args[0]->max_length - 9;
+ }
const char *func_name() const { return "des_decrypt"; }
};
diff --git a/sql/lex.h b/sql/lex.h
index 352d80da5c6..33217ee4bc4 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -87,6 +87,7 @@ static SYMBOL symbols[] = {
{ "BINLOG", SYM(BINLOG_SYM)},
{ "BIT", SYM(BIT_SYM)},
{ "BLOB", SYM(BLOB_SYM)},
+ { "BLOCK", SYM(BLOCK_SYM)},
{ "BOOL", SYM(BOOL_SYM)},
{ "BOOLEAN", SYM(BOOLEAN_SYM)},
{ "BOTH", SYM(BOTH)},
@@ -125,8 +126,10 @@ static SYMBOL symbols[] = {
{ "CONSISTENT", SYM(CONSISTENT_SYM)},
{ "CONSTRAINT", SYM(CONSTRAINT)},
{ "CONTAINS", SYM(CONTAINS_SYM)},
+ { "CONTEXT", SYM(CONTEXT_SYM)},
{ "CONTINUE", SYM(CONTINUE_SYM)},
{ "CONVERT", SYM(CONVERT_SYM)},
+ { "CPU", SYM(CPU_SYM)},
{ "CREATE", SYM(CREATE)},
{ "CROSS", SYM(CROSS)},
{ "CUBE", SYM(CUBE_SYM)},
@@ -192,6 +195,7 @@ static SYMBOL symbols[] = {
{ "EXTENDED", SYM(EXTENDED_SYM)},
{ "FALSE", SYM(FALSE_SYM)},
{ "FAST", SYM(FAST_SYM)},
+ { "FAULTS", SYM(FAULTS_SYM)},
{ "FETCH", SYM(FETCH_SYM)},
{ "FIELDS", SYM(COLUMNS)},
{ "FILE", SYM(FILE_SYM)},
@@ -251,7 +255,9 @@ static SYMBOL symbols[] = {
{ "INTEGER", SYM(INT_SYM)},
{ "INTERVAL", SYM(INTERVAL_SYM)},
{ "INTO", SYM(INTO)},
+ { "IO", SYM(IO_SYM)},
{ "IO_THREAD", SYM(RELAY_THREAD)},
+ { "IPC", SYM(IPC_SYM)},
{ "IS", SYM(IS)},
{ "ISOLATION", SYM(ISOLATION)},
{ "ISSUER", SYM(ISSUER_SYM)},
@@ -309,6 +315,7 @@ static SYMBOL symbols[] = {
{ "MEDIUMBLOB", SYM(MEDIUMBLOB)},
{ "MEDIUMINT", SYM(MEDIUMINT)},
{ "MEDIUMTEXT", SYM(MEDIUMTEXT)},
+ { "MEMORY", SYM(MEMORY_SYM)},
{ "MERGE", SYM(MERGE_SYM)},
{ "MICROSECOND", SYM(MICROSECOND_SYM)},
{ "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */
@@ -356,6 +363,7 @@ static SYMBOL symbols[] = {
{ "OUT", SYM(OUT_SYM)},
{ "OUTER", SYM(OUTER)},
{ "OUTFILE", SYM(OUTFILE)},
+ { "PAGE", SYM(PAGE_SYM)},
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
{ "PASSWORD", SYM(PASSWORD)},
@@ -370,6 +378,8 @@ static SYMBOL symbols[] = {
{ "PROCEDURE", SYM(PROCEDURE)},
{ "PROCESS" , SYM(PROCESS)},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM)},
+ { "PROFILE", SYM(PROFILE_SYM)},
+ { "PROFILES", SYM(PROFILES_SYM)},
{ "PURGE", SYM(PURGE)},
{ "QUARTER", SYM(QUARTER_SYM)},
{ "QUERY", SYM(QUERY_SYM)},
@@ -437,6 +447,7 @@ static SYMBOL symbols[] = {
{ "SOME", SYM(ANY_SYM)},
{ "SONAME", SYM(UDF_SONAME_SYM)},
{ "SOUNDS", SYM(SOUNDS_SYM)},
+ { "SOURCE", SYM(SOURCE_SYM)},
{ "SPATIAL", SYM(SPATIAL_SYM)},
{ "SPECIFIC", SYM(SPECIFIC_SYM)},
{ "SQL", SYM(SQL_SYM)},
@@ -471,6 +482,8 @@ static SYMBOL symbols[] = {
{ "SUBJECT", SYM(SUBJECT_SYM)},
{ "SUPER", SYM(SUPER_SYM)},
{ "SUSPEND", SYM(SUSPEND_SYM)},
+ { "SWAPS", SYM(SWAPS_SYM)},
+ { "SWITCHES", SYM(SWITCHES_SYM)},
{ "TABLE", SYM(TABLE_SYM)},
{ "TABLES", SYM(TABLES)},
{ "TABLESPACE", SYM(TABLESPACE)},
diff --git a/sql/lock.cc b/sql/lock.cc
index e22eecd9b73..3102497576f 100644
--- a/sql/lock.cc
+++ b/sql/lock.cc
@@ -150,7 +150,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
}
}
- thd->proc_info="System lock";
+ thd_proc_info(thd, "System lock");
if (sql_lock->table_count && lock_external(thd, sql_lock->table,
sql_lock->table_count))
{
@@ -160,7 +160,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
sql_lock=0;
break;
}
- thd->proc_info="Table lock";
+ thd_proc_info(thd, "Table lock");
thd->locked=1;
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
@@ -203,7 +203,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->locked=0;
break;
}
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
/* some table was altered or deleted. reopen tables marked deleted */
mysql_unlock_tables(thd,sql_lock);
@@ -218,7 +218,7 @@ retry:
if (wait_for_tables(thd))
break; // Couldn't open tables
}
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
if (thd->killed)
{
thd->send_kill_message();
diff --git a/sql/log.cc b/sql/log.cc
index d979dd101e0..b16303ee232 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -158,7 +158,8 @@ static int binlog_commit(THD *thd, bool all)
*/
if (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))
{
- Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"), TRUE, FALSE);
+ Query_log_event qev(thd, STRING_WITH_LEN("COMMIT"),
+ TRUE, FALSE, THD::KILLED_NO_VALUE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
DBUG_RETURN(binlog_end_trans(thd, trans_log, &qev));
}
@@ -202,7 +203,8 @@ static int binlog_rollback(THD *thd, bool all)
*/
if (unlikely(thd->transaction.all.modified_non_trans_table))
{
- Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"), TRUE, FALSE);
+ Query_log_event qev(thd, STRING_WITH_LEN("ROLLBACK"),
+ TRUE, FALSE, THD::KILLED_NO_VALUE);
qev.error_code= 0; // see comment in MYSQL_LOG::write(THD, IO_CACHE)
error= binlog_end_trans(thd, trans_log, &qev);
}
@@ -240,7 +242,8 @@ static int binlog_savepoint_set(THD *thd, void *sv)
*(my_off_t *)sv= my_b_tell(trans_log);
/* Write it to the binary log */
- Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ TRUE, FALSE, THD::KILLED_NO_VALUE);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
@@ -257,7 +260,8 @@ static int binlog_savepoint_rollback(THD *thd, void *sv)
*/
if (unlikely(thd->transaction.all.modified_non_trans_table))
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, TRUE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ TRUE, FALSE, THD::KILLED_NO_VALUE);
DBUG_RETURN(mysql_bin_log.write(&qinfo));
}
reinit_io_cache(trans_log, WRITE_CACHE, *(my_off_t *)sv, 0, 0);
@@ -2089,7 +2093,8 @@ bool MYSQL_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event)
transaction is either a BEGIN..COMMIT block or a single
statement in autocommit mode.
*/
- Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"), TRUE, FALSE);
+ Query_log_event qinfo(thd, STRING_WITH_LEN("BEGIN"),
+ TRUE, FALSE, THD::KILLED_NO_VALUE);
/*
Imagine this is rollback due to net timeout, after all
statements of the transaction succeeded. Then we want a
diff --git a/sql/log_event.cc b/sql/log_event.cc
index c4cdfc27fa0..3912308cafa 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1358,6 +1358,9 @@ Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
{
time_t end_time;
+ DBUG_EXECUTE_IF("debug_lock_before_query_log_event",
+ DBUG_SYNC_POINT("debug_lock.before_query_log_event", 10););
+
if (killed_status_arg == THD::KILLED_NO_VALUE)
killed_status_arg= thd_arg->killed;
error_code=
@@ -4601,7 +4604,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
bzero((char*)&file, sizeof(file));
fname_buf= strmov(proc_info, "Making temp file ");
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
- thd->proc_info= proc_info;
+ thd_proc_info(thd, proc_info);
my_delete(fname_buf, MYF(0)); // old copy may exist already
if ((fd= my_create(fname_buf, CREATE_MODE,
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
@@ -4655,7 +4658,7 @@ err:
end_io_cache(&file);
if (fd >= 0)
my_close(fd, MYF(0));
- thd->proc_info= 0;
+ thd_proc_info(thd, 0);
return error ? 1 : Log_event::exec_event(rli);
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@@ -4775,7 +4778,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
fname= strmov(proc_info, "Making temp file ");
slave_load_file_stem(fname, file_id, server_id, ".data");
- thd->proc_info= proc_info;
+ thd_proc_info(thd, proc_info);
if (get_create_or_append())
{
my_delete(fname, MYF(0)); // old copy may exist already
@@ -4809,7 +4812,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
err:
if (fd >= 0)
my_close(fd, MYF(0));
- thd->proc_info= 0;
+ thd_proc_info(thd, 0);
DBUG_RETURN(error ? error : Log_event::exec_event(rli));
}
#endif
diff --git a/sql/log_event.h b/sql/log_event.h
index 6ccbf8e4d5c..45e3d11b48c 100644
--- a/sql/log_event.h
+++ b/sql/log_event.h
@@ -813,9 +813,13 @@ public:
#ifndef MYSQL_CLIENT
+ /*
+ for argument killed_err_arg, use ` THD::NOT_KILLED ' if the killed
+ status should be ignored, otherwise use `THD::KILLED_NO_VALUE'
+ */
Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
bool using_trans, bool suppress_use,
- THD::killed_state killed_err_arg= THD::KILLED_NO_VALUE);
+ THD::killed_state killed_err_arg);
const char* get_db() { return db; }
#ifdef HAVE_REPLICATION
void pack_info(Protocol* protocol);
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index 58ab7a08837..9768668f103 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -199,6 +199,8 @@ MY_LOCALE *my_locale_by_number(uint number);
#define BDB_LOG_ALLOC_BLOCK_SIZE 1024
#define WARN_ALLOC_BLOCK_SIZE 2048
#define WARN_ALLOC_PREALLOC_SIZE 1024
+#define PROFILE_ALLOC_BLOCK_SIZE 2048
+#define PROFILE_ALLOC_PREALLOC_SIZE 1024
/*
The following parameters is to decide when to use an extra cache to
@@ -376,6 +378,8 @@ MY_LOCALE *my_locale_by_number(uint number);
fulltext functions when reading from it.
*/
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
+#define OPTION_PROFILING (ULL(1) << 33)
+
/*
@@ -456,6 +460,13 @@ MY_LOCALE *my_locale_by_number(uint number);
The client tells the server to block with SELECT GET_LOCK()
and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult
concurrency problems
+
+ NOTE: This will release the user lock that the thread currently
+ locked, which can cause problem if users want to use user locks for
+ other purposes. In order to overcome this problem, it's adviced to
+ wrap the call to DBUG_SYNC_POINT() within the DBUG_EXECUTE_IF(), so
+ that it will only be activated if the given keyword is included in
+ the 'debug' option, and will not fiddle user locks otherwise.
*/
#define DBUG_SYNC_POINT(lock_name,lock_timeout) \
debug_sync_point(lock_name,lock_timeout)
@@ -508,6 +519,8 @@ enum enum_parsing_place
struct st_table;
class THD;
+#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__)
+
/* Struct to handle simple linked lists */
typedef struct st_sql_list {
@@ -579,6 +592,8 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "field.h" /* Field definitions */
#include "protocol.h"
#include "sql_udf.h"
+#include "sql_profile.h"
+
class user_var_entry;
class Security_context;
enum enum_var_type
@@ -591,6 +606,16 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
#include "item.h"
extern my_decimal decimal_zero;
+/**
+ The meat of thd_proc_info(THD*, char*), a macro that packs the last
+ three calling-info parameters.
+*/
+extern "C"
+const char *set_thd_proc_info(THD *thd, const char *info,
+ const char *calling_func,
+ const char *calling_file,
+ const unsigned int calling_line);
+
/* sql_parse.cc */
void free_items(Item *item);
void cleanup_items(Item *item);
@@ -992,6 +1017,8 @@ bool get_schema_tables_result(JOIN *join,
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
bool schema_table_store_record(THD *thd, TABLE *table);
+bool schema_table_store_record(THD *thd, TABLE *table);
+
#define is_schema_db(X) \
!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
@@ -1274,7 +1301,7 @@ void my_dbopt_free(void);
External variables
*/
-extern time_t server_start_time;
+extern time_t server_start_time, flush_status_time;
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
mysql_unpacked_real_data_home[],
@@ -1464,6 +1491,8 @@ extern SHOW_COMP_OPTION have_query_cache;
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
extern SHOW_COMP_OPTION have_crypt;
extern SHOW_COMP_OPTION have_compress;
+extern SHOW_COMP_OPTION have_community_features;
+extern SHOW_COMP_OPTION have_profiling;
#ifndef __WIN__
extern pthread_t signal_thread;
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index ad3521e5dde..592ae3e755a 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -472,7 +472,7 @@ ulong slow_launch_threads = 0, sync_binlog_period;
ulong expire_logs_days = 0;
ulong rpl_recovery_rank=0;
-time_t server_start_time;
+time_t server_start_time, flush_status_time;
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
char *default_tz_name;
@@ -538,6 +538,8 @@ SHOW_COMP_OPTION have_isam;
SHOW_COMP_OPTION have_raid, have_ssl, have_symlink, have_query_cache;
SHOW_COMP_OPTION have_geometry, have_rtree_keys, have_dlopen;
SHOW_COMP_OPTION have_crypt, have_compress;
+SHOW_COMP_OPTION have_community_features;
+SHOW_COMP_OPTION have_profiling;
/* Thread specific variables */
@@ -2832,7 +2834,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
tzset(); // Set tzname
max_system_variables.pseudo_thread_id= (ulong)~0;
- server_start_time= time((time_t*) 0);
+ server_start_time= flush_status_time= time((time_t*) 0);
if (init_thread_environment())
return 1;
mysql_init_variables();
@@ -5040,11 +5042,13 @@ enum options_mysqld
OPT_PLUGIN_DIR,
OPT_PORT_OPEN_TIMEOUT,
OPT_MERGE,
+ OPT_PROFILING,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_SECURE_FILE_PRIV,
OPT_KEEP_FILES_ON_CREATE,
OPT_INNODB_ADAPTIVE_HASH_INDEX,
- OPT_FEDERATED
+ OPT_FEDERATED,
+ OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM
};
@@ -5351,6 +5355,14 @@ Disable with --skip-innodb-doublewrite.", (gptr*) &innobase_use_doublewrite,
(gptr*) &global_system_variables.innodb_table_locks,
(gptr*) &global_system_variables.innodb_table_locks,
0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
+ {"innodb_use_legacy_cardinality_algorithm",
+ OPT_INNODB_USE_LEGACY_CARDINALITY_ALGORITHM,
+ "Use legacy algorithm for picking random pages during index cardinality "
+ "estimation. Disable this to use a better algorithm, but note that your "
+ "query plans may change (enabled by default).",
+ (gptr*) &srv_use_legacy_cardinality_algorithm,
+ (gptr*) &srv_use_legacy_cardinality_algorithm,
+ 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0},
#endif /* End HAVE_INNOBASE_DB */
{"isam", OPT_ISAM, "Obsolete. ISAM storage engine is no longer supported.",
(gptr*) &opt_isam, (gptr*) &opt_isam, 0, GET_BOOL, NO_ARG, 0, 0, 0,
@@ -5637,6 +5649,12 @@ Disable with --skip-ndbcluster (will save memory).",
"Maximum time in seconds to wait for the port to become free. "
"(Default: no wait)", (gptr*) &mysqld_port_timeout,
(gptr*) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ {"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory",
+ (gptr*) &global_system_variables.profiling_history_size,
+ (gptr*) &max_system_variables.profiling_history_size,
+ 0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
+#endif
{"relay-log", OPT_RELAY_LOG,
"The location and name to use for relay logs.",
(gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0,
@@ -6678,6 +6696,9 @@ struct show_var_st status_vars[]= {
{"Threads_created", (char*) &thread_created, SHOW_LONG_CONST},
{"Threads_running", (char*) &thread_running, SHOW_INT_CONST},
{"Uptime", (char*) 0, SHOW_STARTTIME},
+#ifdef COMMUNITY_SERVER
+ {"Uptime_since_flush_status",(char*) 0, SHOW_FLUSHTIME},
+#endif
{NullS, NullS, SHOW_LONG}
};
@@ -6984,6 +7005,16 @@ static void mysql_init_variables(void)
#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
opt_specialflag |= SPECIAL_NO_PRIOR;
#endif
+#ifdef ENABLED_PROFILING
+ have_profiling = SHOW_OPTION_YES;
+#else
+ have_profiling = SHOW_OPTION_NO;
+#endif
+#ifdef COMMUNITY_SERVER
+ have_community_features = SHOW_OPTION_YES;
+#else
+ have_community_features = SHOW_OPTION_NO;
+#endif
#if defined(__WIN__) || defined(__NETWARE__)
/* Allow Win32 and NetWare users to move MySQL anywhere */
@@ -8008,6 +8039,9 @@ void refresh_status(THD *thd)
/* Reset the counters of all key caches (default and named). */
process_key_caches(reset_key_cache_counters);
+#ifdef COMMUNITY_SERVER
+ flush_status_time= time((time_t*) 0);
+#endif
pthread_mutex_unlock(&LOCK_status);
/*
diff --git a/sql/repl_failsafe.cc b/sql/repl_failsafe.cc
index 7f98dd2d64a..b309a39f583 100644
--- a/sql/repl_failsafe.cc
+++ b/sql/repl_failsafe.cc
@@ -92,7 +92,7 @@ static int init_failsafe_rpl_thread(THD* thd)
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options|= OPTION_BIG_SELECTS;
- thd->proc_info="Thread initialized";
+ thd_proc_info(thd, "Thread initialized");
thd->version=refresh_version;
thd->set_time();
DBUG_RETURN(0);
@@ -603,7 +603,7 @@ pthread_handler_t handle_failsafe_rpl(void *arg)
{
bool break_req_chain = 0;
pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
- thd->proc_info="Processing request";
+ thd_proc_info(thd, "Processing request");
while (!break_req_chain)
{
switch (rpl_status) {
@@ -947,7 +947,7 @@ bool load_master_data(THD* thd)
goto err;
}
}
- thd->proc_info="purging old relay logs";
+ thd_proc_info(thd, "purging old relay logs");
if (purge_relay_logs(&active_mi->rli,thd,
0 /* not only reset, but also reinit */,
&errmsg))
@@ -974,7 +974,7 @@ bool load_master_data(THD* thd)
flush_relay_log_info(&active_mi->rli);
pthread_cond_broadcast(&active_mi->rli.data_cond);
pthread_mutex_unlock(&active_mi->rli.data_lock);
- thd->proc_info = "starting slave";
+ thd_proc_info(thd, "starting slave");
if (restart_thread_mask)
{
error=start_slave_threads(0 /* mutex not needed */,
@@ -986,7 +986,7 @@ bool load_master_data(THD* thd)
err:
unlock_slave_threads(active_mi);
pthread_mutex_unlock(&LOCK_active_mi);
- thd->proc_info = 0;
+ thd_proc_info(thd, 0);
mysql_close(&mysql); // safe to call since we always do mysql_init()
if (!error)
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 735bb5279bd..2cdd306d542 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -450,6 +450,9 @@ sys_var_thd_bool sys_innodb_table_locks("innodb_table_locks",
&SV::innodb_table_locks);
sys_var_thd_bool sys_innodb_support_xa("innodb_support_xa",
&SV::innodb_support_xa);
+sys_var_bool_ptr sys_innodb_use_legacy_cardinality_algorithm(
+ "innodb_use_legacy_cardinality_algorithm",
+ &srv_use_legacy_cardinality_algorithm);
sys_var_long_ptr sys_innodb_autoextend_increment("innodb_autoextend_increment",
&srv_auto_extend_increment);
sys_var_long_ptr sys_innodb_sync_spin_loops("innodb_sync_spin_loops",
@@ -564,6 +567,12 @@ static sys_var_thd_bit sys_unique_checks("unique_checks", 0,
set_option_bit,
OPTION_RELAXED_UNIQUE_CHECKS,
1);
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+static sys_var_thd_bit sys_profiling("profiling", NULL, set_option_bit,
+ ulonglong(OPTION_PROFILING));
+static sys_var_thd_ulong sys_profiling_history_size("profiling_history_size",
+ &SV::profiling_history_size);
+#endif
/* Local state variables */
@@ -727,6 +736,10 @@ sys_var *sys_variables[]=
&sys_optimizer_prune_level,
&sys_optimizer_search_depth,
&sys_preload_buff_size,
+#ifdef ENABLED_PROFILING
+ &sys_profiling,
+ &sys_profiling_history_size,
+#endif
&sys_pseudo_thread_id,
&sys_query_alloc_block_size,
&sys_query_cache_size,
@@ -804,6 +817,7 @@ sys_var *sys_variables[]=
&sys_innodb_max_purge_lag,
&sys_innodb_table_locks,
&sys_innodb_support_xa,
+ &sys_innodb_use_legacy_cardinality_algorithm,
&sys_innodb_autoextend_increment,
&sys_innodb_sync_spin_loops,
&sys_innodb_concurrency_tickets,
@@ -889,6 +903,8 @@ struct show_var_st init_vars[]= {
{"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
{"have_blackhole_engine", (char*) &have_blackhole_db, SHOW_HAVE},
{"have_compress", (char*) &have_compress, SHOW_HAVE},
+ {"have_community_features", (char*) &have_community_features, SHOW_HAVE},
+ {"have_profiling", (char*) &have_profiling, SHOW_HAVE},
{"have_crypt", (char*) &have_crypt, SHOW_HAVE},
{"have_csv", (char*) &have_csv_db, SHOW_HAVE},
{"have_dynamic_loading", (char*) &have_dlopen, SHOW_HAVE},
@@ -946,6 +962,8 @@ struct show_var_st init_vars[]= {
{sys_innodb_table_locks.name, (char*) &sys_innodb_table_locks, SHOW_SYS},
{sys_innodb_thread_concurrency.name, (char*) &sys_innodb_thread_concurrency, SHOW_SYS},
{sys_innodb_thread_sleep_delay.name, (char*) &sys_innodb_thread_sleep_delay, SHOW_SYS},
+ {sys_innodb_use_legacy_cardinality_algorithm.name,
+ (char*) &sys_innodb_use_legacy_cardinality_algorithm, SHOW_SYS},
#endif
{sys_interactive_timeout.name,(char*) &sys_interactive_timeout, SHOW_SYS},
{sys_join_buffer_size.name, (char*) &sys_join_buffer_size, SHOW_SYS},
@@ -1042,6 +1060,10 @@ struct show_var_st init_vars[]= {
{sys_plugin_dir.name, (char*) &sys_plugin_dir, SHOW_SYS},
{"port", (char*) &mysqld_port, SHOW_INT},
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
+#ifdef ENABLED_PROFILING
+ {sys_profiling.name, (char*) &sys_profiling, SHOW_SYS},
+ {sys_profiling_history_size.name, (char*) &sys_profiling_history_size, SHOW_SYS},
+#endif
{"protocol_version", (char*) &protocol_version, SHOW_INT},
{sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
SHOW_SYS},
@@ -3021,7 +3043,7 @@ static bool set_option_autocommit(THD *thd, set_var *var)
if ((org_options & OPTION_NOT_AUTOCOMMIT))
{
/* We changed to auto_commit mode */
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->options&= ~OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
if (ha_commit(thd))
diff --git a/sql/slave.cc b/sql/slave.cc
index cc82710dec7..f29936c5942 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -78,6 +78,11 @@ static int request_table_dump(MYSQL* mysql, const char* db, const char* table);
static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
const char* table_name, bool overwrite);
static int get_master_version_and_clock(MYSQL* mysql, MASTER_INFO* mi);
+static int terminate_slave_thread(THD *thd,
+ pthread_mutex_t *term_lock,
+ pthread_cond_t *term_cond,
+ volatile uint *slave_running,
+ bool skip_lock);
/*
Find out which replications threads are running
@@ -637,55 +642,96 @@ int terminate_slave_threads(MASTER_INFO* mi,int thread_mask,bool skip_lock)
return 0; /* successfully do nothing */
int error,force_all = (thread_mask & SLAVE_FORCE_ALL);
pthread_mutex_t *sql_lock = &mi->rli.run_lock, *io_lock = &mi->run_lock;
- pthread_mutex_t *sql_cond_lock,*io_cond_lock;
DBUG_ENTER("terminate_slave_threads");
- sql_cond_lock=sql_lock;
- io_cond_lock=io_lock;
-
- if (skip_lock)
- {
- sql_lock = io_lock = 0;
- }
- if ((thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL)) && mi->slave_running)
+ if (thread_mask & (SLAVE_IO|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating IO thread"));
mi->abort_slave=1;
- if ((error=terminate_slave_thread(mi->io_thd,io_lock,
- io_cond_lock,
+ if ((error=terminate_slave_thread(mi->io_thd, io_lock,
&mi->stop_cond,
- &mi->slave_running)) &&
+ &mi->slave_running,
+ skip_lock)) &&
!force_all)
DBUG_RETURN(error);
}
- if ((thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL)) && mi->rli.slave_running)
+ if (thread_mask & (SLAVE_SQL|SLAVE_FORCE_ALL))
{
DBUG_PRINT("info",("Terminating SQL thread"));
- DBUG_ASSERT(mi->rli.sql_thd != 0) ;
mi->rli.abort_slave=1;
- if ((error=terminate_slave_thread(mi->rli.sql_thd,sql_lock,
- sql_cond_lock,
+ if ((error=terminate_slave_thread(mi->rli.sql_thd, sql_lock,
&mi->rli.stop_cond,
- &mi->rli.slave_running)) &&
+ &mi->rli.slave_running,
+ skip_lock)) &&
!force_all)
DBUG_RETURN(error);
}
DBUG_RETURN(0);
}
+/**
+ Wait for a slave thread to terminate.
-int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
- pthread_mutex_t *cond_lock,
- pthread_cond_t* term_cond,
- volatile uint *slave_running)
+ This function is called after requesting the thread to terminate
+ (by setting abort_slave member of Relay_log_info or
+ Master_info structure to 1). Termination of the thread is
+ controlled with the the predicate *slave_running.
+
+ Function will acquire term_lock before waiting on the condition
+ unless skip_lock is true in which case the mutex should be owned
+ by the caller of this function and will remain acquired after
+ return from the function.
+
+ term_lock
+ Associated lock to use when waiting for term_cond
+
+ term_cond
+ Condition that is signalled when the thread has terminated
+
+ slave_running
+ Pointer to predicate to check for slave thread termination
+
+ skip_lock
+ If true the lock will not be acquired before waiting on
+ the condition. In this case, it is assumed that the calling
+ function acquires the lock before calling this function.
+
+
+ returns zero if success, ER_SLAVE_NOT_RUNNING otherwise.
+
+ NOTE:
+ If the executing thread has to acquire term_lock (skip_lock is false),
+ the negative running status does not represent any issue therefore no error is reported.
+*/
+
+int terminate_slave_thread(THD* thd,
+ pthread_mutex_t *term_lock,
+ pthread_cond_t *term_cond,
+ volatile uint *slave_running,
+ bool skip_lock)
{
DBUG_ENTER("terminate_slave_thread");
- if (term_lock)
+ if (!skip_lock)
{
pthread_mutex_lock(term_lock);
- if (!*slave_running)
+ }
+ else
+ {
+ safe_mutex_assert_owner(term_lock);
+ }
+ if (!*slave_running)
+ {
+ if (!skip_lock)
{
+ /*
+ if run_lock (term_lock) is acquired locally then either
+ slave_running status is fine
+ */
pthread_mutex_unlock(term_lock);
+ DBUG_RETURN(0);
+ }
+ else
+ {
DBUG_RETURN(ER_SLAVE_NOT_RUNNING);
}
}
@@ -698,6 +744,7 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
while (*slave_running) // Should always be true
{
+ int error;
DBUG_PRINT("loop", ("killing slave thread"));
pthread_mutex_lock(&thd->LOCK_delete);
@@ -719,9 +766,13 @@ int terminate_slave_thread(THD* thd, pthread_mutex_t* term_lock,
*/
struct timespec abstime;
set_timespec(abstime,2);
- pthread_cond_timedwait(term_cond, cond_lock, &abstime);
+ error= pthread_cond_timedwait(term_cond, term_lock, &abstime);
+ DBUG_ASSERT(error == ETIMEDOUT || error == 0);
}
- if (term_lock)
+
+ DBUG_ASSERT(*slave_running == 0);
+
+ if (!skip_lock)
pthread_mutex_unlock(term_lock);
DBUG_RETURN(0);
}
@@ -834,7 +885,7 @@ int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
&mi->rli.slave_running, &mi->rli.slave_run_id,
mi, 0);
if (error)
- terminate_slave_threads(mi, thread_mask & SLAVE_IO, 0);
+ terminate_slave_threads(mi, thread_mask & SLAVE_IO, !need_slave_mutex);
}
DBUG_RETURN(error);
}
@@ -1053,8 +1104,7 @@ int add_wild_table_rule(DYNAMIC_ARRAY* a, const char* table_spec)
e->tbl_name = e->db + (dot - table_spec) + 1;
e->key_len = len;
memcpy(e->db, table_spec, len);
- insert_dynamic(a, (gptr)&e);
- return 0;
+ return insert_dynamic(a, (gptr)&e);
}
@@ -1575,8 +1625,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
/* Create the table. We do not want to log the "create table" statement */
save_options = thd->options;
- thd->options &= ~(ulong) (OPTION_BIN_LOG);
- thd->proc_info = "Creating table from master dump";
+ thd->options &= ~ (OPTION_BIN_LOG);
+ thd_proc_info(thd, "Creating table from master dump");
// save old db in case we are creating in a different database
save_db = thd->db;
save_db_length= thd->db_length;
@@ -1590,7 +1640,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
if (thd->query_error)
goto err; // mysql_parse took care of the error send
- thd->proc_info = "Opening master dump table";
+ thd_proc_info(thd, "Opening master dump table");
tables.lock_type = TL_WRITE;
if (!open_ltable(thd, &tables, TL_WRITE))
{
@@ -1599,7 +1649,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
}
file = tables.table->file;
- thd->proc_info = "Reading master dump table data";
+ thd_proc_info(thd, "Reading master dump table data");
/* Copy the data file */
if (file->net_read_dump(net))
{
@@ -1611,7 +1661,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
check_opt.init();
check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
- thd->proc_info = "Rebuilding the index on master dump table";
+ thd_proc_info(thd, "Rebuilding the index on master dump table");
/*
We do not want repair() to spam us with messages
just send them to the error log, and report the failure in case of
@@ -2952,9 +3002,9 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
#endif
if (thd_type == SLAVE_THD_SQL)
- thd->proc_info= "Waiting for the next event in relay log";
+ thd_proc_info(thd, "Waiting for the next event in relay log");
else
- thd->proc_info= "Waiting for master update";
+ thd_proc_info(thd, "Waiting for master update");
thd->version=refresh_version;
thd->set_time();
DBUG_RETURN(0);
@@ -3572,7 +3622,7 @@ slave_begin:
goto err;
}
- thd->proc_info = "Connecting to master";
+ thd_proc_info(thd, "Connecting to master");
// we can get killed during safe_connect
if (!safe_connect(thd, mysql, mi))
{
@@ -3599,7 +3649,7 @@ connected:
// TODO: the assignment below should be under mutex (5.0)
mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
thd->slave_net = &mysql->net;
- thd->proc_info = "Checking master version";
+ thd_proc_info(thd, "Checking master version");
if (get_master_version_and_clock(mysql, mi))
goto err;
@@ -3610,7 +3660,7 @@ connected:
If fails, this is not fatal - we just print the error message and go
on with life.
*/
- thd->proc_info = "Registering slave on master";
+ thd_proc_info(thd, "Registering slave on master");
if (register_slave_on_master(mysql))
goto err;
}
@@ -3619,7 +3669,7 @@ connected:
while (!io_slave_killed(thd,mi))
{
bool suppress_warnings= 0;
- thd->proc_info = "Requesting binlog dump";
+ thd_proc_info(thd, "Requesting binlog dump");
if (request_dump(mysql, mi, &suppress_warnings))
{
sql_print_error("Failed on request_dump()");
@@ -3631,7 +3681,7 @@ dump");
}
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
- thd->proc_info= "Waiting to reconnect after a failed binlog dump request";
+ thd_proc_info(thd, "Waiting to reconnect after a failed binlog dump request");
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->clear_active_vio();
#endif
@@ -3655,7 +3705,7 @@ dump");
goto err;
}
- thd->proc_info = "Reconnecting after a failed binlog dump request";
+ thd_proc_info(thd, "Reconnecting after a failed binlog dump request");
if (!suppress_warnings)
sql_print_error("Slave I/O thread: failed dump request, \
reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
@@ -3682,7 +3732,7 @@ after reconnect");
important thing is to not confuse users by saying "reading" whereas
we're in fact receiving nothing.
*/
- thd->proc_info= "Waiting for master to send event";
+ thd_proc_info(thd, "Waiting for master to send event");
event_len= read_event(mysql, mi, &suppress_warnings);
if (io_slave_killed(thd,mi))
{
@@ -3713,7 +3763,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
goto err;
}
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
- thd->proc_info = "Waiting to reconnect after a failed master event read";
+ thd_proc_info(thd, "Waiting to reconnect after a failed master event read");
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->clear_active_vio();
#endif
@@ -3732,7 +3782,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
reconnect after a failed read");
goto err;
}
- thd->proc_info = "Reconnecting after a failed master event read";
+ thd_proc_info(thd, "Reconnecting after a failed master event read");
if (!suppress_warnings)
sql_print_information("Slave I/O thread: Failed reading log event, \
reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
@@ -3749,7 +3799,7 @@ reconnect done to recover from failed read");
} // if (event_len == packet_error)
retry_count=0; // ok event, reset retry counter
- thd->proc_info = "Queueing master event to the relay log";
+ thd_proc_info(thd, "Queueing master event to the relay log");
if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
event_len))
{
@@ -3831,7 +3881,7 @@ err:
mi->mysql=0;
}
write_ignored_events_info_to_relay_log(thd, mi);
- thd->proc_info = "Waiting for slave mutex on exit";
+ thd_proc_info(thd, "Waiting for slave mutex on exit");
pthread_mutex_lock(&mi->run_lock);
/* Forget the relay log's format */
@@ -3855,6 +3905,7 @@ err:
delete the mi structure leading to a crash! (see BUG#25306 for details)
*/
pthread_cond_broadcast(&mi->stop_cond); // tell the world we are done
+ DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
pthread_mutex_unlock(&mi->run_lock);
#ifndef DBUG_OFF
if (abort_slave_event_count && !events_till_abort)
@@ -4024,7 +4075,7 @@ Slave SQL thread aborted. Can't execute init_slave query");
while (!sql_slave_killed(thd,rli))
{
- thd->proc_info = "Reading event from the relay log";
+ thd_proc_info(thd, "Reading event from the relay log");
DBUG_ASSERT(rli->sql_thd == thd);
THD_CHECK_SENTRY(thd);
if (exec_relay_log_event(thd,rli))
@@ -4056,7 +4107,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
thd->query= 0;
thd->query_length= 0;
VOID(pthread_mutex_unlock(&LOCK_thread_count));
- thd->proc_info = "Waiting for slave mutex on exit";
+ thd_proc_info(thd, "Waiting for slave mutex on exit");
pthread_mutex_lock(&rli->run_lock);
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
pthread_mutex_lock(&rli->data_lock);
@@ -4103,6 +4154,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
*/
const int eta= rli->events_till_abort;
#endif
+ DBUG_EXECUTE_IF("simulate_slave_delay_at_terminate_bug38694", sleep(5););
pthread_mutex_unlock(&rli->run_lock); // tell the world we are done
#ifndef DBUG_OFF // TODO: reconsider the code below
diff --git a/sql/slave.h b/sql/slave.h
index da548e145d3..5ae596f1eb5 100644
--- a/sql/slave.h
+++ b/sql/slave.h
@@ -504,10 +504,6 @@ bool flush_relay_log_info(RELAY_LOG_INFO* rli);
int register_slave_on_master(MYSQL* mysql);
int terminate_slave_threads(MASTER_INFO* mi, int thread_mask,
bool skip_lock = 0);
-int terminate_slave_thread(THD* thd, pthread_mutex_t* term_mutex,
- pthread_mutex_t* cond_lock,
- pthread_cond_t* term_cond,
- volatile uint* slave_running);
int start_slave_threads(bool need_slave_mutex, bool wait_for_start,
MASTER_INFO* mi, const char* master_info_fname,
const char* slave_info_fname, int thread_mask);
diff --git a/sql/sp.cc b/sql/sp.cc
index 3af51b82521..2450e9564d0 100644
--- a/sql/sp.cc
+++ b/sql/sp.cc
@@ -646,7 +646,7 @@ db_create_routine(THD *thd, int type, sp_head *sp)
/* Such a statement can always go directly to binlog, no trans cache */
Query_log_event qinfo(thd, log_query.c_ptr(), log_query.length(), 0,
- FALSE);
+ FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
@@ -680,7 +680,8 @@ db_drop_routine(THD *thd, int type, sp_name *name)
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -725,7 +726,8 @@ db_update_routine(THD *thd, int type, sp_name *name, st_sp_chistics *chistics)
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 76b0f2e22d2..240948d217c 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1103,15 +1103,36 @@ sp_head::execute(THD *thd)
*/
thd->spcont->callers_arena= &backup_arena;
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ /* Discard the initial part of executing routines. */
+ thd->profiling.discard_current_query();
+#endif
do
{
sp_instr *i;
uint hip; // Handler ip
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ /*
+ Treat each "instr" of a routine as discrete unit that could be profiled.
+ Profiling only records information for segments of code that set the
+ source of the query, and almost all kinds of instructions in s-p do not.
+ */
+ thd->profiling.finish_current_query();
+ thd->profiling.start_new_query("continuing inside routine");
+#endif
+
i = get_instr(ip); // Returns NULL when we're done.
if (i == NULL)
+ {
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.discard_current_query();
+#endif
break;
+ }
+
DBUG_PRINT("execute", ("Instruction %u", ip));
+
/* Don't change NOW() in FUNCTION or TRIGGER */
if (!thd->in_sub_stmt)
thd->set_time(); // Make current_time() et al work
@@ -1188,6 +1209,10 @@ sp_head::execute(THD *thd)
}
} while (!err_status && !thd->killed);
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.finish_current_query();
+ thd->profiling.start_new_query("tail end of routine");
+#endif
thd->restore_active_arena(&execute_arena, &backup_arena);
thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
@@ -1605,7 +1630,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount,
if (need_binlog_call && thd->binlog_evt_union.unioned_events)
{
Query_log_event qinfo(thd, binlog_buf.ptr(), binlog_buf.length(),
- thd->binlog_evt_union.unioned_events_trans, FALSE);
+ thd->binlog_evt_union.unioned_events_trans,
+ FALSE, THD::KILLED_NO_VALUE);
if (mysql_bin_log.write(&qinfo) &&
thd->binlog_evt_union.unioned_events_trans)
{
@@ -1928,17 +1954,16 @@ sp_head::restore_lex(THD *thd)
DBUG_VOID_RETURN;
}
-void
+int
sp_head::push_backpatch(sp_instr *i, sp_label_t *lab)
{
bp_t *bp= (bp_t *)sql_alloc(sizeof(bp_t));
- if (bp)
- {
- bp->lab= lab;
- bp->instr= i;
- (void)m_backpatch.push_front(bp);
- }
+ if (!bp)
+ return 1;
+ bp->lab= lab;
+ bp->instr= i;
+ return m_backpatch.push_front(bp);
}
void
@@ -2013,7 +2038,7 @@ sp_head::fill_field_definition(THD *thd, LEX *lex,
}
-void
+int
sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
{
m_cont_level+= 1;
@@ -2021,15 +2046,17 @@ sp_head::new_cont_backpatch(sp_instr_opt_meta *i)
{
/* Use the cont. destination slot to store the level */
i->m_cont_dest= m_cont_level;
- (void)m_cont_backpatch.push_front(i);
+ if (m_cont_backpatch.push_front(i))
+ return 1;
}
+ return 0;
}
-void
+int
sp_head::add_cont_backpatch(sp_instr_opt_meta *i)
{
i->m_cont_dest= m_cont_level;
- (void)m_cont_backpatch.push_front(i);
+ return m_cont_backpatch.push_front(i);
}
void
@@ -2211,7 +2238,7 @@ sp_head::show_create_procedure(THD *thd)
instr Instruction
*/
-void sp_head::add_instr(sp_instr *instr)
+int sp_head::add_instr(sp_instr *instr)
{
instr->free_list= m_thd->free_list;
m_thd->free_list= 0;
@@ -2222,7 +2249,7 @@ void sp_head::add_instr(sp_instr *instr)
entire stored procedure, as their life span is equal.
*/
instr->mem_root= &main_mem_root;
- insert_dynamic(&m_instr, (gptr)&instr);
+ return insert_dynamic(&m_instr, (gptr)&instr);
}
@@ -2518,9 +2545,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
m_lex->unit.cleanup();
- thd->proc_info="closing tables";
+ thd_proc_info(thd, "closing tables");
close_thread_tables(thd);
- thd->proc_info= 0;
+ thd_proc_info(thd, 0);
if (m_lex->query_tables_own_last)
{
@@ -2608,6 +2635,10 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
query= thd->query;
query_length= thd->query_length;
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ /* This s-p instr is profilable and will be captured. */
+ thd->profiling.set_query_source(m_query.str, m_query.length);
+#endif
if (!(res= alloc_query(thd, m_query.str, m_query.length+1)) &&
!(res=subst_spvars(thd, this, &m_query)))
{
diff --git a/sql/sp_head.h b/sql/sp_head.h
index 91f465a4e2a..c54dc7401c4 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -226,7 +226,7 @@ public:
int
show_create_function(THD *thd);
- void
+ int
add_instr(sp_instr *instr);
inline uint
@@ -254,7 +254,7 @@ public:
restore_lex(THD *thd);
// Put the instruction on the backpatch list, associated with the label.
- void
+ int
push_backpatch(sp_instr *, struct sp_label *);
// Update all instruction with this label in the backpatch list to
@@ -263,11 +263,11 @@ public:
backpatch(struct sp_label *);
// Start a new cont. backpatch level. If 'i' is NULL, the level is just incr.
- void
+ int
new_cont_backpatch(sp_instr_opt_meta *i);
// Add an instruction to the current level
- void
+ int
add_cont_backpatch(sp_instr_opt_meta *i);
// Backpatch (and pop) the current level to the current position.
diff --git a/sql/sp_pcontext.cc b/sql/sp_pcontext.cc
index 780243cc79f..265964d3d45 100644
--- a/sql/sp_pcontext.cc
+++ b/sql/sp_pcontext.cc
@@ -263,7 +263,8 @@ sp_pcontext::push_variable(LEX_STRING *name, enum enum_field_types type,
p->mode= mode;
p->offset= current_var_count();
p->dflt= NULL;
- insert_dynamic(&m_vars, (gptr)&p);
+ if (insert_dynamic(&m_vars, (gptr)&p))
+ return NULL;
return p;
}
@@ -308,18 +309,17 @@ sp_pcontext::find_label(char *name)
return NULL;
}
-void
+int
sp_pcontext::push_cond(LEX_STRING *name, sp_cond_type_t *val)
{
sp_cond_t *p= (sp_cond_t *)sql_alloc(sizeof(sp_cond_t));
- if (p)
- {
- p->name.str= name->str;
- p->name.length= name->length;
- p->val= val;
- insert_dynamic(&m_conds, (gptr)&p);
- }
+ if (p == NULL)
+ return 1;
+ p->name.str= name->str;
+ p->name.length= name->length;
+ p->val= val;
+ return insert_dynamic(&m_conds, (gptr)&p);
}
/*
@@ -382,7 +382,7 @@ sp_pcontext::find_handler(sp_cond_type_t *cond)
return FALSE;
}
-void
+int
sp_pcontext::push_cursor(LEX_STRING *name)
{
LEX_STRING n;
@@ -391,7 +391,7 @@ sp_pcontext::push_cursor(LEX_STRING *name)
m_max_cursor_index+= 1;
n.str= name->str;
n.length= name->length;
- insert_dynamic(&m_cursors, (gptr)&n);
+ return insert_dynamic(&m_cursors, (gptr)&n);
}
/*
diff --git a/sql/sp_pcontext.h b/sql/sp_pcontext.h
index 5bffda79f98..db8bed349f2 100644
--- a/sql/sp_pcontext.h
+++ b/sql/sp_pcontext.h
@@ -323,7 +323,7 @@ public:
// Conditions
//
- void
+ int
push_cond(LEX_STRING *name, sp_cond_type_t *val);
inline void
@@ -365,7 +365,7 @@ public:
// Cursors
//
- void
+ int
push_cursor(LEX_STRING *name);
my_bool
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index b2d0304f007..f61304a1e26 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -1506,7 +1506,8 @@ bool change_password(THD *thd, const char *host, const char *user,
acl_user->host.hostname ? acl_user->host.hostname : "",
new_password));
thd->clear_error();
- Query_log_event qinfo(thd, buff, query_length, 0, FALSE);
+ Query_log_event qinfo(thd, buff, query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
end:
@@ -3014,7 +3015,8 @@ int mysql_table_grant(THD *thd, TABLE_LIST *table_list,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -3181,7 +3183,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list, bool is_proc,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -3294,7 +3297,8 @@ bool mysql_grant(THD *thd, const char *db, List &list,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -5404,7 +5408,8 @@ bool mysql_create_user(THD *thd, List &list)
if (some_users_created && mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
@@ -5473,7 +5478,8 @@ bool mysql_drop_user(THD *thd, List &list)
if (some_users_deleted && mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
@@ -5553,7 +5559,8 @@ bool mysql_rename_user(THD *thd, List &list)
if (some_users_renamed && mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
@@ -5731,7 +5738,8 @@ bool mysql_revoke_all(THD *thd, List &list)
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index b43085436e5..854e603d21a 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -360,7 +360,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
*/
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
- thd->proc_info="Flushing tables";
+ thd_proc_info(thd, "Flushing tables");
close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL,
@@ -416,7 +416,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
pthread_mutex_unlock(&thd->mysys_var->mutex);
}
DBUG_RETURN(result);
@@ -609,7 +609,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
good idea to turn off OPTION_TABLE_LOCK flag.
*/
DBUG_ASSERT(thd->lex->requires_prelocking());
- thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ thd->options&= ~(OPTION_TABLE_LOCK);
}
DBUG_VOID_RETURN;
@@ -793,18 +793,9 @@ void close_temporary_tables(THD *thd)
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);
+ 0, FALSE, THD::NOT_KILLED);
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
- "killed", because it's not really a statement updating data, and there
- are 99.99% chances it will succeed on slave.
- If a real update (one updating a persistent table) was killed on the
- master, then this real update will be logged with error_code=killed,
- rightfully causing the slave to stop.
- */
- qinfo.error_code= 0;
+ DBUG_ASSERT(qinfo.error_code == 0);
mysql_bin_log.write(&qinfo);
}
else
@@ -1211,7 +1202,7 @@ void wait_for_refresh(THD *thd)
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
proc_info=thd->proc_info;
- thd->proc_info="Waiting for table";
+ thd_proc_info(thd, "Waiting for table");
if (!thd->killed)
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@@ -1219,7 +1210,7 @@ void wait_for_refresh(THD *thd)
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
- thd->proc_info= proc_info;
+ thd_proc_info(thd, proc_info);
pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_VOID_RETURN;
}
@@ -2323,7 +2314,7 @@ bool wait_for_tables(THD *thd)
bool result;
DBUG_ENTER("wait_for_tables");
- thd->proc_info="Waiting for tables";
+ thd_proc_info(thd, "Waiting for tables");
pthread_mutex_lock(&LOCK_open);
while (!thd->killed)
{
@@ -2339,12 +2330,12 @@ bool wait_for_tables(THD *thd)
else
{
/* Now we can open all tables without any interference */
- thd->proc_info="Reopen tables";
+ thd_proc_info(thd, "Reopen tables");
thd->version= refresh_version;
result=reopen_tables(thd,0,0);
}
pthread_mutex_unlock(&LOCK_open);
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
DBUG_RETURN(result);
}
@@ -2562,7 +2553,8 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
{
end = strxmov(strmov(query, "DELETE FROM `"),
db,"`.`",name,"`", NullS);
- Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE);
+ Query_log_event qinfo(thd, query, (ulong)(end-query),
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
my_free(query, MYF(0));
}
@@ -2645,7 +2637,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
restart:
*counter= 0;
query_tables_last_own= 0;
- thd->proc_info="Opening tables";
+ thd_proc_info(thd, "Opening tables");
/*
If we are not already executing prelocked statement and don't have
@@ -2873,7 +2865,7 @@ process_view_routines:
}
err:
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
if (query_tables_last_own)
@@ -2947,7 +2939,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
bool refresh;
DBUG_ENTER("open_ltable");
- thd->proc_info="Opening table";
+ thd_proc_info(thd, "Opening table");
thd->current_tablenr= 0;
/* open_ltable can be used only for BASIC TABLEs */
table_list->required_type= FRMTYPE_TABLE;
@@ -2974,7 +2966,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
table= 0;
}
}
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
DBUG_RETURN(table);
}
@@ -3194,7 +3186,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
{
if (thd->lex->requires_prelocking())
{
- thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ thd->options&= ~(OPTION_TABLE_LOCK);
thd->in_lock_tables=0;
}
DBUG_RETURN(-1);
@@ -3227,7 +3219,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
ha_rollback_stmt(thd);
mysql_unlock_tables(thd, thd->locked_tables);
thd->locked_tables= 0;
- thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ thd->options&= ~(OPTION_TABLE_LOCK);
DBUG_RETURN(-1);
}
}
@@ -6236,7 +6228,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
List_iterator li(*(select_lex->ftfunc_list));
Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
- thd->proc_info="FULLTEXT initialization";
+ thd_proc_info(thd, "FULLTEXT initialization");
while ((ifm=li++))
ifm->init_search(no_order);
diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc
index bd56994e216..b618ded8079 100644
--- a/sql/sql_cache.cc
+++ b/sql/sql_cache.cc
@@ -706,6 +706,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
void query_cache_abort(NET *net)
{
DBUG_ENTER("query_cache_abort");
+ THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
@@ -724,6 +725,7 @@ void query_cache_abort(NET *net)
net->query_cache_query);
if (query_block) // Test if changed by other thread
{
+ thd_proc_info(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
// The following call will remove the lock on query_block
@@ -772,6 +774,7 @@ void query_cache_end_of_result(THD *thd)
query_block= ((Query_cache_block*) thd->net.query_cache_query);
if (query_block)
{
+ thd_proc_info(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
@@ -1194,6 +1197,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_PRINT("qcache", ("No active database"));
}
+ thd_proc_info(thd, "checking query cache for query");
+
// fill all gaps between fields with 0 to get repeatable key
bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
flags.client_long_flag= test(thd->client_capabilities & CLIENT_LONG_FLAG);
@@ -1277,6 +1282,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
}
// Check access;
+ thd_proc_info(thd, "checking privileges on cached query");
block_table= query_block->table(0);
block_table_end= block_table+query_block->n_tables;
for (; block_table != block_table_end; block_table++)
@@ -1369,6 +1375,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
Send cached result to client
*/
#ifndef EMBEDDED_LIBRARY
+ thd_proc_info(thd, "sending cached result to client");
do
{
DBUG_PRINT("qcache", ("Results (len: %lu used: %lu headers: %lu)",
@@ -1446,9 +1453,11 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
{
+ THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate (changed table list)");
if (tables_used)
{
+ thd_proc_info(thd, "invalidating query cache entries (table list)");
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
@@ -1479,9 +1488,11 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
*/
void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
{
+ THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate_locked_for_write");
if (tables_used)
{
+ thd_proc_info(thd, "invalidating query cache entries (table)");
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
@@ -1531,6 +1542,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
+ thd_proc_info(thd, "invalidating query cache entries (key)");
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions) // used for innodb => has_transactions() is TRUE
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 4389fd5039e..f2e04647452 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -165,6 +165,20 @@ Open_tables_state::Open_tables_state(ulong version_arg)
reset_open_tables_state();
}
+extern "C"
+const char *set_thd_proc_info(THD *thd, const char *info,
+ const char *calling_function,
+ const char *calling_file,
+ const unsigned int calling_line)
+{
+ const char *old_info= thd->proc_info;
+ DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, info));
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.status_change(info, calling_function, calling_file, calling_line);
+#endif
+ thd->proc_info= info;
+ return old_info;
+}
THD::THD()
@@ -258,6 +272,9 @@ THD::THD()
init();
/* Initialize sub structures */
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ profiling.set_thd(this);
+#endif
user_connect=(USER_CONN *)0;
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
diff --git a/sql/sql_class.h b/sql/sql_class.h
index d4f054a2b19..82c464cb475 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -547,6 +547,7 @@ struct system_variables
ulong optimizer_prune_level;
ulong optimizer_search_depth;
ulong preload_buff_size;
+ ulong profiling_history_size;
ulong query_cache_type;
ulong read_buff_size;
ulong read_rnd_buff_size;
@@ -1258,6 +1259,9 @@ public:
Points to info-string that we show in SHOW PROCESSLIST
You are supposed to update thd->proc_info only if you have coded
a time-consuming piece that MySQL can get stuck in for a long time.
+
+ Set it using the thd_proc_info(THD *thread, const char *message)
+ macro/function.
*/
const char *proc_info;
@@ -1430,6 +1434,10 @@ public:
List warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count;
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ PROFILING profiling;
+#endif
+
/*
Id of current query. Statement can be reused to execute several queries
query_id is global in context of the whole MySQL server.
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 80fea3ef1b1..be538783458 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -70,7 +70,7 @@ static byte* dboptions_get_key(my_dbopt_t *opt, uint *length,
static inline void write_to_binlog(THD *thd, char *query, uint q_len,
char *db, uint db_len)
{
- Query_log_event qinfo(thd, query, q_len, 0, 0);
+ Query_log_event qinfo(thd, query, q_len, 0, 0, THD::NOT_KILLED);
qinfo.error_code= 0;
qinfo.db= db;
qinfo.db_len= db_len;
@@ -562,7 +562,7 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info,
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, query, query_length, 0,
- /* suppress_use */ TRUE);
+ /* suppress_use */ TRUE, THD::NOT_KILLED);
/*
Write should use the database being created as the "current
@@ -645,7 +645,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info)
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length, 0,
- /* suppress_use */ TRUE);
+ /* suppress_use */ TRUE, THD::NOT_KILLED);
/*
Write should use the database being created as the "current
@@ -770,7 +770,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent)
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, query, query_length, 0,
- /* suppress_use */ TRUE);
+ /* suppress_use */ TRUE, THD::NOT_KILLED);
/*
Write should use the database being created as the "current
database" and not the threads current database, which is the
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 38f89683065..7a48044877b 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -56,7 +56,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
table->map=1;
if (mysql_prepare_delete(thd, table_list, &conds))
@@ -220,7 +220,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
deleted=0L;
init_ftfuncs(thd, select_lex, 1);
- thd->proc_info="updating";
+ thd_proc_info(thd, "updating");
if (triggers_applicable)
{
@@ -288,7 +288,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
killed_status= thd->killed;
error= (killed_status == THD::NOT_KILLED)? error : 1;
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
end_read_record(&info);
free_io_cache(table); // Will not do any harm
if (options & OPTION_QUICK)
@@ -522,7 +522,7 @@ multi_delete::prepare(List- &values, SELECT_LEX_UNIT *u)
DBUG_ENTER("multi_delete::prepare");
unit= u;
do_delete= 1;
- thd->proc_info="deleting from main table";
+ thd_proc_info(thd, "deleting from main table");
DBUG_RETURN(0);
}
@@ -730,7 +730,7 @@ void multi_delete::send_error(uint errcode,const char *err)
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
+ transactional_tables, FALSE, THD::KILLED_NO_VALUE);
mysql_bin_log.write(&qinfo);
}
thd->transaction.all.modified_non_trans_table= true;
@@ -823,7 +823,7 @@ int multi_delete::do_deletes()
bool multi_delete::send_eof()
{
THD::killed_state killed_status= THD::NOT_KILLED;
- thd->proc_info="deleting from reference tables";
+ thd_proc_info(thd, "deleting from reference tables");
/* Does deletes for the last n - 1 tables, returns 0 if ok */
int local_error= do_deletes(); // returns 0 if success
@@ -832,7 +832,7 @@ bool multi_delete::send_eof()
local_error= local_error || error;
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
/* reset used flags */
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
/*
We must invalidate the query cache before binlog writing and
@@ -958,7 +958,7 @@ end:
{
thd->clear_error();
Query_log_event qinfo(thd, thd->query, thd->query_length,
- 0, FALSE);
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
send_ok(thd); // This should return record count
@@ -979,7 +979,7 @@ end:
/* Probably InnoDB table */
ulonglong save_options= thd->options;
table_list->lock_type= TL_WRITE;
- thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
+ thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
ha_enable_transaction(thd, FALSE);
mysql_init_select(thd->lex);
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index c376f1b3d1d..721b365a7b9 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -190,6 +190,14 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen)
tables->db, tables->table_name, tables->alias,
(int) reopen));
+ if (tables->schema_table)
+ {
+ my_error(ER_WRONG_USAGE, MYF(0), "HANDLER OPEN",
+ INFORMATION_SCHEMA_NAME.str);
+ DBUG_PRINT("exit",("ERROR"));
+ DBUG_RETURN(TRUE);
+ }
+
if (! hash_inited(&thd->handler_tables_hash))
{
/*
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 48438ba033c..d9027e3f5b9 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -622,7 +622,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
}
lock_type= table_list->lock_type;
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
thd->used_tables=0;
values= its++;
value_count= values->elements;
@@ -708,7 +708,11 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
error=0;
id=0;
- thd->proc_info="update";
+
+ thd_proc_info(thd, "update");
+ if (duplic != DUP_ERROR || ignore)
+ table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
+
if (duplic == DUP_REPLACE)
{
if (!table->triggers || !table->triggers->has_delete_triggers())
@@ -945,7 +949,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->lock=0;
}
}
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
table->next_number_field=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
thd->next_insert_id=0; // Reset this if wrongly used
@@ -1723,7 +1727,7 @@ I_List delayed_threads;
static
Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
{
- thd->proc_info="waiting for delay_list";
+ thd_proc_info(thd, "waiting for delay_list");
pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list
I_List_iterator it(delayed_threads);
Delayed_insert *di;
@@ -1805,7 +1809,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
*/
if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads)
DBUG_RETURN(0);
- thd->proc_info="Creating delayed handler";
+ thd_proc_info(thd, "Creating delayed handler");
pthread_mutex_lock(&LOCK_delayed_create);
/*
The first search above was done without LOCK_delayed_create.
@@ -1852,13 +1856,13 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list)
}
/* Wait until table is open */
- thd->proc_info="waiting for handler open";
+ thd_proc_info(thd, "waiting for handler open");
while (!di->thd.killed && !di->table && !thd->killed)
{
pthread_cond_wait(&di->cond_client, &di->mutex);
}
pthread_mutex_unlock(&di->mutex);
- thd->proc_info="got old table";
+ thd_proc_info(thd, "got old table");
if (di->thd.killed)
{
if (di->thd.net.report_error)
@@ -1933,13 +1937,13 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
tables_in_use++;
if (!thd.lock) // Table is not locked
{
- client_thd->proc_info="waiting for handler lock";
+ thd_proc_info(client_thd, "waiting for handler lock");
pthread_cond_signal(&cond); // Tell handler to lock table
while (!dead && !thd.lock && ! client_thd->killed)
{
pthread_cond_wait(&cond_client,&mutex);
}
- client_thd->proc_info="got handler lock";
+ thd_proc_info(client_thd, "got handler lock");
if (client_thd->killed)
goto error;
if (dead)
@@ -1956,7 +1960,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
bytes. Since the table copy is used for creating one record only,
the other record buffers and alignment are unnecessary.
*/
- client_thd->proc_info="allocating local table";
+ thd_proc_info(client_thd, "allocating local table");
copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
(table->s->fields+1)*sizeof(Field**)+
table->s->reclength);
@@ -2037,11 +2041,11 @@ int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore,
Delayed_insert *di=thd->di;
DBUG_ENTER("write_delayed");
- thd->proc_info="waiting for handler insert";
+ thd_proc_info(thd, "waiting for handler insert");
pthread_mutex_lock(&di->mutex);
while (di->stacked_inserts >= delayed_queue_size && !thd->killed)
pthread_cond_wait(&di->cond_client,&di->mutex);
- thd->proc_info="storing row into queue";
+ thd_proc_info(thd, "storing row into queue");
if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
goto err;
@@ -2271,7 +2275,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
/* Information for pthread_kill */
di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond;
- di->thd.proc_info="Waiting for INSERT";
+ thd_proc_info(&(di->thd), "Waiting for INSERT");
DBUG_PRINT("info",("Waiting for someone to insert rows"));
while (!thd->killed)
@@ -2306,7 +2310,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
}
- di->thd.proc_info=0;
+ thd_proc_info(&(di->thd), 0);
if (di->tables_in_use && ! thd->lock)
{
@@ -2425,7 +2429,7 @@ bool Delayed_insert::handle_inserts(void)
table->next_number_field=table->found_next_number_field;
- thd.proc_info="upgrading lock";
+ thd_proc_info(&thd, "upgrading lock");
if (thr_upgrade_write_delay_lock(*thd.lock->locks))
{
/* This can only happen if thread is killed by shutdown */
@@ -2433,7 +2437,7 @@ bool Delayed_insert::handle_inserts(void)
goto err;
}
- thd.proc_info="insert";
+ thd_proc_info(&thd, "insert");
max_rows= delayed_insert_limit;
if (thd.killed || table->needs_reopen_or_name_lock())
{
@@ -2539,7 +2543,8 @@ bool Delayed_insert::handle_inserts(void)
thd.variables.time_zone = row->time_zone;
}
- Query_log_event qinfo(&thd, row->query, row->query_length, 0, FALSE);
+ Query_log_event qinfo(&thd, row->query, row->query_length,
+ 0, FALSE, THD::KILLED_NO_VALUE);
mysql_bin_log.write(&qinfo);
thd.time_zone_used = backup_time_zone_used;
@@ -2567,7 +2572,7 @@ bool Delayed_insert::handle_inserts(void)
{
if (tables_in_use)
pthread_cond_broadcast(&cond_client); // If waiting clients
- thd.proc_info="reschedule";
+ thd_proc_info(&thd, "reschedule");
pthread_mutex_unlock(&mutex);
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{
@@ -2586,14 +2591,14 @@ bool Delayed_insert::handle_inserts(void)
if (!using_bin_log)
table->file->extra(HA_EXTRA_WRITE_CACHE);
pthread_mutex_lock(&mutex);
- thd.proc_info="insert";
+ thd_proc_info(&thd, "insert");
}
if (tables_in_use)
pthread_cond_broadcast(&cond_client); // If waiting clients
}
}
- thd.proc_info=0;
+ thd_proc_info(&thd, 0);
table->next_number_field=0;
pthread_mutex_unlock(&mutex);
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
@@ -3101,7 +3106,7 @@ void select_insert::abort()
if (mysql_bin_log.is_open())
{
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_table, FALSE);
+ transactional_table, FALSE, THD::KILLED_NO_VALUE);
mysql_bin_log.write(&qinfo);
}
if (thd->transaction.stmt.modified_non_trans_table)
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 4c53772bc25..436f41dd209 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -200,10 +200,11 @@ void lex_start(THD *thd)
lex->proc_list.first= 0;
lex->escape_used= FALSE;
lex->reset_query_tables_list(FALSE);
-
+ lex->profile_options= PROFILE_NONE;
lex->nest_level=0 ;
lex->allow_sum_func= 0;
lex->in_sum_func= NULL;
+ lex->protect_against_global_read_lock= FALSE;
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 9f020f4adc5..5c0367632e1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -94,8 +94,13 @@ enum enum_sql_command {
SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
- /* This should be the last !!! */
+ SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
+ /*
+ When a command is added here, be sure it's also added in mysqld.cc
+ in "struct show_var_st status_vars[]= {" ...
+ */
+ /* This should be the last !!! */
SQLCOM_END
};
@@ -1076,6 +1081,9 @@ typedef struct st_lex : public Query_tables_list
enum enum_var_type option_type;
enum enum_view_create_mode create_view_mode;
enum enum_drop_mode drop_mode;
+
+ uint profile_query_id;
+ uint profile_options;
uint uint_geom_type;
uint grant, grant_tot_col, which_columns;
uint fk_delete_opt, fk_update_opt, fk_match_option;
@@ -1176,6 +1184,22 @@ typedef struct st_lex : public Query_tables_list
bool escape_used;
+ /*
+ Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE.
+
+ Protect from a impending GRL as otherwise the thread might deadlock
+ if it starts waiting for the GRL in mysql_lock_tables.
+
+ The protection is needed because there is a race between setting
+ the global read lock and waiting for all open tables to be closed.
+ The problem is a circular wait where a thread holding "old" open
+ tables will wait for the global read lock to be released while the
+ thread holding the global read lock will wait for all "old" open
+ tables to be closed -- the flush part of flush tables with read
+ lock.
+ */
+ bool protect_against_global_read_lock;
+
st_lex();
virtual ~st_lex()
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ba887486aa1..507805ec0c4 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -178,14 +178,14 @@ static bool end_active_trans(THD *thd)
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
- DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options));
+ DBUG_PRINT("info",("options: 0x%llx", thd->options));
/* Safety if one did "drop table" on locked tables */
if (!thd->locked_tables)
thd->options&= ~OPTION_TABLE_LOCK;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->options&= ~OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
}
DBUG_RETURN(error);
@@ -211,7 +211,7 @@ static bool begin_trans(THD *thd)
{
LEX *lex= thd->lex;
thd->transaction.all.modified_non_trans_table= FALSE;
- thd->options|= (ulong) OPTION_BEGIN;
+ thd->options|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
error= ha_start_consistent_snapshot(thd);
@@ -1099,7 +1099,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
Vio* save_vio;
ulong save_client_capabilities;
- thd->proc_info= "Execution of init_command";
+ thd_proc_info(thd, "Execution of init_command");
/*
We need to lock init_command_var because
during execution of init_command_var query
@@ -1203,7 +1203,7 @@ pthread_handler_t handle_one_connection(void *arg)
net->compress=1; // Use compression
thd->version= refresh_version;
- thd->proc_info= 0;
+ thd_proc_info(thd, 0);
thd->command= COM_SLEEP;
thd->init_for_queries();
@@ -1219,7 +1219,7 @@ pthread_handler_t handle_one_connection(void *arg)
sctx->host_or_ip, "init_connect command failed");
sql_print_warning("%s", net->last_error);
}
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
thd->init_for_queries();
}
@@ -1311,7 +1311,7 @@ pthread_handler_t handle_bootstrap(void *arg)
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
thd->version=refresh_version;
thd->security_ctx->priv_user=
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
@@ -1355,6 +1355,10 @@ pthread_handler_t handle_bootstrap(void *arg)
thd->db_length+1+QUERY_CACHE_FLAGS_SIZE);
thd->query[length] = '\0';
DBUG_PRINT("query",("%-.4096s",thd->query));
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.set_query_source(thd->query, length);
+#endif
+
/*
We don't need to obtain LOCK_thread_count here because in bootstrap
mode we have only one thread.
@@ -1512,7 +1516,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
*/
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
res= ha_commit(thd);
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->options&= ~OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
break;
case COMMIT_RELEASE:
@@ -1530,7 +1534,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_rollback(thd))
res= -1;
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->options&= ~OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd);
@@ -1564,6 +1568,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
static bool do_command(THD *thd)
{
+ bool return_value;
char *packet= 0;
ulong packet_length;
NET *net= &thd->net;
@@ -1587,7 +1592,12 @@ static bool do_command(THD *thd)
thd->clear_error(); // Clear error message
net_new_transaction(net);
- if ((packet_length=my_net_read(net)) == packet_error)
+
+ packet_length= my_net_read(net);
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.start_new_query();
+#endif
+ if (packet_length == packet_error)
{
DBUG_PRINT("info",("Got error %d reading command from socket %s",
net->error,
@@ -1596,11 +1606,15 @@ static bool do_command(THD *thd)
/* Check if we can continue without closing the connection */
if (net->error != 3)
- DBUG_RETURN(TRUE); // We have to close it.
+ {
+ return_value= TRUE; // We have to close it.
+ goto out;
+ }
net_send_error(thd, net->last_errno, NullS);
net->error= 0;
- DBUG_RETURN(FALSE);
+ return_value= FALSE;
+ goto out;
}
else
{
@@ -1625,7 +1639,13 @@ static bool do_command(THD *thd)
command == packet[0] == COM_SLEEP).
In dispatch_command packet[packet_length] points beyond the end of packet.
*/
- DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
+ return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length));
+
+out:
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.finish_current_query();
+#endif
+ DBUG_RETURN(return_value);
}
#endif /* EMBEDDED_LIBRARY */
@@ -1931,6 +1951,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_log.write(thd,command, format, thd->query_length, thd->query);
DBUG_PRINT("query",("%-.4096s",thd->query));
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.set_query_source(thd->query, thd->query_length);
+#endif
if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
@@ -1957,6 +1980,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
next_packet++;
length--;
}
+
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.finish_current_query();
+ thd->profiling.start_new_query("continuing");
+ thd->profiling.set_query_source(next_packet, length);
+#endif
+
VOID(pthread_mutex_lock(&LOCK_thread_count));
thd->query_length= length;
thd->query= next_packet;
@@ -2273,7 +2303,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->lock || thd->open_tables || thd->derived_tables ||
thd->prelocked_mode)
{
- thd->proc_info="closing tables";
+ thd_proc_info(thd, "closing tables");
close_thread_tables(thd); /* Free tables */
}
/*
@@ -2296,9 +2326,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
log_slow_statement(thd);
- thd->proc_info="cleaning up";
+ thd_proc_info(thd, "cleaning up");
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
- thd->proc_info=0;
+ thd_proc_info(thd, 0);
thd->command=COM_SLEEP;
thd->query=0;
thd->query_length=0;
@@ -2331,7 +2361,7 @@ void log_slow_statement(THD *thd)
*/
if (thd->enable_slow_log && !thd->user_time)
{
- thd->proc_info="logging slow query";
+ thd_proc_info(thd, "logging slow query");
if ((thd->start_time > thd->time_after_lock &&
(ulong) (thd->start_time - thd->time_after_lock) >
@@ -2342,6 +2372,7 @@ void log_slow_statement(THD *thd)
/* == SQLCOM_END unless this is a SHOW command */
thd->lex->orig_sql_command == SQLCOM_END)
{
+ thd_proc_info(thd, "logging slow query");
thd->status_var.long_query_count++;
mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
}
@@ -2449,6 +2480,15 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
break;
}
#endif
+ case SCH_PROFILES:
+ /*
+ Mark this current profiling record to be discarded. We don't
+ wish to have SHOW commands show up in profiling.
+ */
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.discard_current_query();
+#endif
+ break;
case SCH_OPEN_TABLES:
case SCH_VARIABLES:
case SCH_STATUS:
@@ -2800,6 +2840,10 @@ mysql_execute_command(THD *thd)
if (res)
goto error;
+ if (!thd->locked_tables && lex->protect_against_global_read_lock &&
+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
+
if (!(res= open_and_lock_tables(thd, all_tables)))
{
if (lex->describe)
@@ -2919,6 +2963,19 @@ mysql_execute_command(THD *thd)
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
break;
}
+ case SQLCOM_SHOW_PROFILES:
+ {
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.discard_current_query();
+ res= thd->profiling.show_profiles();
+ if (res)
+ goto error;
+#else
+ my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
+ goto error;
+#endif
+ break;
+ }
case SQLCOM_SHOW_NEW_MASTER:
{
if (check_global_access(thd, REPL_SLAVE_ACL))
@@ -3587,7 +3644,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -3622,7 +3680,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -3648,7 +3707,8 @@ end_with_restore_list:
if (mysql_bin_log.is_open())
{
thd->clear_error(); // No binlog error generated
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -3660,6 +3720,9 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (update_precheck(thd, all_tables))
break;
+ if (!thd->locked_tables &&
+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
DBUG_ASSERT(select_lex->offset_limit == 0);
unit->set_limit(select_lex);
res= (up_result= mysql_update(thd, all_tables,
@@ -3686,6 +3749,15 @@ end_with_restore_list:
else
res= 0;
+ /*
+ Protection might have already been risen if its a fall through
+ from the SQLCOM_UPDATE case above.
+ */
+ if (!thd->locked_tables &&
+ lex->sql_command == SQLCOM_UPDATE_MULTI &&
+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
+
res= mysql_multi_update_prepare(thd);
#ifdef HAVE_REPLICATION
@@ -3853,7 +3925,8 @@ end_with_restore_list:
ER(ER_LOCK_OR_ACTIVE_TRANSACTION), MYF(0));
goto error;
}
-
+ if (!(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
res= mysql_truncate(thd, first_table, 0);
break;
case SQLCOM_DELETE:
@@ -3900,7 +3973,7 @@ end_with_restore_list:
if (add_item_to_list(thd, new Item_null()))
goto error;
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
if ((res= open_and_lock_tables(thd, all_tables)))
break;
@@ -4027,6 +4100,10 @@ end_with_restore_list:
if (check_one_table_access(thd, privilege, all_tables))
goto error;
+ if (!thd->locked_tables &&
+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
+
res= mysql_load(thd, lex->exchange, first_table, lex->field_list,
lex->update_list, lex->value_list, lex->duplicates,
lex->ignore, (bool) lex->local_file);
@@ -4067,7 +4144,7 @@ end_with_restore_list:
if (thd->options & OPTION_TABLE_LOCK)
{
end_active_trans(thd);
- thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ thd->options&= ~(OPTION_TABLE_LOCK);
}
if (thd->global_read_lock)
unlock_global_read_lock(thd);
@@ -4082,6 +4159,9 @@ end_with_restore_list:
goto error;
if (check_table_access(thd, LOCK_TABLES_ACL | SELECT_ACL, all_tables, 0))
goto error;
+ if (lex->protect_against_global_read_lock &&
+ !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1)))
+ goto error;
thd->in_lock_tables=1;
thd->options|= OPTION_TABLE_LOCK;
@@ -4103,7 +4183,7 @@ end_with_restore_list:
that it can't lock a table in its list
*/
end_active_trans(thd);
- thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
+ thd->options&= ~(OPTION_TABLE_LOCK);
}
thd->in_lock_tables=0;
break;
@@ -4430,7 +4510,8 @@ end_with_restore_list:
{
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -5039,6 +5120,14 @@ create_sp_error:
case SP_KEY_NOT_FOUND:
if (lex->drop_if_exists)
{
+ if (mysql_bin_log.is_open())
+ {
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ /* using_trans */ 0,
+ /* suppress use */ FALSE,
+ THD::NOT_KILLED);
+ mysql_bin_log.write(&qinfo);
+ }
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
ER_SP_DOES_NOT_EXIST, ER(ER_SP_DOES_NOT_EXIST),
SP_COM_STRING(lex), lex->spname->m_name.str);
@@ -5205,7 +5294,7 @@ create_sp_error:
thd->transaction.xid_state.xid.set(thd->lex->xid);
xid_cache_insert(&thd->transaction.xid_state);
thd->transaction.all.modified_non_trans_table= FALSE;
- thd->options|= (ulong) OPTION_BEGIN;
+ thd->options|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
send_ok(thd);
break;
@@ -5311,7 +5400,7 @@ create_sp_error:
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
- thd->options&= ~(ulong) OPTION_BEGIN;
+ thd->options&= ~OPTION_BEGIN;
thd->transaction.all.modified_non_trans_table= FALSE;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
@@ -5356,7 +5445,7 @@ create_sp_error:
send_ok(thd);
break;
}
- thd->proc_info="query end";
+ thd_proc_info(thd, "query end");
/* Two binlog-related cleanups: */
/*
@@ -5540,6 +5629,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
else
save_priv= &dummy;
+ thd_proc_info(thd, "checking permissions");
if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
{
DBUG_PRINT("error",("No database"));
@@ -5738,6 +5828,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
case SCH_COLUMN_PRIVILEGES:
case SCH_TABLE_CONSTRAINTS:
case SCH_KEY_COLUMN_USAGE:
+ case SCH_PROFILES:
break;
}
@@ -6365,7 +6456,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
thd->lex->sphead= 0;
}
lex->unit.cleanup();
- thd->proc_info="freeing items";
+ thd_proc_info(thd, "freeing items");
thd->end_statement();
thd->cleanup_after_query();
DBUG_ASSERT(thd->change_list.is_empty());
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index a07fcc37856..a20f61436a7 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2283,6 +2283,9 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
DBUG_VOID_RETURN;
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ thd->profiling.set_query_source(stmt->query, stmt->query_length);
+#endif
DBUG_PRINT("exec_query", ("%s", stmt->query));
DBUG_PRINT("info",("stmt: %p", stmt));
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
new file mode 100644
index 00000000000..551a103da10
--- /dev/null
+++ b/sql/sql_profile.cc
@@ -0,0 +1,672 @@
+/* Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+
+/**
+ @file
+
+ Implement query profiling as as list of metaphorical fences, with one fence
+ per query, and each fencepost a change of thd->proc_info state (with a
+ snapshot of system statistics). When asked, we can then iterate over the
+ fenceposts and calculate the distance between them, to inform the user what
+ happened during a particular query or thd->proc_info state.
+
+ User variables that inform profiling behavior:
+ - "profiling", boolean, session only, "Are queries profiled?"
+ - "profiling_history_size", integer, session + global, "Num queries stored?"
+*/
+
+
+#include "mysql_priv.h"
+#include "my_sys.h"
+
+#define TIME_FLOAT_DIGITS 9
+/** two vals encoded: (dec*100)+len */
+#define TIME_I_S_DECIMAL_SIZE (TIME_FLOAT_DIGITS*100)+(TIME_FLOAT_DIGITS-3)
+
+#define MAX_QUERY_LENGTH 300
+
+/* Reserved for systems that can't record the function name in source. */
+const char * const _unknown_func_ = "";
+
+/**
+ Connects Information_Schema and Profiling.
+*/
+int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables,
+ Item *cond)
+{
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+ return(thd->profiling.fill_statistics_info(thd, tables, cond));
+#else
+ my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILE", "enable-profiling");
+ return(1);
+#endif
+}
+
+ST_FIELD_INFO query_profile_statistics_info[]=
+{
+ /* name, length, type, value, maybe_null, old_name, open_method */
+ {"QUERY_ID", 20, MYSQL_TYPE_LONG, 0, false, "Query_id"},
+ {"SEQ", 20, MYSQL_TYPE_LONG, 0, false, "Seq"},
+ {"STATE", 30, MYSQL_TYPE_STRING, 0, false, "Status"},
+ {"DURATION", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, false, "Duration"},
+ {"CPU_USER", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, true, "CPU_user"},
+ {"CPU_SYSTEM", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, true, "CPU_system"},
+ {"CONTEXT_VOLUNTARY", 20, MYSQL_TYPE_LONG, 0, true, "Context_voluntary"},
+ {"CONTEXT_INVOLUNTARY", 20, MYSQL_TYPE_LONG, 0, true, "Context_involuntary"},
+ {"BLOCK_OPS_IN", 20, MYSQL_TYPE_LONG, 0, true, "Block_ops_in"},
+ {"BLOCK_OPS_OUT", 20, MYSQL_TYPE_LONG, 0, true, "Block_ops_out"},
+ {"MESSAGES_SENT", 20, MYSQL_TYPE_LONG, 0, true, "Messages_sent"},
+ {"MESSAGES_RECEIVED", 20, MYSQL_TYPE_LONG, 0, true, "Messages_received"},
+ {"PAGE_FAULTS_MAJOR", 20, MYSQL_TYPE_LONG, 0, true, "Page_faults_major"},
+ {"PAGE_FAULTS_MINOR", 20, MYSQL_TYPE_LONG, 0, true, "Page_faults_minor"},
+ {"SWAPS", 20, MYSQL_TYPE_LONG, 0, true, "Swaps"},
+ {"SOURCE_FUNCTION", 30, MYSQL_TYPE_STRING, 0, true, "Source_function"},
+ {"SOURCE_FILE", 20, MYSQL_TYPE_STRING, 0, true, "Source_file"},
+ {"SOURCE_LINE", 20, MYSQL_TYPE_LONG, 0, true, "Source_line"},
+ {NULL, 0, MYSQL_TYPE_STRING, 0, true, NULL}
+};
+
+
+int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
+{
+ int profile_options = thd->lex->profile_options;
+ int fields_include_condition_truth_values[]= {
+ FALSE, /* Query_id */
+ FALSE, /* Seq */
+ TRUE, /* Status */
+ TRUE, /* Duration */
+ profile_options & PROFILE_CPU, /* CPU_user */
+ profile_options & PROFILE_CPU, /* CPU_system */
+ profile_options & PROFILE_CONTEXT, /* Context_voluntary */
+ profile_options & PROFILE_CONTEXT, /* Context_involuntary */
+ profile_options & PROFILE_BLOCK_IO, /* Block_ops_in */
+ profile_options & PROFILE_BLOCK_IO, /* Block_ops_out */
+ profile_options & PROFILE_IPC, /* Messages_sent */
+ profile_options & PROFILE_IPC, /* Messages_received */
+ profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_major */
+ profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_minor */
+ profile_options & PROFILE_SWAPS, /* Swaps */
+ profile_options & PROFILE_SOURCE, /* Source_function */
+ profile_options & PROFILE_SOURCE, /* Source_file */
+ profile_options & PROFILE_SOURCE, /* Source_line */
+ };
+
+ ST_FIELD_INFO *field_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+ int i;
+
+ for (i= 0; schema_table->fields_info[i].field_name != NULL; i++)
+ {
+ if (! fields_include_condition_truth_values[i])
+ continue;
+
+ field_info= &schema_table->fields_info[i];
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
+ if (field)
+ {
+ field->set_name(field_info->old_name,
+ strlen(field_info->old_name),
+ system_charset_info);
+ if (add_item_to_list(thd, field))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+
+#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
+#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
+
+
+PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char
+ *status_arg)
+ :profile(profile_arg)
+{
+ collect();
+ set_label(status_arg, NULL, NULL, 0);
+}
+
+PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg,
+ const char *status_arg,
+ const char *function_arg,
+ const char *file_arg,
+ unsigned int line_arg)
+ :profile(profile_arg)
+{
+ collect();
+ set_label(status_arg, function_arg, file_arg, line_arg);
+}
+
+PROF_MEASUREMENT::~PROF_MEASUREMENT()
+{
+ if (allocated_status_memory != NULL)
+ my_free(allocated_status_memory, MYF(0));
+ status= function= file= NULL;
+}
+
+void PROF_MEASUREMENT::set_label(const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg)
+{
+ size_t sizes[3]; /* 3 == status+function+file */
+ char *cursor;
+
+ /*
+ Compute all the space we'll need to allocate one block for everything
+ we'll need, instead of N mallocs.
+ */
+ sizes[0]= (status_arg == NULL) ? 0 : strlen(status_arg) + 1;
+ sizes[1]= (function_arg == NULL) ? 0 : strlen(function_arg) + 1;
+ sizes[2]= (file_arg == NULL) ? 0 : strlen(file_arg) + 1;
+
+ allocated_status_memory= (char *) my_malloc(sizes[0] + sizes[1] + sizes[2], MYF(0));
+ DBUG_ASSERT(allocated_status_memory != NULL);
+
+ cursor= allocated_status_memory;
+
+ if (status_arg != NULL)
+ {
+ strcpy(cursor, status_arg);
+ status= cursor;
+ cursor+= sizes[0];
+ }
+ else
+ status= NULL;
+
+ if (function_arg != NULL)
+ {
+ strcpy(cursor, function_arg);
+ function= cursor;
+ cursor+= sizes[1];
+ }
+ else
+ function= NULL;
+
+ if (file_arg != NULL)
+ {
+ strcpy(cursor, file_arg);
+ file= cursor;
+ cursor+= sizes[2];
+ }
+ else
+ file= NULL;
+
+ line= line_arg;
+}
+
+/**
+ This updates the statistics for this moment of time. It captures the state
+ of the running system, so later we can compare points in time and infer what
+ happened in the mean time. It should only be called immediately upon
+ instantiation of this PROF_MEASUREMENT.
+
+ @todo Implement resource capture for OSes not like BSD.
+*/
+void PROF_MEASUREMENT::collect()
+{
+ time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
+#ifdef HAVE_GETRUSAGE
+ getrusage(RUSAGE_SELF, &rusage);
+#endif
+}
+
+
+QUERY_PROFILE::QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg)
+ :profiling(profiling_arg), profiling_query_id(0), query_source(NULL)
+{
+ profile_start= new PROF_MEASUREMENT(this, status_arg);
+ entries.push_back(profile_start);
+ profile_end= profile_start;
+}
+
+QUERY_PROFILE::~QUERY_PROFILE()
+{
+ while (! entries.is_empty())
+ delete entries.pop();
+
+ if (query_source != NULL)
+ my_free(query_source, MYF(0));
+}
+
+/**
+ @todo Provide a way to include the full text, as in SHOW PROCESSLIST.
+*/
+void QUERY_PROFILE::set_query_source(char *query_source_arg,
+ uint query_length_arg)
+{
+ /* Truncate to avoid DoS attacks. */
+ uint length= min(MAX_QUERY_LENGTH, query_length_arg);
+
+ DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
+ if (query_source_arg != NULL)
+ query_source= my_strndup(query_source_arg, length, MYF(0));
+}
+
+void QUERY_PROFILE::new_status(const char *status_arg,
+ const char *function_arg, const char *file_arg,
+ unsigned int line_arg)
+{
+ PROF_MEASUREMENT *prof;
+ DBUG_ENTER("QUERY_PROFILE::status");
+
+ DBUG_ASSERT(status_arg != NULL);
+
+ if ((function_arg != NULL) && (file_arg != NULL))
+ prof= new PROF_MEASUREMENT(this, status_arg, function_arg, file_arg, line_arg);
+ else
+ prof= new PROF_MEASUREMENT(this, status_arg);
+
+ profile_end= prof;
+ entries.push_back(prof);
+
+ DBUG_VOID_RETURN;
+}
+
+
+
+PROFILING::PROFILING()
+ :profile_id_counter(1), current(NULL), last(NULL)
+{
+}
+
+PROFILING::~PROFILING()
+{
+ while (! history.is_empty())
+ delete history.pop();
+
+ if (current != NULL)
+ delete current;
+}
+
+/**
+ A new state is given, and that signals the profiler to start a new
+ timed step for the current query's profile.
+
+ @param status_arg name of this step
+ @param function_arg calling function (usually supplied from compiler)
+ @param function_arg calling file (usually supplied from compiler)
+ @param function_arg calling line number (usually supplied from compiler)
+*/
+void PROFILING::status_change(const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg)
+{
+ DBUG_ENTER("PROFILING::status_change");
+
+ if (status_arg == NULL) /* We don't know how to handle that */
+ DBUG_VOID_RETURN;
+
+ if (current == NULL) /* This profile was already discarded. */
+ DBUG_VOID_RETURN;
+
+ if (unlikely(enabled))
+ current->new_status(status_arg, function_arg, file_arg, line_arg);
+
+ DBUG_VOID_RETURN;
+}
+
+/**
+ Prepare to start processing a new query. It is an error to do this
+ if there's a query already in process; nesting is not supported.
+
+ @param initial_state (optional) name of period before first state change
+*/
+void PROFILING::start_new_query(const char *initial_state)
+{
+ DBUG_ENTER("PROFILING::start_new_query");
+
+ /* This should never happen unless the server is radically altered. */
+ if (unlikely(current != NULL))
+ {
+ DBUG_PRINT("warning", ("profiling code was asked to start a new query "
+ "before the old query was finished. This is "
+ "probably a bug."));
+ finish_current_query();
+ }
+
+ enabled= (((thd)->options & OPTION_PROFILING) != 0);
+
+ if (! enabled) DBUG_VOID_RETURN;
+
+ DBUG_ASSERT(current == NULL);
+ current= new QUERY_PROFILE(this, initial_state);
+
+ DBUG_VOID_RETURN;
+}
+
+/**
+ Throw away the current profile, because it's useless or unwanted
+ or corrupted.
+*/
+void PROFILING::discard_current_query()
+{
+ DBUG_ENTER("PROFILING::discard_current_profile");
+
+ delete current;
+ current= NULL;
+
+ DBUG_VOID_RETURN;
+}
+
+/**
+ Try to save the current profile entry, clean up the data if it shouldn't be
+ saved, and maintain the profile history size. Naturally, this may not
+ succeed if the profile was previously discarded, and that's expected.
+*/
+void PROFILING::finish_current_query()
+{
+ DBUG_ENTER("PROFILING::finish_current_profile");
+ if (current != NULL)
+ {
+ /* The last fence-post, so we can support the span before this. */
+ status_change("ending", NULL, NULL, 0);
+
+ if ((enabled) && /* ON at start? */
+ ((thd->options & OPTION_PROFILING) != 0) && /* and ON at end? */
+ (current->query_source != NULL) &&
+ (! current->entries.is_empty()))
+ {
+ current->profiling_query_id= next_profile_id(); /* assign an id */
+
+ history.push_back(current);
+ last= current; /* never contains something that is not in the history. */
+ current= NULL;
+ }
+ else
+ {
+ delete current;
+ current= NULL;
+ }
+ }
+
+ /* Maintain the history size. */
+ while (history.elements > thd->variables.profiling_history_size)
+ delete history.pop();
+
+ DBUG_VOID_RETURN;
+}
+
+bool PROFILING::show_profiles()
+{
+ DBUG_ENTER("PROFILING::show_profiles");
+ QUERY_PROFILE *prof;
+ List
- field_list;
+
+ field_list.push_back(new Item_return_int("Query_ID", 10,
+ MYSQL_TYPE_LONG));
+ field_list.push_back(new Item_return_int("Duration", TIME_FLOAT_DIGITS-1,
+ MYSQL_TYPE_DOUBLE));
+ field_list.push_back(new Item_empty_string("Query", 40));
+
+ if (thd->protocol->send_fields(&field_list,
+ Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
+ DBUG_RETURN(TRUE);
+
+ SELECT_LEX *sel= &thd->lex->select_lex;
+ SELECT_LEX_UNIT *unit= &thd->lex->unit;
+ ha_rows idx= 0;
+ Protocol *protocol= thd->protocol;
+
+ unit->set_limit(sel);
+
+ void *iterator;
+ for (iterator= history.new_iterator();
+ iterator != NULL;
+ iterator= history.iterator_next(iterator))
+ {
+ prof= history.iterator_value(iterator);
+
+ String elapsed;
+
+ PROF_MEASUREMENT *ps= prof->profile_start;
+ PROF_MEASUREMENT *pe= prof->profile_end;
+
+ if (++idx <= unit->offset_limit_cnt)
+ continue;
+ if (idx > unit->select_limit_cnt)
+ break;
+
+ protocol->prepare_for_resend();
+ protocol->store((uint32)(prof->profiling_query_id));
+ protocol->store((double)(pe->time_usecs - ps->time_usecs)/(1000.0*1000),
+ (uint32) TIME_FLOAT_DIGITS-1, &elapsed);
+ if (prof->query_source != NULL)
+ protocol->store(prof->query_source, strlen(prof->query_source),
+ system_charset_info);
+ else
+ protocol->store_null();
+
+ if (protocol->write())
+ DBUG_RETURN(TRUE);
+ }
+ send_eof(thd);
+ DBUG_RETURN(FALSE);
+}
+
+/**
+ At a point in execution where we know the query source, save the text
+ of it in the query profile.
+
+ This must be called exactly once per descrete statement.
+*/
+void PROFILING::set_query_source(char *query_source_arg, uint query_length_arg)
+{
+ DBUG_ENTER("PROFILING::set_query_source");
+
+ if (! enabled)
+ DBUG_VOID_RETURN;
+
+ if (current != NULL)
+ current->set_query_source(query_source_arg, query_length_arg);
+ else
+ DBUG_PRINT("info", ("no current profile to send query source to"));
+ DBUG_VOID_RETURN;
+}
+
+/**
+ Fill the information schema table, "query_profile", as defined in show.cc .
+ There are two ways to get to this function: Selecting from the information
+ schema, and a SHOW command.
+*/
+int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
+{
+ DBUG_ENTER("PROFILING::fill_statistics_info");
+ TABLE *table= tables->table;
+ ulonglong row_number= 0;
+
+ QUERY_PROFILE *query;
+ /* Go through each query in this thread's stored history... */
+ void *history_iterator;
+ for (history_iterator= history.new_iterator();
+ history_iterator != NULL;
+ history_iterator= history.iterator_next(history_iterator))
+ {
+ query= history.iterator_value(history_iterator);
+
+ /*
+ Because we put all profiling info into a table that may be reordered, let
+ us also include a numbering of each state per query. The query_id and
+ the "seq" together are unique.
+ */
+ ulonglong seq;
+
+ void *entry_iterator;
+ PROF_MEASUREMENT *entry, *previous= NULL;
+ /* ...and for each query, go through all its state-change steps. */
+ for (seq= 0, entry_iterator= query->entries.new_iterator();
+ entry_iterator != NULL;
+ entry_iterator= query->entries.iterator_next(entry_iterator),
+ seq++, previous=entry, row_number++)
+ {
+ entry= query->entries.iterator_value(entry_iterator);
+
+ /* Skip the first. We count spans of fence, not fence-posts. */
+ if (previous == NULL) continue;
+
+ if (thd->lex->orig_sql_command == SQLCOM_SHOW_PROFILE)
+ {
+ /*
+ We got here via a SHOW command. That means that we stored
+ information about the query we wish to show and that isn't
+ in a WHERE clause at a higher level to filter out rows we
+ wish to exclude.
+
+ Because that functionality isn't available in the server yet,
+ we must filter here, at the wrong level. Once one can con-
+ struct where and having conditions at the SQL layer, then this
+ condition should be ripped out.
+ */
+ if (thd->lex->profile_query_id == 0) /* 0 == show final query */
+ {
+ if (query != last)
+ continue;
+ }
+ else
+ {
+ if (thd->lex->profile_query_id != query->profiling_query_id)
+ continue;
+ }
+ }
+
+ /* Set default values for this row. */
+ restore_record(table, s->default_values);
+
+ /*
+ The order of these fields is set by the query_profile_statistics_info
+ array.
+ */
+ table->field[0]->store((ulonglong) query->profiling_query_id);
+ table->field[1]->store((ulonglong) seq); /* the step in the sequence */
+ /*
+ This entry, n, has a point in time, T(n), and a status phrase, S(n).
+ The status phrase S(n) describes the period of time that begins at
+ T(n). The previous status phrase S(n-1) describes the period of time
+ that starts at T(n-1) and ends at T(n). Since we want to describe the
+ time that a status phrase took T(n)-T(n-1), this line must describe the
+ previous status.
+ */
+ table->field[2]->store(previous->status, strlen(previous->status),
+ system_charset_info);
+
+ my_decimal duration_decimal;
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ (entry->time_usecs-previous->time_usecs)/(1000.0*1000),
+ &duration_decimal);
+
+ table->field[3]->store_decimal(&duration_decimal);
+
+
+#ifdef HAVE_GETRUSAGE
+
+ my_decimal cpu_utime_decimal, cpu_stime_decimal;
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ RUSAGE_DIFF_USEC(entry->rusage.ru_utime,
+ previous->rusage.ru_utime) /
+ (1000.0*1000),
+ &cpu_utime_decimal);
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ RUSAGE_DIFF_USEC(entry->rusage.ru_stime,
+ previous->rusage.ru_stime) /
+ (1000.0*1000),
+ &cpu_stime_decimal);
+
+ table->field[4]->store_decimal(&cpu_utime_decimal);
+ table->field[5]->store_decimal(&cpu_stime_decimal);
+ table->field[4]->set_notnull();
+ table->field[5]->set_notnull();
+#else
+ /* TODO: Add CPU-usage info for non-BSD systems */
+#endif
+
+#ifdef HAVE_GETRUSAGE
+ table->field[6]->store((uint32)(entry->rusage.ru_nvcsw -
+ previous->rusage.ru_nvcsw));
+ table->field[6]->set_notnull();
+ table->field[7]->store((uint32)(entry->rusage.ru_nivcsw -
+ previous->rusage.ru_nivcsw));
+ table->field[7]->set_notnull();
+#else
+ /* TODO: Add context switch info for non-BSD systems */
+#endif
+
+#ifdef HAVE_GETRUSAGE
+ table->field[8]->store((uint32)(entry->rusage.ru_inblock -
+ previous->rusage.ru_inblock));
+ table->field[8]->set_notnull();
+ table->field[9]->store((uint32)(entry->rusage.ru_oublock -
+ previous->rusage.ru_oublock));
+ table->field[9]->set_notnull();
+#else
+ /* TODO: Add block IO info for non-BSD systems */
+#endif
+
+#ifdef HAVE_GETRUSAGE
+ table->field[10]->store((uint32)(entry->rusage.ru_msgsnd -
+ previous->rusage.ru_msgsnd), true);
+ table->field[10]->set_notnull();
+ table->field[11]->store((uint32)(entry->rusage.ru_msgrcv -
+ previous->rusage.ru_msgrcv), true);
+ table->field[11]->set_notnull();
+#else
+ /* TODO: Add message info for non-BSD systems */
+#endif
+
+#ifdef HAVE_GETRUSAGE
+ table->field[12]->store((uint32)(entry->rusage.ru_majflt -
+ previous->rusage.ru_majflt), true);
+ table->field[12]->set_notnull();
+ table->field[13]->store((uint32)(entry->rusage.ru_minflt -
+ previous->rusage.ru_minflt), true);
+ table->field[13]->set_notnull();
+#else
+ /* TODO: Add page fault info for non-BSD systems */
+#endif
+
+#ifdef HAVE_GETRUSAGE
+ table->field[14]->store((uint32)(entry->rusage.ru_nswap -
+ previous->rusage.ru_nswap), true);
+ table->field[14]->set_notnull();
+#else
+ /* TODO: Add swap info for non-BSD systems */
+#endif
+
+ /* Emit the location that started this step, not that ended it. */
+ if ((previous->function != NULL) && (previous->file != NULL))
+ {
+ table->field[15]->store(previous->function, strlen(previous->function),
+ system_charset_info);
+ table->field[15]->set_notnull();
+ table->field[16]->store(previous->file, strlen(previous->file), system_charset_info);
+ table->field[16]->set_notnull();
+ table->field[17]->store(previous->line, true);
+ table->field[17]->set_notnull();
+ }
+
+ if (schema_table_store_record(thd, table))
+ DBUG_RETURN(1);
+
+ }
+ }
+
+ DBUG_RETURN(0);
+}
+#endif /* ENABLED_PROFILING */
diff --git a/sql/sql_profile.h b/sql/sql_profile.h
new file mode 100644
index 00000000000..2483cb3cb6a
--- /dev/null
+++ b/sql/sql_profile.h
@@ -0,0 +1,297 @@
+/* Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _SQL_PROFILE_H
+#define _SQL_PROFILE_H
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ _unknown_func_
+extern const char * const _unknown_func_;
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER < 1300
+# define __func__ _unknown_func_
+extern const char * const _unknown_func_;
+# else
+# define __func__ __FUNCTION__
+# endif
+#elif defined(__BORLANDC__)
+# define __func__ __FUNC__
+#else
+# define __func__ _unknown_func_
+extern const char * const _unknown_func_;
+#endif
+
+extern ST_FIELD_INFO query_profile_statistics_info[];
+int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
+int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
+
+
+#define PROFILE_NONE 0
+#define PROFILE_CPU (1<<0)
+#define PROFILE_MEMORY (1<<1)
+#define PROFILE_BLOCK_IO (1<<2)
+#define PROFILE_CONTEXT (1<<3)
+#define PROFILE_PAGE_FAULTS (1<<4)
+#define PROFILE_IPC (1<<5)
+#define PROFILE_SWAPS (1<<6)
+#define PROFILE_SOURCE (1<<16)
+#define PROFILE_ALL (~0)
+
+
+#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#include "mysql_priv.h"
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include
+#endif
+
+
+class PROF_MEASUREMENT;
+class QUERY_PROFILE;
+class PROFILING;
+
+
+/**
+ Implements a persistent FIFO using server List method names. Not
+ thread-safe. Intended to be used on thread-local data only.
+*/
+template class Queue
+{
+private:
+
+ struct queue_item
+ {
+ T *payload;
+ struct queue_item *next, *previous;
+ };
+
+ struct queue_item *first, *last;
+
+public:
+ Queue()
+ {
+ elements= 0;
+ first= last= NULL;
+ }
+
+ void empty()
+ {
+ struct queue_item *i, *after_i;
+ for (i= first; i != NULL; i= after_i)
+ {
+ after_i= i->next;
+ my_free((char *) i, MYF(0));
+ }
+ elements= 0;
+ }
+
+ ulong elements; /* The count of items in the Queue */
+
+ void push_back(T *payload)
+ {
+ struct queue_item *new_item;
+
+ new_item= (struct queue_item *) my_malloc(sizeof(struct queue_item), MYF(0));
+
+ new_item->payload= payload;
+
+ if (first == NULL)
+ first= new_item;
+ if (last != NULL)
+ {
+ DBUG_ASSERT(last->next == NULL);
+ last->next= new_item;
+ }
+ new_item->previous= last;
+ new_item->next= NULL;
+ last= new_item;
+
+ elements++;
+ }
+
+ T *pop()
+ {
+ struct queue_item *old_item= first;
+ T *ret= NULL;
+
+ if (first == NULL)
+ {
+ DBUG_PRINT("warning", ("tried to pop nonexistent item from Queue"));
+ return NULL;
+ }
+
+ ret= old_item->payload;
+ if (first->next != NULL)
+ first->next->previous= NULL;
+ else
+ last= NULL;
+ first= first->next;
+
+ my_free((char *)old_item, MYF(0));
+ elements--;
+
+ return ret;
+ }
+
+ bool is_empty()
+ {
+ DBUG_ASSERT(((elements > 0) && (first != NULL)) || ((elements == 0) || (first == NULL)));
+ return (elements == 0);
+ }
+
+ void *new_iterator()
+ {
+ return first;
+ }
+
+ void *iterator_next(void *current)
+ {
+ return ((struct queue_item *) current)->next;
+ }
+
+ T *iterator_value(void *current)
+ {
+ return ((struct queue_item *) current)->payload;
+ }
+
+};
+
+
+/**
+ A single entry in a single profile.
+*/
+class PROF_MEASUREMENT
+{
+private:
+ friend class QUERY_PROFILE;
+ friend class PROFILING;
+
+ QUERY_PROFILE *profile;
+ char *status;
+#ifdef HAVE_GETRUSAGE
+ struct rusage rusage;
+#endif
+
+ char *function;
+ char *file;
+ unsigned int line;
+
+ double time_usecs;
+ char *allocated_status_memory;
+
+ void set_label(const char *status_arg, const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+ void clean_up();
+
+ PROF_MEASUREMENT();
+ PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg);
+ PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+ ~PROF_MEASUREMENT();
+ void collect();
+};
+
+
+/**
+ The full profile for a single query, and includes multiple PROF_MEASUREMENT
+ objects.
+*/
+class QUERY_PROFILE
+{
+private:
+ friend class PROFILING;
+
+ PROFILING *profiling;
+
+ query_id_t profiling_query_id; /* Session-specific id. */
+ char *query_source;
+
+ PROF_MEASUREMENT *profile_start;
+ PROF_MEASUREMENT *profile_end;
+ Queue entries;
+
+
+ QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg);
+ ~QUERY_PROFILE();
+
+ void set_query_source(char *query_source_arg, uint query_length_arg);
+
+ /* Add a profile status change to the current profile. */
+ void new_status(const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+
+ /* Reset the contents of this profile entry. */
+ void reset();
+
+ /* Show this profile. This is called by PROFILING. */
+ bool show(uint options);
+};
+
+
+/**
+ Profiling state for a single THD; contains multiple QUERY_PROFILE objects.
+*/
+class PROFILING
+{
+private:
+ friend class PROF_MEASUREMENT;
+ friend class QUERY_PROFILE;
+
+ /*
+ Not the system query_id, but a counter unique to profiling.
+ */
+ query_id_t profile_id_counter;
+ THD *thd;
+ bool keeping;
+ bool enabled;
+
+ QUERY_PROFILE *current;
+ QUERY_PROFILE *last;
+ Queue history;
+
+ query_id_t next_profile_id() { return(profile_id_counter++); }
+
+public:
+ PROFILING();
+ ~PROFILING();
+ void set_query_source(char *query_source_arg, uint query_length_arg);
+
+ void start_new_query(const char *initial_state= "starting");
+
+ void discard_current_query();
+
+ void finish_current_query();
+
+ void status_change(const char *status_arg,
+ const char *function_arg,
+ const char *file_arg, unsigned int line_arg);
+
+ inline void set_thd(THD *thd_arg) { thd= thd_arg; };
+
+ /* SHOW PROFILES */
+ bool show_profiles();
+
+ /* ... from INFORMATION_SCHEMA.PROFILING ... */
+ int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
+};
+
+# endif /* HAVE_PROFILING */
+#endif /* _SQL_PROFILE_H */
diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc
index f6766aec285..cec9e4c39de 100644
--- a/sql/sql_rename.cc
+++ b/sql/sql_rename.cc
@@ -84,7 +84,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list)
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
send_ok(thd);
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 5966176012f..33c2855c20b 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -650,7 +650,7 @@ impossible position";
if (read_packet)
{
- thd->proc_info = "Sending binlog event to slave";
+ thd_proc_info(thd, "Sending binlog event to slave");
if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
{
errmsg = "Failed on my_net_write()";
@@ -688,7 +688,7 @@ impossible position";
bool loop_breaker = 0;
/* need this to break out of the for loop from switch */
- thd->proc_info = "Finished reading one binlog; switching to next binlog";
+ thd_proc_info(thd, "Finished reading one binlog; switching to next binlog");
switch (mysql_bin_log.find_next_log(&linfo, 1)) {
case LOG_INFO_EOF:
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
@@ -734,14 +734,14 @@ end:
(void)my_close(file, MYF(MY_WME));
send_eof(thd);
- thd->proc_info = "Waiting to finalize termination";
+ thd_proc_info(thd, "Waiting to finalize termination");
pthread_mutex_lock(&LOCK_thread_count);
thd->current_linfo = 0;
pthread_mutex_unlock(&LOCK_thread_count);
DBUG_VOID_RETURN;
err:
- thd->proc_info = "Waiting to finalize termination";
+ thd_proc_info(thd, "Waiting to finalize termination");
end_io_cache(&log);
/*
Exclude iteration through thread list
@@ -895,7 +895,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
if (check_access(thd, SUPER_ACL, any_db,0,0,0,0))
DBUG_RETURN(1);
- thd->proc_info = "Killing slave";
+ thd_proc_info(thd, "Killing slave");
int thread_mask;
lock_slave_threads(mi);
// Get a mask of _running_ threads
@@ -922,7 +922,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
ER(ER_SLAVE_WAS_NOT_RUNNING));
}
unlock_slave_threads(mi);
- thd->proc_info = 0;
+ thd_proc_info(thd, 0);
if (slave_errno)
{
@@ -1078,7 +1078,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
DBUG_RETURN(TRUE);
}
- thd->proc_info = "Changing master";
+ thd_proc_info(thd, "Changing master");
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
// TODO: see if needs re-write
if (init_master_info(mi, master_info_file, relay_log_info_file, 0,
@@ -1203,7 +1203,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
if (need_relay_log_purge)
{
relay_log_purge= 1;
- thd->proc_info="Purging old relay logs";
+ thd_proc_info(thd, "Purging old relay logs");
if (purge_relay_logs(&mi->rli, thd,
0 /* not only reset, but also reinit */,
&errmsg))
@@ -1264,7 +1264,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
pthread_mutex_unlock(&mi->rli.data_lock);
unlock_slave_threads(mi);
- thd->proc_info = 0;
+ thd_proc_info(thd, 0);
send_ok(thd);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 777d32ba149..ced01c2db47 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -755,6 +755,7 @@ JOIN::optimize()
if (thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
thd->status_var.last_query_cost= 0.0;
+ thd_proc_info(thd, "optimizing");
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
unit->select_limit_cnt);
/* select_limit is used to decide if we are likely to scan the whole table */
@@ -871,7 +872,7 @@ JOIN::optimize()
thd->fatal_error();
error= res;
DBUG_PRINT("error",("Error from opt_sum_query"));
- DBUG_RETURN(1);
+ DBUG_RETURN(1);
}
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
@@ -907,7 +908,7 @@ JOIN::optimize()
sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
/* Calculate how to do the join */
- thd->proc_info= "statistics";
+ thd_proc_info(thd, "statistics");
if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
thd->is_fatal_error)
{
@@ -917,7 +918,7 @@ JOIN::optimize()
/* Remove distinct if only const tables */
select_distinct= select_distinct && (const_tables != tables);
- thd->proc_info= "preparing";
+ thd_proc_info(thd, "preparing");
if (result->initialize_tables(this))
{
DBUG_PRINT("error",("Error: initialize_tables() failed"));
@@ -1306,8 +1307,9 @@ JOIN::optimize()
join_tab[const_tables].type != JT_REF_OR_NULL &&
(order && simple_order || group_list && simple_group))
{
- if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
+ if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
DBUG_RETURN(1);
+ }
}
if (!(select_options & SELECT_BIG_RESULT) &&
@@ -1365,7 +1367,7 @@ JOIN::optimize()
if (need_tmp)
{
DBUG_PRINT("info",("Creating tmp table"));
- thd->proc_info="Creating tmp table";
+ thd_proc_info(thd, "Creating tmp table");
init_items_ref_array();
@@ -1393,7 +1395,9 @@ JOIN::optimize()
select_options,
tmp_rows_limit,
(char *) "")))
+ {
DBUG_RETURN(1);
+ }
/*
We don't have to store rows in temp table that doesn't match HAVING if:
@@ -1413,28 +1417,34 @@ JOIN::optimize()
if (group_list && simple_group)
{
DBUG_PRINT("info",("Sorting for group"));
- thd->proc_info="Sorting for group";
+ thd_proc_info(thd, "Sorting for group");
if (create_sort_index(thd, this, group_list,
HA_POS_ERROR, HA_POS_ERROR) ||
alloc_group_fields(this, group_list) ||
make_sum_func_list(all_fields, fields_list, 1) ||
setup_sum_funcs(thd, sum_funcs))
- DBUG_RETURN(1);
+ {
+ DBUG_RETURN(1);
+ }
group_list=0;
}
else
{
if (make_sum_func_list(all_fields, fields_list, 0) ||
setup_sum_funcs(thd, sum_funcs))
- DBUG_RETURN(1);
+ {
+ DBUG_RETURN(1);
+ }
+
if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
{
- DBUG_PRINT("info",("Sorting for order"));
- thd->proc_info="Sorting for order";
- if (create_sort_index(thd, this, order,
+ thd_proc_info(thd, "Sorting for order");
+ if (create_sort_index(thd, this, order,
HA_POS_ERROR, HA_POS_ERROR))
- DBUG_RETURN(1);
- order=0;
+ {
+ DBUG_RETURN(1);
+ }
+ order=0;
}
}
@@ -1577,6 +1587,7 @@ JOIN::exec()
int tmp_error;
DBUG_ENTER("JOIN::exec");
+ thd_proc_info(thd, "executing");
error= 0;
if (procedure)
{
@@ -1724,7 +1735,7 @@ JOIN::exec()
curr_tmp_table= exec_tmp_table1;
/* Copy data to the temporary table */
- thd->proc_info= "Copying to tmp table";
+ thd_proc_info(thd, "Copying to tmp table");
DBUG_PRINT("info", ("%s", thd->proc_info));
if ((tmp_error= do_select(curr_join, (List
- *) 0, curr_tmp_table, 0)))
{
@@ -1848,7 +1859,7 @@ JOIN::exec()
}
if (curr_join->group_list)
{
- thd->proc_info= "Creating sort index";
+ thd_proc_info(thd, "Creating sort index");
if (curr_join->join_tab == join_tab && save_join_tab())
{
DBUG_VOID_RETURN;
@@ -1862,7 +1873,7 @@ JOIN::exec()
sortorder= curr_join->sortorder;
}
- thd->proc_info="Copying to group table";
+ thd_proc_info(thd, "Copying to group table");
DBUG_PRINT("info", ("%s", thd->proc_info));
tmp_error= -1;
if (curr_join != this)
@@ -1918,7 +1929,7 @@ JOIN::exec()
curr_join->join_free(); /* Free quick selects */
if (curr_join->select_distinct && ! curr_join->group_list)
{
- thd->proc_info="Removing duplicates";
+ thd_proc_info(thd, "Removing duplicates");
if (curr_join->tmp_having)
curr_join->tmp_having->update_used_tables();
if (remove_duplicates(curr_join, curr_tmp_table,
@@ -1981,7 +1992,7 @@ JOIN::exec()
if (curr_join->group_list || curr_join->order)
{
DBUG_PRINT("info",("Sorting for send_fields"));
- thd->proc_info="Sorting result";
+ thd_proc_info(thd, "Sorting result");
/* If we have already done the group, add HAVING to sorted table */
if (curr_join->tmp_having && ! curr_join->group_list &&
! curr_join->sort_and_group)
@@ -2105,7 +2116,7 @@ JOIN::exec()
}
else
{
- thd->proc_info="Sending data";
+ thd_proc_info(thd, "Sending data");
DBUG_PRINT("info", ("%s", thd->proc_info));
result->send_fields((procedure ? curr_join->procedure_fields_list :
*curr_fields_list),
@@ -2265,7 +2276,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
{
if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE);
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
thd->used_tables=0; // Updated by setup_fields
if (err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
@@ -2310,8 +2321,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
err:
if (free_join)
{
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
err|= select_lex->cleanup();
+ thd_proc_info(thd, "end");
DBUG_RETURN(err || thd->net.report_error);
}
DBUG_RETURN(join->error);
@@ -3371,10 +3383,6 @@ add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
}
}
-/*
- Add all keys with uses 'field' for some keypart
- If field->and_level != and_level then only mark key_part as const_part
-*/
static uint
max_part_bit(key_part_map bits)
@@ -3384,7 +3392,16 @@ max_part_bit(key_part_map bits)
return found;
}
-static void
+/*
+ Add all keys with uses 'field' for some keypart
+ If field->and_level != and_level then only mark key_part as const_part
+
+ RETURN
+ 0 - OK
+ 1 - Out of memory.
+*/
+
+static bool
add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
{
Field *field=key_field->field;
@@ -3414,24 +3431,26 @@ add_key_part(DYNAMIC_ARRAY *keyuse_array,KEY_FIELD *key_field)
keyuse.optimize= key_field->optimize & KEY_OPTIMIZE_REF_OR_NULL;
keyuse.null_rejecting= key_field->null_rejecting;
keyuse.cond_guard= key_field->cond_guard;
- VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
+ if (insert_dynamic(keyuse_array,(gptr) &keyuse))
+ return TRUE;
}
}
}
}
+ return FALSE;
}
#define FT_KEYPART (MAX_REF_PARTS+10)
-static void
+static bool
add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
JOIN_TAB *stat,COND *cond,table_map usable_tables)
{
Item_func_match *cond_func=NULL;
if (!cond)
- return;
+ return FALSE;
if (cond->type() == Item::FUNC_ITEM)
{
@@ -3465,13 +3484,16 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
{
Item *item;
while ((item=li++))
- add_ft_keys(keyuse_array,stat,item,usable_tables);
+ {
+ if (add_ft_keys(keyuse_array,stat,item,usable_tables))
+ return TRUE;
+ }
}
}
if (!cond_func || cond_func->key == NO_SUCH_KEY ||
!(usable_tables & cond_func->table->map))
- return;
+ return FALSE;
KEYUSE keyuse;
keyuse.table= cond_func->table;
@@ -3481,7 +3503,7 @@ add_ft_keys(DYNAMIC_ARRAY *keyuse_array,
keyuse.used_tables=cond_func->key_item()->used_tables();
keyuse.optimize= 0;
keyuse.keypart_map= 0;
- VOID(insert_dynamic(keyuse_array,(gptr) &keyuse));
+ return insert_dynamic(keyuse_array,(gptr) &keyuse);
}
@@ -3631,7 +3653,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
sargables);
for (; field != end ; field++)
{
- add_key_part(keyuse,field);
+ if (add_key_part(keyuse,field))
+ return TRUE;
/* Mark that we can optimize LEFT JOIN */
if (field->val->type() == Item::NULL_ITEM &&
!field->field->real_maybe_null())
@@ -3669,11 +3692,15 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
/* fill keyuse with found key parts */
for ( ; field != end ; field++)
- add_key_part(keyuse,field);
+ {
+ if (add_key_part(keyuse,field))
+ return TRUE;
+ }
if (select_lex->ftfunc_list->elements)
{
- add_ft_keys(keyuse,join_tab,cond,normal_tables);
+ if (add_ft_keys(keyuse,join_tab,cond,normal_tables))
+ return TRUE;
}
/*
@@ -3694,7 +3721,8 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab,
(qsort_cmp) sort_keyuse);
bzero((char*) &key_end,sizeof(key_end)); /* Add for easy testing */
- VOID(insert_dynamic(keyuse,(gptr) &key_end));
+ if (insert_dynamic(keyuse,(gptr) &key_end))
+ return TRUE;
use=save_pos=dynamic_element(keyuse,0,KEYUSE*);
prev= &key_end;
@@ -10188,7 +10216,7 @@ free_tmp_table(THD *thd, TABLE *entry)
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
- thd->proc_info="removing tmp table";
+ thd_proc_info(thd, "removing tmp table");
if (entry->file)
{
@@ -10216,7 +10244,7 @@ free_tmp_table(THD *thd, TABLE *entry)
bitmap_clear_bit(&temp_pool, entry->temp_pool_slot);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
- thd->proc_info=save_proc_info;
+ thd_proc_info(thd, save_proc_info);
DBUG_VOID_RETURN;
}
@@ -10246,7 +10274,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
- thd->proc_info="converting HEAP to MyISAM";
+ thd_proc_info(thd, "converting HEAP to MyISAM");
if (create_myisam_tmp_table(&new_table,param,
thd->lex->select_lex.options | thd->options))
@@ -10301,8 +10329,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->s= &table->share_not_to_be_used;
table->file->change_table_ptr(table);
if (save_proc_info)
- thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ?
- "Copying to tmp table on disk" : save_proc_info);
+ thd_proc_info(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
+ "Copying to tmp table on disk" : save_proc_info));
DBUG_RETURN(0);
err:
@@ -10314,7 +10342,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table.file->delete_table(new_table.s->table_name);
delete new_table.file;
err2:
- thd->proc_info=save_proc_info;
+ thd_proc_info(thd, save_proc_info);
table->mem_root= new_table.mem_root;
DBUG_RETURN(1);
}
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 34e3193378f..59679c96120 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -1402,7 +1402,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
#if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
if (pthread_kill(tmp->real_id,0))
- tmp->proc_info="*** DEAD ***"; // This shouldn't happen
+ thd_proc_info(tmp, "*** DEAD ***"); // This shouldn't happen
#endif
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;
@@ -1549,6 +1549,12 @@ static bool show_status_array(THD *thd, const char *wild,
nr= (long) (thd->query_start() - server_start_time);
end= int10_to_str(nr, buff, 10);
break;
+#ifdef COMMUNITY_SERVER
+ case SHOW_FLUSHTIME:
+ nr= (long) (thd->query_start() - flush_status_time);
+ end= int10_to_str(nr, buff, 10);
+ break;
+#endif
case SHOW_QUERIES:
end= int10_to_str((long) thd->query_id, buff, 10);
break;
@@ -3668,6 +3674,14 @@ ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
/*
Create information_schema table using schema_table data
+ @note
+ For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
+ into it two numbers, based on modulus of base-10 numbers. In the ones
+ position is the number of decimals. Tens position is unused. In the
+ hundreds and thousands position is a two-digit decimal number representing
+ length. Encode this value with (decimals*100)+length , where
+ 0field_length)) == NULL)
DBUG_RETURN(NULL);
break;
+ case MYSQL_TYPE_DECIMAL:
+ if (!(item= new Item_decimal((longlong) fields_info->value, false)))
+ {
+ DBUG_RETURN(0);
+ }
+ item->decimals= fields_info->field_length%10;
+ item->max_length= (fields_info->field_length/100)%100;
+ if (item->unsigned_flag == 0)
+ item->max_length+= 1;
+ if (item->decimals > 0)
+ item->max_length+= 1;
+ item->set_name(fields_info->field_name,
+ strlen(fields_info->field_name), cs);
+ break;
+ case MYSQL_TYPE_STRING:
default:
/* Don't let unimplemented types pass through. Could be a grave error. */
- DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
+ DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING ||
+ fields_info->field_type == MYSQL_TYPE_DECIMAL);
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
{
@@ -4443,6 +4473,9 @@ ST_SCHEMA_TABLE schema_tables[]=
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
fill_open_tables, make_old_format, 0, -1, -1, 1},
+ {"PROFILING", query_profile_statistics_info, create_schema_table,
+ fill_query_profile_statistics_info, make_profile_table_for_show,
+ NULL, -1, -1, false},
{"ROUTINES", proc_fields_info, create_schema_table,
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
{"SCHEMATA", schema_fields_info, create_schema_table,
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 963a98cfb59..9952fca6bcb 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -333,7 +333,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
if (!error)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
@@ -1790,7 +1791,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
- thd->proc_info="creating table";
+ thd_proc_info(thd, "creating table");
create_info->table_existed= 0; // Mark that table is created
if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
@@ -1814,14 +1815,15 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
if (!internal_tmp_table && mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
error= FALSE;
end:
VOID(pthread_mutex_unlock(&LOCK_open));
- thd->proc_info="After create";
+ thd_proc_info(thd, "After create");
DBUG_RETURN(error);
warn:
@@ -2903,7 +2905,8 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST *src_table,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
res= FALSE;
@@ -2976,7 +2979,7 @@ mysql_discard_or_import_tablespace(THD *thd,
ALTER TABLE
*/
- thd->proc_info="discard_or_import_tablespace";
+ thd_proc_info(thd, "discard_or_import_tablespace");
discard= test(tablespace_op == DISCARD_TABLESPACE);
@@ -2993,7 +2996,7 @@ mysql_discard_or_import_tablespace(THD *thd,
error=table->file->discard_or_import_tablespace(discard);
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
if (error)
goto err;
@@ -3012,7 +3015,8 @@ mysql_discard_or_import_tablespace(THD *thd,
goto err;
if (mysql_bin_log.is_open())
{
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
err:
@@ -3120,7 +3124,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
create_field *new_datetime_field= 0;
DBUG_ENTER("mysql_alter_table");
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
table_name=table_list->table_name;
alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
@@ -3168,7 +3172,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
send_ok(thd);
@@ -3260,7 +3265,7 @@ view_err:
DBUG_RETURN(TRUE);
}
- thd->proc_info="setup";
+ thd_proc_info(thd, "setup");
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
!table->s->tmp_table) // no need to touch frm
{
@@ -3311,7 +3316,7 @@ view_err:
if (!error && (new_name != table_name || new_db != db))
{
- thd->proc_info="rename";
+ thd_proc_info(thd, "rename");
/*
Then do a 'simple' rename of the table. First we need to close all
instances of 'source' table.
@@ -3360,7 +3365,8 @@ view_err:
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
send_ok(thd);
@@ -3811,7 +3817,7 @@ view_err:
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
- thd->proc_info="copy to tmp table";
+ thd_proc_info(thd, "copy to tmp table");
next_insert_id=thd->next_insert_id; // Remember for logging
copied=deleted=0;
if (new_table && !new_table->s->is_view)
@@ -3872,7 +3878,8 @@ view_err:
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
goto end_temporary;
@@ -3897,7 +3904,7 @@ view_err:
from the cache, free all locks, close the old table and remove it.
*/
- thd->proc_info="rename result table";
+ thd_proc_info(thd, "rename result table");
my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id);
if (lower_case_table_names)
@@ -4003,11 +4010,12 @@ view_err:
goto err;
}
}
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
if (mysql_bin_log.is_open())
{
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, FALSE, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ FALSE, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
broadcast_refresh();
@@ -4368,6 +4376,16 @@ bool mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
{
for (;;)
{
+ if (thd->killed)
+ {
+ /*
+ we've been killed; let handler clean up, and remove the
+ partial current row from the recordset (embedded lib)
+ */
+ t->file->ha_rnd_end();
+ thd->protocol->remove_last_row();
+ goto err;
+ }
ha_checksum row_crc= 0;
int error= t->file->rnd_next(t->record[0]);
if (unlikely(error))
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 930e3601699..d2ae494d4eb 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -304,7 +304,7 @@ end:
/* Such a statement can always go directly to binlog, no trans cache. */
Query_log_event qinfo(thd, stmt_query.ptr(), stmt_query.length(), 0,
- FALSE);
+ FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 8a3f5bcdc26..69f876ace39 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -165,7 +165,7 @@ int mysql_update(THD *thd,
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
DBUG_RETURN(1);
- thd->proc_info="init";
+ thd_proc_info(thd, "init");
table= table_list->table;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@@ -362,7 +362,7 @@ int mysql_update(THD *thd,
else
init_read_record_idx(&info, thd, table, 1, used_index);
- thd->proc_info="Searching rows for update";
+ thd_proc_info(thd, "Searching rows for update");
ha_rows tmp_limit= limit;
while (!(error=info.read_record(&info)) && !thd->killed)
@@ -427,7 +427,7 @@ int mysql_update(THD *thd,
updated= found= 0;
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
- thd->proc_info="Updating";
+ thd_proc_info(thd, "Updating");
query_id=thd->query_id;
transactional_table= table->file->has_transactions();
@@ -543,7 +543,7 @@ int mysql_update(THD *thd,
end_read_record(&info);
free_io_cache(table); // If ORDER BY
delete select;
- thd->proc_info="end";
+ thd_proc_info(thd, "end");
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
/*
@@ -1033,7 +1033,7 @@ int multi_update::prepare(List
- ¬_used_values,
thd->count_cuted_fields= CHECK_FIELD_WARN;
thd->cuted_fields=0L;
- thd->proc_info="updating main table";
+ thd_proc_info(thd, "updating main table");
tables_to_update= get_table_map(fields);
@@ -1575,7 +1575,7 @@ void multi_update::send_error(uint errcode,const char *err)
into repl event.
*/
Query_log_event qinfo(thd, thd->query, thd->query_length,
- transactional_tables, FALSE);
+ transactional_tables, FALSE, THD::KILLED_NO_VALUE);
mysql_bin_log.write(&qinfo);
}
thd->transaction.all.modified_non_trans_table= TRUE;
@@ -1762,7 +1762,7 @@ bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
THD::killed_state killed_status= THD::NOT_KILLED;
- thd->proc_info="updating reference tables";
+ thd_proc_info(thd, "updating reference tables");
/*
Does updates for the last n - 1 tables, returns 0 if ok;
@@ -1774,7 +1774,7 @@ bool multi_update::send_eof()
later carried out killing should not affect binlogging.
*/
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
- thd->proc_info= "end";
+ thd_proc_info(thd, "end");
/* We must invalidate the query cache before binlog writing and
ha_autocommit_... */
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 9e0fa87d5f5..d1d84e76811 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -655,7 +655,8 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
else if (views->with_check == VIEW_CHECK_CASCADED)
buff.append(STRING_WITH_LEN(" WITH CASCADED CHECK OPTION"));
- Query_log_event qinfo(thd, buff.ptr(), buff.length(), 0, FALSE);
+ Query_log_event qinfo(thd, buff.ptr(), buff.length(),
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
@@ -671,7 +672,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
DBUG_RETURN(0);
err:
- thd->proc_info= "end";
+ thd_proc_info(thd, "end");
lex->link_first_table_back(view, link_to_local);
unit->cleanup();
DBUG_RETURN(res || thd->net.report_error);
@@ -1544,7 +1545,8 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode)
{
if (!something_wrong)
thd->clear_error();
- Query_log_event qinfo(thd, thd->query, thd->query_length, 0, FALSE);
+ Query_log_event qinfo(thd, thd->query, thd->query_length,
+ 0, FALSE, THD::NOT_KILLED);
mysql_bin_log.write(&qinfo);
}
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 51fb5dbdfe4..61020a3eed0 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -234,9 +234,7 @@ int case_stmt_action_expr(LEX *lex, Item* expr)
parsing_ctx, case_expr_id, expr, lex);
sp->add_cont_backpatch(i);
- sp->add_instr(i);
-
- return 0;
+ return sp->add_instr(i);
}
/**
@@ -247,7 +245,7 @@ int case_stmt_action_expr(LEX *lex, Item* expr)
@param simple true for simple cases, false for searched cases
*/
-void case_stmt_action_when(LEX *lex, Item *when, bool simple)
+int case_stmt_action_when(LEX *lex, Item *when, bool simple)
{
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
@@ -279,9 +277,10 @@ void case_stmt_action_when(LEX *lex, Item *when, bool simple)
(jump_if_not from instruction 2 to 5, 5 to 8 ... in the example)
*/
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- sp->add_cont_backpatch(i);
- sp->add_instr(i);
+ return !test(i) ||
+ sp->push_backpatch(i, ctx->push_label((char *)"", 0)) ||
+ sp->add_cont_backpatch(i) ||
+ sp->add_instr(i);
}
/**
@@ -290,13 +289,14 @@ void case_stmt_action_when(LEX *lex, Item *when, bool simple)
@param lex the parser lex context
*/
-void case_stmt_action_then(LEX *lex)
+int case_stmt_action_then(LEX *lex)
{
sp_head *sp= lex->sphead;
sp_pcontext *ctx= lex->spcont;
uint ip= sp->instructions();
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
- sp->add_instr(i);
+ if (!test(i) || sp->add_instr(i))
+ return 1;
/*
BACKPATCH: Resolving forward jump from
@@ -312,7 +312,7 @@ void case_stmt_action_then(LEX *lex)
(jump from instruction 4 to 12, 7 to 12 ... in the example)
*/
- sp->push_backpatch(i, ctx->last_label());
+ return sp->push_backpatch(i, ctx->last_label());
}
/**
@@ -502,6 +502,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token BIT_SYM
%token BIT_XOR
%token BLOB_SYM
+%token BLOCK_SYM
%token BOOLEAN_SYM
%token BOOL_SYM
%token BOTH
@@ -542,10 +543,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CONSISTENT_SYM
%token CONSTRAINT
%token CONTAINS_SYM
+%token CONTEXT_SYM
%token CONTINUE_SYM
%token CONVERT_SYM
%token CONVERT_TZ_SYM
%token COUNT_SYM
+%token CPU_SYM
%token CREATE
%token CROSS
%token CUBE_SYM
@@ -619,6 +622,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token EXTRACT_SYM
%token FALSE_SYM
%token FAST_SYM
+%token FAULTS_SYM
%token FETCH_SYM
%token FIELD_FUNC
%token FILE_SYM
@@ -688,6 +692,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token INT_SYM
%token INVOKER_SYM
%token IN_SYM
+%token IO_SYM
+%token IPC_SYM
%token IS
%token ISOLATION
%token ISSUER_SYM
@@ -756,6 +762,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token MEDIUMINT
%token MEDIUMTEXT
%token MEDIUM_SYM
+%token MEMORY_SYM
%token MERGE_SYM
%token MICROSECOND_SYM
%token MIGRATE_SYM
@@ -814,6 +821,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token OUTFILE
%token OUT_SYM
%token PACK_KEYS_SYM
+%token PAGE_SYM
%token PARTIAL
%token PASSWORD
%token PARAM_MARKER
@@ -831,6 +839,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PROCEDURE
%token PROCESS
%token PROCESSLIST_SYM
+%token PROFILE_SYM
+%token PROFILES_SYM
%token PURGE
%token QUARTER_SYM
%token QUERY_SYM
@@ -901,6 +911,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SMALLINT
%token SNAPSHOT_SYM
%token SOUNDS_SYM
+%token SOURCE_SYM
%token SPATIAL_SYM
%token SPECIFIC_SYM
%token SQLEXCEPTION_SYM
@@ -931,6 +942,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SUM_SYM
%token SUPER_SYM
%token SUSPEND_SYM
+%token SWAPS_SYM
+%token SWITCHES_SYM
%token SYSDATE
%token TABLES
%token TABLESPACE
@@ -1905,10 +1918,9 @@ sp_decl:
var_type,
lex,
(i == num_vars - 1));
- if (is == NULL)
+ if (is == NULL ||
+ lex->sphead->add_instr(is))
MYSQL_YYABORT;
-
- lex->sphead->add_instr(is);
}
pctx->declare_var_boundary(0);
@@ -1927,7 +1939,8 @@ sp_decl:
my_error(ER_SP_DUP_COND, MYF(0), $2.str);
MYSQL_YYABORT;
}
- YYTHD->lex->spcont->push_cond(&$2, $5);
+ if(YYTHD->lex->spcont->push_cond(&$2, $5))
+ MYSQL_YYABORT;
$$.vars= $$.hndlrs= $$.curs= 0;
$$.conds= 1;
}
@@ -1942,10 +1955,10 @@ sp_decl:
sp_instr_hpush_jump *i=
new sp_instr_hpush_jump(sp->instructions(), ctx, $2,
ctx->current_var_count());
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
}
sp_hcond_list sp_proc_stmt
@@ -1960,17 +1973,17 @@ sp_decl:
{
i= new sp_instr_hreturn(sp->instructions(), ctx,
ctx->current_var_count());
- if (i == NULL )
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
else
{ /* EXIT or UNDO handler, just jump to the end of the block */
i= new sp_instr_hreturn(sp->instructions(), ctx, 0);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i) ||
+ sp->push_backpatch(i, lex->spcont->last_label())) /* Block end */
MYSQL_YYABORT;
- sp->add_instr(i);
- sp->push_backpatch(i, lex->spcont->last_label()); /* Block end */
}
lex->sphead->backpatch(hlab);
@@ -1996,10 +2009,10 @@ sp_decl:
}
i= new sp_instr_cpush(sp->instructions(), ctx, $5,
ctx->current_cursor_count());
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i) ||
+ ctx->push_cursor(&$2))
MYSQL_YYABORT;
- sp->add_instr(i);
- ctx->push_cursor(&$2);
$$.vars= $$.conds= $$.hndlrs= 0;
$$.curs= 1;
}
@@ -2223,10 +2236,11 @@ sp_proc_stmt:
i->m_query.length= lip->ptr - sp->m_tmp_query;
else
i->m_query.length= lip->tok_end - sp->m_tmp_query;
- i->m_query.str= strmake_root(thd->mem_root,
- sp->m_tmp_query,
- i->m_query.length);
- sp->add_instr(i);
+ if (!(i->m_query.str= strmake_root(thd->mem_root,
+ sp->m_tmp_query,
+ i->m_query.length)) ||
+ sp->add_instr(i))
+ MYSQL_YYABORT;
}
sp->restore_lex(thd);
}
@@ -2251,9 +2265,9 @@ sp_proc_stmt:
i= new sp_instr_freturn(sp->instructions(), lex->spcont, $3,
sp->m_return_field_def.sql_type, lex);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
sp->m_flags|= sp_head::HAS_RETURN;
}
sp->restore_lex(YYTHD);
@@ -2311,23 +2325,23 @@ sp_proc_stmt:
if (n)
{
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
- if (hpop == NULL)
+ if (hpop == NULL ||
+ sp->add_instr(hpop))
MYSQL_YYABORT;
- sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, exclusive);
if (n)
{
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
- if (cpop == NULL)
+ if (cpop == NULL ||
+ sp->add_instr(cpop))
MYSQL_YYABORT;
- sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx);
- if (i == NULL)
+ if (i == NULL ||
+ sp->push_backpatch(i, lab) || /* Jumping forward */
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->push_backpatch(i, lab); /* Jumping forward */
- sp->add_instr(i);
}
}
| ITERATE_SYM label_ident
@@ -2352,22 +2366,22 @@ sp_proc_stmt:
if (n)
{
sp_instr_hpop *hpop= new sp_instr_hpop(ip++, ctx, n);
- if (hpop == NULL)
+ if (hpop == NULL ||
+ sp->add_instr(hpop))
MYSQL_YYABORT;
- sp->add_instr(hpop);
}
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
if (n)
{
sp_instr_cpop *cpop= new sp_instr_cpop(ip++, ctx, n);
- if (cpop == NULL)
+ if (cpop == NULL ||
+ sp->add_instr(cpop))
MYSQL_YYABORT;
- sp->add_instr(cpop);
}
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
}
| OPEN_SYM ident
@@ -2383,9 +2397,9 @@ sp_proc_stmt:
MYSQL_YYABORT;
}
i= new sp_instr_copen(sp->instructions(), lex->spcont, offset);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
| FETCH_SYM sp_opt_fetch_noise ident INTO
{
@@ -2400,9 +2414,9 @@ sp_proc_stmt:
MYSQL_YYABORT;
}
i= new sp_instr_cfetch(sp->instructions(), lex->spcont, offset);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
sp_fetch_list
{ }
@@ -2419,9 +2433,9 @@ sp_proc_stmt:
MYSQL_YYABORT;
}
i= new sp_instr_cclose(sp->instructions(), lex->spcont, offset);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
;
@@ -2488,11 +2502,11 @@ sp_if:
uint ip= sp->instructions();
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, ctx,
$2, lex);
- if (i == NULL)
+ if (i == NULL ||
+ sp->push_backpatch(i, ctx->push_label((char *)"", 0)) ||
+ sp->add_cont_backpatch(i) ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->push_backpatch(i, ctx->push_label((char *)"", 0));
- sp->add_cont_backpatch(i);
- sp->add_instr(i);
sp->restore_lex(YYTHD);
}
sp_proc_stmts1
@@ -2501,9 +2515,9 @@ sp_if:
sp_pcontext *ctx= Lex->spcont;
uint ip= sp->instructions();
sp_instr_jump *i = new sp_instr_jump(ip, ctx);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
sp->backpatch(ctx->pop_label());
sp->push_backpatch(i, ctx->push_label((char *)"", 0));
}
@@ -2589,14 +2603,16 @@ simple_when_clause:
/* Simple case: = */
LEX *lex= Lex;
- case_stmt_action_when(lex, $3, true);
+ if (case_stmt_action_when(lex, $3, true))
+ MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
}
THEN_SYM
sp_proc_stmts1
{
LEX *lex= Lex;
- case_stmt_action_then(lex);
+ if (case_stmt_action_then(lex))
+ MYSQL_YYABORT;
}
;
@@ -2609,14 +2625,16 @@ searched_when_clause:
expr
{
LEX *lex= Lex;
- case_stmt_action_when(lex, $3, false);
+ if (case_stmt_action_when(lex, $3, false))
+ MYSQL_YYABORT;
lex->sphead->restore_lex(YYTHD); /* For expr $3 */
}
THEN_SYM
sp_proc_stmts1
{
LEX *lex= Lex;
- case_stmt_action_then(lex);
+ if (case_stmt_action_then(lex))
+ MYSQL_YYABORT;
}
;
@@ -2628,9 +2646,9 @@ else_clause_opt:
uint ip= sp->instructions();
sp_instr_error *i= new sp_instr_error(ip, lex->spcont,
ER_SP_CASE_NOT_FOUND);
- if (i == NULL)
+ if (i == NULL ||
+ sp->add_instr(i))
MYSQL_YYABORT;
- sp->add_instr(i);
}
| ELSE sp_proc_stmts1
;
@@ -2744,17 +2762,17 @@ sp_block_content:
{
sp_instr_hpop *hpop= new sp_instr_hpop(sp->instructions(), ctx,
$3.hndlrs);
- if (hpop == NULL)
+ if (hpop == NULL ||
+ sp->add_instr(hpop))
MYSQL_YYABORT;
- sp->add_instr(hpop);
}
if ($3.curs)
{
sp_instr_cpop *cpop= new sp_instr_cpop(sp->instructions(), ctx,
$3.curs);
- if (cpop == NULL)
+ if (cpop == NULL ||
+ sp->add_instr(cpop))
MYSQL_YYABORT;
- sp->add_instr(cpop);
}
lex->spcont= ctx->pop_context();
}
@@ -2768,9 +2786,9 @@ sp_unlabeled_control:
uint ip= lex->sphead->instructions();
sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
- if (i == NULL)
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
MYSQL_YYABORT;
- lex->sphead->add_instr(i);
}
| WHILE_SYM
{
@@ -2784,12 +2802,12 @@ sp_unlabeled_control:
uint ip= sp->instructions();
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
$3, lex);
- if (i == NULL)
- MYSQL_YYABORT;
+ if (i == NULL ||
/* Jumping forward */
- sp->push_backpatch(i, lex->spcont->last_label());
- sp->new_cont_backpatch(i);
- sp->add_instr(i);
+ sp->push_backpatch(i, lex->spcont->last_label()) ||
+ sp->new_cont_backpatch(i) ||
+ sp->add_instr(i))
+ MYSQL_YYABORT;
sp->restore_lex(YYTHD);
}
sp_proc_stmts1 END WHILE_SYM
@@ -2798,9 +2816,9 @@ sp_unlabeled_control:
uint ip= lex->sphead->instructions();
sp_label_t *lab= lex->spcont->last_label(); /* Jumping back */
sp_instr_jump *i = new sp_instr_jump(ip, lex->spcont, lab->ip);
- if (i == NULL)
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
MYSQL_YYABORT;
- lex->sphead->add_instr(i);
lex->sphead->do_cont_backpatch();
}
| REPEAT_SYM sp_proc_stmts1 UNTIL_SYM
@@ -2816,9 +2834,9 @@ sp_unlabeled_control:
sp_instr_jump_if_not *i = new sp_instr_jump_if_not(ip, lex->spcont,
$5, lab->ip,
lex);
- if (i == NULL)
+ if (i == NULL ||
+ lex->sphead->add_instr(i))
MYSQL_YYABORT;
- lex->sphead->add_instr(i);
lex->sphead->restore_lex(YYTHD);
/* We can shortcut the cont_backpatch here */
i->m_cont_dest= ip+1;
@@ -4522,6 +4540,7 @@ select_lock_type:
LEX *lex=Lex;
lex->current_select->set_lock_for_tables(TL_WRITE);
lex->safe_to_cache_query=0;
+ lex->protect_against_global_read_lock= TRUE;
}
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
{
@@ -7937,6 +7956,64 @@ opt_table_sym:
/* empty */
| TABLE_SYM;
+opt_profile_defs:
+ /* empty */
+ | profile_defs;
+
+profile_defs:
+ profile_def
+ | profile_defs ',' profile_def;
+
+profile_def:
+ CPU_SYM
+ {
+ Lex->profile_options|= PROFILE_CPU;
+ }
+ | MEMORY_SYM
+ {
+ Lex->profile_options|= PROFILE_MEMORY;
+ }
+ | BLOCK_SYM IO_SYM
+ {
+ Lex->profile_options|= PROFILE_BLOCK_IO;
+ }
+ | CONTEXT_SYM SWITCHES_SYM
+ {
+ Lex->profile_options|= PROFILE_CONTEXT;
+ }
+ | PAGE_SYM FAULTS_SYM
+ {
+ Lex->profile_options|= PROFILE_PAGE_FAULTS;
+ }
+ | IPC_SYM
+ {
+ Lex->profile_options|= PROFILE_IPC;
+ }
+ | SWAPS_SYM
+ {
+ Lex->profile_options|= PROFILE_SWAPS;
+ }
+ | SOURCE_SYM
+ {
+ Lex->profile_options|= PROFILE_SOURCE;
+ }
+ | ALL
+ {
+ Lex->profile_options|= PROFILE_ALL;
+ }
+ ;
+
+opt_profile_args:
+ /* empty */
+ {
+ Lex->profile_query_id= 0;
+ }
+ | FOR_SYM QUERY_SYM NUM
+ {
+ Lex->profile_query_id= atoi($3.str);
+ }
+ ;
+
/* Show things */
show: SHOW
@@ -8072,6 +8149,16 @@ show_param:
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
| ERRORS opt_limit_clause_init
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;}
+ | PROFILES_SYM
+ { Lex->sql_command = SQLCOM_SHOW_PROFILES; }
+ | PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause_init
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SELECT;
+ lex->orig_sql_command= SQLCOM_SHOW_PROFILE;
+ if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
+ YYABORT;
+ }
| opt_var_type STATUS_SYM wild_and_where
{
LEX *lex= Lex;
@@ -9350,6 +9437,7 @@ keyword_sp:
| BERKELEY_DB_SYM {}
| BINLOG_SYM {}
| BIT_SYM {}
+ | BLOCK_SYM {}
| BOOL_SYM {}
| BOOLEAN_SYM {}
| BTREE_SYM {}
@@ -9367,6 +9455,8 @@ keyword_sp:
| CONCURRENT {}
| CONNECTION_SYM {}
| CONSISTENT_SYM {}
+ | CONTEXT_SYM {}
+ | CPU_SYM {}
| CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
@@ -9389,6 +9479,7 @@ keyword_sp:
| EXPANSION_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
+ | FAULTS_SYM {}
| FOUND_SYM {}
| DISABLE_SYM {}
| ENABLE_SYM {}
@@ -9413,6 +9504,8 @@ keyword_sp:
| ISSUER_SYM {}
| INNOBASE_SYM {}
| INSERT_METHOD {}
+ | IO_SYM {}
+ | IPC_SYM {}
| RELAY_THREAD {}
| LAST_SYM {}
| LEAVES {}
@@ -9442,6 +9535,7 @@ keyword_sp:
| MAX_UPDATES_PER_HOUR {}
| MAX_USER_CONNECTIONS_SYM {}
| MEDIUM_SYM {}
+ | MEMORY_SYM {}
| MERGE_SYM {}
| MICROSECOND_SYM {}
| MIGRATE_SYM {}
@@ -9468,6 +9562,7 @@ keyword_sp:
| ONE_SHOT_SYM {}
| ONE_SYM {}
| PACK_KEYS_SYM {}
+ | PAGE_SYM {}
| PARTIAL {}
| PASSWORD {}
| PHASE_SYM {}
@@ -9477,6 +9572,8 @@ keyword_sp:
| PRIVILEGES {}
| PROCESS {}
| PROCESSLIST_SYM {}
+ | PROFILE_SYM {}
+ | PROFILES_SYM {}
| QUARTER_SYM {}
| QUERY_SYM {}
| QUICK {}
@@ -9510,6 +9607,7 @@ keyword_sp:
| SHUTDOWN {}
| SNAPSHOT_SYM {}
| SOUNDS_SYM {}
+ | SOURCE_SYM {}
| SQL_CACHE_SYM {}
| SQL_BUFFER_RESULT {}
| SQL_NO_CACHE_SYM {}
@@ -9521,6 +9619,8 @@ keyword_sp:
| SUBJECT_SYM {}
| SUPER_SYM {}
| SUSPEND_SYM {}
+ | SWAPS_SYM {}
+ | SWITCHES_SYM {}
| TABLES {}
| TABLESPACE {}
| TEMPORARY {}
@@ -9648,7 +9748,8 @@ option_type_value:
qbuff.length);
qbuff.length+= 4;
i->m_query= qbuff;
- sp->add_instr(i);
+ if (sp->add_instr(i))
+ MYSQL_YYABORT;
}
lex->sphead->restore_lex(thd);
}
@@ -9730,7 +9831,8 @@ sys_option_value:
lex->trg_table_fields.link_in_list((byte *)trg_fld,
(byte **)&trg_fld->next_trg_field);
- lex->sphead->add_instr(sp_fld);
+ if (lex->sphead->add_instr(sp_fld))
+ MYSQL_YYABORT;
}
else if ($2.var)
{ /* System variable */
@@ -9760,11 +9862,12 @@ sys_option_value:
it= spv->dflt;
else
it= new Item_null();
- if (it == NULL)
+ if (it == NULL ||
+ (sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
+ spv->offset, it, spv->type, lex,
+ TRUE)) == NULL ||
+ lex->sphead->add_instr(sp_set))
MYSQL_YYABORT;
- sp_set= new sp_instr_set(lex->sphead->instructions(), ctx,
- spv->offset, it, spv->type, lex, TRUE);
- lex->sphead->add_instr(sp_set);
}
}
| option_type TRANSACTION_SYM ISOLATION LEVEL_SYM isolation_types
@@ -10058,8 +10161,12 @@ table_lock_list:
table_lock:
table_ident opt_table_alias lock_option
{
- if (!Select->add_table_to_list(YYTHD, $1, $2, 0, (thr_lock_type) $3))
+ thr_lock_type lock_type= (thr_lock_type) $3;
+ if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type))
MYSQL_YYABORT;
+ /* If table is to be write locked, protect from a impending GRL. */
+ if (lock_type >= TL_WRITE_ALLOW_WRITE)
+ Lex->protect_against_global_read_lock= TRUE;
}
;
diff --git a/sql/structs.h b/sql/structs.h
index 9882119b7c5..be55527eaa0 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -173,6 +173,7 @@ enum SHOW_TYPE
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUERIES,
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
SHOW_VARS,
+ SHOW_FLUSHTIME,
#ifdef HAVE_OPENSSL
SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,
diff --git a/sql/table.h b/sql/table.h
index 0884f5ba3d2..ad578044371 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -377,6 +377,7 @@ enum enum_schema_tables
SCH_COLUMN_PRIVILEGES,
SCH_KEY_COLUMN_USAGE,
SCH_OPEN_TABLES,
+ SCH_PROFILES,
SCH_PROCEDURES,
SCH_SCHEMATA,
SCH_SCHEMA_PRIVILEGES,
diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh
index 59ad308086c..fa3c3a8b4ce 100644
--- a/support-files/mysql.spec.sh
+++ b/support-files/mysql.spec.sh
@@ -330,7 +330,7 @@ do
BuildMySQL "\
%if %{STATIC_BUILD}
- --disable-shared \
+ --enable-shared \
--with-mysqld-ldflags='-all-static' \
--with-client-ldflags='-all-static' \
$USE_OTHER_LIBC_DIR \
@@ -364,6 +364,22 @@ done
./libtool --mode=execute nm --numeric-sort sql/mysqld > sql/mysqld.sym
+# Include libgcc.a in the devel subpackage (BUG 4921)
+if expr "$CC" : ".*gcc.*" > /dev/null ;
+then
+ libgcc=`$CC $CFLAGS --print-libgcc-file`
+ if [ -f $libgcc ]
+ then
+ %define have_libgcc 1
+ install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a
+ fi
+fi
+
+# Save the libraries
+(cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*)
+(cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*)
+(cd ndb/src/.libs; tar rf $RBR/shared-libs.tar *.so*)
+
# We might want to save the config log file
if test -n "$MYSQL_CONFLOG_DEST"
then
@@ -396,18 +412,7 @@ make install-strip DESTDIR=$RBR benchdir_root=%{_datadir}
install -s -m 755 $MBD/sql/mysqld-debug $RBR%{_sbindir}/mysqld-debug
# Install shared libraries (Disable for architectures that don't support it)
-# (cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar)
-
-# Include libgcc.a in the devel subpackage (BUG 4921)
-if expr "$CC" : ".*gcc.*" > /dev/null ;
-then
- libgcc=`$CC $CFLAGS --print-libgcc-file`
- if [ -f $libgcc ]
- then
- %define have_libgcc 1
- install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a
- fi
-fi
+(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar)
# install symbol files ( for stack trace resolution)
# install -m 644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index d006a557819..9e026a27b6d 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -15904,61 +15904,6 @@ static void test_bug28934()
}
-#ifdef HAVE_SPATIAL
-/**
- Bug#37956 memory leak and / or crash with geometry and prepared statements!
-*/
-
-static void test_bug37956(void)
-{
- const char *query="select point(?,?)";
- MYSQL_STMT *stmt=NULL;
- ulong val=0;
- MYSQL_BIND bind_param[2];
- unsigned char buff[2]= { 134, 211 };
- DBUG_ENTER("test_bug37956");
- myheader("test_bug37956");
-
- stmt= mysql_simple_prepare(mysql, query);
- check_stmt(stmt);
-
- val=1;
- mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void *)&val);
- val=CURSOR_TYPE_READ_ONLY;
- mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void *)&val);
- val=0;
- mysql_stmt_attr_set(stmt, STMT_ATTR_PREFETCH_ROWS, (void *)&val);
-
- memset(bind_param, 0, sizeof(bind_param));
- bind_param[0].buffer_type=MYSQL_TYPE_TINY;
- bind_param[0].buffer= (void *)buff;
- bind_param[0].is_null=NULL;
- bind_param[0].error=NULL;
- bind_param[0].is_unsigned=1;
- bind_param[1].buffer_type=MYSQL_TYPE_TINY;
- bind_param[1].buffer= (void *)(buff+1);
- bind_param[1].is_null=NULL;
- bind_param[1].error=NULL;
- bind_param[1].is_unsigned=1;
-
- if (mysql_stmt_bind_param(stmt, bind_param))
- {
- mysql_stmt_close(stmt);
- DIE_UNLESS(0);
- }
-
- if (mysql_stmt_execute(stmt))
- {
- mysql_stmt_close(stmt);
- DBUG_VOID_RETURN;
- }
- /* Should never reach here: execution returns an error. */
- mysql_stmt_close(stmt);
- DIE_UNLESS(0);
- DBUG_VOID_RETURN;
-}
-#endif
-
/*
Bug#27592 (stack overrun when storing datetime value using prepared statements)
*/
@@ -16945,9 +16890,6 @@ static struct my_tests_st my_tests[]= {
{ "test_bug32265", test_bug32265 },
{ "test_bug38486", test_bug38486 },
{ "test_bug40365", test_bug40365 },
-#ifdef HAVE_SPATIAL
- { "test_bug37956", test_bug37956 },
-#endif
#ifdef HAVE_QUERY_CACHE
{ "test_bug36326", test_bug36326 },
#endif